From 931bdceb4916f1c1942bc225be04a68fb4c81036 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 12 Jan 2016 03:08:11 +0100 Subject: Letting the user override the code generation a bit. Example of use: protoc --grpc_out=use_system_headers=false,grpc_search_path=a/b/c/d:path/to/output/... --- src/compiler/cpp_generator.cc | 95 +++++++++++++++++++++++++++---------------- src/compiler/cpp_generator.h | 4 ++ src/compiler/cpp_plugin.cc | 12 ++++++ 3 files changed, 76 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 3c8ca8ab45..fb52b58047 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -111,37 +111,52 @@ grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file, grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file, const Parameters ¶ms) { - grpc::string temp = - "#include \n" - "#include \n" - "#include \n" - "#include \n" - "#include \n" - "#include \n" - "#include \n" - "#include \n" - "\n" - "namespace grpc {\n" - "class CompletionQueue;\n" - "class Channel;\n" - "class RpcService;\n" - "class ServerCompletionQueue;\n" - "class ServerContext;\n" - "} // namespace grpc\n\n"; + grpc::string output; + { + // Scope the output stream so it closes and finalizes output to the string. + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map vars; - if (!file->package().empty()) { - std::vector parts = - grpc_generator::tokenize(file->package(), "."); + vars["l"] = params.use_system_headers ? '<' : '"'; + vars["r"] = params.use_system_headers ? '>' : '"'; - for (auto part = parts.begin(); part != parts.end(); part++) { - temp.append("namespace "); - temp.append(*part); - temp.append(" {\n"); + if (!params.grpc_search_path.empty()) { + vars["l"] += params.grpc_search_path; + if (params.grpc_search_path.back() != '/') { + vars["l"] += '/'; + } } - temp.append("\n"); - } - return temp; + printer.Print(vars, "#include $l$grpc++/support/async_stream.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/impl/rpc_method.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/impl/proto_utils.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/impl/service_type.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/support/async_unary_call.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/support/status.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/support/stub_options.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/support/sync_stream.h$r$\n"); + printer.Print(vars, "\n"); + printer.Print(vars, "namespace grpc {\n"); + printer.Print(vars, "class CompletionQueue;\n"); + printer.Print(vars, "class Channel;\n"); + printer.Print(vars, "class RpcService;\n"); + printer.Print(vars, "class ServerCompletionQueue;\n"); + printer.Print(vars, "class ServerContext;\n"); + printer.Print(vars, "} // namespace grpc\n\n"); + + if (!file->package().empty()) { + std::vector parts = + grpc_generator::tokenize(file->package(), "."); + + for (auto part = parts.begin(); part != parts.end(); part++) { + vars["part"] = *part; + printer.Print(vars, "namespace $part$ {\n"); + } + printer.Print(vars, "\n"); + } + } + return output; } void PrintHeaderClientMethodInterfaces( @@ -694,7 +709,7 @@ grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file, } grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file, - const Parameters ¶m) { + const Parameters ¶ms) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -702,13 +717,23 @@ grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file, grpc::protobuf::io::Printer printer(&output_stream, '$'); std::map vars; - printer.Print(vars, "#include \n"); - printer.Print(vars, "#include \n"); - printer.Print(vars, "#include \n"); - printer.Print(vars, "#include \n"); - printer.Print(vars, "#include \n"); - printer.Print(vars, "#include \n"); - printer.Print(vars, "#include \n"); + vars["l"] = params.use_system_headers ? '<' : '"'; + vars["r"] = params.use_system_headers ? '>' : '"'; + + if (!params.grpc_search_path.empty()) { + vars["l"] += params.grpc_search_path; + if (params.grpc_search_path.back() != '/') { + vars["l"] += '/'; + } + } + + printer.Print(vars, "#include $l$grpc++/channel.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/impl/client_unary_call.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/impl/rpc_service_method.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/impl/service_type.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/support/async_unary_call.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/support/async_stream.h$r$\n"); + printer.Print(vars, "#include $l$grpc++/support/sync_stream.h$r$\n"); if (!file->package().empty()) { std::vector parts = diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h index 70c2e985f6..03621c8794 100644 --- a/src/compiler/cpp_generator.h +++ b/src/compiler/cpp_generator.h @@ -42,6 +42,10 @@ namespace grpc_cpp_generator { struct Parameters { // Puts the service into a namespace grpc::string services_namespace; + // Use system includes (<>) or local includes ("") + bool use_system_headers; + // Prefix to any grpc include + grpc::string grpc_search_path; }; // Return the prologue of the generated header file. diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc index 88c704948e..92a9ba7549 100644 --- a/src/compiler/cpp_plugin.cc +++ b/src/compiler/cpp_plugin.cc @@ -59,6 +59,7 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { } grpc_cpp_generator::Parameters generator_parameters; + generator_parameters.use_system_headers = true; if (!parameter.empty()) { std::vector parameters_list = @@ -70,6 +71,17 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { grpc_generator::tokenize(*parameter_string, "="); if (param[0] == "services_namespace") { generator_parameters.services_namespace = param[1]; + } else if (param[0] == "use_system_headers") { + if (param[1] == "true") { + generator_parameters.use_system_headers = true; + } else if (param[1] == "false") { + generator_parameters.use_system_headers = false; + } else { + *error = grpc::string("Invalid parameter: ") + *parameter_string; + return false; + } + } else if (param[0] == "grpc_search_path") { + generator_parameters.grpc_search_path = param[1]; } else { *error = grpc::string("Unknown parameter: ") + *parameter_string; return false; -- cgit v1.2.3 From 9474c4afdf80b64650723fba1a1184c3ee386874 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 25 Feb 2016 07:02:39 -0800 Subject: Give more details why we fail --- src/core/iomgr/wakeup_fd_pipe.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/core/iomgr/wakeup_fd_pipe.c b/src/core/iomgr/wakeup_fd_pipe.c index 80de181d9d..40c27aca12 100644 --- a/src/core/iomgr/wakeup_fd_pipe.c +++ b/src/core/iomgr/wakeup_fd_pipe.c @@ -47,6 +47,11 @@ static void pipe_init(grpc_wakeup_fd* fd_info) { int pipefd[2]; /* TODO(klempner): Make this nonfatal */ + int r = pipe(pipefd); + if (0 != r) { + gpr_log(GPR_ERROR, "pipe creation failed (%d): %s", errno, strerror(errno)); + abort(); + } GPR_ASSERT(0 == pipe(pipefd)); GPR_ASSERT(grpc_set_socket_nonblocking(pipefd[0], 1)); GPR_ASSERT(grpc_set_socket_nonblocking(pipefd[1], 1)); -- cgit v1.2.3 From 8b280763f99c860aada004d1eb029d661773c4fd Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 29 Feb 2016 16:34:41 -0800 Subject: Add error output for failed ruby credentials plugin --- src/ruby/ext/grpc/rb_call_credentials.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ruby/ext/grpc/rb_call_credentials.c b/src/ruby/ext/grpc/rb_call_credentials.c index 2426f106a9..a32117b3cf 100644 --- a/src/ruby/ext/grpc/rb_call_credentials.c +++ b/src/ruby/ext/grpc/rb_call_credentials.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "rb_call.h" #include "rb_event_thread.h" @@ -81,14 +82,23 @@ static VALUE grpc_rb_call_credentials_callback(VALUE callback_args) { static VALUE grpc_rb_call_credentials_callback_rescue(VALUE args, VALUE exception_object) { VALUE result = rb_hash_new(); + VALUE backtrace = rb_funcall( + rb_ivar_get(exception_object, rb_intern("backtrace")), + rb_intern("join"), + 1, rb_str_new2("\n\tfrom ")); + VALUE exception_info = rb_funcall(exception_object, rb_intern("to_s"), 0); + const char *exception_classname = rb_obj_classname(exception_object); (void)args; + gpr_log(GPR_INFO, "Call credentials callback failed: %s %s\n%s", + exception_classname, StringValueCStr(exception_info), + StringValueCStr(backtrace)); rb_hash_aset(result, rb_str_new2("metadata"), Qnil); /* Currently only gives the exception class name. It should be possible get more details */ rb_hash_aset(result, rb_str_new2("status"), INT2NUM(GRPC_STATUS_PERMISSION_DENIED)); rb_hash_aset(result, rb_str_new2("details"), - rb_str_new2(rb_obj_classname(exception_object))); + rb_str_new2(exception_classname)); return result; } -- cgit v1.2.3 From 011641bb13db752413b8cc188e2200a60943ea80 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 29 Feb 2016 17:36:10 -0800 Subject: Minor fix to backtrace retreival code --- src/ruby/ext/grpc/rb_call_credentials.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ruby/ext/grpc/rb_call_credentials.c b/src/ruby/ext/grpc/rb_call_credentials.c index a32117b3cf..c7697f4628 100644 --- a/src/ruby/ext/grpc/rb_call_credentials.c +++ b/src/ruby/ext/grpc/rb_call_credentials.c @@ -83,13 +83,13 @@ static VALUE grpc_rb_call_credentials_callback_rescue(VALUE args, VALUE exception_object) { VALUE result = rb_hash_new(); VALUE backtrace = rb_funcall( - rb_ivar_get(exception_object, rb_intern("backtrace")), + rb_funcall(exception_object, rb_intern("backtrace"), 0), rb_intern("join"), 1, rb_str_new2("\n\tfrom ")); VALUE exception_info = rb_funcall(exception_object, rb_intern("to_s"), 0); const char *exception_classname = rb_obj_classname(exception_object); (void)args; - gpr_log(GPR_INFO, "Call credentials callback failed: %s %s\n%s", + gpr_log(GPR_INFO, "Call credentials callback failed: %s: %s\n%s", exception_classname, StringValueCStr(exception_info), StringValueCStr(backtrace)); rb_hash_aset(result, rb_str_new2("metadata"), Qnil); -- cgit v1.2.3 From 749f10b65d3ce9ed3155292befacda4316950c57 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 7 Mar 2016 20:11:46 -0800 Subject: Fix copyright --- src/core/iomgr/wakeup_fd_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/iomgr/wakeup_fd_pipe.c b/src/core/iomgr/wakeup_fd_pipe.c index 40c27aca12..d1ed505875 100644 --- a/src/core/iomgr/wakeup_fd_pipe.c +++ b/src/core/iomgr/wakeup_fd_pipe.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.3 From 476bb3b8d5b3a9d132ac2db6438e778167f2a51a Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 11 Mar 2016 12:54:40 -0800 Subject: Integrate backoff library with dns retries --- src/core/client_config/resolvers/dns_resolver.c | 27 +++++++++++++++++-------- src/core/support/backoff.c | 5 +++++ src/core/support/backoff.h | 3 +++ 3 files changed, 27 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/core/client_config/resolvers/dns_resolver.c b/src/core/client_config/resolvers/dns_resolver.c index e28e4757a1..2b2ee97e12 100644 --- a/src/core/client_config/resolvers/dns_resolver.c +++ b/src/core/client_config/resolvers/dns_resolver.c @@ -42,8 +42,14 @@ #include "src/core/client_config/lb_policy_registry.h" #include "src/core/iomgr/resolve_address.h" #include "src/core/iomgr/timer.h" +#include "src/core/support/backoff.h" #include "src/core/support/string.h" +#define BACKOFF_MULTIPLIER 1.6 +#define BACKOFF_JITTER 0.2 +#define BACKOFF_MIN_SECONDS 1 +#define BACKOFF_MAX_SECONDS 120 + typedef struct { /** base class: must be first */ grpc_resolver base; @@ -75,6 +81,8 @@ typedef struct { /** retry timer */ bool have_retry_timer; grpc_timer retry_timer; + /** retry backoff state */ + gpr_backoff backoff_state; } dns_resolver; static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r); @@ -111,6 +119,7 @@ static void dns_channel_saw_error(grpc_exec_ctx *exec_ctx, dns_resolver *r = (dns_resolver *)resolver; gpr_mu_lock(&r->mu); if (!r->resolving) { + gpr_backoff_reset(&r->backoff_state); dns_start_resolving_locked(r); } gpr_mu_unlock(&r->mu); @@ -125,6 +134,7 @@ static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, r->next_completion = on_complete; r->target_config = target_config; if (r->resolved_version == 0 && !r->resolving) { + gpr_backoff_reset(&r->backoff_state); dns_start_resolving_locked(r); } else { dns_maybe_finish_next_locked(exec_ctx, r); @@ -185,17 +195,16 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg, grpc_resolved_addresses_destroy(addresses); gpr_free(subchannels); } else { - int retry_seconds = 15; - gpr_log(GPR_DEBUG, "dns resolution failed: retrying in %d seconds", - retry_seconds); + gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); + gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now); + gpr_timespec timeout = gpr_time_sub(next_try, now); + gpr_log(GPR_DEBUG, "dns resolution failed: retrying in %d.%09d seconds", + timeout.tv_sec, timeout.tv_nsec); GPR_ASSERT(!r->have_retry_timer); r->have_retry_timer = true; - gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); GRPC_RESOLVER_REF(&r->base, "retry-timer"); - grpc_timer_init( - exec_ctx, &r->retry_timer, - gpr_time_add(now, gpr_time_from_seconds(retry_seconds, GPR_TIMESPAN)), - dns_on_retry_timer, r, now); + grpc_timer_init(exec_ctx, &r->retry_timer, next_try, dns_on_retry_timer, r, + now); } if (r->resolved_config) { grpc_client_config_unref(exec_ctx, r->resolved_config); @@ -263,6 +272,8 @@ static grpc_resolver *dns_create(grpc_resolver_args *args, r->name = gpr_strdup(path); r->default_port = gpr_strdup(default_port); r->subchannel_factory = args->subchannel_factory; + gpr_backoff_init(&r->backoff_state, BACKOFF_MULTIPLIER, BACKOFF_JITTER, + BACKOFF_MIN_SECONDS * 1000, BACKOFF_MAX_SECONDS * 1000); grpc_subchannel_factory_ref(r->subchannel_factory); r->lb_policy_name = gpr_strdup(lb_policy_name); return &r->base; diff --git a/src/core/support/backoff.c b/src/core/support/backoff.c index 7458219645..4ccfb774ed 100644 --- a/src/core/support/backoff.c +++ b/src/core/support/backoff.c @@ -69,3 +69,8 @@ gpr_timespec gpr_backoff_step(gpr_backoff *backoff, gpr_timespec now) { return gpr_time_add( now, gpr_time_from_millis(backoff->current_timeout_millis, GPR_TIMESPAN)); } + +void gpr_backoff_reset(gpr_backoff *backoff) { + // forces step() to return a timeout of min_timeout_millis + backoff->current_timeout_millis = 0; +} diff --git a/src/core/support/backoff.h b/src/core/support/backoff.h index 3234aa214d..232a28d48c 100644 --- a/src/core/support/backoff.h +++ b/src/core/support/backoff.h @@ -61,5 +61,8 @@ void gpr_backoff_init(gpr_backoff *backoff, double multiplier, double jitter, gpr_timespec gpr_backoff_begin(gpr_backoff *backoff, gpr_timespec now); /// Step a retry loop: returns a timespec for the NEXT retry gpr_timespec gpr_backoff_step(gpr_backoff *backoff, gpr_timespec now); +/// Reset the backoff, so the next gpr_backoff_step will be a gpr_backoff_begin +/// instead +void gpr_backoff_reset(gpr_backoff *backoff); #endif // GRPC_INTERNAL_CORE_SUPPORT_BACKOFF_H -- cgit v1.2.3 From 93019f733f62fc9e0ac16770adfd1a76f27cd870 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 14 Mar 2016 11:53:42 -0700 Subject: Properly mark proc used in call credentials for garbage collection --- src/ruby/ext/grpc/rb_call_credentials.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ruby/ext/grpc/rb_call_credentials.c b/src/ruby/ext/grpc/rb_call_credentials.c index 2426f106a9..402becf6aa 100644 --- a/src/ruby/ext/grpc/rb_call_credentials.c +++ b/src/ruby/ext/grpc/rb_call_credentials.c @@ -57,6 +57,10 @@ typedef struct grpc_rb_call_credentials { /* Holder of ruby objects involved in contructing the credentials */ VALUE mark; + /* The proc called when getting the credentials. Same pointer as + wrapped->state */ + VALUE proc; + /* The actual credentials */ grpc_call_credentials *wrapped; } grpc_rb_call_credentials; @@ -164,11 +168,11 @@ static void grpc_rb_call_credentials_mark(void *p) { return; } wrapper = (grpc_rb_call_credentials *)p; - /* If it's not already cleaned up, mark the mark object */ if (wrapper->mark != Qnil) { rb_gc_mark(wrapper->mark); } + rb_gc_mark(wrapper->proc); } static rb_data_type_t grpc_rb_call_credentials_data_type = { @@ -187,6 +191,7 @@ static rb_data_type_t grpc_rb_call_credentials_data_type = { static VALUE grpc_rb_call_credentials_alloc(VALUE cls) { grpc_rb_call_credentials *wrapper = ALLOC(grpc_rb_call_credentials); wrapper->wrapped = NULL; + wrapper->proc = Qnil; wrapper->mark = Qnil; return TypedData_Wrap_Struct(cls, &grpc_rb_call_credentials_data_type, wrapper); } @@ -267,6 +272,7 @@ static VALUE grpc_rb_call_credentials_init(VALUE self, VALUE proc) { return Qnil; } + wrapper->proc = proc; wrapper->wrapped = creds; rb_ivar_set(self, id_callback, proc); -- cgit v1.2.3 From 096386f3c8bfcf8fc4d5e6328a4405484c3b7bff Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 14 Mar 2016 13:01:00 -0700 Subject: Add GC marking for composite credentials --- src/ruby/ext/grpc/rb_call_credentials.c | 32 +++++++++++------------------- src/ruby/ext/grpc/rb_channel_credentials.c | 23 ++++++++++----------- 2 files changed, 23 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/ruby/ext/grpc/rb_call_credentials.c b/src/ruby/ext/grpc/rb_call_credentials.c index 402becf6aa..7c4b69f7f0 100644 --- a/src/ruby/ext/grpc/rb_call_credentials.c +++ b/src/ruby/ext/grpc/rb_call_credentials.c @@ -50,17 +50,13 @@ * grpc_call_credentials */ static VALUE grpc_rb_cCallCredentials = Qnil; -/* grpc_rb_call_credentials wraps a grpc_call_credentials. It provides a peer - * ruby object, 'mark' to minimize copying when a credential is created from - * ruby. */ +/* grpc_rb_call_credentials wraps a grpc_call_credentials. It provides a mark + * object that is used to hold references to any objects used to create the + * credentials. */ typedef struct grpc_rb_call_credentials { /* Holder of ruby objects involved in contructing the credentials */ VALUE mark; - /* The proc called when getting the credentials. Same pointer as - wrapped->state */ - VALUE proc; - /* The actual credentials */ grpc_call_credentials *wrapped; } grpc_rb_call_credentials; @@ -150,13 +146,8 @@ static void grpc_rb_call_credentials_free(void *p) { return; } wrapper = (grpc_rb_call_credentials *)p; - - /* Delete the wrapped object if the mark object is Qnil, which indicates that - * no other object is the actual owner. */ - if (wrapper->wrapped != NULL && wrapper->mark == Qnil) { - grpc_call_credentials_release(wrapper->wrapped); - wrapper->wrapped = NULL; - } + grpc_call_credentials_release(wrapper->wrapped); + wrapper->wrapped = NULL; xfree(p); } @@ -168,11 +159,9 @@ static void grpc_rb_call_credentials_mark(void *p) { return; } wrapper = (grpc_rb_call_credentials *)p; - /* If it's not already cleaned up, mark the mark object */ if (wrapper->mark != Qnil) { rb_gc_mark(wrapper->mark); } - rb_gc_mark(wrapper->proc); } static rb_data_type_t grpc_rb_call_credentials_data_type = { @@ -191,7 +180,6 @@ static rb_data_type_t grpc_rb_call_credentials_data_type = { static VALUE grpc_rb_call_credentials_alloc(VALUE cls) { grpc_rb_call_credentials *wrapper = ALLOC(grpc_rb_call_credentials); wrapper->wrapped = NULL; - wrapper->proc = Qnil; wrapper->mark = Qnil; return TypedData_Wrap_Struct(cls, &grpc_rb_call_credentials_data_type, wrapper); } @@ -199,7 +187,7 @@ static VALUE grpc_rb_call_credentials_alloc(VALUE cls) { /* Creates a wrapping object for a given call credentials. This should only be * called with grpc_call_credentials objects that are not already associated * with any Ruby object */ -VALUE grpc_rb_wrap_call_credentials(grpc_call_credentials *c) { +VALUE grpc_rb_wrap_call_credentials(grpc_call_credentials *c, VALUE mark) { VALUE rb_wrapper; grpc_rb_call_credentials *wrapper; if (c == NULL) { @@ -209,6 +197,7 @@ VALUE grpc_rb_wrap_call_credentials(grpc_call_credentials *c) { TypedData_Get_Struct(rb_wrapper, grpc_rb_call_credentials, &grpc_rb_call_credentials_data_type, wrapper); wrapper->wrapped = c; + wrapper->mark = mark; return rb_wrapper; } @@ -272,7 +261,7 @@ static VALUE grpc_rb_call_credentials_init(VALUE self, VALUE proc) { return Qnil; } - wrapper->proc = proc; + wrapper->mark = proc; wrapper->wrapped = creds; rb_ivar_set(self, id_callback, proc); @@ -283,15 +272,18 @@ static VALUE grpc_rb_call_credentials_compose(int argc, VALUE *argv, VALUE self) { grpc_call_credentials *creds; grpc_call_credentials *other; + VALUE mark; if (argc == 0) { return self; } + mark = rb_ary_new(); creds = grpc_rb_get_wrapped_call_credentials(self); for (int i = 0; i < argc; i++) { + rb_ary_push(mark, argv[i]); other = grpc_rb_get_wrapped_call_credentials(argv[i]); creds = grpc_composite_call_credentials_create(creds, other, NULL); } - return grpc_rb_wrap_call_credentials(creds); + return grpc_rb_wrap_call_credentials(creds, mark); } void Init_grpc_call_credentials() { diff --git a/src/ruby/ext/grpc/rb_channel_credentials.c b/src/ruby/ext/grpc/rb_channel_credentials.c index 8c6fc3b7eb..f649084311 100644 --- a/src/ruby/ext/grpc/rb_channel_credentials.c +++ b/src/ruby/ext/grpc/rb_channel_credentials.c @@ -49,8 +49,8 @@ static VALUE grpc_rb_cChannelCredentials = Qnil; /* grpc_rb_channel_credentials wraps a grpc_channel_credentials. It provides a - * peer ruby object, 'mark' to minimize copying when a credential is - * created from ruby. */ + * mark object that is used to hold references to any objects used to create + * the credentials. */ typedef struct grpc_rb_channel_credentials { /* Holder of ruby objects involved in constructing the credentials */ VALUE mark; @@ -66,13 +66,8 @@ static void grpc_rb_channel_credentials_free(void *p) { return; }; wrapper = (grpc_rb_channel_credentials *)p; - - /* Delete the wrapped object if the mark object is Qnil, which indicates that - * no other object is the actual owner. */ - if (wrapper->wrapped != NULL && wrapper->mark == Qnil) { - grpc_channel_credentials_release(wrapper->wrapped); - wrapper->wrapped = NULL; - } + grpc_channel_credentials_release(wrapper->wrapped); + wrapper->wrapped = NULL; xfree(p); } @@ -85,7 +80,6 @@ static void grpc_rb_channel_credentials_mark(void *p) { } wrapper = (grpc_rb_channel_credentials *)p; - /* If it's not already cleaned up, mark the mark object */ if (wrapper->mark != Qnil) { rb_gc_mark(wrapper->mark); } @@ -114,7 +108,7 @@ static VALUE grpc_rb_channel_credentials_alloc(VALUE cls) { /* Creates a wrapping object for a given channel credentials. This should only * be called with grpc_channel_credentials objects that are not already * associated with any Ruby object. */ -VALUE grpc_rb_wrap_channel_credentials(grpc_channel_credentials *c) { +VALUE grpc_rb_wrap_channel_credentials(grpc_channel_credentials *c, VALUE mark) { VALUE rb_wrapper; grpc_rb_channel_credentials *wrapper; if (c == NULL) { @@ -124,6 +118,7 @@ VALUE grpc_rb_wrap_channel_credentials(grpc_channel_credentials *c) { TypedData_Get_Struct(rb_wrapper, grpc_rb_channel_credentials, &grpc_rb_channel_credentials_data_type, wrapper); wrapper->wrapped = c; + wrapper->mark = mark; return rb_wrapper; } @@ -222,11 +217,15 @@ static VALUE grpc_rb_channel_credentials_compose(int argc, VALUE *argv, VALUE self) { grpc_channel_credentials *creds; grpc_call_credentials *other; + VALUE mark; if (argc == 0) { return self; } + mark = rb_ary_new(); + rb_ary_push(mark, self); creds = grpc_rb_get_wrapped_channel_credentials(self); for (int i = 0; i < argc; i++) { + rb_ary_push(mark, argv[i]); other = grpc_rb_get_wrapped_call_credentials(argv[i]); creds = grpc_composite_channel_credentials_create(creds, other, NULL); if (creds == NULL) { @@ -234,7 +233,7 @@ static VALUE grpc_rb_channel_credentials_compose(int argc, VALUE *argv, "Failed to compose channel and call credentials"); } } - return grpc_rb_wrap_channel_credentials(creds); + return grpc_rb_wrap_channel_credentials(creds, mark); } void Init_grpc_channel_credentials() { -- cgit v1.2.3 From a00d7c0b3520a28ffc6397d62a7fdca0f64253a4 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 14 Mar 2016 15:51:56 -0700 Subject: Make channels and calls properly mark references to their credentials --- src/ruby/ext/grpc/rb_call.c | 6 ++++++ src/ruby/ext/grpc/rb_channel.c | 22 ++++++++-------------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c index af05ddf6e7..cd0aa6aaf2 100644 --- a/src/ruby/ext/grpc/rb_call.c +++ b/src/ruby/ext/grpc/rb_call.c @@ -72,6 +72,10 @@ static ID id_cq; * the flags used to create metadata from a Hash */ static ID id_flags; +/* id_credentials is the name of the hidden ivar that preserves the value + * of the credentials added to the call */ +static ID id_credentials; + /* id_input_md is the name of the hidden ivar that preserves the hash used to * create metadata, so that references to the strings it contains last as long * as the call the metadata is added to. */ @@ -299,6 +303,7 @@ static VALUE grpc_rb_call_set_credentials(VALUE self, VALUE credentials) { "grpc_call_set_credentials failed with %s (code=%d)", grpc_call_error_detail_of(err), err); } + rb_ivar_set(self, id_credentials, credentials); return Qnil; } @@ -859,6 +864,7 @@ void Init_grpc_call() { id_cq = rb_intern("__cq"); id_flags = rb_intern("__flags"); id_input_md = rb_intern("__input_md"); + id_credentials = rb_intern("__credentials"); /* Ids used in constructing the batch result. */ sym_send_message = ID2SYM(rb_intern("send_message")); diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index 0e6badbdaf..e1aaa539db 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -70,11 +70,10 @@ static VALUE grpc_rb_cChannel = Qnil; /* Used during the conversion of a hash to channel args during channel setup */ static VALUE grpc_rb_cChannelArgs; -/* grpc_rb_channel wraps a grpc_channel. It provides a peer ruby object, - * 'mark' to minimize copying when a channel is created from ruby. */ +/* grpc_rb_channel wraps a grpc_channel. */ typedef struct grpc_rb_channel { - /* Holder of ruby objects involved in constructing the channel */ - VALUE mark; + VALUE credentials; + /* The actual channel */ grpc_channel *wrapped; } grpc_rb_channel; @@ -87,13 +86,8 @@ static void grpc_rb_channel_free(void *p) { }; ch = (grpc_rb_channel *)p; - /* Deletes the wrapped object if the mark object is Qnil, which indicates - * that no other object is the actual owner. */ - if (ch->wrapped != NULL && ch->mark == Qnil) { + if (ch->wrapped != NULL) { grpc_channel_destroy(ch->wrapped); - rb_warning("channel gc: destroyed the c channel"); - } else { - rb_warning("channel gc: did not destroy the c channel"); } xfree(p); @@ -106,8 +100,8 @@ static void grpc_rb_channel_mark(void *p) { return; } channel = (grpc_rb_channel *)p; - if (channel->mark != Qnil) { - rb_gc_mark(channel->mark); + if (channel->credentials != Qnil) { + rb_gc_mark(channel->credentials); } } @@ -125,7 +119,7 @@ static rb_data_type_t grpc_channel_data_type = { static VALUE grpc_rb_channel_alloc(VALUE cls) { grpc_rb_channel *wrapper = ALLOC(grpc_rb_channel); wrapper->wrapped = NULL; - wrapper->mark = Qnil; + wrapper->credentials = Qnil; return TypedData_Wrap_Struct(cls, &grpc_channel_data_type, wrapper); } @@ -162,6 +156,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) { } ch = grpc_insecure_channel_create(target_chars, &args, NULL); } else { + wrapper->credentials = credentials; creds = grpc_rb_get_wrapped_channel_credentials(credentials); ch = grpc_secure_channel_create(creds, target_chars, &args, NULL); } @@ -330,7 +325,6 @@ static VALUE grpc_rb_channel_destroy(VALUE self) { if (ch != NULL) { grpc_channel_destroy(ch); wrapper->wrapped = NULL; - wrapper->mark = Qnil; } return Qnil; -- cgit v1.2.3 From 803931d2303778eeda1126d0890a27a4c0274440 Mon Sep 17 00:00:00 2001 From: ahedberg Date: Fri, 11 Mar 2016 17:24:12 -0500 Subject: Make use of unix sockets optional. --- include/grpc/impl/codegen/port_platform.h | 4 ++++ .../client_config/resolvers/sockaddr_resolver.c | 4 ++-- src/core/iomgr/endpoint_pair_posix.c | 2 ++ src/core/iomgr/resolve_address_posix.c | 5 +++++ src/core/iomgr/sockaddr_utils.c | 6 ++++-- src/core/iomgr/tcp_client_posix.c | 10 ++++++++++ src/core/iomgr/tcp_server_posix.c | 21 +++++++++++++++++++++ src/core/iomgr/udp_server.c | 10 ++++++++++ 8 files changed, 58 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 92569043fc..43716a74dd 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -133,6 +133,7 @@ #define GPR_POSIX_TIME 1 #define GPR_GETPID_IN_UNISTD_H 1 #define GPR_HAVE_MSG_NOSIGNAL 1 +#define GPR_HAVE_UNIX_SOCKET 1 #elif defined(__linux__) #define GPR_POSIX_CRASH_HANDLER 1 #define GPR_PLATFORM_STRING "linux" @@ -154,6 +155,7 @@ #define GPR_POSIX_WAKEUP_FD 1 #define GPR_POSIX_SOCKET 1 #define GPR_POSIX_SOCKETADDR 1 +#define GPR_HAVE_UNIX_SOCKET 1 #ifdef __GLIBC_PREREQ #if __GLIBC_PREREQ(2, 9) #define GPR_LINUX_EVENTFD 1 @@ -214,6 +216,7 @@ #define GPR_POSIX_TIME 1 #define GPR_GETPID_IN_UNISTD_H 1 #define GPR_HAVE_SO_NOSIGPIPE 1 +#define GPR_HAVE_UNIX_SOCKET 1 #ifdef _LP64 #define GPR_ARCH_64 1 #else /* _LP64 */ @@ -242,6 +245,7 @@ #define GPR_POSIX_TIME 1 #define GPR_GETPID_IN_UNISTD_H 1 #define GPR_HAVE_SO_NOSIGPIPE 1 +#define GPR_HAVE_UNIX_SOCKET 1 #ifdef _LP64 #define GPR_ARCH_64 1 #else /* _LP64 */ diff --git a/src/core/client_config/resolvers/sockaddr_resolver.c b/src/core/client_config/resolvers/sockaddr_resolver.c index 68910ad975..418413315f 100644 --- a/src/core/client_config/resolvers/sockaddr_resolver.c +++ b/src/core/client_config/resolvers/sockaddr_resolver.c @@ -37,7 +37,7 @@ #include #include -#ifdef GPR_POSIX_SOCKET +#ifdef GPR_HAVE_UNIX_SOCKET #include #endif @@ -168,7 +168,7 @@ static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) { gpr_free(r); } -#ifdef GPR_POSIX_SOCKET +#ifdef GPR_HAVE_UNIX_SOCKET static int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { struct sockaddr_un *un = (struct sockaddr_un *)addr; diff --git a/src/core/iomgr/endpoint_pair_posix.c b/src/core/iomgr/endpoint_pair_posix.c index 56f6f146fd..d3a45f83e0 100644 --- a/src/core/iomgr/endpoint_pair_posix.c +++ b/src/core/iomgr/endpoint_pair_posix.c @@ -52,7 +52,9 @@ static void create_sockets(int sv[2]) { int flags; +#ifdef GPR_HAVE_UNIX_SOCKET GPR_ASSERT(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); +#endif flags = fcntl(sv[0], F_GETFL, 0); GPR_ASSERT(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK) == 0); flags = fcntl(sv[1], F_GETFL, 0); diff --git a/src/core/iomgr/resolve_address_posix.c b/src/core/iomgr/resolve_address_posix.c index a6c9893f23..16bdb20c82 100644 --- a/src/core/iomgr/resolve_address_posix.c +++ b/src/core/iomgr/resolve_address_posix.c @@ -39,7 +39,10 @@ #include #include +#ifdef GPR_HAVE_UNIX_SOCKET #include +#endif +#include #include #include @@ -71,6 +74,7 @@ static grpc_resolved_addresses *blocking_resolve_address_impl( int s; size_t i; grpc_resolved_addresses *addrs = NULL; +#ifdef GPR_HAVE_UNIX_SOCKET struct sockaddr_un *un; if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' && @@ -84,6 +88,7 @@ static grpc_resolved_addresses *blocking_resolve_address_impl( addrs->addrs->len = strlen(un->sun_path) + sizeof(un->sun_family) + 1; return addrs; } +#endif /* parse name, splitting it into host and port parts */ gpr_split_host_port(name, &host, &port); diff --git a/src/core/iomgr/sockaddr_utils.c b/src/core/iomgr/sockaddr_utils.c index 61006d7a7a..3d464a228f 100644 --- a/src/core/iomgr/sockaddr_utils.c +++ b/src/core/iomgr/sockaddr_utils.c @@ -36,7 +36,7 @@ #include #include -#ifdef GPR_POSIX_SOCKET +#ifdef GPR_HAVE_UNIX_SOCKET #include #endif @@ -191,7 +191,7 @@ char *grpc_sockaddr_to_uri(const struct sockaddr *addr) { gpr_asprintf(&result, "ipv6:%s", temp); gpr_free(temp); return result; -#ifdef GPR_POSIX_SOCKET +#ifdef GPR_HAVE_UNIX_SOCKET case AF_UNIX: gpr_asprintf(&result, "unix:%s", ((struct sockaddr_un *)addr)->sun_path); return result; @@ -207,8 +207,10 @@ int grpc_sockaddr_get_port(const struct sockaddr *addr) { return ntohs(((struct sockaddr_in *)addr)->sin_port); case AF_INET6: return ntohs(((struct sockaddr_in6 *)addr)->sin6_port); +#ifdef GPR_HAVE_UNIX_SOCKET case AF_UNIX: return 1; +#endif default: gpr_log(GPR_ERROR, "Unknown socket family %d in grpc_sockaddr_get_port", addr->sa_family); diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c index 15727856ab..b04e1dbb68 100644 --- a/src/core/iomgr/tcp_client_posix.c +++ b/src/core/iomgr/tcp_client_posix.c @@ -76,6 +76,7 @@ static int prepare_socket(const struct sockaddr *addr, int fd) { goto error; } +#ifdef GPR_HAVE_UNIX_SOCKET if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || (addr->sa_family != AF_UNIX && !grpc_set_socket_low_latency(fd, 1)) || !grpc_set_socket_no_sigpipe_if_possible(fd)) { @@ -83,6 +84,15 @@ static int prepare_socket(const struct sockaddr *addr, int fd) { strerror(errno)); goto error; } +#else + if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || + !grpc_set_socket_low_latency(fd, 1) || + !grpc_set_socket_no_sigpipe_if_possible(fd)) { + gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, + strerror(errno)); + goto error; + } +#endif return 1; diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c index 5e07f8261c..f47a00c118 100644 --- a/src/core/iomgr/tcp_server_posix.c +++ b/src/core/iomgr/tcp_server_posix.c @@ -52,7 +52,9 @@ #include #include #include +#ifdef GPR_HAVE_UNIX_SOCKET #include +#endif #include #include "src/core/iomgr/pollset_posix.h" @@ -81,7 +83,9 @@ struct grpc_tcp_listener { union { uint8_t untyped[GRPC_MAX_SOCKADDR_SIZE]; struct sockaddr sockaddr; +#ifdef GPR_HAVE_UNIX_SOCKET struct sockaddr_un un; +#endif } addr; size_t addr_len; int port; @@ -98,6 +102,7 @@ struct grpc_tcp_listener { int is_sibling; }; +#ifdef GPR_HAVE_UNIX_SOCKET static void unlink_if_unix_domain_socket(const struct sockaddr_un *un) { struct stat st; @@ -105,6 +110,7 @@ static void unlink_if_unix_domain_socket(const struct sockaddr_un *un) { unlink(un->sun_path); } } +#endif /* the overall server */ struct grpc_tcp_server { @@ -203,9 +209,11 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { if (s->head) { grpc_tcp_listener *sp; for (sp = s->head; sp; sp = sp->next) { +#ifdef GPR_HAVE_UNIX_SOCKET if (sp->addr.sockaddr.sa_family == AF_UNIX) { unlink_if_unix_domain_socket(&sp->addr.un); } +#endif sp->destroyed_closure.cb = destroyed_port; sp->destroyed_closure.cb_arg = s; grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, @@ -280,6 +288,7 @@ static int prepare_socket(int fd, const struct sockaddr *addr, goto error; } +#ifdef GPR_HAVE_UNIX_SOCKET if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || (addr->sa_family != AF_UNIX && (!grpc_set_socket_low_latency(fd, 1) || !grpc_set_socket_reuse_addr(fd, 1))) || @@ -288,6 +297,16 @@ static int prepare_socket(int fd, const struct sockaddr *addr, strerror(errno)); goto error; } +#else + if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || + !grpc_set_socket_low_latency(fd, 1) || + !grpc_set_socket_reuse_addr(fd, 1) || + !grpc_set_socket_no_sigpipe_if_possible(fd)) { + gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, + strerror(errno)); + goto error; + } +#endif GPR_ASSERT(addr_len < ~(socklen_t)0); if (bind(fd, addr, (socklen_t)addr_len) < 0) { @@ -451,9 +470,11 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, if (s->tail != NULL) { port_index = s->tail->port_index + 1; } +#ifdef GPR_HAVE_UNIX_SOCKET if (((struct sockaddr *)addr)->sa_family == AF_UNIX) { unlink_if_unix_domain_socket(addr); } +#endif /* Check if this is a wildcard port, and if so, try to keep the port the same as some previously created listener. */ diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c index ef548cfe4d..df2f449a9a 100644 --- a/src/core/iomgr/udp_server.c +++ b/src/core/iomgr/udp_server.c @@ -52,7 +52,9 @@ #include #include #include +#ifdef GPR_HAVE_UNIX_SOCKET #include +#endif #include #include "src/core/iomgr/fd_posix.h" @@ -77,7 +79,9 @@ typedef struct { union { uint8_t untyped[GRPC_MAX_SOCKADDR_SIZE]; struct sockaddr sockaddr; +#ifdef GPR_HAVE_UNIX_SOCKET struct sockaddr_un un; +#endif } addr; size_t addr_len; grpc_closure read_closure; @@ -85,6 +89,7 @@ typedef struct { grpc_udp_server_read_cb read_cb; } server_port; +#ifdef GPR_HAVE_UNIX_SOCKET static void unlink_if_unix_domain_socket(const struct sockaddr_un *un) { struct stat st; @@ -92,6 +97,7 @@ static void unlink_if_unix_domain_socket(const struct sockaddr_un *un) { unlink(un->sun_path); } } +#endif /* the overall server */ struct grpc_udp_server { @@ -176,9 +182,11 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { if (s->nports) { for (i = 0; i < s->nports; i++) { server_port *sp = &s->ports[i]; +#ifdef GPR_HAVE_UNIX_SOCKET if (sp->addr.sockaddr.sa_family == AF_UNIX) { unlink_if_unix_domain_socket(&sp->addr.un); } +#endif sp->destroyed_closure.cb = destroyed_port; sp->destroyed_closure.cb_arg = s; grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, @@ -336,9 +344,11 @@ int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, socklen_t sockname_len; int port; +#ifdef GPR_HAVE_UNIX_SOCKET if (((struct sockaddr *)addr)->sa_family == AF_UNIX) { unlink_if_unix_domain_socket(addr); } +#endif /* Check if this is a wildcard port, and if so, try to keep the port the same as some previously created listener. */ -- cgit v1.2.3 From 24ebdfb3a5441d901f124df474131c6750ddd117 Mon Sep 17 00:00:00 2001 From: ahedberg Date: Tue, 15 Mar 2016 12:58:07 -0400 Subject: Remove duplicate include of string.h --- src/core/iomgr/resolve_address_posix.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/core/iomgr/resolve_address_posix.c b/src/core/iomgr/resolve_address_posix.c index 16bdb20c82..0360ab717c 100644 --- a/src/core/iomgr/resolve_address_posix.c +++ b/src/core/iomgr/resolve_address_posix.c @@ -42,7 +42,6 @@ #ifdef GPR_HAVE_UNIX_SOCKET #include #endif -#include #include #include -- cgit v1.2.3 From 734c8db5993ed8ab960760f00eeef0298c8315f4 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 16 Mar 2016 11:39:15 -0700 Subject: Node: made call credentials properly use UV async events. Also deleted some log lines --- src/node/ext/call_credentials.cc | 81 ++++++++++++++++++++++++++-------------- src/node/ext/call_credentials.h | 16 +++++--- src/node/ext/node_grpc.cc | 1 + src/node/src/credentials.js | 2 - 4 files changed, 64 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc index 98696db232..a2ac5c17b6 100644 --- a/src/node/ext/call_credentials.cc +++ b/src/node/ext/call_credentials.cc @@ -35,6 +35,8 @@ #include #include +#include + #include "grpc/grpc.h" #include "grpc/grpc_security.h" #include "grpc/support/log.h" @@ -161,6 +163,14 @@ NAN_METHOD(CallCredentials::CreateFromPlugin) { grpc_metadata_credentials_plugin plugin; plugin_state *state = new plugin_state; state->callback = new Nan::Callback(info[0].As()); + state->pending_callbacks = new std::list(); + uv_mutex_init(&state->plugin_mutex); + uv_async_init(uv_default_loop(), + &state->plugin_async, + SendPluginCallback); + + state->plugin_async.data = state; + plugin.get_metadata = plugin_get_metadata; plugin.destroy = plugin_destroy_state; plugin.state = reinterpret_cast(state); @@ -208,48 +218,61 @@ NAN_METHOD(PluginCallback) { NAUV_WORK_CB(SendPluginCallback) { Nan::HandleScope scope; - plugin_callback_data *data = reinterpret_cast( - async->data); - // Attach cb and user_data to plugin_callback so that it can access them later - v8::Local plugin_callback = Nan::GetFunction( - Nan::New(PluginCallback)).ToLocalChecked(); - Nan::Set(plugin_callback, Nan::New("cb").ToLocalChecked(), - Nan::New(reinterpret_cast(data->cb))); - Nan::Set(plugin_callback, Nan::New("user_data").ToLocalChecked(), - Nan::New(data->user_data)); - const int argc = 2; - v8::Local argv[argc] = { - Nan::New(data->service_url).ToLocalChecked(), - plugin_callback - }; - Nan::Callback *callback = data->state->callback; - callback->Call(argc, argv); - delete data; - uv_unref((uv_handle_t *)async); - uv_close((uv_handle_t *)async, (uv_close_cb)free); + plugin_state *state = reinterpret_cast(async->data); + std::list callbacks; + uv_mutex_lock(&state->plugin_mutex); + callbacks.splice(callbacks.begin(), *state->pending_callbacks); + uv_mutex_unlock(&state->plugin_mutex); + while (!callbacks.empty()) { + plugin_callback_data *data = callbacks.front(); + callbacks.pop_front(); + // Attach cb and user_data to plugin_callback so that it can access them later + v8::Local plugin_callback = Nan::GetFunction( + Nan::New(PluginCallback)).ToLocalChecked(); + Nan::Set(plugin_callback, Nan::New("cb").ToLocalChecked(), + Nan::New(reinterpret_cast(data->cb))); + Nan::Set(plugin_callback, Nan::New("user_data").ToLocalChecked(), + Nan::New(data->user_data)); + const int argc = 2; + v8::Local argv[argc] = { + Nan::New(data->service_url).ToLocalChecked(), + plugin_callback + }; + Nan::Callback *callback = state->callback; + callback->Call(argc, argv); + delete data; + } } void plugin_get_metadata(void *state, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void *user_data) { - uv_async_t *async = static_cast(malloc(sizeof(uv_async_t))); - uv_async_init(uv_default_loop(), - async, - SendPluginCallback); + plugin_state *p_state = reinterpret_cast(state); plugin_callback_data *data = new plugin_callback_data; - data->state = reinterpret_cast(state); data->service_url = context.service_url; data->cb = cb; data->user_data = user_data; - async->data = data; - /* libuv says that it will coalesce calls to uv_async_send. If there is ever a - * problem with a callback not getting called, that is probably the reason */ - uv_async_send(async); + + uv_mutex_lock(&p_state->plugin_mutex); + p_state->pending_callbacks->push_back(data); + uv_mutex_unlock(&p_state->plugin_mutex); + + uv_async_send(&p_state->plugin_async); +} + +void plugin_uv_close_cb(uv_handle_t *handle) { + uv_async_t *async = reinterpret_cast(handle); + plugin_state *state = reinterpret_cast(async->data); + uv_mutex_destroy(&state->plugin_mutex); + delete state->pending_callbacks; + delete state->callback; + delete state; } void plugin_destroy_state(void *ptr) { plugin_state *state = reinterpret_cast(ptr); - delete state->callback; + uv_unref((uv_handle_t*)&state->plugin_async); + uv_close((uv_handle_t*)&state->plugin_async, plugin_uv_close_cb); } } // namespace node diff --git a/src/node/ext/call_credentials.h b/src/node/ext/call_credentials.h index a9bfe30f94..04c852bea1 100644 --- a/src/node/ext/call_credentials.h +++ b/src/node/ext/call_credentials.h @@ -34,8 +34,11 @@ #ifndef GRPC_NODE_CALL_CREDENTIALS_H_ #define GRPC_NODE_CALL_CREDENTIALS_H_ +#include + #include #include +#include #include "grpc/grpc_security.h" namespace grpc { @@ -73,17 +76,20 @@ class CallCredentials : public Nan::ObjectWrap { /* Auth metadata plugin functionality */ -typedef struct plugin_state { - Nan::Callback *callback; -} plugin_state; - typedef struct plugin_callback_data { - plugin_state *state; const char *service_url; grpc_credentials_plugin_metadata_cb cb; void *user_data; } plugin_callback_data; +typedef struct plugin_state { + Nan::Callback *callback; + std::list *pending_callbacks; + uv_mutex_t plugin_mutex; + // async.data == this + uv_async_t plugin_async; +} plugin_state; + void plugin_get_metadata(void *state, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void *user_data); diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc index 0c71b2d610..d5fdd7c9c7 100644 --- a/src/node/ext/node_grpc.cc +++ b/src/node/ext/node_grpc.cc @@ -35,6 +35,7 @@ #include #include #include "grpc/grpc.h" +#include "grpc/support/log.h" #include "call.h" #include "call_credentials.h" diff --git a/src/node/src/credentials.js b/src/node/src/credentials.js index 1d73723cc0..97c4bd73ac 100644 --- a/src/node/src/credentials.js +++ b/src/node/src/credentials.js @@ -118,7 +118,6 @@ exports.createFromMetadataGenerator = function(metadata_generator) { exports.createFromGoogleCredential = function(google_credential) { return exports.createFromMetadataGenerator(function(auth_context, callback) { var service_url = auth_context.service_url; - console.log('Service URL:', service_url); google_credential.getRequestMetadata(service_url, function(err, header) { if (err) { console.log('Auth error:', err); @@ -127,7 +126,6 @@ exports.createFromGoogleCredential = function(google_credential) { } var metadata = new Metadata(); metadata.add('authorization', header.Authorization); - console.log(header.Authorization); callback(null, metadata); }); }); -- cgit v1.2.3 From 7fb87e75cf44760a34b198e0e5853508a82902e2 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 16 Mar 2016 11:43:17 -0700 Subject: Removed unnecessary include --- src/node/ext/node_grpc.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc index d5fdd7c9c7..0c71b2d610 100644 --- a/src/node/ext/node_grpc.cc +++ b/src/node/ext/node_grpc.cc @@ -35,7 +35,6 @@ #include #include #include "grpc/grpc.h" -#include "grpc/support/log.h" #include "call.h" #include "call_credentials.h" -- cgit v1.2.3 From 25269f07c9845253b38595066aabab1ec56aa2b3 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 16 Mar 2016 16:00:07 -0700 Subject: Fixed copyright --- src/node/ext/call_credentials.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/node/ext/call_credentials.h b/src/node/ext/call_credentials.h index 04c852bea1..1f35595f3d 100644 --- a/src/node/ext/call_credentials.h +++ b/src/node/ext/call_credentials.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.3 From 1f375d782a6d4d086a3575cac389aa22ed9e9693 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 17 Mar 2016 07:47:18 -0700 Subject: Duh --- src/core/iomgr/wakeup_fd_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/wakeup_fd_pipe.c b/src/core/iomgr/wakeup_fd_pipe.c index d1ed505875..dd2fd1f057 100644 --- a/src/core/iomgr/wakeup_fd_pipe.c +++ b/src/core/iomgr/wakeup_fd_pipe.c @@ -41,9 +41,10 @@ #include #include -#include "src/core/iomgr/socket_utils_posix.h" #include +#include "src/core/iomgr/socket_utils_posix.h" + static void pipe_init(grpc_wakeup_fd* fd_info) { int pipefd[2]; /* TODO(klempner): Make this nonfatal */ @@ -52,7 +53,6 @@ static void pipe_init(grpc_wakeup_fd* fd_info) { gpr_log(GPR_ERROR, "pipe creation failed (%d): %s", errno, strerror(errno)); abort(); } - GPR_ASSERT(0 == pipe(pipefd)); GPR_ASSERT(grpc_set_socket_nonblocking(pipefd[0], 1)); GPR_ASSERT(grpc_set_socket_nonblocking(pipefd[1], 1)); fd_info->read_fd = pipefd[0]; -- cgit v1.2.3 From 4718a387fd5716b606ad667be884ec798b83a9c5 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 17 Mar 2016 11:49:24 -0700 Subject: Unref uv_async after construction to avoid blocking at shutdown --- src/node/ext/call_credentials.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc index a2ac5c17b6..bd2d146bbc 100644 --- a/src/node/ext/call_credentials.cc +++ b/src/node/ext/call_credentials.cc @@ -168,6 +168,7 @@ NAN_METHOD(CallCredentials::CreateFromPlugin) { uv_async_init(uv_default_loop(), &state->plugin_async, SendPluginCallback); + uv_unref((uv_handle_t*)&state->plugin_async); state->plugin_async.data = state; @@ -271,7 +272,6 @@ void plugin_uv_close_cb(uv_handle_t *handle) { void plugin_destroy_state(void *ptr) { plugin_state *state = reinterpret_cast(ptr); - uv_unref((uv_handle_t*)&state->plugin_async); uv_close((uv_handle_t*)&state->plugin_async, plugin_uv_close_cb); } -- cgit v1.2.3 From 1ba1f63a03ac47eca208bd39024fca069dab97fc Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 17 Mar 2016 19:57:54 +0100 Subject: Factorizing code out. --- src/compiler/cpp_generator.cc | 84 +++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 644ae87fb1..206a6e1fe5 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -83,6 +83,28 @@ grpc::string FilenameIdentifier(const grpc::string &filename) { } } // namespace +template +T *array_end(T (&array)[N]) { return array + N; } + +void PrintIncludes(grpc::protobuf::io::Printer *printer, const std::vector& headers, const Parameters ¶ms) { + std::map vars; + + vars["l"] = params.use_system_headers ? '<' : '"'; + vars["r"] = params.use_system_headers ? '>' : '"'; + + if (!params.grpc_search_path.empty()) { + vars["l"] += params.grpc_search_path; + if (params.grpc_search_path.back() != '/') { + vars["l"] += '/'; + } + } + + for (auto i = headers.begin(); i != headers.end(); i++) { + vars["h"] = *i; + printer->Print(vars, "#include $l$$h$$r$\n"); + } +} + grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file, const Parameters ¶ms) { grpc::string output; @@ -118,24 +140,18 @@ grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file, grpc::protobuf::io::Printer printer(&output_stream, '$'); std::map vars; - vars["l"] = params.use_system_headers ? '<' : '"'; - vars["r"] = params.use_system_headers ? '>' : '"'; - - if (!params.grpc_search_path.empty()) { - vars["l"] += params.grpc_search_path; - if (params.grpc_search_path.back() != '/') { - vars["l"] += '/'; - } - } - - printer.Print(vars, "#include $l$grpc++/impl/codegen/async_stream.h$r$\n"); - printer.Print(vars, "#include $l$grpc++/impl/codegen/async_unary_call.h$r$\n"); - printer.Print(vars, "#include $l$grpc++/impl/codegen/proto_utils.h$r$\n"); - printer.Print(vars, "#include $l$grpc++/impl/codegen/rpc_method.h$r$\n"); - printer.Print(vars, "#include $l$grpc++/impl/codegen/service_type.h$r$\n"); - printer.Print(vars, "#include $l$grpc++/impl/codegen/status.h$r$\n"); - printer.Print(vars, "#include $l$grpc++/impl/codegen/stub_options.h$r$\n"); - printer.Print(vars, "#include $l$grpc++/impl/codegen/sync_stream.h$r$\n"); + static const char *headers_strs[] = { + "grpc++/impl/codegen/async_stream.h", + "grpc++/impl/codegen/async_unary_call.h", + "grpc++/impl/codegen/proto_utils.h", + "grpc++/impl/codegen/rpc_method.h", + "grpc++/impl/codegen/service_type.h", + "grpc++/impl/codegen/status.h", + "grpc++/impl/codegen/stub_options.h", + "grpc++/impl/codegen/sync_stream.h" + }; + std::vector headers(headers_strs, array_end(headers_strs)); + PrintIncludes(&printer, headers, params); printer.Print(vars, "\n"); printer.Print(vars, "namespace grpc {\n"); printer.Print(vars, "class CompletionQueue;\n"); @@ -876,26 +892,18 @@ grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file, grpc::protobuf::io::Printer printer(&output_stream, '$'); std::map vars; - vars["l"] = params.use_system_headers ? '<' : '"'; - vars["r"] = params.use_system_headers ? '>' : '"'; - - if (!params.grpc_search_path.empty()) { - vars["l"] += params.grpc_search_path; - if (params.grpc_search_path.back() != '/') { - vars["l"] += '/'; - } - } - - printer.Print(vars, "#include $l$grpc++/impl/codegen/async_stream.h$r$\n"); - printer.Print(vars, "#include $l$grpc++/impl/codegen/async_unary_call.h$r$\n"); - printer.Print(vars, "#include $l$grpc++/impl/codegen/channel_interface.h$r$\n"); - printer.Print(vars, "#include $l$grpc++/impl/codegen/client_unary_call.h$r$\n"); - printer.Print(vars, - "#include $l$grpc++/impl/codegen/method_handler_impl.h$r$\n"); - printer.Print(vars, - "#include $l$grpc++/impl/codegen/rpc_service_method.h$r$\n"); - printer.Print(vars, "#include $l$grpc++/impl/codegen/service_type.h$r$\n"); - printer.Print(vars, "#include $l$grpc++/impl/codegen/sync_stream.h$r$\n"); + static const char *headers_strs[] = { + "grpc++/impl/codegen/async_stream.h", + "grpc++/impl/codegen/async_unary_call.h", + "grpc++/impl/codegen/channel_interface.h", + "grpc++/impl/codegen/client_unary_call.h", + "grpc++/impl/codegen/method_handler_impl.h", + "grpc++/impl/codegen/rpc_service_method.h", + "grpc++/impl/codegen/service_type.h", + "grpc++/impl/codegen/sync_stream.h" + }; + std::vector headers(headers_strs, array_end(headers_strs)); + PrintIncludes(&printer, headers, params); if (!file->package().empty()) { std::vector parts = -- cgit v1.2.3 From f7b1d74bf8b48e9de7395fa75b1a8449c28109ff Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 17 Mar 2016 20:50:25 +0100 Subject: Fixing (c)s. --- src/compiler/cpp_generator.h | 2 +- src/compiler/cpp_plugin.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h index 03621c8794..4f9de9d11a 100644 --- a/src/compiler/cpp_generator.h +++ b/src/compiler/cpp_generator.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc index 92a9ba7549..d8ada4835c 100644 --- a/src/compiler/cpp_plugin.cc +++ b/src/compiler/cpp_plugin.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.3 From 80d6b12a86a636edc8811b880296fbe45bb214a6 Mon Sep 17 00:00:00 2001 From: ahedberg Date: Thu, 17 Mar 2016 17:37:35 -0400 Subject: move unix socket functionality to unix_sockets_posix module --- .../client_config/resolvers/sockaddr_resolver.c | 22 +---- src/core/iomgr/endpoint_pair_posix.c | 5 +- src/core/iomgr/resolve_address_posix.c | 16 +--- src/core/iomgr/sockaddr_utils.c | 21 ++--- src/core/iomgr/tcp_client_posix.c | 14 +-- src/core/iomgr/tcp_server_posix.c | 45 ++------- src/core/iomgr/udp_server.c | 29 +----- src/core/iomgr/unix_sockets_posix.c | 102 +++++++++++++++++++++ src/core/iomgr/unix_sockets_posix.h | 67 ++++++++++++++ src/core/iomgr/unix_sockets_posix_noop.c | 59 ++++++++++++ 10 files changed, 250 insertions(+), 130 deletions(-) create mode 100644 src/core/iomgr/unix_sockets_posix.c create mode 100644 src/core/iomgr/unix_sockets_posix.h create mode 100644 src/core/iomgr/unix_sockets_posix_noop.c (limited to 'src') diff --git a/src/core/client_config/resolvers/sockaddr_resolver.c b/src/core/client_config/resolvers/sockaddr_resolver.c index 418413315f..d2a081a131 100644 --- a/src/core/client_config/resolvers/sockaddr_resolver.c +++ b/src/core/client_config/resolvers/sockaddr_resolver.c @@ -37,9 +37,6 @@ #include #include -#ifdef GPR_HAVE_UNIX_SOCKET -#include -#endif #include #include @@ -47,6 +44,7 @@ #include "src/core/client_config/lb_policy_registry.h" #include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/unix_sockets_posix.h" #include "src/core/support/string.h" typedef struct { @@ -168,24 +166,6 @@ static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) { gpr_free(r); } -#ifdef GPR_HAVE_UNIX_SOCKET -static int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, - size_t *len) { - struct sockaddr_un *un = (struct sockaddr_un *)addr; - - un->sun_family = AF_UNIX; - strcpy(un->sun_path, uri->path); - *len = strlen(un->sun_path) + sizeof(un->sun_family) + 1; - - return 1; -} - -static char *unix_get_default_authority(grpc_resolver_factory *factory, - grpc_uri *uri) { - return gpr_strdup("localhost"); -} -#endif - static char *ip_get_default_authority(grpc_uri *uri) { const char *path = uri->path; if (path[0] == '/') ++path; diff --git a/src/core/iomgr/endpoint_pair_posix.c b/src/core/iomgr/endpoint_pair_posix.c index d3a45f83e0..f6da8f1d1b 100644 --- a/src/core/iomgr/endpoint_pair_posix.c +++ b/src/core/iomgr/endpoint_pair_posix.c @@ -37,6 +37,7 @@ #include "src/core/iomgr/endpoint_pair.h" #include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/iomgr/unix_sockets_posix.h" #include #include @@ -52,9 +53,7 @@ static void create_sockets(int sv[2]) { int flags; -#ifdef GPR_HAVE_UNIX_SOCKET - GPR_ASSERT(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); -#endif + grpc_create_socketpair_if_unix(sv); flags = fcntl(sv[0], F_GETFL, 0); GPR_ASSERT(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK) == 0); flags = fcntl(sv[1], F_GETFL, 0); diff --git a/src/core/iomgr/resolve_address_posix.c b/src/core/iomgr/resolve_address_posix.c index 0360ab717c..ef193c02ec 100644 --- a/src/core/iomgr/resolve_address_posix.c +++ b/src/core/iomgr/resolve_address_posix.c @@ -39,9 +39,6 @@ #include #include -#ifdef GPR_HAVE_UNIX_SOCKET -#include -#endif #include #include @@ -53,6 +50,7 @@ #include "src/core/iomgr/executor.h" #include "src/core/iomgr/iomgr_internal.h" #include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/iomgr/unix_posix_sockets.h" #include "src/core/support/block_annotate.h" #include "src/core/support/string.h" @@ -73,21 +71,11 @@ static grpc_resolved_addresses *blocking_resolve_address_impl( int s; size_t i; grpc_resolved_addresses *addrs = NULL; -#ifdef GPR_HAVE_UNIX_SOCKET - struct sockaddr_un *un; if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' && name[4] == ':' && name[5] != 0) { - addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); - addrs->naddrs = 1; - addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address)); - un = (struct sockaddr_un *)addrs->addrs->addr; - un->sun_family = AF_UNIX; - strcpy(un->sun_path, name + 5); - addrs->addrs->len = strlen(un->sun_path) + sizeof(un->sun_family) + 1; - return addrs; + return grpc_resolve_unix_domain_address(name + 5); } -#endif /* parse name, splitting it into host and port parts */ gpr_split_host_port(name, &host, &port); diff --git a/src/core/iomgr/sockaddr_utils.c b/src/core/iomgr/sockaddr_utils.c index 3d464a228f..667ab01432 100644 --- a/src/core/iomgr/sockaddr_utils.c +++ b/src/core/iomgr/sockaddr_utils.c @@ -36,16 +36,13 @@ #include #include -#ifdef GPR_HAVE_UNIX_SOCKET -#include -#endif - #include #include #include #include #include +#include "src/core/iomgr/unix_sockets_posix.h" #include "src/core/support/string.h" static const uint8_t kV4MappedPrefix[] = {0, 0, 0, 0, 0, 0, @@ -191,14 +188,9 @@ char *grpc_sockaddr_to_uri(const struct sockaddr *addr) { gpr_asprintf(&result, "ipv6:%s", temp); gpr_free(temp); return result; -#ifdef GPR_HAVE_UNIX_SOCKET - case AF_UNIX: - gpr_asprintf(&result, "unix:%s", ((struct sockaddr_un *)addr)->sun_path); - return result; -#endif + default: + return grpc_sockaddr_to_uri_unix_if_possible(addr); } - - return NULL; } int grpc_sockaddr_get_port(const struct sockaddr *addr) { @@ -207,11 +199,10 @@ int grpc_sockaddr_get_port(const struct sockaddr *addr) { return ntohs(((struct sockaddr_in *)addr)->sin_port); case AF_INET6: return ntohs(((struct sockaddr_in6 *)addr)->sin6_port); -#ifdef GPR_HAVE_UNIX_SOCKET - case AF_UNIX: - return 1; -#endif default: + if (grpc_is_unix_socket(addr->sa_family)) { + return 1; + } gpr_log(GPR_ERROR, "Unknown socket family %d in grpc_sockaddr_get_port", addr->sa_family); return 0; diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c index b04e1dbb68..2ed6fb107b 100644 --- a/src/core/iomgr/tcp_client_posix.c +++ b/src/core/iomgr/tcp_client_posix.c @@ -76,24 +76,14 @@ static int prepare_socket(const struct sockaddr *addr, int fd) { goto error; } -#ifdef GPR_HAVE_UNIX_SOCKET if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || - (addr->sa_family != AF_UNIX && !grpc_set_socket_low_latency(fd, 1)) || + (!grpc_is_unix_socket(addr->sa_family) && + !grpc_set_socket_low_latency(fd, 1)) || !grpc_set_socket_no_sigpipe_if_possible(fd)) { gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, strerror(errno)); goto error; } -#else - if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || - !grpc_set_socket_low_latency(fd, 1) || - !grpc_set_socket_no_sigpipe_if_possible(fd)) { - gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, - strerror(errno)); - goto error; - } -#endif - return 1; error: diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c index f47a00c118..0bef9f6254 100644 --- a/src/core/iomgr/tcp_server_posix.c +++ b/src/core/iomgr/tcp_server_posix.c @@ -52,9 +52,6 @@ #include #include #include -#ifdef GPR_HAVE_UNIX_SOCKET -#include -#endif #include #include "src/core/iomgr/pollset_posix.h" @@ -62,6 +59,7 @@ #include "src/core/iomgr/sockaddr_utils.h" #include "src/core/iomgr/socket_utils_posix.h" #include "src/core/iomgr/tcp_posix.h" +#include "src/core/iomgr/unix_sockets_posix.h" #include "src/core/support/string.h" #include #include @@ -83,9 +81,6 @@ struct grpc_tcp_listener { union { uint8_t untyped[GRPC_MAX_SOCKADDR_SIZE]; struct sockaddr sockaddr; -#ifdef GPR_HAVE_UNIX_SOCKET - struct sockaddr_un un; -#endif } addr; size_t addr_len; int port; @@ -102,16 +97,6 @@ struct grpc_tcp_listener { int is_sibling; }; -#ifdef GPR_HAVE_UNIX_SOCKET -static void unlink_if_unix_domain_socket(const struct sockaddr_un *un) { - struct stat st; - - if (stat(un->sun_path, &st) == 0 && (st.st_mode & S_IFMT) == S_IFSOCK) { - unlink(un->sun_path); - } -} -#endif - /* the overall server */ struct grpc_tcp_server { gpr_refcount refs; @@ -209,11 +194,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { if (s->head) { grpc_tcp_listener *sp; for (sp = s->head; sp; sp = sp->next) { -#ifdef GPR_HAVE_UNIX_SOCKET - if (sp->addr.sockaddr.sa_family == AF_UNIX) { - unlink_if_unix_domain_socket(&sp->addr.un); - } -#endif + unlink_if_unix_domain_socket(&sp->addr.sockaddr); sp->destroyed_closure.cb = destroyed_port; sp->destroyed_closure.cb_arg = s; grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, @@ -288,25 +269,15 @@ static int prepare_socket(int fd, const struct sockaddr *addr, goto error; } -#ifdef GPR_HAVE_UNIX_SOCKET if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || - (addr->sa_family != AF_UNIX && (!grpc_set_socket_low_latency(fd, 1) || - !grpc_set_socket_reuse_addr(fd, 1))) || + (!grpc_is_unix_socket(addr) && + (!grpc_set_socket_low_latency(fd, 1) || + !grpc_set_socket_reuse_addr(fd, 1))) || !grpc_set_socket_no_sigpipe_if_possible(fd)) { gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, strerror(errno)); goto error; } -#else - if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || - !grpc_set_socket_low_latency(fd, 1) || - !grpc_set_socket_reuse_addr(fd, 1) || - !grpc_set_socket_no_sigpipe_if_possible(fd)) { - gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, - strerror(errno)); - goto error; - } -#endif GPR_ASSERT(addr_len < ~(socklen_t)0); if (bind(fd, addr, (socklen_t)addr_len) < 0) { @@ -470,11 +441,7 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, if (s->tail != NULL) { port_index = s->tail->port_index + 1; } -#ifdef GPR_HAVE_UNIX_SOCKET - if (((struct sockaddr *)addr)->sa_family == AF_UNIX) { - unlink_if_unix_domain_socket(addr); - } -#endif + unlink_if_unix_domain_socket((struct sockaddr *)addr); /* Check if this is a wildcard port, and if so, try to keep the port the same as some previously created listener. */ diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c index df2f449a9a..c1a438398d 100644 --- a/src/core/iomgr/udp_server.c +++ b/src/core/iomgr/udp_server.c @@ -52,9 +52,6 @@ #include #include #include -#ifdef GPR_HAVE_UNIX_SOCKET -#include -#endif #include #include "src/core/iomgr/fd_posix.h" @@ -62,6 +59,7 @@ #include "src/core/iomgr/resolve_address.h" #include "src/core/iomgr/sockaddr_utils.h" #include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/iomgr/unix_sockets_posix.h" #include "src/core/support/string.h" #include #include @@ -79,9 +77,6 @@ typedef struct { union { uint8_t untyped[GRPC_MAX_SOCKADDR_SIZE]; struct sockaddr sockaddr; -#ifdef GPR_HAVE_UNIX_SOCKET - struct sockaddr_un un; -#endif } addr; size_t addr_len; grpc_closure read_closure; @@ -89,16 +84,6 @@ typedef struct { grpc_udp_server_read_cb read_cb; } server_port; -#ifdef GPR_HAVE_UNIX_SOCKET -static void unlink_if_unix_domain_socket(const struct sockaddr_un *un) { - struct stat st; - - if (stat(un->sun_path, &st) == 0 && (st.st_mode & S_IFMT) == S_IFSOCK) { - unlink(un->sun_path); - } -} -#endif - /* the overall server */ struct grpc_udp_server { gpr_mu mu; @@ -182,11 +167,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { if (s->nports) { for (i = 0; i < s->nports; i++) { server_port *sp = &s->ports[i]; -#ifdef GPR_HAVE_UNIX_SOCKET - if (sp->addr.sockaddr.sa_family == AF_UNIX) { - unlink_if_unix_domain_socket(&sp->addr.un); - } -#endif + unlink_if_unix_domain_socket(&sp->addr.sockaddr); sp->destroyed_closure.cb = destroyed_port; sp->destroyed_closure.cb_arg = s; grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, @@ -344,11 +325,7 @@ int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, socklen_t sockname_len; int port; -#ifdef GPR_HAVE_UNIX_SOCKET - if (((struct sockaddr *)addr)->sa_family == AF_UNIX) { - unlink_if_unix_domain_socket(addr); - } -#endif + unlink_if_unix_domain_socket((struct sockaddr *)addr); /* Check if this is a wildcard port, and if so, try to keep the port the same as some previously created listener. */ diff --git a/src/core/iomgr/unix_sockets_posix.c b/src/core/iomgr/unix_sockets_posix.c new file mode 100644 index 0000000000..531ddcb37d --- /dev/null +++ b/src/core/iomgr/unix_sockets_posix.c @@ -0,0 +1,102 @@ +/* + * + * Copyright 2015, 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/iomgr/unix_sockets_posix.h" + +#ifdef GPR_HAVE_UNIX_SOCKET + +#include +#include + +#include + +void grpc_create_socketpair_if_unix(int sv[2]) { + GPR_ASSERT(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); +} + +grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char* name) { + struct sockaddr_un *un; + + addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); + addrs->naddrs = 1; + addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address)); + un = (struct sockaddr_un *)addrs->addrs->addr; + un->sun_family = AF_UNIX; + strcpy(un->sun_path, name); + addrs->addrs->len = strlen(un->sun_path) + sizeof(un->sun_family) + 1; + return addrs; +} + +int grpc_is_unix_socket(sa_family_t addr_family) { + return addr_family == AF_UNIX; +} + +static void unlink_if_unix_domain_socket(const struct sockaddr *addr) { + if (addr->sa_family != AF_UNIX) { + return; + } + struct sockaddr_un *un = (struct sockaddr_un *)addr; + struct stat st; + + if (stat(un->sun_path, &st) == 0 && (st.st_mode & S_IFMT) == S_IFSOCK) { + unlink(un->sun_path); + } +} + +static int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, + size_t *len) { + struct sockaddr_un *un = (struct sockaddr_un *)addr; + + un->sun_family = AF_UNIX; + strcpy(un->sun_path, uri->path); + *len = strlen(un->sun_path) + sizeof(un->sun_family) + 1; + + return 1; +} + +static char *unix_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) { + return gpr_strdup("localhost"); +} + +char *grpc_sockaddr_to_uri_unix_if_possible(struct sockaddr *addr) { + if (addr->sa_family != AF_UNIX) { + return NULL; + } + + char* result; + gpr_asprintf(&result, "unix:%s", ((struct sockaddr_un *)addr)->sun_path); + return result; +} + +#endif diff --git a/src/core/iomgr/unix_sockets_posix.h b/src/core/iomgr/unix_sockets_posix.h new file mode 100644 index 0000000000..6023611373 --- /dev/null +++ b/src/core/iomgr/unix_sockets_posix.h @@ -0,0 +1,67 @@ +/* + * + * 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_INTERNAL_CORE_IOMGR_UNIX_SOCKETS_POSIX_H +#define GRPC_INTERNAL_CORE_IOMGR_UNIX_SOCKETS_POSIX_H + +#include + +#ifdef GPR_POSIX_SOCKET + +#include + +#include + +#include "src/core/client_config/resolver_factory.h" +#include "src/core/client_config/uri_parser.h"; +#include "src/core/iomgr/resolve_address.h" + +void grpc_create_socketpair_if_unix(int sv[2]); + +grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char* name); + +int grpc_is_unix_socket(sa_family_t addr_family); + +static void unlink_if_unix_domain_socket(const struct sockaddr *addr); + +static int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, + size_t *len); + +static char *unix_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri); + +char *grpc_sockaddr_to_uri_unix_if_possible(char **strp, + const char *format, ...); + +#endif +#endif /* GRPC_INTERNAL_CORE_IOMGR_UNIX_SOCKETS_POSIX_H */ diff --git a/src/core/iomgr/unix_sockets_posix_noop.c b/src/core/iomgr/unix_sockets_posix_noop.c new file mode 100644 index 0000000000..1e29242486 --- /dev/null +++ b/src/core/iomgr/unix_sockets_posix_noop.c @@ -0,0 +1,59 @@ +/* + * + * Copyright 2015, 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/iomgr/unix_sockets_posix.h" + +void grpc_create_socketpair_if_unix(int sv[2]) {} + +void grpc_resolve_unix_domain_address(const char* name) { + return NULL; +} + +int grpc_is_unix_socket(sa_family_t addr_family) { + return false; +} + +static void unlink_if_unix_domain_socket(const struct sockaddr *addr) {} + +static int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, + size_t *len) {} + +static char *unix_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) {} + +char *grpc_sockaddr_to_uri_unix_if_possible(struct sockaddr *addr) { + return NULL; +} + +#endif -- cgit v1.2.3 From 43df29552865541e6d6d11a14b3cf47a4c162b42 Mon Sep 17 00:00:00 2001 From: ahedberg Date: Fri, 18 Mar 2016 10:46:38 -0400 Subject: add unix_sockets_posix module to build system and fix compilation errors --- BUILD | 9 +++++++++ Makefile | 4 ++++ binding.gyp | 2 ++ build.yaml | 3 +++ config.m4 | 2 ++ gRPC.podspec | 4 ++++ grpc.gemspec | 3 +++ package.json | 3 +++ package.xml | 3 +++ src/core/iomgr/resolve_address_posix.c | 2 +- src/core/iomgr/sockaddr_utils.c | 2 +- src/core/iomgr/tcp_client_posix.c | 4 ++-- src/core/iomgr/unix_sockets_posix.c | 18 ++++++++--------- src/core/iomgr/unix_sockets_posix.h | 15 ++++++-------- src/core/iomgr/unix_sockets_posix_noop.c | 23 +++++++++++++--------- src/python/grpcio/grpc_core_dependencies.py | 2 ++ tools/doxygen/Doxyfile.core.internal | 3 +++ tools/run_tests/sources_and_headers.json | 8 ++++++++ vsprojects/vcxproj/grpc/grpc.vcxproj | 5 +++++ vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 9 +++++++++ .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj | 5 +++++ .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 9 +++++++++ 22 files changed, 107 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/BUILD b/BUILD index 0e9f37a0e3..70d188afdf 100644 --- a/BUILD +++ b/BUILD @@ -221,6 +221,7 @@ cc_library( "src/core/iomgr/timer.h", "src/core/iomgr/timer_heap.h", "src/core/iomgr/udp_server.h", + "src/core/iomgr/unix_sockets_posix.h", "src/core/iomgr/wakeup_fd_pipe.h", "src/core/iomgr/wakeup_fd_posix.h", "src/core/iomgr/workqueue.h", @@ -361,6 +362,8 @@ cc_library( "src/core/iomgr/timer.c", "src/core/iomgr/timer_heap.c", "src/core/iomgr/udp_server.c", + "src/core/iomgr/unix_sockets_posix.c", + "src/core/iomgr/unix_sockets_posix_noop.c", "src/core/iomgr/wakeup_fd_eventfd.c", "src/core/iomgr/wakeup_fd_nospecial.c", "src/core/iomgr/wakeup_fd_pipe.c", @@ -551,6 +554,7 @@ cc_library( "src/core/iomgr/timer.h", "src/core/iomgr/timer_heap.h", "src/core/iomgr/udp_server.h", + "src/core/iomgr/unix_sockets_posix.h", "src/core/iomgr/wakeup_fd_pipe.h", "src/core/iomgr/wakeup_fd_posix.h", "src/core/iomgr/workqueue.h", @@ -678,6 +682,8 @@ cc_library( "src/core/iomgr/timer.c", "src/core/iomgr/timer_heap.c", "src/core/iomgr/udp_server.c", + "src/core/iomgr/unix_sockets_posix.c", + "src/core/iomgr/unix_sockets_posix_noop.c", "src/core/iomgr/wakeup_fd_eventfd.c", "src/core/iomgr/wakeup_fd_nospecial.c", "src/core/iomgr/wakeup_fd_pipe.c", @@ -1339,6 +1345,8 @@ objc_library( "src/core/iomgr/timer.c", "src/core/iomgr/timer_heap.c", "src/core/iomgr/udp_server.c", + "src/core/iomgr/unix_sockets_posix.c", + "src/core/iomgr/unix_sockets_posix_noop.c", "src/core/iomgr/wakeup_fd_eventfd.c", "src/core/iomgr/wakeup_fd_nospecial.c", "src/core/iomgr/wakeup_fd_pipe.c", @@ -1510,6 +1518,7 @@ objc_library( "src/core/iomgr/timer.h", "src/core/iomgr/timer_heap.h", "src/core/iomgr/udp_server.h", + "src/core/iomgr/unix_sockets_posix.h", "src/core/iomgr/wakeup_fd_pipe.h", "src/core/iomgr/wakeup_fd_posix.h", "src/core/iomgr/workqueue.h", diff --git a/Makefile b/Makefile index f118d54253..e980b1c877 100644 --- a/Makefile +++ b/Makefile @@ -2432,6 +2432,8 @@ LIBGRPC_SRC = \ src/core/iomgr/timer.c \ src/core/iomgr/timer_heap.c \ src/core/iomgr/udp_server.c \ + src/core/iomgr/unix_sockets_posix.c \ + src/core/iomgr/unix_sockets_posix_noop.c \ src/core/iomgr/wakeup_fd_eventfd.c \ src/core/iomgr/wakeup_fd_nospecial.c \ src/core/iomgr/wakeup_fd_pipe.c \ @@ -2744,6 +2746,8 @@ LIBGRPC_UNSECURE_SRC = \ src/core/iomgr/timer.c \ src/core/iomgr/timer_heap.c \ src/core/iomgr/udp_server.c \ + src/core/iomgr/unix_sockets_posix.c \ + src/core/iomgr/unix_sockets_posix_noop.c \ src/core/iomgr/wakeup_fd_eventfd.c \ src/core/iomgr/wakeup_fd_nospecial.c \ src/core/iomgr/wakeup_fd_pipe.c \ diff --git a/binding.gyp b/binding.gyp index d1e086cfa0..e1f41c224e 100644 --- a/binding.gyp +++ b/binding.gyp @@ -627,6 +627,8 @@ 'src/core/iomgr/timer.c', 'src/core/iomgr/timer_heap.c', 'src/core/iomgr/udp_server.c', + 'src/core/iomgr/unix_sockets_posix.c', + 'src/core/iomgr/unix_sockets_posix_noop.c', 'src/core/iomgr/wakeup_fd_eventfd.c', 'src/core/iomgr/wakeup_fd_nospecial.c', 'src/core/iomgr/wakeup_fd_pipe.c', diff --git a/build.yaml b/build.yaml index 83b7714e65..3f9abccf9f 100644 --- a/build.yaml +++ b/build.yaml @@ -310,6 +310,7 @@ filegroups: - src/core/iomgr/timer.h - src/core/iomgr/timer_heap.h - src/core/iomgr/udp_server.h + - src/core/iomgr/unix_sockets_posix.h - src/core/iomgr/wakeup_fd_pipe.h - src/core/iomgr/wakeup_fd_posix.h - src/core/iomgr/workqueue.h @@ -430,6 +431,8 @@ filegroups: - src/core/iomgr/timer.c - src/core/iomgr/timer_heap.c - src/core/iomgr/udp_server.c + - src/core/iomgr/unix_sockets_posix.c + - src/core/iomgr/unix_sockets_posix_noop.c - src/core/iomgr/wakeup_fd_eventfd.c - src/core/iomgr/wakeup_fd_nospecial.c - src/core/iomgr/wakeup_fd_pipe.c diff --git a/config.m4 b/config.m4 index 8ab45e6603..37d71ecb94 100644 --- a/config.m4 +++ b/config.m4 @@ -149,6 +149,8 @@ if test "$PHP_GRPC" != "no"; then src/core/iomgr/timer.c \ src/core/iomgr/timer_heap.c \ src/core/iomgr/udp_server.c \ + src/core/iomgr/unix_sockets_posix.c \ + src/core/iomgr/unix_sockets_posix_noop.c \ src/core/iomgr/wakeup_fd_eventfd.c \ src/core/iomgr/wakeup_fd_nospecial.c \ src/core/iomgr/wakeup_fd_pipe.c \ diff --git a/gRPC.podspec b/gRPC.podspec index f3103ea79a..ea178960fe 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -225,6 +225,7 @@ Pod::Spec.new do |s| 'src/core/iomgr/timer.h', 'src/core/iomgr/timer_heap.h', 'src/core/iomgr/udp_server.h', + 'src/core/iomgr/unix_sockets_posix.h', 'src/core/iomgr/wakeup_fd_pipe.h', 'src/core/iomgr/wakeup_fd_posix.h', 'src/core/iomgr/workqueue.h', @@ -378,6 +379,8 @@ Pod::Spec.new do |s| 'src/core/iomgr/timer.c', 'src/core/iomgr/timer_heap.c', 'src/core/iomgr/udp_server.c', + 'src/core/iomgr/unix_sockets_posix.c', + 'src/core/iomgr/unix_sockets_posix_noop.c', 'src/core/iomgr/wakeup_fd_eventfd.c', 'src/core/iomgr/wakeup_fd_nospecial.c', 'src/core/iomgr/wakeup_fd_pipe.c', @@ -546,6 +549,7 @@ Pod::Spec.new do |s| 'src/core/iomgr/timer.h', 'src/core/iomgr/timer_heap.h', 'src/core/iomgr/udp_server.h', + 'src/core/iomgr/unix_sockets_posix.h', 'src/core/iomgr/wakeup_fd_pipe.h', 'src/core/iomgr/wakeup_fd_posix.h', 'src/core/iomgr/workqueue.h', diff --git a/grpc.gemspec b/grpc.gemspec index 1b3f15ecf3..6d94258a21 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -221,6 +221,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/iomgr/timer.h ) s.files += %w( src/core/iomgr/timer_heap.h ) s.files += %w( src/core/iomgr/udp_server.h ) + s.files += %w( src/core/iomgr/unix_sockets_posix.h ) s.files += %w( src/core/iomgr/wakeup_fd_pipe.h ) s.files += %w( src/core/iomgr/wakeup_fd_posix.h ) s.files += %w( src/core/iomgr/workqueue.h ) @@ -361,6 +362,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/iomgr/timer.c ) s.files += %w( src/core/iomgr/timer_heap.c ) s.files += %w( src/core/iomgr/udp_server.c ) + s.files += %w( src/core/iomgr/unix_sockets_posix.c ) + s.files += %w( src/core/iomgr/unix_sockets_posix_noop.c ) s.files += %w( src/core/iomgr/wakeup_fd_eventfd.c ) s.files += %w( src/core/iomgr/wakeup_fd_nospecial.c ) s.files += %w( src/core/iomgr/wakeup_fd_pipe.c ) diff --git a/package.json b/package.json index db7f299e13..27342cceb0 100644 --- a/package.json +++ b/package.json @@ -165,6 +165,7 @@ "src/core/iomgr/timer.h", "src/core/iomgr/timer_heap.h", "src/core/iomgr/udp_server.h", + "src/core/iomgr/unix_sockets_posix.h", "src/core/iomgr/wakeup_fd_pipe.h", "src/core/iomgr/wakeup_fd_posix.h", "src/core/iomgr/workqueue.h", @@ -305,6 +306,8 @@ "src/core/iomgr/timer.c", "src/core/iomgr/timer_heap.c", "src/core/iomgr/udp_server.c", + "src/core/iomgr/unix_sockets_posix.c", + "src/core/iomgr/unix_sockets_posix_noop.c", "src/core/iomgr/wakeup_fd_eventfd.c", "src/core/iomgr/wakeup_fd_nospecial.c", "src/core/iomgr/wakeup_fd_pipe.c", diff --git a/package.xml b/package.xml index bb4dcc2037..b992470343 100644 --- a/package.xml +++ b/package.xml @@ -225,6 +225,7 @@ + @@ -365,6 +366,8 @@ + + diff --git a/src/core/iomgr/resolve_address_posix.c b/src/core/iomgr/resolve_address_posix.c index ef193c02ec..26b3aa8189 100644 --- a/src/core/iomgr/resolve_address_posix.c +++ b/src/core/iomgr/resolve_address_posix.c @@ -50,7 +50,7 @@ #include "src/core/iomgr/executor.h" #include "src/core/iomgr/iomgr_internal.h" #include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/unix_posix_sockets.h" +#include "src/core/iomgr/unix_sockets_posix.h" #include "src/core/support/block_annotate.h" #include "src/core/support/string.h" diff --git a/src/core/iomgr/sockaddr_utils.c b/src/core/iomgr/sockaddr_utils.c index 667ab01432..682b290a83 100644 --- a/src/core/iomgr/sockaddr_utils.c +++ b/src/core/iomgr/sockaddr_utils.c @@ -200,7 +200,7 @@ int grpc_sockaddr_get_port(const struct sockaddr *addr) { case AF_INET6: return ntohs(((struct sockaddr_in6 *)addr)->sin6_port); default: - if (grpc_is_unix_socket(addr->sa_family)) { + if (grpc_is_unix_socket(addr)) { return 1; } gpr_log(GPR_ERROR, "Unknown socket family %d in grpc_sockaddr_get_port", diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c index 2ed6fb107b..1d3f9b6555 100644 --- a/src/core/iomgr/tcp_client_posix.c +++ b/src/core/iomgr/tcp_client_posix.c @@ -54,6 +54,7 @@ #include "src/core/iomgr/socket_utils_posix.h" #include "src/core/iomgr/tcp_posix.h" #include "src/core/iomgr/timer.h" +#include "src/core/iomgr/unix_sockets_posix.h" #include "src/core/support/string.h" extern int grpc_tcp_trace; @@ -77,8 +78,7 @@ static int prepare_socket(const struct sockaddr *addr, int fd) { } if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || - (!grpc_is_unix_socket(addr->sa_family) && - !grpc_set_socket_low_latency(fd, 1)) || + (!grpc_is_unix_socket(addr) && !grpc_set_socket_low_latency(fd, 1)) || !grpc_set_socket_no_sigpipe_if_possible(fd)) { gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, strerror(errno)); diff --git a/src/core/iomgr/unix_sockets_posix.c b/src/core/iomgr/unix_sockets_posix.c index 531ddcb37d..0ff48320ca 100644 --- a/src/core/iomgr/unix_sockets_posix.c +++ b/src/core/iomgr/unix_sockets_posix.c @@ -36,6 +36,7 @@ #ifdef GPR_HAVE_UNIX_SOCKET #include +#include #include #include @@ -47,7 +48,7 @@ void grpc_create_socketpair_if_unix(int sv[2]) { grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char* name) { struct sockaddr_un *un; - addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); + grpc_resolved_addresses *addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); addrs->naddrs = 1; addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address)); un = (struct sockaddr_un *)addrs->addrs->addr; @@ -57,11 +58,11 @@ grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char* name) { return addrs; } -int grpc_is_unix_socket(sa_family_t addr_family) { - return addr_family == AF_UNIX; +int grpc_is_unix_socket(const struct sockaddr *addr) { + return addr->sa_family == AF_UNIX; } -static void unlink_if_unix_domain_socket(const struct sockaddr *addr) { +void unlink_if_unix_domain_socket(const struct sockaddr *addr) { if (addr->sa_family != AF_UNIX) { return; } @@ -73,8 +74,7 @@ static void unlink_if_unix_domain_socket(const struct sockaddr *addr) { } } -static int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, - size_t *len) { +int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { struct sockaddr_un *un = (struct sockaddr_un *)addr; un->sun_family = AF_UNIX; @@ -84,12 +84,12 @@ static int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, return 1; } -static char *unix_get_default_authority(grpc_resolver_factory *factory, - grpc_uri *uri) { +char *unix_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) { return gpr_strdup("localhost"); } -char *grpc_sockaddr_to_uri_unix_if_possible(struct sockaddr *addr) { +char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr) { if (addr->sa_family != AF_UNIX) { return NULL; } diff --git a/src/core/iomgr/unix_sockets_posix.h b/src/core/iomgr/unix_sockets_posix.h index 6023611373..c7ba0bfe09 100644 --- a/src/core/iomgr/unix_sockets_posix.h +++ b/src/core/iomgr/unix_sockets_posix.h @@ -43,25 +43,22 @@ #include #include "src/core/client_config/resolver_factory.h" -#include "src/core/client_config/uri_parser.h"; +#include "src/core/client_config/uri_parser.h" #include "src/core/iomgr/resolve_address.h" void grpc_create_socketpair_if_unix(int sv[2]); grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char* name); -int grpc_is_unix_socket(sa_family_t addr_family); +int grpc_is_unix_socket(const struct sockaddr *addr); -static void unlink_if_unix_domain_socket(const struct sockaddr *addr); +void unlink_if_unix_domain_socket(const struct sockaddr *addr); -static int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, - size_t *len); +int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len); -static char *unix_get_default_authority(grpc_resolver_factory *factory, - grpc_uri *uri); +char *unix_get_default_authority(grpc_resolver_factory *factory, grpc_uri *uri); -char *grpc_sockaddr_to_uri_unix_if_possible(char **strp, - const char *format, ...); +char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr); #endif #endif /* GRPC_INTERNAL_CORE_IOMGR_UNIX_SOCKETS_POSIX_H */ diff --git a/src/core/iomgr/unix_sockets_posix_noop.c b/src/core/iomgr/unix_sockets_posix_noop.c index 1e29242486..1f6773576c 100644 --- a/src/core/iomgr/unix_sockets_posix_noop.c +++ b/src/core/iomgr/unix_sockets_posix_noop.c @@ -34,26 +34,31 @@ #include "src/core/iomgr/unix_sockets_posix.h" +#ifdef GPR_POSIX_SOCKET + void grpc_create_socketpair_if_unix(int sv[2]) {} -void grpc_resolve_unix_domain_address(const char* name) { +grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char* name) { return NULL; } -int grpc_is_unix_socket(sa_family_t addr_family) { +int grpc_is_unix_socket(const struct sockaddr *addr) { return false; } -static void unlink_if_unix_domain_socket(const struct sockaddr *addr) {} +void unlink_if_unix_domain_socket(const struct sockaddr *addr) {} -static int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, - size_t *len) {} +int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { + return 0; +} -static char *unix_get_default_authority(grpc_resolver_factory *factory, - grpc_uri *uri) {} +char *unix_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) { + return NULL; +} -char *grpc_sockaddr_to_uri_unix_if_possible(struct sockaddr *addr) { - return NULL; +char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr) { + return NULL; } #endif diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index a543791f5c..9c131bb4f0 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -143,6 +143,8 @@ CORE_SOURCE_FILES = [ 'src/core/iomgr/timer.c', 'src/core/iomgr/timer_heap.c', 'src/core/iomgr/udp_server.c', + 'src/core/iomgr/unix_sockets_posix.c', + 'src/core/iomgr/unix_sockets_posix_noop.c', 'src/core/iomgr/wakeup_fd_eventfd.c', 'src/core/iomgr/wakeup_fd_nospecial.c', 'src/core/iomgr/wakeup_fd_pipe.c', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index a894eaf22b..fe8dbe0418 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -839,6 +839,7 @@ src/core/iomgr/time_averaged_stats.h \ src/core/iomgr/timer.h \ src/core/iomgr/timer_heap.h \ src/core/iomgr/udp_server.h \ +src/core/iomgr/unix_sockets_posix.h \ src/core/iomgr/wakeup_fd_pipe.h \ src/core/iomgr/wakeup_fd_posix.h \ src/core/iomgr/workqueue.h \ @@ -979,6 +980,8 @@ src/core/iomgr/time_averaged_stats.c \ src/core/iomgr/timer.c \ src/core/iomgr/timer_heap.c \ src/core/iomgr/udp_server.c \ +src/core/iomgr/unix_sockets_posix.c \ +src/core/iomgr/unix_sockets_posix_noop.c \ src/core/iomgr/wakeup_fd_eventfd.c \ src/core/iomgr/wakeup_fd_nospecial.c \ src/core/iomgr/wakeup_fd_pipe.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 092ed35ad9..83dbf0ba5f 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -3955,6 +3955,7 @@ "src/core/iomgr/timer.h", "src/core/iomgr/timer_heap.h", "src/core/iomgr/udp_server.h", + "src/core/iomgr/unix_sockets_posix.h", "src/core/iomgr/wakeup_fd_pipe.h", "src/core/iomgr/wakeup_fd_posix.h", "src/core/iomgr/workqueue.h", @@ -4185,6 +4186,9 @@ "src/core/iomgr/timer_heap.h", "src/core/iomgr/udp_server.c", "src/core/iomgr/udp_server.h", + "src/core/iomgr/unix_sockets_posix.c", + "src/core/iomgr/unix_sockets_posix.h", + "src/core/iomgr/unix_sockets_posix_noop.c", "src/core/iomgr/wakeup_fd_eventfd.c", "src/core/iomgr/wakeup_fd_nospecial.c", "src/core/iomgr/wakeup_fd_pipe.c", @@ -4512,6 +4516,7 @@ "src/core/iomgr/timer.h", "src/core/iomgr/timer_heap.h", "src/core/iomgr/udp_server.h", + "src/core/iomgr/unix_sockets_posix.h", "src/core/iomgr/wakeup_fd_pipe.h", "src/core/iomgr/wakeup_fd_posix.h", "src/core/iomgr/workqueue.h", @@ -4726,6 +4731,9 @@ "src/core/iomgr/timer_heap.h", "src/core/iomgr/udp_server.c", "src/core/iomgr/udp_server.h", + "src/core/iomgr/unix_sockets_posix.c", + "src/core/iomgr/unix_sockets_posix.h", + "src/core/iomgr/unix_sockets_posix_noop.c", "src/core/iomgr/wakeup_fd_eventfd.c", "src/core/iomgr/wakeup_fd_nospecial.c", "src/core/iomgr/wakeup_fd_pipe.c", diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index c2635c31a3..ac87537a85 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -348,6 +348,7 @@ + @@ -560,6 +561,10 @@ + + + + diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index 6dd10d3dd3..3a36073b9d 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -211,6 +211,12 @@ src\core\iomgr + + src\core\iomgr + + + src\core\iomgr + src\core\iomgr @@ -722,6 +728,9 @@ src\core\iomgr + + src\core\iomgr + src\core\iomgr diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index f0d869ba93..9126183e20 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -338,6 +338,7 @@ + @@ -538,6 +539,10 @@ + + + + diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index 1f240212a3..b7cf0764e8 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -214,6 +214,12 @@ src\core\iomgr + + src\core\iomgr + + + src\core\iomgr + src\core\iomgr @@ -659,6 +665,9 @@ src\core\iomgr + + src\core\iomgr + src\core\iomgr -- cgit v1.2.3 From aea32070ef96e2dc38a2b06c5fc9e80e4cd347d7 Mon Sep 17 00:00:00 2001 From: vjpai Date: Fri, 18 Mar 2016 12:22:59 -0700 Subject: Remove a typedef that was causing a redefinition error on some compilers --- src/core/iomgr/udp_server.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/udp_server.h b/src/core/iomgr/udp_server.h index a9d0489edf..3f98708318 100644 --- a/src/core/iomgr/udp_server.h +++ b/src/core/iomgr/udp_server.h @@ -37,15 +37,16 @@ #include "src/core/iomgr/endpoint.h" #include "src/core/iomgr/fd_posix.h" -/* Forward decl of grpc_server */ -typedef struct grpc_server grpc_server; +/* Forward decl of struct grpc_server */ +/* This is not typedef'ed to avoid a typedef-redefinition error */ +struct grpc_server; /* Forward decl of grpc_udp_server */ typedef struct grpc_udp_server grpc_udp_server; /* Called when data is available to read from the socket. */ typedef void (*grpc_udp_server_read_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, - grpc_server *server); + struct grpc_server *server); /* Create a server, initially not bound to any ports */ grpc_udp_server *grpc_udp_server_create(void); @@ -53,7 +54,7 @@ grpc_udp_server *grpc_udp_server_create(void); /* Start listening to bound ports */ void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *udp_server, grpc_pollset **pollsets, size_t pollset_count, - grpc_server *server); + struct grpc_server *server); int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned index); -- cgit v1.2.3 From 554c7dd22f5be8abf8cd447270cec2a1e754631c Mon Sep 17 00:00:00 2001 From: Leifur Halldor Asgeirsson Date: Thu, 18 Feb 2016 17:24:05 -0500 Subject: py3 compatibility for test runner & loader --- setup.py | 4 ++-- src/python/grpcio/tests/__init__.py | 4 +++- src/python/grpcio/tests/_loader.py | 4 +++- src/python/grpcio/tests/_result.py | 8 +++++--- src/python/grpcio/tests/_runner.py | 7 +++++-- 5 files changed, 18 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/setup.py b/setup.py index 45ff2cec89..d429282248 100644 --- a/setup.py +++ b/setup.py @@ -106,7 +106,7 @@ if "linux" in sys.platform or "darwin" in sys.platform: DEFINE_MACROS += (('PyMODINIT_FUNC', '__attribute__((visibility ("default"))) void'),) -def cython_extensions(package_names, module_names, extra_sources, include_dirs, +def cython_extensions(module_names, extra_sources, include_dirs, libraries, define_macros, build_with_cython=False): # Set compiler directives linetrace argument only if we care about tracing; # this is due to Cython having different behavior between linetrace being @@ -139,7 +139,7 @@ def cython_extensions(package_names, module_names, extra_sources, include_dirs, return extensions CYTHON_EXTENSION_MODULES = cython_extensions( - list(CYTHON_EXTENSION_PACKAGE_NAMES), list(CYTHON_EXTENSION_MODULE_NAMES), + list(CYTHON_EXTENSION_MODULE_NAMES), list(CYTHON_HELPER_C_FILES) + list(CORE_C_FILES), list(EXTENSION_INCLUDE_DIRECTORIES), list(EXTENSION_LIBRARIES), list(DEFINE_MACROS), bool(BUILD_WITH_CYTHON)) diff --git a/src/python/grpcio/tests/__init__.py b/src/python/grpcio/tests/__init__.py index b76b3985a1..c3b80d766d 100644 --- a/src/python/grpcio/tests/__init__.py +++ b/src/python/grpcio/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,6 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +from __future__ import absolute_import + from tests import _loader from tests import _runner diff --git a/src/python/grpcio/tests/_loader.py b/src/python/grpcio/tests/_loader.py index 6992029b5e..2f9e5c660e 100644 --- a/src/python/grpcio/tests/_loader.py +++ b/src/python/grpcio/tests/_loader.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,6 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +from __future__ import absolute_import + import importlib import pkgutil import re diff --git a/src/python/grpcio/tests/_result.py b/src/python/grpcio/tests/_result.py index 0670be921f..065153f0c3 100644 --- a/src/python/grpcio/tests/_result.py +++ b/src/python/grpcio/tests/_result.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,7 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import cStringIO as StringIO +from __future__ import absolute_import + import collections import itertools import traceback @@ -35,6 +36,7 @@ import unittest from xml.etree import ElementTree import coverage +from six import moves from tests import _loader @@ -356,7 +358,7 @@ def _traceback_string(type, value, trace): Returns: str: Formatted exception descriptive string. """ - buffer = StringIO.StringIO() + buffer = moves.cStringIO() traceback.print_exception(type, value, trace, file=buffer) return buffer.getvalue() diff --git a/src/python/grpcio/tests/_runner.py b/src/python/grpcio/tests/_runner.py index 3b5ca03dd9..e899154b0b 100644 --- a/src/python/grpcio/tests/_runner.py +++ b/src/python/grpcio/tests/_runner.py @@ -27,7 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import cStringIO as StringIO +from __future__ import absolute_import + import collections import fcntl import multiprocessing @@ -41,6 +42,8 @@ import time import unittest import uuid +from six import moves + from tests import _loader from tests import _result @@ -143,7 +146,7 @@ class Runner(object): for case in filtered_cases] case_id_by_case = dict((augmented_case.case, augmented_case.id) for augmented_case in augmented_cases) - result_out = StringIO.StringIO() + result_out = moves.cStringIO() result = _result.TerminalResult( result_out, id_map=lambda case: case_id_by_case[case]) stdout_pipe = CaptureFile(sys.stdout.fileno()) -- cgit v1.2.3 From fbe766ad46cc3a55d507ec1078d4b077b378d7cc Mon Sep 17 00:00:00 2001 From: Leifur Halldor Asgeirsson Date: Thu, 3 Mar 2016 12:04:38 -0500 Subject: replace uses of iteritems with six.iteritems --- .../grpcio/grpc/framework/alpha/_face_utilities.py | 8 +++-- .../grpcio/grpc/framework/alpha/_reexport.py | 6 ++-- .../grpcio/grpc/framework/crust/implementations.py | 6 ++-- .../grpcio/grpc/framework/face/implementations.py | 6 ++-- .../unit/_core_over_links_base_interface_test.py | 6 ++-- ...ust_over_core_over_links_face_interface_test.py | 8 +++-- .../grpcio/tests/unit/beta/_face_interface_test.py | 8 +++-- .../_crust_over_core_face_interface_test.py | 6 ++-- ...blocking_invocation_inline_service_test_case.py | 30 ++++++++-------- .../tests/unit/framework/face/testing/digest.py | 6 ++-- ...vocation_synchronous_event_service_test_case.py | 40 +++++++++++---------- ...ocation_asynchronous_event_service_test_case.py | 40 +++++++++++---------- .../face/_blocking_invocation_inline_service.py | 32 +++++++++-------- .../unit/framework/interfaces/face/_digest.py | 6 ++-- ...future_invocation_asynchronous_event_service.py | 42 +++++++++++----------- src/python/grpcio/tests/unit/test_common.py | 6 ++-- 16 files changed, 144 insertions(+), 112 deletions(-) (limited to 'src') diff --git a/src/python/grpcio/grpc/framework/alpha/_face_utilities.py b/src/python/grpcio/grpc/framework/alpha/_face_utilities.py index fb0cfe426d..9cfdcafe5d 100644 --- a/src/python/grpcio/grpc/framework/alpha/_face_utilities.py +++ b/src/python/grpcio/grpc/framework/alpha/_face_utilities.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -30,6 +30,8 @@ import abc import collections +import six + # face_interfaces is referenced from specification in this module. from grpc.framework.common import cardinality from grpc.framework.face import interfaces as face_interfaces # pylint: disable=unused-import @@ -111,7 +113,7 @@ def break_down_invocation(service_name, method_descriptions): face_cardinalities = {} request_serializers = {} response_deserializers = {} - for name, method_description in method_descriptions.iteritems(): + for name, method_description in six.iteritems(method_descriptions): qualified_name = _qualified_name(service_name, name) method_cardinality = method_description.cardinality() cardinalities[name] = method_description.cardinality() @@ -139,7 +141,7 @@ def break_down_service(service_name, method_descriptions): implementations = {} request_deserializers = {} response_serializers = {} - for name, method_description in method_descriptions.iteritems(): + for name, method_description in six.iteritems(method_descriptions): qualified_name = _qualified_name(service_name, name) method_cardinality = method_description.cardinality() if method_cardinality is interfaces.Cardinality.UNARY_UNARY: diff --git a/src/python/grpcio/grpc/framework/alpha/_reexport.py b/src/python/grpcio/grpc/framework/alpha/_reexport.py index 198cb95ad5..4ea0e94d80 100644 --- a/src/python/grpcio/grpc/framework/alpha/_reexport.py +++ b/src/python/grpcio/grpc/framework/alpha/_reexport.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,6 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import six + from grpc.framework.common import cardinality from grpc.framework.face import exceptions as face_exceptions from grpc.framework.face import interfaces as face_interfaces @@ -181,7 +183,7 @@ def common_cardinality(early_adopter_cardinality): def common_cardinalities(early_adopter_cardinalities): common_cardinalities = {} - for name, early_adopter_cardinality in early_adopter_cardinalities.iteritems(): + for name, early_adopter_cardinality in six.iteritems(early_adopter_cardinalities): common_cardinalities[name] = _EARLY_ADOPTER_CARDINALITY_TO_COMMON_CARDINALITY[ early_adopter_cardinality] return common_cardinalities diff --git a/src/python/grpcio/grpc/framework/crust/implementations.py b/src/python/grpcio/grpc/framework/crust/implementations.py index 4ebc4e9ae8..d0ecafcaf6 100644 --- a/src/python/grpcio/grpc/framework/crust/implementations.py +++ b/src/python/grpcio/grpc/framework/crust/implementations.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -29,6 +29,8 @@ """Entry points into the Crust layer of RPC Framework.""" +import six + from grpc.framework.common import cardinality from grpc.framework.common import style from grpc.framework.crust import _calls @@ -271,7 +273,7 @@ class _DynamicStub(face.DynamicStub): def _adapt_method_implementations(method_implementations, pool): adapted_implementations = {} - for name, method_implementation in method_implementations.iteritems(): + for name, method_implementation in six.iteritems(method_implementations): if method_implementation.style is style.Service.INLINE: if method_implementation.cardinality is cardinality.Cardinality.UNARY_UNARY: adapted_implementations[name] = _service.adapt_inline_unary_unary( diff --git a/src/python/grpcio/grpc/framework/face/implementations.py b/src/python/grpcio/grpc/framework/face/implementations.py index 4a6de52974..9c75a5faf4 100644 --- a/src/python/grpcio/grpc/framework/face/implementations.py +++ b/src/python/grpcio/grpc/framework/face/implementations.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -29,6 +29,8 @@ """Entry points into the Face layer of RPC Framework.""" +import six + from grpc.framework.common import cardinality from grpc.framework.common import style from grpc.framework.base import exceptions as _base_exceptions @@ -228,7 +230,7 @@ class _DynamicStub(interfaces.DynamicStub): def _adapt_method_implementations(method_implementations, pool): adapted_implementations = {} - for name, method_implementation in method_implementations.iteritems(): + for name, method_implementation in six.iteritems(method_implementations): if method_implementation.style is style.Service.INLINE: if method_implementation.cardinality is cardinality.Cardinality.UNARY_UNARY: adapted_implementations[name] = _service.adapt_inline_value_in_value_out( diff --git a/src/python/grpcio/tests/unit/_core_over_links_base_interface_test.py b/src/python/grpcio/tests/unit/_core_over_links_base_interface_test.py index efc990421a..881633754c 100644 --- a/src/python/grpcio/tests/unit/_core_over_links_base_interface_test.py +++ b/src/python/grpcio/tests/unit/_core_over_links_base_interface_test.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -35,6 +35,8 @@ import random import time import unittest +import six + from grpc._adapter import _intermediary_low from grpc._links import invocation from grpc._links import service @@ -68,7 +70,7 @@ def _serialization_behaviors_from_serializations(serializations): request_deserializers = {} response_serializers = {} response_deserializers = {} - for (group, method), serialization in serializations.iteritems(): + for (group, method), serialization in six.iteritems(serializations): request_serializers[group, method] = serialization.serialize_request request_deserializers[group, method] = serialization.deserialize_request response_serializers[group, method] = serialization.serialize_response diff --git a/src/python/grpcio/tests/unit/_crust_over_core_over_links_face_interface_test.py b/src/python/grpcio/tests/unit/_crust_over_core_over_links_face_interface_test.py index 4faaaadc2b..3be3b051fb 100644 --- a/src/python/grpcio/tests/unit/_crust_over_core_over_links_face_interface_test.py +++ b/src/python/grpcio/tests/unit/_crust_over_core_over_links_face_interface_test.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -32,6 +32,8 @@ import collections import unittest +import six + from grpc._adapter import _intermediary_low from grpc._links import invocation from grpc._links import service @@ -59,7 +61,7 @@ def _serialization_behaviors_from_test_methods(test_methods): request_deserializers = {} response_serializers = {} response_deserializers = {} - for (group, method), test_method in test_methods.iteritems(): + for (group, method), test_method in six.iteritems(test_methods): request_serializers[group, method] = test_method.serialize_request request_deserializers[group, method] = test_method.deserialize_request response_serializers[group, method] = test_method.serialize_response @@ -108,7 +110,7 @@ class _Implementation(test_interfaces.Implementation): # _digest.TestServiceDigest. cardinalities = { method: method_object.cardinality() - for (group, method), method_object in methods.iteritems()} + for (group, method), method_object in six.iteritems(methods)} dynamic_stub = crust_implementations.dynamic_stub( invocation_end_link, group, cardinalities, pool) diff --git a/src/python/grpcio/tests/unit/beta/_face_interface_test.py b/src/python/grpcio/tests/unit/beta/_face_interface_test.py index 1c21dfd03d..cb302bbf68 100644 --- a/src/python/grpcio/tests/unit/beta/_face_interface_test.py +++ b/src/python/grpcio/tests/unit/beta/_face_interface_test.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -32,6 +32,8 @@ import collections import unittest +import six + from grpc.beta import implementations from grpc.beta import interfaces from tests.unit import resources @@ -57,7 +59,7 @@ def _serialization_behaviors_from_test_methods(test_methods): request_deserializers = {} response_serializers = {} response_deserializers = {} - for (group, method), test_method in test_methods.iteritems(): + for (group, method), test_method in six.iteritems(test_methods): request_serializers[group, method] = test_method.serialize_request request_deserializers[group, method] = test_method.deserialize_request response_serializers[group, method] = test_method.serialize_response @@ -79,7 +81,7 @@ class _Implementation(test_interfaces.Implementation): # _digest.TestServiceDigest. cardinalities = { method: method_object.cardinality() - for (group, method), method_object in methods.iteritems()} + for (group, method), method_object in six.iteritems(methods)} server_options = implementations.server_options( request_deserializers=serialization_behaviors.request_deserializers, diff --git a/src/python/grpcio/tests/unit/framework/_crust_over_core_face_interface_test.py b/src/python/grpcio/tests/unit/framework/_crust_over_core_face_interface_test.py index 360ecc95d5..fd2d4298f9 100644 --- a/src/python/grpcio/tests/unit/framework/_crust_over_core_face_interface_test.py +++ b/src/python/grpcio/tests/unit/framework/_crust_over_core_face_interface_test.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -32,6 +32,8 @@ import collections import unittest +import six + from grpc.framework.core import implementations as core_implementations from grpc.framework.crust import implementations as crust_implementations from grpc.framework.foundation import logging_pool @@ -66,7 +68,7 @@ class _Implementation(test_interfaces.Implementation): # _digest.TestServiceDigest. cardinalities = { method: method_object.cardinality() - for (group, method), method_object in methods.iteritems()} + for (group, method), method_object in six.iteritems(methods)} dynamic_stub = crust_implementations.dynamic_stub( invocation_end_link, group, cardinalities, pool) diff --git a/src/python/grpcio/tests/unit/framework/face/testing/blocking_invocation_inline_service_test_case.py b/src/python/grpcio/tests/unit/framework/face/testing/blocking_invocation_inline_service_test_case.py index 0613516421..362ad6bf09 100644 --- a/src/python/grpcio/tests/unit/framework/face/testing/blocking_invocation_inline_service_test_case.py +++ b/src/python/grpcio/tests/unit/framework/face/testing/blocking_invocation_inline_service_test_case.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -33,6 +33,8 @@ import abc import unittest # pylint: disable=unused-import +import six + from grpc.framework.face import exceptions from tests.unit.framework.common import test_constants from tests.unit.framework.face.testing import control @@ -72,7 +74,7 @@ class BlockingInvocationInlineServiceTestCase( def testSuccessfulUnaryRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -83,7 +85,7 @@ class BlockingInvocationInlineServiceTestCase( def testSuccessfulUnaryRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -95,7 +97,7 @@ class BlockingInvocationInlineServiceTestCase( def testSuccessfulStreamRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -106,7 +108,7 @@ class BlockingInvocationInlineServiceTestCase( def testSuccessfulStreamRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -118,7 +120,7 @@ class BlockingInvocationInlineServiceTestCase( def testSequentialInvocations(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: first_request = test_messages.request() second_request = test_messages.request() @@ -135,7 +137,7 @@ class BlockingInvocationInlineServiceTestCase( def testExpiredUnaryRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -146,7 +148,7 @@ class BlockingInvocationInlineServiceTestCase( def testExpiredUnaryRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -158,7 +160,7 @@ class BlockingInvocationInlineServiceTestCase( def testExpiredStreamRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -169,7 +171,7 @@ class BlockingInvocationInlineServiceTestCase( def testExpiredStreamRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -181,7 +183,7 @@ class BlockingInvocationInlineServiceTestCase( def testFailedUnaryRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -191,7 +193,7 @@ class BlockingInvocationInlineServiceTestCase( def testFailedUnaryRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -202,7 +204,7 @@ class BlockingInvocationInlineServiceTestCase( def testFailedStreamRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -212,7 +214,7 @@ class BlockingInvocationInlineServiceTestCase( def testFailedStreamRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() diff --git a/src/python/grpcio/tests/unit/framework/face/testing/digest.py b/src/python/grpcio/tests/unit/framework/face/testing/digest.py index 39f28b9657..100067cc83 100644 --- a/src/python/grpcio/tests/unit/framework/face/testing/digest.py +++ b/src/python/grpcio/tests/unit/framework/face/testing/digest.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -32,6 +32,8 @@ import collections import threading +import six + # testing_control, interfaces, and testing_service are referenced from # specification in this module. from grpc.framework.common import cardinality @@ -368,7 +370,7 @@ def _assemble( events = {} adaptations = {} messages = {} - for name, scenario in scenarios.iteritems(): + for name, scenario in six.iteritems(scenarios): if name in names: raise ValueError('Repeated name "%s"!' % name) diff --git a/src/python/grpcio/tests/unit/framework/face/testing/event_invocation_synchronous_event_service_test_case.py b/src/python/grpcio/tests/unit/framework/face/testing/event_invocation_synchronous_event_service_test_case.py index 179f3a2f67..3b5c21e2af 100644 --- a/src/python/grpcio/tests/unit/framework/face/testing/event_invocation_synchronous_event_service_test_case.py +++ b/src/python/grpcio/tests/unit/framework/face/testing/event_invocation_synchronous_event_service_test_case.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -32,6 +32,8 @@ import abc import unittest +import six + from grpc.framework.face import interfaces from tests.unit.framework.common import test_constants from tests.unit.framework.face.testing import callback as testing_callback @@ -72,7 +74,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testSuccessfulUnaryRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() callback = testing_callback.Callback() @@ -87,7 +89,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testSuccessfulUnaryRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() callback = testing_callback.Callback() @@ -102,7 +104,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testSuccessfulStreamRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() callback = testing_callback.Callback() @@ -120,7 +122,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testSuccessfulStreamRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() callback = testing_callback.Callback() @@ -138,7 +140,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testSequentialInvocations(self): # pylint: disable=cell-var-from-loop for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: first_request = test_messages.request() second_request = test_messages.request() @@ -163,7 +165,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testExpiredUnaryRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() callback = testing_callback.Callback() @@ -178,7 +180,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testExpiredUnaryRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() callback = testing_callback.Callback() @@ -193,7 +195,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testExpiredStreamRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_unary_messages_sequences)): for unused_test_messages in test_messages_sequence: callback = testing_callback.Callback() @@ -206,7 +208,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testExpiredStreamRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() callback = testing_callback.Callback() @@ -221,7 +223,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testFailedUnaryRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() callback = testing_callback.Callback() @@ -237,7 +239,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testFailedUnaryRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() callback = testing_callback.Callback() @@ -253,7 +255,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testFailedStreamRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() callback = testing_callback.Callback() @@ -272,7 +274,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testFailedStreamRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() callback = testing_callback.Callback() @@ -289,7 +291,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testParallelInvocations(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: first_request = test_messages.request() first_callback = testing_callback.Callback() @@ -316,7 +318,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testCancelledUnaryRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() callback = testing_callback.Callback() @@ -332,7 +334,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testCancelledUnaryRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() callback = testing_callback.Callback() @@ -347,7 +349,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testCancelledStreamRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() callback = testing_callback.Callback() @@ -364,7 +366,7 @@ class EventInvocationSynchronousEventServiceTestCase( def testCancelledStreamRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_stream_messages_sequences)): for unused_test_messages in test_messages_sequence: callback = testing_callback.Callback() diff --git a/src/python/grpcio/tests/unit/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py b/src/python/grpcio/tests/unit/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py index 485524a356..79a5399150 100644 --- a/src/python/grpcio/tests/unit/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py +++ b/src/python/grpcio/tests/unit/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -34,6 +34,8 @@ import contextlib import threading import unittest +import six + from grpc.framework.face import exceptions from grpc.framework.foundation import future from grpc.framework.foundation import logging_pool @@ -105,7 +107,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testSuccessfulUnaryRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -117,7 +119,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testSuccessfulUnaryRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -129,7 +131,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testSuccessfulStreamRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() request_iterator = _PauseableIterator(iter(requests)) @@ -145,7 +147,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testSuccessfulStreamRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() request_iterator = _PauseableIterator(iter(requests)) @@ -161,7 +163,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testSequentialInvocations(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: first_request = test_messages.request() second_request = test_messages.request() @@ -180,7 +182,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testExpiredUnaryRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -195,7 +197,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testExpiredUnaryRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -207,7 +209,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testExpiredStreamRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -222,7 +224,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testExpiredStreamRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -234,7 +236,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testFailedUnaryRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -253,7 +255,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testFailedUnaryRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -268,7 +270,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testFailedStreamRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -287,7 +289,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testFailedStreamRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -302,7 +304,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testParallelInvocations(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: first_request = test_messages.request() second_request = test_messages.request() @@ -324,7 +326,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testCancelledUnaryRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -338,7 +340,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testCancelledUnaryRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -352,7 +354,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testCancelledStreamRequestUnaryResponse(self): for name, test_messages_sequence in ( - self.digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -366,7 +368,7 @@ class FutureInvocationAsynchronousEventServiceTestCase( def testCancelledStreamRequestStreamResponse(self): for name, test_messages_sequence in ( - self.digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self.digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() diff --git a/src/python/grpcio/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py b/src/python/grpcio/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py index c8a3a1bc74..505fffcc89 100644 --- a/src/python/grpcio/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py +++ b/src/python/grpcio/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py @@ -34,6 +34,8 @@ import itertools import unittest from concurrent import futures +import six + # test_interfaces is referenced from specification in this module. from grpc.framework.foundation import logging_pool from grpc.framework.interfaces.face import face @@ -81,7 +83,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testSuccessfulUnaryRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -92,7 +94,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testSuccessfulUnaryRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -104,7 +106,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testSuccessfulStreamRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -115,7 +117,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testSuccessfulStreamRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -127,7 +129,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testSequentialInvocations(self): for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: first_request = test_messages.request() second_request = test_messages.request() @@ -145,7 +147,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testParallelInvocations(self): pool = logging_pool.pool(test_constants.PARALLELISM) for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = [] response_futures = [] @@ -167,7 +169,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testWaitingForSomeButNotAllParallelInvocations(self): pool = logging_pool.pool(test_constants.PARALLELISM) for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = [] response_futures_to_indices = {} @@ -205,7 +207,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testExpiredUnaryRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -216,7 +218,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testExpiredUnaryRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -228,7 +230,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testExpiredStreamRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -239,7 +241,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testExpiredStreamRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -251,7 +253,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testFailedUnaryRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -261,7 +263,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testFailedUnaryRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -272,7 +274,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testFailedStreamRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -282,7 +284,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testFailedStreamRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() diff --git a/src/python/grpcio/tests/unit/framework/interfaces/face/_digest.py b/src/python/grpcio/tests/unit/framework/interfaces/face/_digest.py index 9304b6b1db..40c03f9e71 100644 --- a/src/python/grpcio/tests/unit/framework/interfaces/face/_digest.py +++ b/src/python/grpcio/tests/unit/framework/interfaces/face/_digest.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -32,6 +32,8 @@ import collections import threading +import six + # test_control, _service, and test_interfaces are referenced from specification # in this module. from grpc.framework.common import cardinality @@ -363,7 +365,7 @@ def _assemble( events = {} adaptations = {} messages = {} - for identifier, scenario in scenarios.iteritems(): + for identifier, scenario in six.iteritems(scenarios): if identifier in identifiers: raise ValueError('Repeated identifier "(%s, %s)"!' % identifier) diff --git a/src/python/grpcio/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py b/src/python/grpcio/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py index 1d36a931e8..f411bcaee9 100644 --- a/src/python/grpcio/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py +++ b/src/python/grpcio/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py @@ -36,6 +36,8 @@ import threading import unittest from concurrent import futures +import six + # test_interfaces is referenced from specification in this module. from grpc.framework.foundation import logging_pool from grpc.framework.interfaces.face import face @@ -141,7 +143,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testSuccessfulUnaryRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() callback = _Callback() @@ -156,7 +158,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testSuccessfulUnaryRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -168,7 +170,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testSuccessfulStreamRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() request_iterator = _PauseableIterator(iter(requests)) @@ -188,7 +190,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testSuccessfulStreamRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() request_iterator = _PauseableIterator(iter(requests)) @@ -204,7 +206,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testSequentialInvocations(self): for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: first_request = test_messages.request() second_request = test_messages.request() @@ -223,7 +225,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testParallelInvocations(self): for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: first_request = test_messages.request() second_request = test_messages.request() @@ -239,7 +241,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): test_messages.verify(second_request, second_response, self) for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = [] response_futures = [] @@ -259,7 +261,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testWaitingForSomeButNotAllParallelInvocations(self): pool = logging_pool.pool(test_constants.PARALLELISM) for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = [] response_futures_to_indices = {} @@ -281,7 +283,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testCancelledUnaryRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() callback = _Callback() @@ -298,7 +300,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testCancelledUnaryRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -312,7 +314,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testCancelledStreamRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() callback = _Callback() @@ -329,7 +331,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testCancelledStreamRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -343,7 +345,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testExpiredUnaryRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() callback = _Callback() @@ -360,7 +362,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testExpiredUnaryRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -372,7 +374,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testExpiredStreamRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() callback = _Callback() @@ -389,7 +391,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testExpiredStreamRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() @@ -401,7 +403,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testFailedUnaryRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_unary_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() callback = _Callback() @@ -423,7 +425,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testFailedUnaryRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.unary_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.unary_stream_messages_sequences)): for test_messages in test_messages_sequence: request = test_messages.request() @@ -438,7 +440,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testFailedStreamRequestUnaryResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_unary_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_unary_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() callback = _Callback() @@ -460,7 +462,7 @@ class TestCase(test_coverage.Coverage, unittest.TestCase): def testFailedStreamRequestStreamResponse(self): for (group, method), test_messages_sequence in ( - self._digest.stream_stream_messages_sequences.iteritems()): + six.iteritems(self._digest.stream_stream_messages_sequences)): for test_messages in test_messages_sequence: requests = test_messages.requests() diff --git a/src/python/grpcio/tests/unit/test_common.py b/src/python/grpcio/tests/unit/test_common.py index 29431bfb9d..824f1cbd16 100644 --- a/src/python/grpcio/tests/unit/test_common.py +++ b/src/python/grpcio/tests/unit/test_common.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -31,6 +31,8 @@ import collections +import six + INVOCATION_INITIAL_METADATA = ((b'0', b'abc'), (b'1', b'def'), (b'2', b'ghi'),) SERVICE_INITIAL_METADATA = ((b'3', b'jkl'), (b'4', b'mno'), (b'5', b'pqr'),) SERVICE_TERMINAL_METADATA = ((b'6', b'stu'), (b'7', b'vwx'), (b'8', b'yza'),) @@ -65,7 +67,7 @@ def metadata_transmitted(original_metadata, transmitted_metadata): key, value = tuple(key_value_pair) transmitted[key].append(value) - for key, values in original.iteritems(): + for key, values in six.iteritems(original): transmitted_values = transmitted[key] transmitted_iterator = iter(transmitted_values) try: -- cgit v1.2.3 From 798eeda24e29c24bcd06adef521853ff3db6dc86 Mon Sep 17 00:00:00 2001 From: Leifur Halldor Asgeirsson Date: Tue, 8 Mar 2016 13:18:14 -0500 Subject: python 2/3 compatible abstract servicers/stubs --- src/compiler/python_generator.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc index 4fd5dfbecb..5a2ecce1d4 100644 --- a/src/compiler/python_generator.cc +++ b/src/compiler/python_generator.cc @@ -190,11 +190,10 @@ bool PrintBetaServicer(const ServiceDescriptor* service, "Documentation", doc, }); out->Print("\n"); - out->Print(dict, "class Beta$Service$Servicer(object):\n"); + out->Print(dict, "class Beta$Service$Servicer(six.with_metaclass(abc.ABCMeta, object)):\n"); { IndentScope raii_class_indent(out); out->Print(dict, "\"\"\"$Documentation$\"\"\"\n"); - out->Print("__metaclass__ = abc.ABCMeta\n"); for (int i = 0; i < service->method_count(); ++i) { auto meth = service->method(i); grpc::string arg_name = meth->client_streaming() ? @@ -219,11 +218,10 @@ bool PrintBetaStub(const ServiceDescriptor* service, "Documentation", doc, }); out->Print("\n"); - out->Print(dict, "class Beta$Service$Stub(object):\n"); + out->Print(dict, "class Beta$Service$Stub(six.with_metaclass(abc.ABCMeta, object)):\n"); { IndentScope raii_class_indent(out); out->Print(dict, "\"\"\"$Documentation$\"\"\"\n"); - out->Print("__metaclass__ = abc.ABCMeta\n"); for (int i = 0; i < service->method_count(); ++i) { const MethodDescriptor* meth = service->method(i); grpc::string arg_name = meth->client_streaming() ? @@ -449,6 +447,7 @@ bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name, bool PrintPreamble(const FileDescriptor* file, const GeneratorConfiguration& config, Printer* out) { out->Print("import abc\n"); + out->Print("import six\n"); out->Print("from $Package$ import implementations as beta_implementations\n", "Package", config.beta_package_root); out->Print("from grpc.framework.common import cardinality\n"); -- cgit v1.2.3 From 244545671d5790a3f01b51e028f71b9b1f072c73 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Fri, 18 Mar 2016 14:35:54 -0700 Subject: DocFixit: Troubleshooting info for Windows and some minor tweaks --- examples/node/README.md | 5 +++++ src/node/README.md | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/examples/node/README.md b/examples/node/README.md index c1ef6b05ab..28878833ce 100644 --- a/examples/node/README.md +++ b/examples/node/README.md @@ -10,6 +10,11 @@ INSTALL ------- ```sh + $ # Get the gRPC repository + $ export REPO_ROOT=grpc # REPO root can be any directory of your choice + $ git clone https://github.com/grpc/grpc.git $REPO_ROOT + $ cd $REPO_ROOT + $ cd examples/node $ npm install ``` diff --git a/src/node/README.md b/src/node/README.md index 3501b54a66..6b832e581c 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -7,6 +7,8 @@ Beta ## PREREQUISITES - `node`: This requires `node` to be installed, version `0.12` or above. If you instead have the `nodejs` executable on Debian, you should install the [`nodejs-legacy`](https://packages.debian.org/sid/nodejs-legacy) package. +- **Note:** If you installed `node` via a package manager and the version is still less than `0.12`, try directly installing it from [nodejs.org](https://nodejs.org). + ## INSTALLATION Install the gRPC NPM package @@ -17,7 +19,21 @@ npm install grpc ## BUILD FROM SOURCE 1. Clone [the grpc Git Repository](https://github.com/grpc/grpc). - 3. Run `npm install`. + 2. Run `npm install` from the repository root. + + - **Note:** On Windows, this might fail due to [issue# 4932](https:\github.com\nodejs\node\issues\4932) in which case, you will see something like the following in `npm install`'s output (towards the very beginning): + + ``` + .. + Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch. + WINDOWS_BUILD_WARNING + "..\IMPORTANT: Due to https:\github.com\nodejs\node\issues\4932, to build this library on Windows, you must first remove C:\Users\jenkins\.node-gyp\4.4.0\include\node\openssl" + ... + .. + ``` + + To fix this, you will have to delete the folder `C:\Users\\.node-gyp\\include\node\openssl` and retry `npm install` + ## TESTING To run the test suite, simply run `npm test` in the install location. -- cgit v1.2.3 From 4ce09cf760db8771f9c9b222d6f06df61c058ff7 Mon Sep 17 00:00:00 2001 From: vjpai Date: Fri, 18 Mar 2016 23:09:15 -0700 Subject: Reorder a release store after the operations it protects. --- src/core/iomgr/fd_posix.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c index 4ba7c5df94..3edafa0b07 100644 --- a/src/core/iomgr/fd_posix.c +++ b/src/core/iomgr/fd_posix.c @@ -72,6 +72,9 @@ static grpc_fd *fd_freelist = NULL; static gpr_mu fd_freelist_mu; static void freelist_fd(grpc_fd *fd) { + // Note that this function must be called after a release store (or + // full-barrier operation) on refst so that prior actions on the fd are + // ordered before the fd becomes visible to the freelist gpr_mu_lock(&fd_freelist_mu); fd->freelist_next = fd_freelist; fd_freelist = fd; @@ -92,7 +95,6 @@ static grpc_fd *alloc_fd(int fd) { gpr_mu_init(&r->mu); } - gpr_atm_rel_store(&r->refst, 1); r->shutdown = 0; r->read_closure = CLOSURE_NOT_READY; r->write_closure = CLOSURE_NOT_READY; @@ -104,6 +106,11 @@ static grpc_fd *alloc_fd(int fd) { r->on_done_closure = NULL; r->closed = 0; r->released = 0; + // The last operation on r before returning it should be a release-store + // so that all the above fields are globally visible before the value of + // r could escape to another thread. Our refcount itself needs a release-store + // so use this + gpr_atm_rel_store(&r->refst, 1); return r; } -- cgit v1.2.3 From 0b6cb7dcb23ea34e5c4d8de0cb0492995750fe5c Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Sun, 20 Mar 2016 23:57:04 -0700 Subject: Revert "Redo "Pass a non-infinite deadline to grpc_completion_queue_next() to prevent queues from blocking indefinitely in poll()"" --- .../GRPCClient/private/GRPCCompletionQueue.h | 7 ------- .../GRPCClient/private/GRPCCompletionQueue.m | 24 +++++----------------- 2 files changed, 5 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h index a52095dd01..7b66cd4c32 100644 --- a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h +++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h @@ -36,8 +36,6 @@ typedef void(^GRPCQueueCompletionHandler)(bool success); -extern const int64_t kGRPCCompletionQueueDefaultTimeoutSecs; - /** * This class lets one more easily use |grpc_completion_queue|. To use it, pass the value of the * |unmanagedQueue| property of an instance of this class to |grpc_channel_create_call|. Then for @@ -51,11 +49,6 @@ extern const int64_t kGRPCCompletionQueueDefaultTimeoutSecs; */ @interface GRPCCompletionQueue : NSObject @property(nonatomic, readonly) grpc_completion_queue *unmanagedQueue; -@property(nonatomic, readonly) int64_t timeoutSecs; + (instancetype)completionQueue; - -- (instancetype)init; -- (instancetype)initWithTimeout:(int64_t)timeoutSecs NS_DESIGNATED_INITIALIZER; - @end diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m index be214d4d36..d89602f7cb 100644 --- a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m +++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m @@ -35,9 +35,6 @@ #import - -const int64_t kGRPCCompletionQueueDefaultTimeoutSecs = 60; - @implementation GRPCCompletionQueue + (instancetype)completionQueue { @@ -50,13 +47,8 @@ const int64_t kGRPCCompletionQueueDefaultTimeoutSecs = 60; } - (instancetype)init { - return [self initWithTimeout:kGRPCCompletionQueueDefaultTimeoutSecs]; -} - -- (instancetype)initWithTimeout:(int64_t)timeoutSecs { if ((self = [super init])) { _unmanagedQueue = grpc_completion_queue_create(NULL); - _timeoutSecs = timeoutSecs; // This is for the following block to capture the pointer by value (instead // of retaining self and doing self->_unmanagedQueue). This is essential @@ -74,28 +66,22 @@ const int64_t kGRPCCompletionQueueDefaultTimeoutSecs = 60; gDefaultConcurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); }); dispatch_async(gDefaultConcurrentQueue, ^{ - // Using a non-infinite deadline to re-enter grpc_completion_queue_next() - // alleviates https://github.com/grpc/grpc/issues/5593 - gpr_timespec deadline = (timeoutSecs < 0) - ? gpr_inf_future(GPR_CLOCK_REALTIME) - : gpr_time_from_seconds(timeoutSecs, GPR_CLOCK_REALTIME); while (YES) { - // The following call blocks until an event is available or the deadline elapses. - grpc_event event = grpc_completion_queue_next(unmanagedQueue, deadline, NULL); + // The following call blocks until an event is available. + grpc_event event = grpc_completion_queue_next(unmanagedQueue, + gpr_inf_future(GPR_CLOCK_REALTIME), + NULL); GRPCQueueCompletionHandler handler; switch (event.type) { case GRPC_OP_COMPLETE: handler = (__bridge_transfer GRPCQueueCompletionHandler)event.tag; handler(event.success); break; - case GRPC_QUEUE_TIMEOUT: - // Nothing to do here - break; case GRPC_QUEUE_SHUTDOWN: grpc_completion_queue_destroy(unmanagedQueue); return; default: - [NSException raise:@"Unrecognized completion type" format:@"type=%d", event.type]; + [NSException raise:@"Unrecognized completion type" format:@""]; } }; }); -- cgit v1.2.3 From 07503b6e5c725ae875b908dd467589e80b4480fe Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Mon, 21 Mar 2016 11:59:33 -0700 Subject: Add identity to static metadata accept-encodings bitmasks --- src/core/transport/static_metadata.c | 2 +- tools/codegen/core/gen_static_metadata.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/core/transport/static_metadata.c b/src/core/transport/static_metadata.c index eeedae0619..84abb59e99 100644 --- a/src/core/transport/static_metadata.c +++ b/src/core/transport/static_metadata.c @@ -50,7 +50,7 @@ grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 7, 5, 2, 4, 8, 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 8, 6, 2, 4, 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index e6ae00e611..593baec7fc 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -196,7 +196,7 @@ for mask in range(1, 1< Date: Mon, 21 Mar 2016 22:19:43 +0100 Subject: For GRPCOperation's, ensure finish _handler can only be called once, and release it when called, so weak ptrs needn't be used with it, and the call won't be released until the finish handler is called. When the connectivityMonitor determines the connection has been lost, pull the host disconnect call. Creates an unreliable connection when connectivity is restored. Calling finishWithError: is sufficient. --- src/objective-c/GRPCClient/GRPCCall.m | 46 +++++++++------------- .../GRPCClient/private/GRPCWrappedCall.m | 4 +- 2 files changed, 22 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 2d45818b6e..1847d6016f 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -308,37 +308,30 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey"; } - (void)invokeCall { - __weak GRPCCall *weakSelf = self; [self invokeCallWithHeadersHandler:^(NSDictionary *headers) { // Response headers received. - GRPCCall *strongSelf = weakSelf; - if (strongSelf) { - strongSelf.responseHeaders = headers; - [strongSelf startNextRead]; - } + self.responseHeaders = headers; + [self startNextRead]; } completionHandler:^(NSError *error, NSDictionary *trailers) { - GRPCCall *strongSelf = weakSelf; - if (strongSelf) { - strongSelf.responseTrailers = trailers; - - if (error) { - NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; - if (error.userInfo) { - [userInfo addEntriesFromDictionary:error.userInfo]; - } - userInfo[kGRPCTrailersKey] = strongSelf.responseTrailers; - // TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be - // called before this one, so an error might end up with trailers but no headers. We - // shouldn't call finishWithError until ater both blocks are called. It is also when this is - // done that we can provide a merged view of response headers and trailers in a thread-safe - // way. - if (strongSelf.responseHeaders) { - userInfo[kGRPCHeadersKey] = strongSelf.responseHeaders; - } - error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; + self.responseTrailers = trailers; + + if (error) { + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + if (error.userInfo) { + [userInfo addEntriesFromDictionary:error.userInfo]; + } + userInfo[kGRPCTrailersKey] = self.responseTrailers; + // TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be + // called before this one, so an error might end up with trailers but no headers. We + // shouldn't call finishWithError until ater both blocks are called. It is also when this is + // done that we can provide a merged view of response headers and trailers in a thread-safe + // way. + if (self.responseHeaders) { + userInfo[kGRPCHeadersKey] = self.responseHeaders; } - [strongSelf finishWithError:error]; + error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; } + [self finishWithError:error]; }]; // Now that the RPC has been initiated, request writes can start. @synchronized(_requestWriter) { @@ -377,7 +370,6 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey"; [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{NSLocalizedDescriptionKey: @"Connectivity lost."}]]; - [[GRPCHost hostWithAddress:strongSelf->_host] disconnect]; } }]; } diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index fe3d51da53..16e5bff7ff 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -54,7 +54,9 @@ - (void)finish { if (_handler) { - _handler(); + void(^handler)() = _handler; + _handler = nil; + handler(); } } @end -- cgit v1.2.3 From d262454b98ca12b68cf0aa3c7330c9c73d4e7ef7 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 21 Mar 2016 14:31:01 -0700 Subject: Fix time encoding --- src/core/transport/chttp2/timeout_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/transport/chttp2/timeout_encoding.c b/src/core/transport/chttp2/timeout_encoding.c index a6f7081d21..c4802e050e 100644 --- a/src/core/transport/chttp2/timeout_encoding.c +++ b/src/core/transport/chttp2/timeout_encoding.c @@ -150,7 +150,7 @@ int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout) { /* spec allows max. 8 digits, but we allow values up to 1,000,000,000 */ if (x >= (100 * 1000 * 1000)) { if (x != (100 * 1000 * 1000) || digit != 0) { - *timeout = gpr_inf_future(GPR_CLOCK_REALTIME); + *timeout = gpr_inf_future(GPR_TIMESPAN); return 1; } } -- cgit v1.2.3 From c6993428c271513dfe15c9ff6f823ca656fbcbd6 Mon Sep 17 00:00:00 2001 From: vjpai Date: Mon, 21 Mar 2016 14:33:16 -0700 Subject: Lock the FD when initializing it out of the freelist. --- src/core/iomgr/fd_posix.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c index 3edafa0b07..b4d038a3a1 100644 --- a/src/core/iomgr/fd_posix.c +++ b/src/core/iomgr/fd_posix.c @@ -72,9 +72,6 @@ static grpc_fd *fd_freelist = NULL; static gpr_mu fd_freelist_mu; static void freelist_fd(grpc_fd *fd) { - // Note that this function must be called after a release store (or - // full-barrier operation) on refst so that prior actions on the fd are - // ordered before the fd becomes visible to the freelist gpr_mu_lock(&fd_freelist_mu); fd->freelist_next = fd_freelist; fd_freelist = fd; @@ -95,6 +92,7 @@ static grpc_fd *alloc_fd(int fd) { gpr_mu_init(&r->mu); } + gpr_mu_lock(&r->mu); r->shutdown = 0; r->read_closure = CLOSURE_NOT_READY; r->write_closure = CLOSURE_NOT_READY; @@ -106,11 +104,9 @@ static grpc_fd *alloc_fd(int fd) { r->on_done_closure = NULL; r->closed = 0; r->released = 0; - // The last operation on r before returning it should be a release-store - // so that all the above fields are globally visible before the value of - // r could escape to another thread. Our refcount itself needs a release-store - // so use this gpr_atm_rel_store(&r->refst, 1); + gpr_mu_unlock(&r->mu); + return r; } -- cgit v1.2.3 From 3abc651db11fbe6b5b7b1ab7a22feef82a51166f Mon Sep 17 00:00:00 2001 From: vjpai Date: Mon, 21 Mar 2016 14:51:52 -0700 Subject: Remove a spammy log --- src/core/channel/channel_stack_builder.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/core/channel/channel_stack_builder.c b/src/core/channel/channel_stack_builder.c index 80e2e393f9..1b1004e5f9 100644 --- a/src/core/channel/channel_stack_builder.c +++ b/src/core/channel/channel_stack_builder.c @@ -216,7 +216,6 @@ void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx, // count the number of filters size_t num_filters = 0; for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) { - gpr_log(GPR_DEBUG, "%d: %s", num_filters, p->filter->name); num_filters++; } -- cgit v1.2.3 From 6bda8497b889f1ca587006bf58bedca16296f72b Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 21 Mar 2016 23:15:09 +0100 Subject: Fixing copyrights. --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 1847d6016f..51263b073c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 16e5bff7ff..f6527e283c 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.3 From fb349b9f7150c20a98565bfffdceaab6b50a92a2 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Mon, 21 Mar 2016 15:37:20 -0700 Subject: removed uchannels --- BUILD | 6 - Makefile | 58 - binding.gyp | 1 - build.yaml | 2 - config.m4 | 1 - gRPC.podspec | 3 - grpc.gemspec | 2 - package.json | 2 - package.xml | 2 - src/core/census/grpc_plugin.c | 2 - src/core/channel/client_uchannel.c | 233 -- src/core/channel/client_uchannel.h | 60 - src/core/channel/subchannel_call_holder.h | 5 +- src/core/surface/channel_connectivity.c | 17 +- src/core/surface/channel_init.c | 2 - src/core/surface/channel_stack_type.c | 2 - src/core/surface/channel_stack_type.h | 3 - src/core/surface/init.c | 6 - src/python/grpcio/grpc_core_dependencies.py | 1 - test/core/end2end/fixtures/h2_uchannel.c | 350 -- test/core/end2end/gen_build_yaml.py | 1 - tools/doxygen/Doxyfile.core.internal | 2 - tools/run_tests/sources_and_headers.json | 40 - tools/run_tests/tests.json | 3442 ++++++-------------- vsprojects/buildtests_c.sln | 56 - vsprojects/vcxproj/grpc/grpc.vcxproj | 3 - vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 6 - .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj | 3 - .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 6 - .../h2_uchannel_nosec_test.vcxproj | 202 -- .../h2_uchannel_nosec_test.vcxproj.filters | 24 - .../h2_uchannel_test/h2_uchannel_test.vcxproj | 202 -- .../h2_uchannel_test.vcxproj.filters | 24 - 33 files changed, 1054 insertions(+), 3715 deletions(-) delete mode 100644 src/core/channel/client_uchannel.c delete mode 100644 src/core/channel/client_uchannel.h delete mode 100644 test/core/end2end/fixtures/h2_uchannel.c delete mode 100644 vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_nosec_test/h2_uchannel_nosec_test.vcxproj delete mode 100644 vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_nosec_test/h2_uchannel_nosec_test.vcxproj.filters delete mode 100644 vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_test/h2_uchannel_test.vcxproj delete mode 100644 vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_test/h2_uchannel_test.vcxproj.filters (limited to 'src') diff --git a/BUILD b/BUILD index 514aea8f53..2c2cce76c4 100644 --- a/BUILD +++ b/BUILD @@ -163,7 +163,6 @@ cc_library( "src/core/channel/channel_stack.h", "src/core/channel/channel_stack_builder.h", "src/core/channel/client_channel.h", - "src/core/channel/client_uchannel.h", "src/core/channel/compress_filter.h", "src/core/channel/connected_channel.h", "src/core/channel/context.h", @@ -305,7 +304,6 @@ cc_library( "src/core/channel/channel_stack.c", "src/core/channel/channel_stack_builder.c", "src/core/channel/client_channel.c", - "src/core/channel/client_uchannel.c", "src/core/channel/compress_filter.c", "src/core/channel/connected_channel.c", "src/core/channel/http_client_filter.c", @@ -537,7 +535,6 @@ cc_library( "src/core/channel/channel_stack.h", "src/core/channel/channel_stack_builder.h", "src/core/channel/client_channel.h", - "src/core/channel/client_uchannel.h", "src/core/channel/compress_filter.h", "src/core/channel/connected_channel.h", "src/core/channel/context.h", @@ -666,7 +663,6 @@ cc_library( "src/core/channel/channel_stack.c", "src/core/channel/channel_stack_builder.c", "src/core/channel/client_channel.c", - "src/core/channel/client_uchannel.c", "src/core/channel/compress_filter.c", "src/core/channel/connected_channel.c", "src/core/channel/http_client_filter.c", @@ -1367,7 +1363,6 @@ objc_library( "src/core/channel/channel_stack.c", "src/core/channel/channel_stack_builder.c", "src/core/channel/client_channel.c", - "src/core/channel/client_uchannel.c", "src/core/channel/compress_filter.c", "src/core/channel/connected_channel.c", "src/core/channel/http_client_filter.c", @@ -1544,7 +1539,6 @@ objc_library( "src/core/channel/channel_stack.h", "src/core/channel/channel_stack_builder.h", "src/core/channel/client_channel.h", - "src/core/channel/client_uchannel.h", "src/core/channel/compress_filter.h", "src/core/channel/connected_channel.h", "src/core/channel/context.h", diff --git a/Makefile b/Makefile index c7f7c9c450..37f0167305 100644 --- a/Makefile +++ b/Makefile @@ -1084,7 +1084,6 @@ h2_sockpair_1byte_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test h2_ssl_test: $(BINDIR)/$(CONFIG)/h2_ssl_test h2_ssl+poll_test: $(BINDIR)/$(CONFIG)/h2_ssl+poll_test h2_ssl_proxy_test: $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test -h2_uchannel_test: $(BINDIR)/$(CONFIG)/h2_uchannel_test h2_uds_test: $(BINDIR)/$(CONFIG)/h2_uds_test h2_uds+poll_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_test h2_census_nosec_test: $(BINDIR)/$(CONFIG)/h2_census_nosec_test @@ -1098,7 +1097,6 @@ h2_proxy_nosec_test: $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test h2_sockpair_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test h2_sockpair+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test h2_sockpair_1byte_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test -h2_uchannel_nosec_test: $(BINDIR)/$(CONFIG)/h2_uchannel_nosec_test h2_uds_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds_nosec_test h2_uds+poll_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_nosec_test @@ -1307,7 +1305,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/h2_ssl_test \ $(BINDIR)/$(CONFIG)/h2_ssl+poll_test \ $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test \ - $(BINDIR)/$(CONFIG)/h2_uchannel_test \ $(BINDIR)/$(CONFIG)/h2_uds_test \ $(BINDIR)/$(CONFIG)/h2_uds+poll_test \ $(BINDIR)/$(CONFIG)/h2_census_nosec_test \ @@ -1321,7 +1318,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test \ $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test \ $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test \ - $(BINDIR)/$(CONFIG)/h2_uchannel_nosec_test \ $(BINDIR)/$(CONFIG)/h2_uds_nosec_test \ $(BINDIR)/$(CONFIG)/h2_uds+poll_nosec_test \ @@ -2414,7 +2410,6 @@ LIBGRPC_SRC = \ src/core/channel/channel_stack.c \ src/core/channel/channel_stack_builder.c \ src/core/channel/client_channel.c \ - src/core/channel/client_uchannel.c \ src/core/channel/compress_filter.c \ src/core/channel/connected_channel.c \ src/core/channel/http_client_filter.c \ @@ -2775,7 +2770,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/channel/channel_stack.c \ src/core/channel/channel_stack_builder.c \ src/core/channel/client_channel.c \ - src/core/channel/client_uchannel.c \ src/core/channel/compress_filter.c \ src/core/channel/connected_channel.c \ src/core/channel/http_client_filter.c \ @@ -13052,38 +13046,6 @@ endif endif -H2_UCHANNEL_TEST_SRC = \ - test/core/end2end/fixtures/h2_uchannel.c \ - -H2_UCHANNEL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_UCHANNEL_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/h2_uchannel_test: openssl_dep_error - -else - - - -$(BINDIR)/$(CONFIG)/h2_uchannel_test: $(H2_UCHANNEL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_UCHANNEL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uchannel_test - -endif - -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uchannel.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_h2_uchannel_test: $(H2_UCHANNEL_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(H2_UCHANNEL_TEST_OBJS:.o=.dep) -endif -endif - - H2_UDS_TEST_SRC = \ test/core/end2end/fixtures/h2_uds.c \ @@ -13368,26 +13330,6 @@ ifneq ($(NO_DEPS),true) endif -H2_UCHANNEL_NOSEC_TEST_SRC = \ - test/core/end2end/fixtures/h2_uchannel.c \ - -H2_UCHANNEL_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_UCHANNEL_NOSEC_TEST_SRC)))) - - -$(BINDIR)/$(CONFIG)/h2_uchannel_nosec_test: $(H2_UCHANNEL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_UCHANNEL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_uchannel_nosec_test - -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uchannel.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_h2_uchannel_nosec_test: $(H2_UCHANNEL_NOSEC_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(H2_UCHANNEL_NOSEC_TEST_OBJS:.o=.dep) -endif - - H2_UDS_NOSEC_TEST_SRC = \ test/core/end2end/fixtures/h2_uds.c \ diff --git a/binding.gyp b/binding.gyp index 5f9dfd9c6d..c16697786a 100644 --- a/binding.gyp +++ b/binding.gyp @@ -565,7 +565,6 @@ 'src/core/channel/channel_stack.c', 'src/core/channel/channel_stack_builder.c', 'src/core/channel/client_channel.c', - 'src/core/channel/client_uchannel.c', 'src/core/channel/compress_filter.c', 'src/core/channel/connected_channel.c', 'src/core/channel/http_client_filter.c', diff --git a/build.yaml b/build.yaml index deec44f143..28e9ce6d75 100644 --- a/build.yaml +++ b/build.yaml @@ -253,7 +253,6 @@ filegroups: - src/core/channel/channel_stack.h - src/core/channel/channel_stack_builder.h - src/core/channel/client_channel.h - - src/core/channel/client_uchannel.h - src/core/channel/compress_filter.h - src/core/channel/connected_channel.h - src/core/channel/context.h @@ -375,7 +374,6 @@ filegroups: - src/core/channel/channel_stack.c - src/core/channel/channel_stack_builder.c - src/core/channel/client_channel.c - - src/core/channel/client_uchannel.c - src/core/channel/compress_filter.c - src/core/channel/connected_channel.c - src/core/channel/http_client_filter.c diff --git a/config.m4 b/config.m4 index 91b87e2448..2d42c405ec 100644 --- a/config.m4 +++ b/config.m4 @@ -87,7 +87,6 @@ if test "$PHP_GRPC" != "no"; then src/core/channel/channel_stack.c \ src/core/channel/channel_stack_builder.c \ src/core/channel/client_channel.c \ - src/core/channel/client_uchannel.c \ src/core/channel/compress_filter.c \ src/core/channel/connected_channel.c \ src/core/channel/http_client_filter.c \ diff --git a/gRPC.podspec b/gRPC.podspec index 86121c9d28..65f24a658c 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -167,7 +167,6 @@ Pod::Spec.new do |s| 'src/core/channel/channel_stack.h', 'src/core/channel/channel_stack_builder.h', 'src/core/channel/client_channel.h', - 'src/core/channel/client_uchannel.h', 'src/core/channel/compress_filter.h', 'src/core/channel/connected_channel.h', 'src/core/channel/context.h', @@ -322,7 +321,6 @@ Pod::Spec.new do |s| 'src/core/channel/channel_stack.c', 'src/core/channel/channel_stack_builder.c', 'src/core/channel/client_channel.c', - 'src/core/channel/client_uchannel.c', 'src/core/channel/compress_filter.c', 'src/core/channel/connected_channel.c', 'src/core/channel/http_client_filter.c', @@ -497,7 +495,6 @@ Pod::Spec.new do |s| 'src/core/channel/channel_stack.h', 'src/core/channel/channel_stack_builder.h', 'src/core/channel/client_channel.h', - 'src/core/channel/client_uchannel.h', 'src/core/channel/compress_filter.h', 'src/core/channel/connected_channel.h', 'src/core/channel/context.h', diff --git a/grpc.gemspec b/grpc.gemspec index c06262212d..0873286e21 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -163,7 +163,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/channel/channel_stack.h ) s.files += %w( src/core/channel/channel_stack_builder.h ) s.files += %w( src/core/channel/client_channel.h ) - s.files += %w( src/core/channel/client_uchannel.h ) s.files += %w( src/core/channel/compress_filter.h ) s.files += %w( src/core/channel/connected_channel.h ) s.files += %w( src/core/channel/context.h ) @@ -305,7 +304,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/channel/channel_stack.c ) s.files += %w( src/core/channel/channel_stack_builder.c ) s.files += %w( src/core/channel/client_channel.c ) - s.files += %w( src/core/channel/client_uchannel.c ) s.files += %w( src/core/channel/compress_filter.c ) s.files += %w( src/core/channel/connected_channel.c ) s.files += %w( src/core/channel/http_client_filter.c ) diff --git a/package.json b/package.json index 371dfdce99..bc15183c93 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,6 @@ "src/core/channel/channel_stack.h", "src/core/channel/channel_stack_builder.h", "src/core/channel/client_channel.h", - "src/core/channel/client_uchannel.h", "src/core/channel/compress_filter.h", "src/core/channel/connected_channel.h", "src/core/channel/context.h", @@ -247,7 +246,6 @@ "src/core/channel/channel_stack.c", "src/core/channel/channel_stack_builder.c", "src/core/channel/client_channel.c", - "src/core/channel/client_uchannel.c", "src/core/channel/compress_filter.c", "src/core/channel/connected_channel.c", "src/core/channel/http_client_filter.c", diff --git a/package.xml b/package.xml index a0d8bfd885..95bc835602 100644 --- a/package.xml +++ b/package.xml @@ -167,7 +167,6 @@ - @@ -309,7 +308,6 @@ - diff --git a/src/core/census/grpc_plugin.c b/src/core/census/grpc_plugin.c index 3be2a48eb8..8d60a5197e 100644 --- a/src/core/census/grpc_plugin.c +++ b/src/core/census/grpc_plugin.c @@ -63,8 +63,6 @@ void census_grpc_plugin_init(void) { } grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, maybe_add_census_filter, NULL); - grpc_channel_init_register_stage(GRPC_CLIENT_UCHANNEL, INT_MAX, - maybe_add_census_filter, NULL); grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, maybe_add_census_filter, NULL); } diff --git a/src/core/channel/client_uchannel.c b/src/core/channel/client_uchannel.c deleted file mode 100644 index d32327206e..0000000000 --- a/src/core/channel/client_uchannel.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * - * Copyright 2015-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/channel/client_uchannel.h" - -#include - -#include "src/core/census/grpc_filter.h" -#include "src/core/channel/channel_args.h" -#include "src/core/channel/client_channel.h" -#include "src/core/channel/compress_filter.h" -#include "src/core/channel/subchannel_call_holder.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/support/string.h" -#include "src/core/surface/channel.h" -#include "src/core/transport/connectivity_state.h" - -#include -#include -#include -#include - -/** Microchannel (uchannel) implementation: a lightweight channel without any - * load-balancing mechanisms meant for communication from within the core. */ - -typedef struct client_uchannel_channel_data { - /** master channel - the grpc_channel instance that ultimately owns - this channel_data via its channel stack. - We occasionally use this to bump the refcount on the master channel - to keep ourselves alive through an asynchronous operation. */ - grpc_channel_stack *owning_stack; - - /** connectivity state being tracked */ - grpc_connectivity_state_tracker state_tracker; - - /** the subchannel wrapped by the microchannel */ - grpc_connected_subchannel *connected_subchannel; - - /** the callback used to stay subscribed to subchannel connectivity - * notifications */ - grpc_closure connectivity_cb; - - /** the current connectivity state of the wrapped subchannel */ - grpc_connectivity_state subchannel_connectivity; - - gpr_mu mu_state; -} channel_data; - -typedef grpc_subchannel_call_holder call_data; - -static void monitor_subchannel(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_success) { - channel_data *chand = arg; - grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, - chand->subchannel_connectivity, - "uchannel_monitor_subchannel"); - grpc_connected_subchannel_notify_on_state_change( - exec_ctx, chand->connected_subchannel, NULL, - &chand->subchannel_connectivity, &chand->connectivity_cb); -} - -static char *cuc_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { - return grpc_subchannel_call_holder_get_peer(exec_ctx, elem->call_data); -} - -static void cuc_start_transport_stream_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - GRPC_CALL_LOG_OP(GPR_INFO, elem, op); - grpc_subchannel_call_holder_perform_op(exec_ctx, elem->call_data, op); -} - -static void cuc_start_transport_op(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_transport_op *op) { - channel_data *chand = elem->channel_data; - - grpc_exec_ctx_enqueue(exec_ctx, op->on_consumed, true, NULL); - - GPR_ASSERT(op->set_accept_stream == false); - GPR_ASSERT(op->bind_pollset == NULL); - - if (op->on_connectivity_state_change != NULL) { - grpc_connectivity_state_notify_on_state_change( - exec_ctx, &chand->state_tracker, op->connectivity_state, - op->on_connectivity_state_change); - op->on_connectivity_state_change = NULL; - op->connectivity_state = NULL; - } - - if (op->disconnect) { - grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, - GRPC_CHANNEL_FATAL_FAILURE, "disconnect"); - } -} - -static int cuc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *arg, - grpc_metadata_batch *initial_metadata, - grpc_connected_subchannel **connected_subchannel, - grpc_closure *on_ready) { - channel_data *chand = arg; - GPR_ASSERT(initial_metadata != NULL); - *connected_subchannel = chand->connected_subchannel; - return 1; -} - -/* Constructor for call_data */ -static void cuc_init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { - grpc_subchannel_call_holder_init(elem->call_data, cuc_pick_subchannel, - elem->channel_data, args->call_stack); -} - -/* Destructor for call_data */ -static void cuc_destroy_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - grpc_subchannel_call_holder_destroy(exec_ctx, elem->call_data); -} - -/* Constructor for channel_data */ -static void cuc_init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - channel_data *chand = elem->channel_data; - memset(chand, 0, sizeof(*chand)); - grpc_closure_init(&chand->connectivity_cb, monitor_subchannel, chand); - GPR_ASSERT(args->is_last); - GPR_ASSERT(elem->filter == &grpc_client_uchannel_filter); - chand->owning_stack = args->channel_stack; - grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, - "client_uchannel"); - gpr_mu_init(&chand->mu_state); -} - -/* Destructor for channel_data */ -static void cuc_destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) { - channel_data *chand = elem->channel_data; - /* cancel subscription */ - grpc_connected_subchannel_notify_on_state_change( - exec_ctx, chand->connected_subchannel, NULL, NULL, - &chand->connectivity_cb); - grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker); - gpr_mu_destroy(&chand->mu_state); - GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, chand->connected_subchannel, - "uchannel"); -} - -static void cuc_set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_pollset *pollset) { - call_data *calld = elem->call_data; - calld->pollset = pollset; -} - -const grpc_channel_filter grpc_client_uchannel_filter = { - cuc_start_transport_stream_op, cuc_start_transport_op, sizeof(call_data), - cuc_init_call_elem, cuc_set_pollset, cuc_destroy_call_elem, - sizeof(channel_data), cuc_init_channel_elem, cuc_destroy_channel_elem, - cuc_get_peer, "client-uchannel", -}; - -grpc_connectivity_state grpc_client_uchannel_check_connectivity_state( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect) { - channel_data *chand = elem->channel_data; - grpc_connectivity_state out; - gpr_mu_lock(&chand->mu_state); - out = grpc_connectivity_state_check(&chand->state_tracker); - gpr_mu_unlock(&chand->mu_state); - return out; -} - -void grpc_client_uchannel_watch_connectivity_state( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset, - grpc_connectivity_state *state, grpc_closure *on_complete) { - channel_data *chand = elem->channel_data; - gpr_mu_lock(&chand->mu_state); - grpc_connectivity_state_notify_on_state_change( - exec_ctx, &chand->state_tracker, state, on_complete); - gpr_mu_unlock(&chand->mu_state); -} - -grpc_channel *grpc_client_uchannel_create(grpc_subchannel *subchannel, - grpc_channel_args *args) { - grpc_channel *channel = NULL; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - channel = - grpc_channel_create(&exec_ctx, NULL, args, GRPC_CLIENT_UCHANNEL, NULL); - - return channel; -} - -void grpc_client_uchannel_set_connected_subchannel( - grpc_channel *uchannel, grpc_connected_subchannel *connected_subchannel) { - grpc_channel_element *elem = - grpc_channel_stack_last_element(grpc_channel_get_channel_stack(uchannel)); - channel_data *chand = elem->channel_data; - GPR_ASSERT(elem->filter == &grpc_client_uchannel_filter); - gpr_mu_lock(&chand->mu_state); - chand->connected_subchannel = connected_subchannel; - GRPC_CONNECTED_SUBCHANNEL_REF(connected_subchannel, "uchannel"); - gpr_mu_unlock(&chand->mu_state); -} diff --git a/src/core/channel/client_uchannel.h b/src/core/channel/client_uchannel.h deleted file mode 100644 index 8bb288e7d4..0000000000 --- a/src/core/channel/client_uchannel.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Copyright 2015-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_CHANNEL_CLIENT_UCHANNEL_H -#define GRPC_CORE_CHANNEL_CLIENT_UCHANNEL_H - -#include "src/core/channel/channel_stack.h" -#include "src/core/client_config/resolver.h" - -#define GRPC_MICROCHANNEL_SUBCHANNEL_ARG "grpc.microchannel_subchannel_key" - -/* A client microchannel (aka uchannel) is a channel wrapping a subchannel, for - * the purposes of lightweight RPC communications from within the core.*/ - -extern const grpc_channel_filter grpc_client_uchannel_filter; - -grpc_connectivity_state grpc_client_uchannel_check_connectivity_state( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect); - -void grpc_client_uchannel_watch_connectivity_state( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset, - grpc_connectivity_state *state, grpc_closure *on_complete); - -grpc_channel *grpc_client_uchannel_create(grpc_subchannel *subchannel, - grpc_channel_args *args); - -void grpc_client_uchannel_set_connected_subchannel( - grpc_channel *uchannel, grpc_connected_subchannel *connected_subchannel); - -#endif /* GRPC_CORE_CHANNEL_CLIENT_UCHANNEL_H */ diff --git a/src/core/channel/subchannel_call_holder.h b/src/core/channel/subchannel_call_holder.h index 9086cdc882..84b4657db4 100644 --- a/src/core/channel/subchannel_call_holder.h +++ b/src/core/channel/subchannel_call_holder.h @@ -55,15 +55,14 @@ typedef enum { for initial metadata before trying to create a call object, and handling cancellation gracefully. - Both the channel and uchannel filter use this as their call_data. */ + The channel filter uses this as their call_data. */ typedef struct grpc_subchannel_call_holder { /** either 0 for no call, 1 for cancelled, or a pointer to a grpc_subchannel_call */ gpr_atm subchannel_call; /** Helper function to choose the subchannel on which to create the call object. Channel filter delegates to the load - balancing policy (once it's ready); uchannel returns - immediately */ + balancing policy (once it's ready). */ grpc_subchannel_call_holder_pick_subchannel pick_subchannel; void *pick_subchannel_arg; diff --git a/src/core/surface/channel_connectivity.c b/src/core/surface/channel_connectivity.c index 2dd4fce26b..18267939ed 100644 --- a/src/core/surface/channel_connectivity.c +++ b/src/core/surface/channel_connectivity.c @@ -37,7 +37,6 @@ #include #include "src/core/channel/client_channel.h" -#include "src/core/channel/client_uchannel.h" #include "src/core/iomgr/timer.h" #include "src/core/surface/api_trace.h" #include "src/core/surface/completion_queue.h" @@ -58,12 +57,6 @@ grpc_connectivity_state grpc_channel_check_connectivity_state( grpc_exec_ctx_finish(&exec_ctx); return state; } - if (client_channel_elem->filter == &grpc_client_uchannel_filter) { - state = grpc_client_uchannel_check_connectivity_state( - &exec_ctx, client_channel_elem, try_to_connect); - grpc_exec_ctx_finish(&exec_ctx); - return state; - } gpr_log(GPR_ERROR, "grpc_channel_check_connectivity_state called on something that is " "not a (u)client channel, but '%s'", @@ -98,9 +91,6 @@ static void delete_state_watcher(grpc_exec_ctx *exec_ctx, state_watcher *w) { if (client_channel_elem->filter == &grpc_client_channel_filter) { GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, w->channel, "watch_channel_connectivity"); - } else if (client_channel_elem->filter == &grpc_client_uchannel_filter) { - GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, w->channel, - "watch_uchannel_connectivity"); } else { abort(); } @@ -209,11 +199,8 @@ void grpc_channel_watch_connectivity_state( grpc_client_channel_watch_connectivity_state(&exec_ctx, client_channel_elem, grpc_cq_pollset(cq), &w->state, &w->on_complete); - } else if (client_channel_elem->filter == &grpc_client_uchannel_filter) { - GRPC_CHANNEL_INTERNAL_REF(channel, "watch_uchannel_connectivity"); - grpc_client_uchannel_watch_connectivity_state( - &exec_ctx, client_channel_elem, grpc_cq_pollset(cq), &w->state, - &w->on_complete); + } else { + abort(); } grpc_exec_ctx_finish(&exec_ctx); diff --git a/src/core/surface/channel_init.c b/src/core/surface/channel_init.c index 538be84696..ac962f3972 100644 --- a/src/core/surface/channel_init.c +++ b/src/core/surface/channel_init.c @@ -112,8 +112,6 @@ static const char *name_for_type(grpc_channel_stack_type type) { return "CLIENT_SUBCHANNEL"; case GRPC_SERVER_CHANNEL: return "SERVER_CHANNEL"; - case GRPC_CLIENT_UCHANNEL: - return "CLIENT_UCHANNEL"; case GRPC_CLIENT_LAME_CHANNEL: return "CLIENT_LAME_CHANNEL"; case GRPC_CLIENT_DIRECT_CHANNEL: diff --git a/src/core/surface/channel_stack_type.c b/src/core/surface/channel_stack_type.c index 6fd33d411d..29bb7704f8 100644 --- a/src/core/surface/channel_stack_type.c +++ b/src/core/surface/channel_stack_type.c @@ -39,8 +39,6 @@ bool grpc_channel_stack_type_is_client(grpc_channel_stack_type type) { switch (type) { case GRPC_CLIENT_CHANNEL: return true; - case GRPC_CLIENT_UCHANNEL: - return true; case GRPC_CLIENT_SUBCHANNEL: return true; case GRPC_CLIENT_LAME_CHANNEL: diff --git a/src/core/surface/channel_stack_type.h b/src/core/surface/channel_stack_type.h index 846391a68a..75a1b9c072 100644 --- a/src/core/surface/channel_stack_type.h +++ b/src/core/surface/channel_stack_type.h @@ -39,9 +39,6 @@ typedef enum { // normal top-half client channel with load-balancing, connection management GRPC_CLIENT_CHANNEL, - // abbreviated top-half client channel bound to one subchannel - for internal - // load balancing implementation - GRPC_CLIENT_UCHANNEL, // bottom-half of a client channel: everything that happens post-load // balancing (bound to a specific transport) GRPC_CLIENT_SUBCHANNEL, diff --git a/src/core/surface/init.c b/src/core/surface/init.c index b50770959f..2ce50a0d82 100644 --- a/src/core/surface/init.c +++ b/src/core/surface/init.c @@ -45,7 +45,6 @@ #include "src/core/channel/compress_filter.h" #include "src/core/channel/connected_channel.h" #include "src/core/channel/client_channel.h" -#include "src/core/channel/client_uchannel.h" #include "src/core/channel/http_client_filter.h" #include "src/core/channel/http_server_filter.h" #include "src/core/client_config/lb_policy_registry.h" @@ -112,9 +111,6 @@ static void register_builtin_channel_init() { grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, prepend_filter, (void *)&grpc_compress_filter); - grpc_channel_init_register_stage(GRPC_CLIENT_UCHANNEL, INT_MAX, - prepend_filter, - (void *)&grpc_compress_filter); grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter, (void *)&grpc_compress_filter); grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX, @@ -134,8 +130,6 @@ static void register_builtin_channel_init() { grpc_add_connected_filter, NULL); grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, append_filter, (void *)&grpc_client_channel_filter); - grpc_channel_init_register_stage(GRPC_CLIENT_UCHANNEL, INT_MAX, append_filter, - (void *)&grpc_client_uchannel_filter); grpc_channel_init_register_stage(GRPC_CLIENT_LAME_CHANNEL, INT_MAX, append_filter, (void *)&grpc_lame_filter); grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter, diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index b9e7d8c898..29506e69bc 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -81,7 +81,6 @@ CORE_SOURCE_FILES = [ 'src/core/channel/channel_stack.c', 'src/core/channel/channel_stack_builder.c', 'src/core/channel/client_channel.c', - 'src/core/channel/client_uchannel.c', 'src/core/channel/compress_filter.c', 'src/core/channel/connected_channel.c', 'src/core/channel/http_client_filter.c', diff --git a/test/core/end2end/fixtures/h2_uchannel.c b/test/core/end2end/fixtures/h2_uchannel.c deleted file mode 100644 index 25a4804bea..0000000000 --- a/test/core/end2end/fixtures/h2_uchannel.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * - * Copyright 2015-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 "test/core/end2end/end2end_tests.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/client_channel.h" -#include "src/core/channel/client_uchannel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_client_filter.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/client_config/resolver_registry.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -typedef struct { - grpc_connector base; - gpr_refcount refs; - - grpc_closure *notify; - grpc_connect_in_args args; - grpc_connect_out_args *result; - - grpc_endpoint *tcp; - - grpc_closure connected; -} connector; - -static void connector_ref(grpc_connector *con) { - connector *c = (connector *)con; - gpr_ref(&c->refs); -} - -static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { - connector *c = (connector *)con; - if (gpr_unref(&c->refs)) { - gpr_free(c); - } -} - -static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - connector *c = arg; - grpc_closure *notify; - grpc_endpoint *tcp = c->tcp; - if (tcp != NULL) { - c->result->transport = - grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, tcp, 1); - grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, - 0); - GPR_ASSERT(c->result->transport); - } else { - memset(c->result, 0, sizeof(*c->result)); - } - notify = c->notify; - c->notify = NULL; - notify->cb(exec_ctx, notify->cb_arg, 1); -} - -static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) {} - -static void connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *con, - const grpc_connect_in_args *args, - grpc_connect_out_args *result, - grpc_closure *notify) { - connector *c = (connector *)con; - GPR_ASSERT(c->notify == NULL); - GPR_ASSERT(notify->cb); - c->notify = notify; - c->args = *args; - c->result = result; - c->tcp = NULL; - grpc_closure_init(&c->connected, connected, c); - grpc_tcp_client_connect(exec_ctx, &c->connected, &c->tcp, - args->interested_parties, args->addr, args->addr_len, - args->deadline); -} - -static const grpc_connector_vtable connector_vtable = { - connector_ref, connector_unref, connector_shutdown, connector_connect}; - -typedef struct { - grpc_subchannel_factory base; - gpr_refcount refs; - grpc_channel_args *merge_args; - grpc_channel *master; - grpc_subchannel **sniffed_subchannel; -} subchannel_factory; - -static void subchannel_factory_ref(grpc_subchannel_factory *scf) { - subchannel_factory *f = (subchannel_factory *)scf; - gpr_ref(&f->refs); -} - -static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx, - grpc_subchannel_factory *scf) { - subchannel_factory *f = (subchannel_factory *)scf; - if (gpr_unref(&f->refs)) { - GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory"); - grpc_channel_args_destroy(f->merge_args); - gpr_free(f); - } -} - -static grpc_subchannel *subchannel_factory_create_subchannel( - grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *scf, - grpc_subchannel_args *args) { - subchannel_factory *f = (subchannel_factory *)scf; - connector *c = gpr_malloc(sizeof(*c)); - grpc_channel_args *final_args = - grpc_channel_args_merge(args->args, f->merge_args); - grpc_subchannel *s; - memset(c, 0, sizeof(*c)); - c->base.vtable = &connector_vtable; - gpr_ref_init(&c->refs, 1); - args->args = final_args; - s = grpc_subchannel_create(exec_ctx, &c->base, args); - grpc_connector_unref(exec_ctx, &c->base); - grpc_channel_args_destroy(final_args); - if (*f->sniffed_subchannel) { - GRPC_SUBCHANNEL_UNREF(exec_ctx, *f->sniffed_subchannel, "sniffed"); - } - *f->sniffed_subchannel = s; - GRPC_SUBCHANNEL_REF(s, "sniffed"); - return s; -} - -static const grpc_subchannel_factory_vtable test_subchannel_factory_vtable = { - subchannel_factory_ref, subchannel_factory_unref, - subchannel_factory_create_subchannel}; - -/* The evil twin of grpc_insecure_channel_create. It allows the test to use the - * custom-built sniffing subchannel_factory */ -grpc_channel *channel_create(const char *target, const grpc_channel_args *args, - grpc_subchannel **sniffed_subchannel) { - grpc_channel *channel = NULL; - grpc_resolver *resolver; - subchannel_factory *f; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - channel = - grpc_channel_create(&exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL); - - f = gpr_malloc(sizeof(*f)); - f->sniffed_subchannel = sniffed_subchannel; - f->base.vtable = &test_subchannel_factory_vtable; - gpr_ref_init(&f->refs, 1); - f->merge_args = grpc_channel_args_copy(args); - f->master = channel; - GRPC_CHANNEL_INTERNAL_REF(f->master, "test_subchannel_factory"); - resolver = grpc_resolver_create(target, &f->base); - if (!resolver) { - return NULL; - } - - grpc_client_channel_set_resolver( - &exec_ctx, grpc_channel_get_channel_stack(channel), resolver); - GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_create"); - grpc_subchannel_factory_unref(&exec_ctx, &f->base); - - grpc_exec_ctx_finish(&exec_ctx); - - return channel; -} - -typedef struct micro_fullstack_fixture_data { - char *localaddr; - grpc_channel *master_channel; - grpc_subchannel *sniffed_subchannel; -} micro_fullstack_fixture_data; - -static grpc_end2end_test_fixture chttp2_create_fixture_micro_fullstack( - grpc_channel_args *client_args, grpc_channel_args *server_args) { - grpc_end2end_test_fixture f; - int port = grpc_pick_unused_port_or_die(); - micro_fullstack_fixture_data *ffd = - gpr_malloc(sizeof(micro_fullstack_fixture_data)); - memset(&f, 0, sizeof(f)); - memset(ffd, 0, sizeof(*ffd)); - - gpr_join_host_port(&ffd->localaddr, "127.0.0.1", port); - - f.fixture_data = ffd; - f.cq = grpc_completion_queue_create(NULL); - - return f; -} - -grpc_connectivity_state g_state = GRPC_CHANNEL_IDLE; -grpc_pollset_set *g_interested_parties; - -static void state_changed(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - if (g_state != GRPC_CHANNEL_READY) { - grpc_subchannel_notify_on_state_change( - exec_ctx, arg, g_interested_parties, &g_state, - grpc_closure_create(state_changed, arg)); - } -} - -static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - grpc_pollset_destroy(arg); -} - -static grpc_connected_subchannel *connect_subchannel(grpc_subchannel *c) { - gpr_mu *mu; - grpc_pollset *pollset = gpr_malloc(grpc_pollset_size()); - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_pollset_init(pollset, &mu); - g_interested_parties = grpc_pollset_set_create(); - grpc_pollset_set_add_pollset(&exec_ctx, g_interested_parties, pollset); - grpc_subchannel_notify_on_state_change(&exec_ctx, c, g_interested_parties, - &g_state, - grpc_closure_create(state_changed, c)); - grpc_exec_ctx_flush(&exec_ctx); - gpr_mu_lock(mu); - while (g_state != GRPC_CHANNEL_READY) { - grpc_pollset_worker *worker = NULL; - grpc_pollset_work(&exec_ctx, pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1)); - gpr_mu_unlock(mu); - grpc_exec_ctx_flush(&exec_ctx); - gpr_mu_lock(mu); - } - grpc_pollset_shutdown(&exec_ctx, pollset, - grpc_closure_create(destroy_pollset, pollset)); - grpc_pollset_set_destroy(g_interested_parties); - gpr_mu_unlock(mu); - grpc_exec_ctx_finish(&exec_ctx); - gpr_free(pollset); - return grpc_subchannel_get_connected_subchannel(c); -} - -static void chttp2_init_client_micro_fullstack(grpc_end2end_test_fixture *f, - grpc_channel_args *client_args) { - micro_fullstack_fixture_data *ffd = f->fixture_data; - grpc_connectivity_state conn_state; - grpc_connected_subchannel *connected_subchannel; - char *ipv4_localaddr; - - gpr_asprintf(&ipv4_localaddr, "ipv4:%s", ffd->localaddr); - ffd->master_channel = - channel_create(ipv4_localaddr, client_args, &ffd->sniffed_subchannel); - gpr_free(ipv4_localaddr); - gpr_log(GPR_INFO, "MASTER CHANNEL %p ", ffd->master_channel); - /* the following will block. That's ok for this test */ - conn_state = grpc_channel_check_connectivity_state(ffd->master_channel, - 1 /* try to connect */); - GPR_ASSERT(conn_state == GRPC_CHANNEL_IDLE); - - /* here sniffed_subchannel should be ready to use */ - GPR_ASSERT(conn_state == GRPC_CHANNEL_IDLE); - GPR_ASSERT(ffd->sniffed_subchannel != NULL); - - connected_subchannel = connect_subchannel(ffd->sniffed_subchannel); - f->client = grpc_client_uchannel_create(ffd->sniffed_subchannel, client_args); - grpc_client_uchannel_set_connected_subchannel(f->client, - connected_subchannel); - gpr_log(GPR_INFO, "CHANNEL WRAPPING SUBCHANNEL: %p(%p)", f->client, - ffd->sniffed_subchannel); - - GPR_ASSERT(f->client); -} - -static void chttp2_init_server_micro_fullstack(grpc_end2end_test_fixture *f, - grpc_channel_args *server_args) { - micro_fullstack_fixture_data *ffd = f->fixture_data; - if (f->server) { - grpc_server_destroy(f->server); - } - f->server = grpc_server_create(server_args, NULL); - grpc_server_register_completion_queue(f->server, f->cq, NULL); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); - grpc_server_start(f->server); -} - -static void chttp2_tear_down_micro_fullstack(grpc_end2end_test_fixture *f) { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - micro_fullstack_fixture_data *ffd = f->fixture_data; - grpc_channel_destroy(ffd->master_channel); - if (ffd->sniffed_subchannel) { - GRPC_SUBCHANNEL_UNREF(&exec_ctx, ffd->sniffed_subchannel, "sniffed"); - } - gpr_free(ffd->localaddr); - gpr_free(ffd); - grpc_exec_ctx_finish(&exec_ctx); -} - -/* All test configurations */ -static grpc_end2end_test_config configs[] = { - {"chttp2/micro_fullstack", 0, chttp2_create_fixture_micro_fullstack, - chttp2_init_client_micro_fullstack, chttp2_init_server_micro_fullstack, - chttp2_tear_down_micro_fullstack}, -}; - -int main(int argc, char **argv) { - size_t i; - - grpc_test_init(argc, argv); - grpc_init(); - - for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { - grpc_end2end_tests(argc, argv, configs[i]); - } - - grpc_shutdown(); - - return 0; -} diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index fa32601c60..93b48c331c 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -72,7 +72,6 @@ END2END_FIXTURES = { 'h2_ssl+poll': default_secure_fixture_options._replace(platforms=['linux']), 'h2_ssl_proxy': default_secure_fixture_options._replace(includes_proxy=True, ci_mac=False), - 'h2_uchannel': default_unsecure_fixture_options._replace(fullstack=False), 'h2_uds+poll': uds_fixture_options._replace(platforms=['linux']), 'h2_uds': uds_fixture_options, } diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 4fcfba3983..694fd2820b 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -779,7 +779,6 @@ src/core/channel/channel_args.h \ src/core/channel/channel_stack.h \ src/core/channel/channel_stack_builder.h \ src/core/channel/client_channel.h \ -src/core/channel/client_uchannel.h \ src/core/channel/compress_filter.h \ src/core/channel/connected_channel.h \ src/core/channel/context.h \ @@ -921,7 +920,6 @@ src/core/channel/channel_args.c \ src/core/channel/channel_stack.c \ src/core/channel/channel_stack_builder.c \ src/core/channel/client_channel.c \ -src/core/channel/client_uchannel.c \ src/core/channel/compress_filter.c \ src/core/channel/connected_channel.c \ src/core/channel/http_client_filter.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 28647e4406..3b787d680a 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -3472,23 +3472,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "end2end_tests", - "gpr", - "gpr_test_util", - "grpc", - "grpc_test_util" - ], - "headers": [], - "language": "c", - "name": "h2_uchannel_test", - "src": [ - "test/core/end2end/fixtures/h2_uchannel.c" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "end2end_tests", @@ -3710,23 +3693,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "end2end_nosec_tests", - "gpr", - "gpr_test_util", - "grpc_test_util_unsecure", - "grpc_unsecure" - ], - "headers": [], - "language": "c", - "name": "h2_uchannel_nosec_test", - "src": [ - "test/core/end2end/fixtures/h2_uchannel.c" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "end2end_nosec_tests", @@ -3967,7 +3933,6 @@ "src/core/channel/channel_stack.h", "src/core/channel/channel_stack_builder.h", "src/core/channel/client_channel.h", - "src/core/channel/client_uchannel.h", "src/core/channel/compress_filter.h", "src/core/channel/connected_channel.h", "src/core/channel/context.h", @@ -4138,8 +4103,6 @@ "src/core/channel/channel_stack_builder.h", "src/core/channel/client_channel.c", "src/core/channel/client_channel.h", - "src/core/channel/client_uchannel.c", - "src/core/channel/client_uchannel.h", "src/core/channel/compress_filter.c", "src/core/channel/compress_filter.h", "src/core/channel/connected_channel.c", @@ -4594,7 +4557,6 @@ "src/core/channel/channel_stack.h", "src/core/channel/channel_stack_builder.h", "src/core/channel/client_channel.h", - "src/core/channel/client_uchannel.h", "src/core/channel/compress_filter.h", "src/core/channel/connected_channel.h", "src/core/channel/context.h", @@ -4750,8 +4712,6 @@ "src/core/channel/channel_stack_builder.h", "src/core/channel/client_channel.c", "src/core/channel/client_channel.h", - "src/core/channel/client_uchannel.c", - "src/core/channel/client_uchannel.h", "src/core/channel/compress_filter.c", "src/core/channel/compress_filter.h", "src/core/channel/connected_channel.c", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index bd652f2aa7..8db852c0f3 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -15226,7 +15226,6 @@ "bad_hostname" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15235,9 +15234,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15248,7 +15246,6 @@ "binary_metadata" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15257,9 +15254,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15270,7 +15266,6 @@ "call_creds" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15279,9 +15274,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15292,7 +15286,6 @@ "cancel_after_accept" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15301,9 +15294,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15314,7 +15306,6 @@ "cancel_after_client_done" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15323,9 +15314,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15336,7 +15326,6 @@ "cancel_after_invoke" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15345,9 +15334,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15358,7 +15346,6 @@ "cancel_before_invoke" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15367,9 +15354,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15380,7 +15366,6 @@ "cancel_in_a_vacuum" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15389,9 +15374,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15402,7 +15386,6 @@ "cancel_with_status" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15411,9 +15394,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15424,7 +15406,6 @@ "compressed_payload" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15433,9 +15414,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15443,21 +15423,19 @@ }, { "args": [ - "empty_batch" + "connectivity" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15465,21 +15443,19 @@ }, { "args": [ - "graceful_server_shutdown" + "disappearing_server" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15487,10 +15463,9 @@ }, { "args": [ - "high_initial_seqno" + "empty_batch" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15499,9 +15474,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15509,21 +15483,19 @@ }, { "args": [ - "hpack_size" + "graceful_server_shutdown" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15531,10 +15503,9 @@ }, { "args": [ - "invoke_large_request" + "high_initial_seqno" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15543,9 +15514,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15553,10 +15523,9 @@ }, { "args": [ - "large_metadata" + "hpack_size" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15565,9 +15534,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15575,10 +15543,9 @@ }, { "args": [ - "max_concurrent_streams" + "invoke_large_request" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15587,9 +15554,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15597,21 +15563,19 @@ }, { "args": [ - "max_message_length" + "large_metadata" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15619,10 +15583,9 @@ }, { "args": [ - "negative_deadline" + "max_concurrent_streams" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15631,9 +15594,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15641,21 +15603,19 @@ }, { "args": [ - "no_op" + "max_message_length" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15663,21 +15623,19 @@ }, { "args": [ - "payload" + "negative_deadline" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15685,10 +15643,9 @@ }, { "args": [ - "ping_pong_streaming" + "no_op" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15697,9 +15654,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15707,21 +15663,19 @@ }, { "args": [ - "registered_call" + "payload" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15729,10 +15683,9 @@ }, { "args": [ - "request_with_flags" + "ping" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15741,9 +15694,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15751,10 +15703,9 @@ }, { "args": [ - "request_with_payload" + "ping_pong_streaming" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15763,9 +15714,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15773,10 +15723,9 @@ }, { "args": [ - "server_finishes_request" + "registered_call" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15785,9 +15734,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15795,10 +15743,9 @@ }, { "args": [ - "shutdown_finishes_calls" + "request_with_flags" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15807,9 +15754,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15817,10 +15763,9 @@ }, { "args": [ - "shutdown_finishes_tags" + "request_with_payload" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15829,9 +15774,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15839,10 +15783,9 @@ }, { "args": [ - "simple_metadata" + "server_finishes_request" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15851,9 +15794,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15861,10 +15803,9 @@ }, { "args": [ - "simple_request" + "shutdown_finishes_calls" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15873,9 +15814,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15883,10 +15823,9 @@ }, { "args": [ - "trailing_metadata" + "shutdown_finishes_tags" ], "ci_platforms": [ - "windows", "linux", "mac", "posix" @@ -15895,9 +15834,8 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_test", + "name": "h2_uds_test", "platforms": [ - "windows", "linux", "mac", "posix" @@ -15905,14 +15843,14 @@ }, { "args": [ - "bad_hostname" + "simple_delayed_request" ], "ci_platforms": [ "linux", "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", @@ -15925,7 +15863,7 @@ }, { "args": [ - "binary_metadata" + "simple_metadata" ], "ci_platforms": [ "linux", @@ -15945,7 +15883,7 @@ }, { "args": [ - "call_creds" + "simple_request" ], "ci_platforms": [ "linux", @@ -15965,14 +15903,14 @@ }, { "args": [ - "cancel_after_accept" + "trailing_metadata" ], "ci_platforms": [ "linux", "mac", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", @@ -15985,162 +15923,194 @@ }, { "args": [ - "cancel_after_client_done" + "bad_hostname" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { "args": [ - "cancel_after_invoke" + "binary_metadata" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { "args": [ - "cancel_before_invoke" + "call_creds" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { "args": [ - "cancel_in_a_vacuum" + "cancel_after_accept" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { "args": [ - "cancel_with_status" + "cancel_after_client_done" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { "args": [ - "compressed_payload" + "cancel_after_invoke" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { "args": [ - "connectivity" + "cancel_before_invoke" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { "args": [ - "disappearing_server" + "cancel_in_a_vacuum" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_uds+poll_test", + "platforms": [ + "linux" + ] + }, + { + "args": [ + "cancel_with_status" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_uds+poll_test", + "platforms": [ + "linux" + ] + }, + { + "args": [ + "compressed_payload" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_uds+poll_test", + "platforms": [ + "linux" + ] + }, + { + "args": [ + "connectivity" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_uds+poll_test", + "platforms": [ + "linux" + ] + }, + { + "args": [ + "disappearing_server" + ], + "ci_platforms": [ + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16148,19 +16118,15 @@ "empty_batch" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16168,19 +16134,15 @@ "graceful_server_shutdown" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16188,19 +16150,15 @@ "high_initial_seqno" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16208,19 +16166,15 @@ "hpack_size" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16228,19 +16182,15 @@ "invoke_large_request" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16248,19 +16198,15 @@ "large_metadata" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16268,19 +16214,15 @@ "max_concurrent_streams" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16288,19 +16230,15 @@ "max_message_length" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16308,19 +16246,15 @@ "negative_deadline" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16328,19 +16262,15 @@ "no_op" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16348,19 +16278,15 @@ "payload" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16368,19 +16294,15 @@ "ping" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16388,19 +16310,15 @@ "ping_pong_streaming" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16408,19 +16326,15 @@ "registered_call" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16428,19 +16342,15 @@ "request_with_flags" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16448,19 +16358,15 @@ "request_with_payload" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16468,19 +16374,15 @@ "server_finishes_request" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16488,19 +16390,15 @@ "shutdown_finishes_calls" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16508,19 +16406,15 @@ "shutdown_finishes_tags" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16528,19 +16422,15 @@ "simple_delayed_request" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16548,19 +16438,15 @@ "simple_metadata" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16568,19 +16454,15 @@ "simple_request" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16588,19 +16470,15 @@ "trailing_metadata" ], "ci_platforms": [ - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds_test", + "name": "h2_uds+poll_test", "platforms": [ - "linux", - "mac", - "posix" + "linux" ] }, { @@ -16608,15 +16486,21 @@ "bad_hostname" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16624,159 +16508,219 @@ "binary_metadata" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { "args": [ - "call_creds" + "cancel_after_accept" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { "args": [ - "cancel_after_accept" + "cancel_after_client_done" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { "args": [ - "cancel_after_client_done" + "cancel_after_invoke" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { "args": [ - "cancel_after_invoke" + "cancel_before_invoke" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { "args": [ - "cancel_before_invoke" + "cancel_in_a_vacuum" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { "args": [ - "cancel_in_a_vacuum" + "cancel_with_status" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { "args": [ - "cancel_with_status" + "compressed_payload" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { "args": [ - "compressed_payload" + "connectivity" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { "args": [ - "connectivity" + "default_host" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16784,15 +16728,21 @@ "disappearing_server" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16800,15 +16750,21 @@ "empty_batch" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16816,15 +16772,21 @@ "graceful_server_shutdown" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16832,15 +16794,21 @@ "high_initial_seqno" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16848,31 +16816,43 @@ "hpack_size" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" - ] + "windows", + "linux", + "mac", + "posix" + ] }, { "args": [ "invoke_large_request" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16880,15 +16860,21 @@ "large_metadata" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16896,15 +16882,21 @@ "max_concurrent_streams" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16912,15 +16904,21 @@ "max_message_length" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16928,15 +16926,21 @@ "negative_deadline" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16944,15 +16948,21 @@ "no_op" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16960,15 +16970,21 @@ "payload" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16976,15 +16992,21 @@ "ping" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -16992,15 +17014,21 @@ "ping_pong_streaming" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -17008,15 +17036,21 @@ "registered_call" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -17024,15 +17058,21 @@ "request_with_flags" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -17040,15 +17080,21 @@ "request_with_payload" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -17056,15 +17102,21 @@ "server_finishes_request" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -17072,15 +17124,21 @@ "shutdown_finishes_calls" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -17088,15 +17146,21 @@ "shutdown_finishes_tags" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -17104,15 +17168,21 @@ "simple_delayed_request" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -17120,15 +17190,21 @@ "simple_metadata" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -17136,15 +17212,21 @@ "simple_request" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -17152,15 +17234,21 @@ "trailing_metadata" ], "ci_platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uds+poll_test", + "name": "h2_census_nosec_test", "platforms": [ - "linux" + "windows", + "linux", + "mac", + "posix" ] }, { @@ -17177,7 +17265,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17199,7 +17287,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17221,7 +17309,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17243,7 +17331,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17265,7 +17353,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17287,7 +17375,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17309,7 +17397,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17331,7 +17419,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17353,7 +17441,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17375,7 +17463,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17397,7 +17485,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17419,7 +17507,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17441,7 +17529,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17463,7 +17551,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17485,7 +17573,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17507,7 +17595,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17529,7 +17617,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17551,7 +17639,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17573,7 +17661,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17595,7 +17683,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17617,7 +17705,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17639,7 +17727,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17661,7 +17749,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17683,7 +17771,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17705,7 +17793,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17727,7 +17815,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17749,7 +17837,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17771,7 +17859,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17793,7 +17881,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17815,7 +17903,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17837,7 +17925,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17859,7 +17947,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17881,7 +17969,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17903,7 +17991,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17925,7 +18013,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_census_nosec_test", + "name": "h2_compress_nosec_test", "platforms": [ "windows", "linux", @@ -17947,7 +18035,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -17969,7 +18057,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -17991,7 +18079,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18013,7 +18101,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18035,7 +18123,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18057,7 +18145,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18079,7 +18167,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18101,7 +18189,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18123,7 +18211,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18145,7 +18233,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18167,7 +18255,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18189,7 +18277,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18211,7 +18299,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18233,7 +18321,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18255,7 +18343,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18277,7 +18365,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18299,7 +18387,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18321,7 +18409,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18343,7 +18431,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18365,7 +18453,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18387,7 +18475,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18409,7 +18497,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18431,7 +18519,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18453,7 +18541,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18475,7 +18563,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18497,7 +18585,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18519,7 +18607,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18541,7 +18629,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18563,7 +18651,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18585,7 +18673,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18607,7 +18695,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18629,7 +18717,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18651,7 +18739,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18673,7 +18761,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18695,7 +18783,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_compress_nosec_test", + "name": "h2_full_nosec_test", "platforms": [ "windows", "linux", @@ -18708,21 +18796,15 @@ "bad_hostname" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18730,21 +18812,15 @@ "binary_metadata" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18752,21 +18828,15 @@ "cancel_after_accept" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18774,21 +18844,15 @@ "cancel_after_client_done" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18796,21 +18860,15 @@ "cancel_after_invoke" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18818,21 +18876,15 @@ "cancel_before_invoke" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18840,21 +18892,15 @@ "cancel_in_a_vacuum" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18862,21 +18908,15 @@ "cancel_with_status" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18884,21 +18924,15 @@ "compressed_payload" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18906,21 +18940,15 @@ "connectivity" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18928,21 +18956,15 @@ "default_host" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18950,21 +18972,15 @@ "disappearing_server" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18972,21 +18988,15 @@ "empty_batch" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -18994,21 +19004,15 @@ "graceful_server_shutdown" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19016,21 +19020,15 @@ "high_initial_seqno" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19038,21 +19036,15 @@ "hpack_size" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19060,21 +19052,15 @@ "invoke_large_request" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19082,21 +19068,15 @@ "large_metadata" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19104,21 +19084,15 @@ "max_concurrent_streams" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19126,21 +19100,15 @@ "max_message_length" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19148,21 +19116,15 @@ "negative_deadline" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19170,21 +19132,15 @@ "no_op" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19192,21 +19148,15 @@ "payload" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19214,21 +19164,15 @@ "ping" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19236,21 +19180,15 @@ "ping_pong_streaming" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19258,21 +19196,15 @@ "registered_call" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19280,21 +19212,15 @@ "request_with_flags" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19302,21 +19228,15 @@ "request_with_payload" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19324,21 +19244,15 @@ "server_finishes_request" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19346,21 +19260,15 @@ "shutdown_finishes_calls" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19368,21 +19276,15 @@ "shutdown_finishes_tags" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19390,21 +19292,15 @@ "simple_delayed_request" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19412,21 +19308,15 @@ "simple_metadata" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19434,21 +19324,15 @@ "simple_request" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19456,21 +19340,15 @@ "trailing_metadata" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full_nosec_test", + "name": "h2_full+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { @@ -19484,7 +19362,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19500,7 +19378,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19516,7 +19394,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19532,7 +19410,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19548,7 +19426,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19564,7 +19442,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19580,7 +19458,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19596,7 +19474,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19612,7 +19490,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19628,7 +19506,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19644,7 +19522,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19660,7 +19538,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19676,7 +19554,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19692,7 +19570,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19708,7 +19586,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19724,7 +19602,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19740,7 +19618,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19756,7 +19634,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19772,7 +19650,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19788,7 +19666,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19804,7 +19682,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19820,7 +19698,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19836,7 +19714,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19852,7 +19730,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19868,7 +19746,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19884,7 +19762,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19900,7 +19778,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19916,7 +19794,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19932,7 +19810,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19948,7 +19826,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19964,7 +19842,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19980,7 +19858,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -19996,7 +19874,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -20012,7 +19890,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -20028,7 +19906,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+pipe_nosec_test", + "name": "h2_full+poll_nosec_test", "platforms": [ "linux" ] @@ -20044,7 +19922,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20060,7 +19938,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20076,7 +19954,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20092,7 +19970,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20108,7 +19986,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20124,7 +20002,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20140,7 +20018,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20156,7 +20034,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20172,7 +20050,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20188,7 +20066,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20204,7 +20082,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20220,7 +20098,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20236,7 +20114,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20252,7 +20130,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20268,7 +20146,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20284,7 +20162,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20300,7 +20178,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20316,7 +20194,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20332,7 +20210,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20348,7 +20226,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20364,7 +20242,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20380,7 +20258,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20396,7 +20274,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20412,7 +20290,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20428,7 +20306,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20444,7 +20322,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20460,7 +20338,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20476,7 +20354,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20492,7 +20370,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20508,7 +20386,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20524,7 +20402,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20540,7 +20418,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" ] @@ -20556,54 +20434,6 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+poll_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "simple_request" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "trailing_metadata" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "bad_hostname" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", "name": "h2_full+poll+pipe_nosec_test", "platforms": [ "linux" @@ -20611,7 +20441,7 @@ }, { "args": [ - "binary_metadata" + "simple_request" ], "ci_platforms": [ "linux" @@ -20627,1151 +20457,23 @@ }, { "args": [ - "cancel_after_accept" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "cancel_after_client_done" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "cancel_after_invoke" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "cancel_before_invoke" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "cancel_in_a_vacuum" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "cancel_with_status" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "compressed_payload" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "connectivity" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "default_host" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "disappearing_server" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "empty_batch" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "graceful_server_shutdown" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "high_initial_seqno" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "hpack_size" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "invoke_large_request" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "large_metadata" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "max_concurrent_streams" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "max_message_length" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "negative_deadline" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "no_op" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "payload" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "ping" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "ping_pong_streaming" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "registered_call" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "request_with_flags" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "request_with_payload" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "server_finishes_request" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "shutdown_finishes_calls" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "shutdown_finishes_tags" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "simple_delayed_request" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "simple_metadata" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "simple_request" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "trailing_metadata" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+poll+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, - { - "args": [ - "bad_hostname" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "binary_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_accept" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_client_done" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_invoke" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_before_invoke" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_in_a_vacuum" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_with_status" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "compressed_payload" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "connectivity" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "default_host" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "disappearing_server" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "empty_batch" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "graceful_server_shutdown" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "high_initial_seqno" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "invoke_large_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "large_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "max_concurrent_streams" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "max_message_length" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "negative_deadline" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "no_op" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "payload" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "ping" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "ping_pong_streaming" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "registered_call" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "request_with_flags" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "request_with_payload" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "server_finishes_request" + "trailing_metadata" ], "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_full+trace_nosec_test", + "name": "h2_full+poll+pipe_nosec_test", "platforms": [ - "windows", - "linux", - "mac", - "posix" + "linux" ] }, { "args": [ - "shutdown_finishes_calls" + "bad_hostname" ], "ci_platforms": [ "windows", @@ -21793,7 +20495,7 @@ }, { "args": [ - "shutdown_finishes_tags" + "binary_metadata" ], "ci_platforms": [ "windows", @@ -21815,7 +20517,7 @@ }, { "args": [ - "simple_delayed_request" + "cancel_after_accept" ], "ci_platforms": [ "windows", @@ -21837,7 +20539,7 @@ }, { "args": [ - "simple_metadata" + "cancel_after_client_done" ], "ci_platforms": [ "windows", @@ -21845,7 +20547,7 @@ "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", @@ -21859,7 +20561,7 @@ }, { "args": [ - "simple_request" + "cancel_after_invoke" ], "ci_platforms": [ "windows", @@ -21867,7 +20569,7 @@ "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", @@ -21881,7 +20583,7 @@ }, { "args": [ - "trailing_metadata" + "cancel_before_invoke" ], "ci_platforms": [ "windows", @@ -21889,7 +20591,7 @@ "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", @@ -21903,18 +20605,19 @@ }, { "args": [ - "bad_hostname" + "cancel_in_a_vacuum" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -21924,18 +20627,19 @@ }, { "args": [ - "binary_metadata" + "cancel_with_status" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -21945,18 +20649,19 @@ }, { "args": [ - "cancel_after_accept" + "compressed_payload" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -21966,18 +20671,19 @@ }, { "args": [ - "cancel_after_client_done" + "connectivity" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -21987,18 +20693,19 @@ }, { "args": [ - "cancel_after_invoke" + "default_host" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22008,18 +20715,19 @@ }, { "args": [ - "cancel_before_invoke" + "disappearing_server" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22029,18 +20737,19 @@ }, { "args": [ - "cancel_in_a_vacuum" + "empty_batch" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22050,18 +20759,19 @@ }, { "args": [ - "cancel_with_status" + "graceful_server_shutdown" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22071,18 +20781,19 @@ }, { "args": [ - "default_host" + "high_initial_seqno" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22092,18 +20803,19 @@ }, { "args": [ - "disappearing_server" + "invoke_large_request" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22113,18 +20825,19 @@ }, { "args": [ - "empty_batch" + "large_metadata" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22134,18 +20847,19 @@ }, { "args": [ - "graceful_server_shutdown" + "max_concurrent_streams" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22155,18 +20869,19 @@ }, { "args": [ - "high_initial_seqno" + "max_message_length" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22176,18 +20891,19 @@ }, { "args": [ - "invoke_large_request" + "negative_deadline" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22197,18 +20913,19 @@ }, { "args": [ - "large_metadata" + "no_op" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22218,18 +20935,19 @@ }, { "args": [ - "max_message_length" + "payload" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22239,18 +20957,19 @@ }, { "args": [ - "negative_deadline" + "ping" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22260,18 +20979,19 @@ }, { "args": [ - "no_op" + "ping_pong_streaming" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22281,39 +21001,19 @@ }, { "args": [ - "payload" + "registered_call" ], "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_proxy_nosec_test", - "platforms": [ "windows", "linux", "mac", "posix" - ] - }, - { - "args": [ - "ping_pong_streaming" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22323,18 +21023,19 @@ }, { "args": [ - "registered_call" + "request_with_flags" ], "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22349,13 +21050,14 @@ "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22370,13 +21072,14 @@ "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22391,13 +21094,14 @@ "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22412,13 +21116,14 @@ "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22433,13 +21138,14 @@ "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22454,13 +21160,14 @@ "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22475,13 +21182,14 @@ "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22496,13 +21204,14 @@ "ci_platforms": [ "windows", "linux", + "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_proxy_nosec_test", + "name": "h2_full+trace_nosec_test", "platforms": [ "windows", "linux", @@ -22523,7 +21232,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22544,7 +21253,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22565,7 +21274,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22586,7 +21295,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22607,7 +21316,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22628,7 +21337,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22649,7 +21358,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22670,7 +21379,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22680,18 +21389,18 @@ }, { "args": [ - "compressed_payload" + "default_host" ], "ci_platforms": [ "windows", "linux", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22701,7 +21410,7 @@ }, { "args": [ - "empty_batch" + "disappearing_server" ], "ci_platforms": [ "windows", @@ -22712,7 +21421,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22722,18 +21431,18 @@ }, { "args": [ - "graceful_server_shutdown" + "empty_batch" ], "ci_platforms": [ "windows", "linux", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22743,18 +21452,18 @@ }, { "args": [ - "high_initial_seqno" + "graceful_server_shutdown" ], "ci_platforms": [ "windows", "linux", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22764,7 +21473,7 @@ }, { "args": [ - "hpack_size" + "high_initial_seqno" ], "ci_platforms": [ "windows", @@ -22775,7 +21484,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22796,7 +21505,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22817,28 +21526,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "max_concurrent_streams" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22859,7 +21547,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22880,7 +21568,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22901,7 +21589,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22922,7 +21610,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22943,7 +21631,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22964,7 +21652,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22974,7 +21662,7 @@ }, { "args": [ - "request_with_flags" + "request_with_payload" ], "ci_platforms": [ "windows", @@ -22985,7 +21673,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -22995,7 +21683,7 @@ }, { "args": [ - "request_with_payload" + "server_finishes_request" ], "ci_platforms": [ "windows", @@ -23006,7 +21694,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -23016,7 +21704,7 @@ }, { "args": [ - "server_finishes_request" + "shutdown_finishes_calls" ], "ci_platforms": [ "windows", @@ -23027,7 +21715,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -23037,7 +21725,7 @@ }, { "args": [ - "shutdown_finishes_calls" + "shutdown_finishes_tags" ], "ci_platforms": [ "windows", @@ -23048,7 +21736,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -23058,18 +21746,18 @@ }, { "args": [ - "shutdown_finishes_tags" + "simple_delayed_request" ], "ci_platforms": [ "windows", "linux", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -23090,7 +21778,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -23111,7 +21799,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -23132,7 +21820,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_nosec_test", + "name": "h2_proxy_nosec_test", "platforms": [ "windows", "linux", @@ -23153,7 +21841,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23174,7 +21862,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23195,7 +21883,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23216,7 +21904,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23237,7 +21925,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23258,7 +21946,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23279,7 +21967,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23300,7 +21988,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23321,7 +22009,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23342,7 +22030,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23363,7 +22051,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23384,7 +22072,28 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "hpack_size" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23405,7 +22114,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23426,7 +22135,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23447,7 +22156,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23468,7 +22177,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23489,7 +22198,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23510,7 +22219,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23531,7 +22240,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23552,7 +22261,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23573,7 +22282,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23594,7 +22303,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23615,7 +22324,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23636,7 +22345,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23657,7 +22366,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23678,7 +22387,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23699,7 +22408,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23720,7 +22429,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23741,7 +22450,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair+trace_nosec_test", + "name": "h2_sockpair_nosec_test", "platforms": [ "windows", "linux", @@ -23762,7 +22471,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -23783,7 +22492,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -23804,7 +22513,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -23825,7 +22534,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -23846,7 +22555,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -23867,7 +22576,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -23888,7 +22597,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -23909,7 +22618,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -23930,7 +22639,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -23951,7 +22660,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -23972,7 +22681,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -23993,28 +22702,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "hpack_size" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "flaky": false, - "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24035,7 +22723,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24056,7 +22744,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24077,7 +22765,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24098,7 +22786,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24119,7 +22807,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24140,7 +22828,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24161,7 +22849,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24182,7 +22870,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24203,7 +22891,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24224,7 +22912,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24245,7 +22933,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24266,7 +22954,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24287,7 +22975,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24308,7 +22996,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24329,7 +23017,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24350,7 +23038,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24371,7 +23059,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_sockpair_1byte_nosec_test", + "name": "h2_sockpair+trace_nosec_test", "platforms": [ "windows", "linux", @@ -24386,14 +23074,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24408,14 +23095,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24430,14 +23116,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24452,14 +23137,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24474,14 +23158,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24496,14 +23179,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24518,14 +23200,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24540,14 +23221,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24562,14 +23242,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24584,14 +23263,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24606,14 +23284,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24628,14 +23305,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24650,14 +23326,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24672,14 +23347,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24694,14 +23368,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24716,14 +23389,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24738,14 +23410,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24760,14 +23431,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24782,14 +23452,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24804,14 +23473,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24826,14 +23494,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24848,14 +23515,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24870,14 +23536,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24892,14 +23557,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24914,14 +23578,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24936,14 +23599,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24958,14 +23620,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -24980,14 +23641,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -25002,14 +23662,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", @@ -25024,14 +23683,13 @@ "ci_platforms": [ "windows", "linux", - "mac", "posix" ], "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_uchannel_nosec_test", + "name": "h2_sockpair_1byte_nosec_test", "platforms": [ "windows", "linux", diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln index 8c64423b51..86f42ee632 100644 --- a/vsprojects/buildtests_c.sln +++ b/vsprojects/buildtests_c.sln @@ -1241,18 +1241,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_ssl_proxy_test", "vcxpro {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_uchannel_test", "vcxproj\test/end2end/fixtures\h2_uchannel_test\h2_uchannel_test.vcxproj", "{E39D59C4-F5CB-7D68-DA6B-C6BC93843435}" - ProjectSection(myProperties) = preProject - lib = "False" - EndProjectSection - ProjectSection(ProjectDependencies) = postProject - {1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4} - {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} - {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9} - {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037} - {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_census_nosec_test", "vcxproj\test/end2end/fixtures\h2_census_nosec_test\h2_census_nosec_test.vcxproj", "{A8039D43-910E-4248-2A22-74366E8C4DCD}" ProjectSection(myProperties) = preProject lib = "False" @@ -1349,18 +1337,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_1byte_nosec_tes {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_uchannel_nosec_test", "vcxproj\test/end2end/fixtures\h2_uchannel_nosec_test\h2_uchannel_nosec_test.vcxproj", "{BD79A629-4181-DB5E-C28F-44EB280A6F91}" - ProjectSection(myProperties) = preProject - lib = "False" - EndProjectSection - ProjectSection(ProjectDependencies) = postProject - {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} - {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} - {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} - {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037} - {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -3245,22 +3221,6 @@ Global {A9092608-E45E-AC96-6533-A6E7DD98211D}.Release-DLL|Win32.Build.0 = Release|Win32 {A9092608-E45E-AC96-6533-A6E7DD98211D}.Release-DLL|x64.ActiveCfg = Release|x64 {A9092608-E45E-AC96-6533-A6E7DD98211D}.Release-DLL|x64.Build.0 = Release|x64 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Debug|Win32.ActiveCfg = Debug|Win32 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Debug|x64.ActiveCfg = Debug|x64 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Release|Win32.ActiveCfg = Release|Win32 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Release|x64.ActiveCfg = Release|x64 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Debug|Win32.Build.0 = Debug|Win32 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Debug|x64.Build.0 = Debug|x64 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Release|Win32.Build.0 = Release|Win32 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Release|x64.Build.0 = Release|x64 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Debug-DLL|Win32.Build.0 = Debug|Win32 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Debug-DLL|x64.ActiveCfg = Debug|x64 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Debug-DLL|x64.Build.0 = Debug|x64 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Release-DLL|Win32.ActiveCfg = Release|Win32 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Release-DLL|Win32.Build.0 = Release|Win32 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Release-DLL|x64.ActiveCfg = Release|x64 - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435}.Release-DLL|x64.Build.0 = Release|x64 {A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug|Win32.ActiveCfg = Debug|Win32 {A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug|x64.ActiveCfg = Debug|x64 {A8039D43-910E-4248-2A22-74366E8C4DCD}.Release|Win32.ActiveCfg = Release|Win32 @@ -3389,22 +3349,6 @@ Global {485E6713-487D-F274-BDE7-5D29300C93FE}.Release-DLL|Win32.Build.0 = Release|Win32 {485E6713-487D-F274-BDE7-5D29300C93FE}.Release-DLL|x64.ActiveCfg = Release|x64 {485E6713-487D-F274-BDE7-5D29300C93FE}.Release-DLL|x64.Build.0 = Release|x64 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Debug|Win32.ActiveCfg = Debug|Win32 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Debug|x64.ActiveCfg = Debug|x64 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Release|Win32.ActiveCfg = Release|Win32 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Release|x64.ActiveCfg = Release|x64 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Debug|Win32.Build.0 = Debug|Win32 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Debug|x64.Build.0 = Debug|x64 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Release|Win32.Build.0 = Release|Win32 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Release|x64.Build.0 = Release|x64 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Debug-DLL|Win32.Build.0 = Debug|Win32 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Debug-DLL|x64.ActiveCfg = Debug|x64 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Debug-DLL|x64.Build.0 = Debug|x64 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Release-DLL|Win32.ActiveCfg = Release|Win32 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Release-DLL|Win32.Build.0 = Release|Win32 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Release-DLL|x64.ActiveCfg = Release|x64 - {BD79A629-4181-DB5E-C28F-44EB280A6F91}.Release-DLL|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index 869acb4039..30726ff5e9 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -288,7 +288,6 @@ - @@ -439,8 +438,6 @@ - - diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index 44cf627d13..26ef8aa781 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -22,9 +22,6 @@ src\core\channel - - src\core\channel - src\core\channel @@ -551,9 +548,6 @@ src\core\channel - - src\core\channel - src\core\channel diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index 83a48c3a3d..1939396e1a 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -278,7 +278,6 @@ - @@ -417,8 +416,6 @@ - - diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index 7c14e8cbc9..6075961030 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -25,9 +25,6 @@ src\core\channel - - src\core\channel - src\core\channel @@ -488,9 +485,6 @@ src\core\channel - - src\core\channel - src\core\channel diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_nosec_test/h2_uchannel_nosec_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_nosec_test/h2_uchannel_nosec_test.vcxproj deleted file mode 100644 index 76a9e5600f..0000000000 --- a/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_nosec_test/h2_uchannel_nosec_test.vcxproj +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {BD79A629-4181-DB5E-C28F-44EB280A6F91} - true - $(SolutionDir)IntDir\$(MSBuildProjectName)\ - - - - v100 - - - v110 - - - v120 - - - v140 - - - Application - true - Unicode - - - Application - false - true - Unicode - - - - - - - - - - - - - - h2_uchannel_nosec_test - static - Debug - static - Debug - - - h2_uchannel_nosec_test - static - Release - static - Release - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDebug - true - None - false - - - Console - true - false - - - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDebug - true - None - false - - - Console - true - false - - - - - - NotUsing - Level3 - MaxSpeed - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - true - true - MultiThreaded - true - None - false - - - Console - true - false - true - true - - - - - - NotUsing - Level3 - MaxSpeed - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - true - true - MultiThreaded - true - None - false - - - Console - true - false - true - true - - - - - - - - - - {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} - - - {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} - - - {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} - - - {EAB0A629-17A9-44DB-B5FF-E91A721FE037} - - - {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} - - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_nosec_test/h2_uchannel_nosec_test.vcxproj.filters b/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_nosec_test/h2_uchannel_nosec_test.vcxproj.filters deleted file mode 100644 index c9adeeebaf..0000000000 --- a/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_nosec_test/h2_uchannel_nosec_test.vcxproj.filters +++ /dev/null @@ -1,24 +0,0 @@ - - - - - test\core\end2end\fixtures - - - - - - {549b9d3c-70c0-f3de-36d6-5b2ce5fb098c} - - - {d37f19b6-6893-6a90-09d2-e50d891899ff} - - - {bde36bf9-4894-e85b-4a35-f7b1abe9387f} - - - {e16ce654-bd8c-2527-1077-e6cd2639c1cb} - - - - diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_test/h2_uchannel_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_test/h2_uchannel_test.vcxproj deleted file mode 100644 index 1564608631..0000000000 --- a/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_test/h2_uchannel_test.vcxproj +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {E39D59C4-F5CB-7D68-DA6B-C6BC93843435} - true - $(SolutionDir)IntDir\$(MSBuildProjectName)\ - - - - v100 - - - v110 - - - v120 - - - v140 - - - Application - true - Unicode - - - Application - false - true - Unicode - - - - - - - - - - - - - - h2_uchannel_test - static - Debug - static - Debug - - - h2_uchannel_test - static - Release - static - Release - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDebug - true - None - false - - - Console - true - false - - - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDebug - true - None - false - - - Console - true - false - - - - - - NotUsing - Level3 - MaxSpeed - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - true - true - MultiThreaded - true - None - false - - - Console - true - false - true - true - - - - - - NotUsing - Level3 - MaxSpeed - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - true - true - MultiThreaded - true - None - false - - - Console - true - false - true - true - - - - - - - - - - {1F1F9084-2A93-B80E-364F-5754894AFAB4} - - - {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} - - - {29D16885-7228-4C31-81ED-5F9187C7F2A9} - - - {EAB0A629-17A9-44DB-B5FF-E91A721FE037} - - - {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} - - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_test/h2_uchannel_test.vcxproj.filters b/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_test/h2_uchannel_test.vcxproj.filters deleted file mode 100644 index 611a643a33..0000000000 --- a/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_test/h2_uchannel_test.vcxproj.filters +++ /dev/null @@ -1,24 +0,0 @@ - - - - - test\core\end2end\fixtures - - - - - - {0e4c3b3f-4d89-039d-c4d2-3bd39bb5701f} - - - {75084bcc-1809-7f7a-8989-d8fe2d5d404f} - - - {9e123c51-0a8c-f222-f2f9-3cee19f2f99e} - - - {999ee744-f147-9430-9a09-a16f69ecfa2a} - - - - -- cgit v1.2.3 From e7077b5c960775eaac2c69afec040735504ce060 Mon Sep 17 00:00:00 2001 From: vjpai Date: Mon, 21 Mar 2016 20:58:44 -0700 Subject: Fix a missing include in UDP_SERVER code and do some typecasts for stronger warning-protection in channel stack builder calls --- src/core/iomgr/udp_server.c | 1 + src/core/surface/init.c | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c index ef548cfe4d..87b4ce4bd2 100644 --- a/src/core/iomgr/udp_server.c +++ b/src/core/iomgr/udp_server.c @@ -61,6 +61,7 @@ #include "src/core/iomgr/sockaddr_utils.h" #include "src/core/iomgr/socket_utils_posix.h" #include "src/core/support/string.h" +#include #include #include #include diff --git a/src/core/surface/init.c b/src/core/surface/init.c index b50770959f..1da2e38308 100644 --- a/src/core/surface/init.c +++ b/src/core/surface/init.c @@ -90,18 +90,21 @@ static void do_basic_init(void) { } static bool append_filter(grpc_channel_stack_builder *builder, void *arg) { - return grpc_channel_stack_builder_append_filter(builder, arg, NULL, NULL); + return grpc_channel_stack_builder_append_filter( + builder, (const grpc_channel_filter *)arg, NULL, NULL); } static bool prepend_filter(grpc_channel_stack_builder *builder, void *arg) { - return grpc_channel_stack_builder_prepend_filter(builder, arg, NULL, NULL); + return grpc_channel_stack_builder_prepend_filter( + builder, (const grpc_channel_filter *)arg, NULL, NULL); } static bool maybe_add_http_filter(grpc_channel_stack_builder *builder, void *arg) { grpc_transport *t = grpc_channel_stack_builder_get_transport(builder); if (t && strstr(t->vtable->name, "http")) { - return grpc_channel_stack_builder_prepend_filter(builder, arg, NULL, NULL); + return grpc_channel_stack_builder_prepend_filter( + builder, (const grpc_channel_filter *)arg, NULL, NULL); } return true; } -- cgit v1.2.3 From fcbcbff290d359746670ae80be27a6e683eb0b12 Mon Sep 17 00:00:00 2001 From: ahedberg Date: Tue, 22 Mar 2016 13:23:47 -0400 Subject: prefix external linkage functions with grpc --- src/core/client_config/resolvers/sockaddr_resolver.c | 13 +++++++------ src/core/iomgr/tcp_server_posix.c | 4 ++-- src/core/iomgr/udp_server.c | 4 ++-- src/core/iomgr/unix_sockets_posix.c | 8 ++++---- src/core/iomgr/unix_sockets_posix.h | 7 ++++--- src/core/iomgr/unix_sockets_posix_noop.c | 8 ++++---- 6 files changed, 23 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/core/client_config/resolvers/sockaddr_resolver.c b/src/core/client_config/resolvers/sockaddr_resolver.c index d2a081a131..0eab787f3d 100644 --- a/src/core/client_config/resolvers/sockaddr_resolver.c +++ b/src/core/client_config/resolvers/sockaddr_resolver.c @@ -351,21 +351,22 @@ static void sockaddr_factory_ref(grpc_resolver_factory *factory) {} static void sockaddr_factory_unref(grpc_resolver_factory *factory) {} -#define DECL_FACTORY(name) \ +#define DECL_FACTORY(name, prefix) \ static grpc_resolver *name##_factory_create_resolver( \ grpc_resolver_factory *factory, grpc_resolver_args *args) { \ - return sockaddr_create(args, "pick_first", parse_##name); \ + return sockaddr_create(args, "pick_first", prefix##parse_##name); \ } \ static const grpc_resolver_factory_vtable name##_factory_vtable = { \ sockaddr_factory_ref, sockaddr_factory_unref, \ - name##_factory_create_resolver, name##_get_default_authority, #name}; \ + name##_factory_create_resolver, prefix##name##_get_default_authority, \ + #name}; \ static grpc_resolver_factory name##_resolver_factory = { \ &name##_factory_vtable}; \ grpc_resolver_factory *grpc_##name##_resolver_factory_create() { \ return &name##_resolver_factory; \ } -#ifdef GPR_POSIX_SOCKET -DECL_FACTORY(unix) +#ifdef GPR_HAVE_UNIX_SOCKET +DECL_FACTORY(unix, grpc_) #endif -DECL_FACTORY(ipv4) DECL_FACTORY(ipv6) +DECL_FACTORY(ipv4, ) DECL_FACTORY(ipv6, ) diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c index 0bef9f6254..403559d912 100644 --- a/src/core/iomgr/tcp_server_posix.c +++ b/src/core/iomgr/tcp_server_posix.c @@ -194,7 +194,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { if (s->head) { grpc_tcp_listener *sp; for (sp = s->head; sp; sp = sp->next) { - unlink_if_unix_domain_socket(&sp->addr.sockaddr); + grpc_unlink_if_unix_domain_socket(&sp->addr.sockaddr); sp->destroyed_closure.cb = destroyed_port; sp->destroyed_closure.cb_arg = s; grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, @@ -441,7 +441,7 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, if (s->tail != NULL) { port_index = s->tail->port_index + 1; } - unlink_if_unix_domain_socket((struct sockaddr *)addr); + grpc_unlink_if_unix_domain_socket((struct sockaddr *)addr); /* Check if this is a wildcard port, and if so, try to keep the port the same as some previously created listener. */ diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c index c1a438398d..efedd9f32e 100644 --- a/src/core/iomgr/udp_server.c +++ b/src/core/iomgr/udp_server.c @@ -167,7 +167,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { if (s->nports) { for (i = 0; i < s->nports; i++) { server_port *sp = &s->ports[i]; - unlink_if_unix_domain_socket(&sp->addr.sockaddr); + grpc_unlink_if_unix_domain_socket(&sp->addr.sockaddr); sp->destroyed_closure.cb = destroyed_port; sp->destroyed_closure.cb_arg = s; grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, @@ -325,7 +325,7 @@ int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, socklen_t sockname_len; int port; - unlink_if_unix_domain_socket((struct sockaddr *)addr); + grpc_unlink_if_unix_domain_socket((struct sockaddr *)addr); /* Check if this is a wildcard port, and if so, try to keep the port the same as some previously created listener. */ diff --git a/src/core/iomgr/unix_sockets_posix.c b/src/core/iomgr/unix_sockets_posix.c index 0ff48320ca..035b55fa69 100644 --- a/src/core/iomgr/unix_sockets_posix.c +++ b/src/core/iomgr/unix_sockets_posix.c @@ -62,7 +62,7 @@ int grpc_is_unix_socket(const struct sockaddr *addr) { return addr->sa_family == AF_UNIX; } -void unlink_if_unix_domain_socket(const struct sockaddr *addr) { +void grpc_unlink_if_unix_domain_socket(const struct sockaddr *addr) { if (addr->sa_family != AF_UNIX) { return; } @@ -74,7 +74,7 @@ void unlink_if_unix_domain_socket(const struct sockaddr *addr) { } } -int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { +int grpc_parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { struct sockaddr_un *un = (struct sockaddr_un *)addr; un->sun_family = AF_UNIX; @@ -84,8 +84,8 @@ int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { return 1; } -char *unix_get_default_authority(grpc_resolver_factory *factory, - grpc_uri *uri) { +char *grpc_unix_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) { return gpr_strdup("localhost"); } diff --git a/src/core/iomgr/unix_sockets_posix.h b/src/core/iomgr/unix_sockets_posix.h index c7ba0bfe09..129eb8fcbc 100644 --- a/src/core/iomgr/unix_sockets_posix.h +++ b/src/core/iomgr/unix_sockets_posix.h @@ -52,11 +52,12 @@ grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char* name); int grpc_is_unix_socket(const struct sockaddr *addr); -void unlink_if_unix_domain_socket(const struct sockaddr *addr); +void grpc_unlink_if_unix_domain_socket(const struct sockaddr *addr); -int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len); +int grpc_parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len); -char *unix_get_default_authority(grpc_resolver_factory *factory, grpc_uri *uri); +char *grpc_unix_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri); char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr); diff --git a/src/core/iomgr/unix_sockets_posix_noop.c b/src/core/iomgr/unix_sockets_posix_noop.c index 1f6773576c..768131581f 100644 --- a/src/core/iomgr/unix_sockets_posix_noop.c +++ b/src/core/iomgr/unix_sockets_posix_noop.c @@ -46,14 +46,14 @@ int grpc_is_unix_socket(const struct sockaddr *addr) { return false; } -void unlink_if_unix_domain_socket(const struct sockaddr *addr) {} +void grpc_unlink_if_unix_domain_socket(const struct sockaddr *addr) {} -int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { +int grpc_parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { return 0; } -char *unix_get_default_authority(grpc_resolver_factory *factory, - grpc_uri *uri) { +char *grpc_unix_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) { return NULL; } -- cgit v1.2.3 From 799fd4bda6e011bcb6dbfce02d8b34a1d9a06736 Mon Sep 17 00:00:00 2001 From: ahedberg Date: Tue, 22 Mar 2016 13:47:46 -0400 Subject: fix compilation errors --- src/core/iomgr/unix_sockets_posix.c | 1 + src/core/iomgr/unix_sockets_posix_noop.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/iomgr/unix_sockets_posix.c b/src/core/iomgr/unix_sockets_posix.c index 035b55fa69..8ff474c6d4 100644 --- a/src/core/iomgr/unix_sockets_posix.c +++ b/src/core/iomgr/unix_sockets_posix.c @@ -35,6 +35,7 @@ #ifdef GPR_HAVE_UNIX_SOCKET +#include #include #include #include diff --git a/src/core/iomgr/unix_sockets_posix_noop.c b/src/core/iomgr/unix_sockets_posix_noop.c index 768131581f..4c41cf5efa 100644 --- a/src/core/iomgr/unix_sockets_posix_noop.c +++ b/src/core/iomgr/unix_sockets_posix_noop.c @@ -34,7 +34,7 @@ #include "src/core/iomgr/unix_sockets_posix.h" -#ifdef GPR_POSIX_SOCKET +#ifndef GPR_HAVE_UNIX_SOCKET void grpc_create_socketpair_if_unix(int sv[2]) {} -- cgit v1.2.3 From ce379382552e118a499db95c0d311849557d0227 Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 22 Mar 2016 17:49:56 +0000 Subject: Make grpc-python ByteBuffer.bytes() linear cost. Currently ByteBuffer.bytes() reads from the underlying grpc byte_buffer a slice at a time, and appends each to a Python string (bytes). In Python strings are immutable, so appending creates a new string by copying the previous data. This means the current implementation is quadratic. The effect is very noticeable when messages have repeated (or large) string fields. We traced execution between two services and observed that when the payload size approached 600kb, the receiving service took ~10s at full CPU to read a response that had taken fractions of a second the send over the network. This commit changes ByteBuffer.bytes() to use an intermediate bytearray, instead of strings, for the in-progress bytes. Once all slices are read, the buffer is converted to a string. --- src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index 851389a261..6ecdcf7222 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -254,7 +254,7 @@ cdef class ByteBuffer: if self.c_byte_buffer != NULL: with nogil: grpc_byte_buffer_reader_init(&reader, self.c_byte_buffer) - result = b"" + result = bytearray() with nogil: while grpc_byte_buffer_reader_next(&reader, &data_slice): data_slice_pointer = gpr_slice_start_ptr(data_slice) @@ -263,7 +263,7 @@ cdef class ByteBuffer: result += (data_slice_pointer)[:data_slice_length] with nogil: grpc_byte_buffer_reader_destroy(&reader) - return result + return bytes(result) else: return None -- cgit v1.2.3 From 8afb88de666d3a7fd20d727fa9d6711f681489bf Mon Sep 17 00:00:00 2001 From: ahedberg Date: Tue, 22 Mar 2016 13:57:47 -0400 Subject: fix copyright dates and style issues --- src/core/iomgr/endpoint_pair_posix.c | 2 +- src/core/iomgr/sockaddr_utils.c | 2 +- src/core/iomgr/tcp_server_posix.c | 5 ++--- src/core/iomgr/unix_sockets_posix.c | 6 +++--- src/core/iomgr/unix_sockets_posix.h | 2 +- src/core/iomgr/unix_sockets_posix_noop.c | 8 +++----- 6 files changed, 11 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/endpoint_pair_posix.c b/src/core/iomgr/endpoint_pair_posix.c index f6da8f1d1b..f84b8441df 100644 --- a/src/core/iomgr/endpoint_pair_posix.c +++ b/src/core/iomgr/endpoint_pair_posix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/iomgr/sockaddr_utils.c b/src/core/iomgr/sockaddr_utils.c index 682b290a83..a3c3a874c1 100644 --- a/src/core/iomgr/sockaddr_utils.c +++ b/src/core/iomgr/sockaddr_utils.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c index 403559d912..03dfddd925 100644 --- a/src/core/iomgr/tcp_server_posix.c +++ b/src/core/iomgr/tcp_server_posix.c @@ -270,9 +270,8 @@ static int prepare_socket(int fd, const struct sockaddr *addr, } if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || - (!grpc_is_unix_socket(addr) && - (!grpc_set_socket_low_latency(fd, 1) || - !grpc_set_socket_reuse_addr(fd, 1))) || + (!grpc_is_unix_socket(addr) && (!grpc_set_socket_low_latency(fd, 1) || + !grpc_set_socket_reuse_addr(fd, 1))) || !grpc_set_socket_no_sigpipe_if_possible(fd)) { gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, strerror(errno)); diff --git a/src/core/iomgr/unix_sockets_posix.c b/src/core/iomgr/unix_sockets_posix.c index 8ff474c6d4..480ff613f6 100644 --- a/src/core/iomgr/unix_sockets_posix.c +++ b/src/core/iomgr/unix_sockets_posix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,7 +46,7 @@ void grpc_create_socketpair_if_unix(int sv[2]) { GPR_ASSERT(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); } -grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char* name) { +grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char *name) { struct sockaddr_un *un; grpc_resolved_addresses *addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); @@ -95,7 +95,7 @@ char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr) { return NULL; } - char* result; + char *result; gpr_asprintf(&result, "unix:%s", ((struct sockaddr_un *)addr)->sun_path); return result; } diff --git a/src/core/iomgr/unix_sockets_posix.h b/src/core/iomgr/unix_sockets_posix.h index 129eb8fcbc..7064d0a7fc 100644 --- a/src/core/iomgr/unix_sockets_posix.h +++ b/src/core/iomgr/unix_sockets_posix.h @@ -48,7 +48,7 @@ void grpc_create_socketpair_if_unix(int sv[2]); -grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char* name); +grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char *name); int grpc_is_unix_socket(const struct sockaddr *addr); diff --git a/src/core/iomgr/unix_sockets_posix_noop.c b/src/core/iomgr/unix_sockets_posix_noop.c index 4c41cf5efa..d9d163290b 100644 --- a/src/core/iomgr/unix_sockets_posix_noop.c +++ b/src/core/iomgr/unix_sockets_posix_noop.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,13 +38,11 @@ void grpc_create_socketpair_if_unix(int sv[2]) {} -grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char* name) { +grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char *name) { return NULL; } -int grpc_is_unix_socket(const struct sockaddr *addr) { - return false; -} +int grpc_is_unix_socket(const struct sockaddr *addr) { return false; } void grpc_unlink_if_unix_domain_socket(const struct sockaddr *addr) {} -- cgit v1.2.3 From 879ce77cb658113af6af45ee89544e1ae7513868 Mon Sep 17 00:00:00 2001 From: ahedberg Date: Tue, 22 Mar 2016 16:18:15 -0400 Subject: include sockaddr.h in unix_sockets_posix.h for platform compatibility --- src/core/iomgr/unix_sockets_posix.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/unix_sockets_posix.h b/src/core/iomgr/unix_sockets_posix.h index 7064d0a7fc..1ab82cca88 100644 --- a/src/core/iomgr/unix_sockets_posix.h +++ b/src/core/iomgr/unix_sockets_posix.h @@ -36,15 +36,12 @@ #include -#ifdef GPR_POSIX_SOCKET - -#include - #include #include "src/core/client_config/resolver_factory.h" #include "src/core/client_config/uri_parser.h" #include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/sockaddr.h" void grpc_create_socketpair_if_unix(int sv[2]); @@ -61,5 +58,4 @@ char *grpc_unix_get_default_authority(grpc_resolver_factory *factory, char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr); -#endif #endif /* GRPC_INTERNAL_CORE_IOMGR_UNIX_SOCKETS_POSIX_H */ -- cgit v1.2.3 From 3811dc78a83e75f9b522b604c7967d0f40f7ae79 Mon Sep 17 00:00:00 2001 From: ahedberg Date: Tue, 22 Mar 2016 16:27:02 -0400 Subject: more style fixes --- src/core/client_config/resolvers/sockaddr_resolver.c | 2 +- src/core/iomgr/unix_sockets_posix_noop.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/core/client_config/resolvers/sockaddr_resolver.c b/src/core/client_config/resolvers/sockaddr_resolver.c index 0eab787f3d..3cb7d79b67 100644 --- a/src/core/client_config/resolvers/sockaddr_resolver.c +++ b/src/core/client_config/resolvers/sockaddr_resolver.c @@ -354,7 +354,7 @@ static void sockaddr_factory_unref(grpc_resolver_factory *factory) {} #define DECL_FACTORY(name, prefix) \ static grpc_resolver *name##_factory_create_resolver( \ grpc_resolver_factory *factory, grpc_resolver_args *args) { \ - return sockaddr_create(args, "pick_first", prefix##parse_##name); \ + return sockaddr_create(args, "pick_first", prefix##parse_##name); \ } \ static const grpc_resolver_factory_vtable name##_factory_vtable = { \ sockaddr_factory_ref, sockaddr_factory_unref, \ diff --git a/src/core/iomgr/unix_sockets_posix_noop.c b/src/core/iomgr/unix_sockets_posix_noop.c index d9d163290b..045467bea4 100644 --- a/src/core/iomgr/unix_sockets_posix_noop.c +++ b/src/core/iomgr/unix_sockets_posix_noop.c @@ -31,7 +31,6 @@ * */ - #include "src/core/iomgr/unix_sockets_posix.h" #ifndef GPR_HAVE_UNIX_SOCKET -- cgit v1.2.3 From 6753ae0cd706c896d667ca4fbea8cfd9ba67ab08 Mon Sep 17 00:00:00 2001 From: ahedberg Date: Tue, 22 Mar 2016 16:28:17 -0400 Subject: fix include guard for unix_sockets_posix --- src/core/iomgr/unix_sockets_posix.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/unix_sockets_posix.h b/src/core/iomgr/unix_sockets_posix.h index 1ab82cca88..e842ba3770 100644 --- a/src/core/iomgr/unix_sockets_posix.h +++ b/src/core/iomgr/unix_sockets_posix.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_INTERNAL_CORE_IOMGR_UNIX_SOCKETS_POSIX_H -#define GRPC_INTERNAL_CORE_IOMGR_UNIX_SOCKETS_POSIX_H +#ifndef GRPC_CORE_IOMGR_UNIX_SOCKETS_POSIX_H +#define GRPC_CORE_IOMGR_UNIX_SOCKETS_POSIX_H #include @@ -58,4 +58,4 @@ char *grpc_unix_get_default_authority(grpc_resolver_factory *factory, char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr); -#endif /* GRPC_INTERNAL_CORE_IOMGR_UNIX_SOCKETS_POSIX_H */ +#endif /* GRPC_CORE_IOMGR_UNIX_SOCKETS_POSIX_H */ -- cgit v1.2.3 From 6346041a256d100217a4f1e46776ea04490b1536 Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 22 Mar 2016 14:58:15 -0700 Subject: Fix failure handling code --- src/core/iomgr/tcp_server_posix.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c index 5e07f8261c..8f23ddff34 100644 --- a/src/core/iomgr/tcp_server_posix.c +++ b/src/core/iomgr/tcp_server_posix.c @@ -490,16 +490,17 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, addr_len = sizeof(wild6); fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode); sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index); - if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) { + if (fd >= 0 && + (dsmode == GRPC_DSMODE_DUALSTACK || dsmode == GRPC_DSMODE_IPV4)) { goto done; } if (sp != NULL) { ++fd_index; + sp2 = sp; } /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */ if (port == 0 && sp != NULL) { grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port); - sp2 = sp; } addr = (struct sockaddr *)&wild4; addr_len = sizeof(wild4); @@ -508,22 +509,25 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode); if (fd < 0) { gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno)); - } - if (dsmode == GRPC_DSMODE_IPV4 && - grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) { - addr = (struct sockaddr *)&addr4_copy; - addr_len = sizeof(addr4_copy); - } - sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index); - if (sp2 != NULL && sp != NULL) { - sp2->sibling = sp; - sp->is_sibling = 1; + } else { + if (dsmode == GRPC_DSMODE_IPV4 && + grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) { + addr = (struct sockaddr *)&addr4_copy; + addr_len = sizeof(addr4_copy); + } + sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index); + if (sp2 != NULL && sp != NULL) { + sp2->sibling = sp; + sp->is_sibling = 1; + } } done: gpr_free(allocated_addr); if (sp != NULL) { return sp->port; + } else if (sp2 != NULL) { + return sp2->port; } else { return -1; } -- cgit v1.2.3 From b9501bcb0bdbef7bbf788ffe3ea66208dd02e24f Mon Sep 17 00:00:00 2001 From: Leifur Halldor Asgeirsson Date: Tue, 22 Mar 2016 14:22:46 -0400 Subject: Python 3: fix a bytes/str runtime issue On python3, in grpc._links.service._Kernel._on_service_acceptance_event, there is a runtime TypeError: ``` _on_service_acceptance_event group, method = service_acceptance.method.split('/')[1:3] TypeError: 'str' does not support the buffer interface ``` It is fixed by using a bytes literal (`b'/'`) instead of a string literal. This exposed another issue in grpc.beta._server where an exception was being raised with a bytes literal for a message (a string should be used instead.) --- src/python/grpcio/grpc/_links/service.py | 4 ++-- src/python/grpcio/grpc/beta/_server.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/python/grpcio/grpc/_links/service.py b/src/python/grpcio/grpc/_links/service.py index 01edee6896..e0f26a5b0f 100644 --- a/src/python/grpcio/grpc/_links/service.py +++ b/src/python/grpcio/grpc/_links/service.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -177,7 +177,7 @@ class _Kernel(object): call = service_acceptance.call call.accept(self._completion_queue, call) try: - group, method = service_acceptance.method.split('/')[1:3] + group, method = service_acceptance.method.split(b'/')[1:3] except ValueError: logging.info('Illegal path "%s"!', service_acceptance.method) return diff --git a/src/python/grpcio/grpc/beta/_server.py b/src/python/grpcio/grpc/beta/_server.py index 2b520cc7e5..12d16e6c18 100644 --- a/src/python/grpcio/grpc/beta/_server.py +++ b/src/python/grpcio/grpc/beta/_server.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -62,7 +62,7 @@ class _GRPCServicer(base.Servicer): if e.code is None and e.details is None: raise base.NoSuchMethodError( interfaces.StatusCode.UNIMPLEMENTED, - b'Method "%s" of service "%s" not implemented!' % (method, group)) + 'Method "%s" of service "%s" not implemented!' % (method, group)) else: raise -- cgit v1.2.3 From 1824f0519f26b00cb5e95e52ea50c7990223157c Mon Sep 17 00:00:00 2001 From: Matthew Iselin Date: Wed, 10 Feb 2016 12:16:06 +1100 Subject: Add HTTP request parsing. This extends the existing http parser to support requests as well as responses. httpcli continues to exist and work as it has previously, though in the new directory src/core/http (to reflect the fact the directory now contains code relevant to parsing requests, which httpcli would not generally involve itself in). --- BUILD | 40 +-- Makefile | 68 ++--- binding.gyp | 8 +- build.yaml | 26 +- config.m4 | 10 +- gRPC.podspec | 20 +- grpc.gemspec | 14 +- package.json | 14 +- package.xml | 14 +- src/core/http/format_request.c | 120 ++++++++ src/core/http/format_request.h | 45 +++ src/core/http/httpcli.c | 293 +++++++++++++++++++ src/core/http/httpcli.h | 144 ++++++++++ src/core/http/httpcli_security_connector.c | 188 +++++++++++++ src/core/http/parser.c | 313 +++++++++++++++++++++ src/core/http/parser.h | 116 ++++++++ src/core/httpcli/format_request.c | 120 -------- src/core/httpcli/format_request.h | 45 --- src/core/httpcli/httpcli.c | 288 ------------------- src/core/httpcli/httpcli.h | 163 ----------- src/core/httpcli/httpcli_security_connector.c | 188 ------------- src/core/httpcli/parser.c | 211 -------------- src/core/httpcli/parser.h | 64 ----- src/core/security/credentials.c | 25 +- src/core/security/credentials.h | 7 +- src/core/security/google_default_credentials.c | 9 +- src/core/security/jwt_verifier.c | 20 +- src/python/grpcio/grpc_core_dependencies.py | 8 +- test/core/http/format_request_test.c | 165 +++++++++++ test/core/http/httpcli_test.c | 200 +++++++++++++ test/core/http/httpscli_test.c | 203 +++++++++++++ test/core/http/parser_test.c | 260 +++++++++++++++++ test/core/http/test_server.py | 71 +++++ test/core/httpcli/format_request_test.c | 165 ----------- test/core/httpcli/httpcli_test.c | 200 ------------- test/core/httpcli/httpscli_test.c | 203 ------------- test/core/httpcli/parser_test.c | 171 ----------- test/core/httpcli/test_server.py | 71 ----- test/core/security/credentials_test.c | 25 +- test/core/security/jwt_verifier_test.c | 10 +- test/core/util/port_posix.c | 1 + test/core/util/port_server_client.c | 8 +- test/core/util/port_windows.c | 1 + tools/doxygen/Doxyfile.core.internal | 14 +- tools/run_tests/sources_and_headers.json | 50 ++-- tools/run_tests/tests.json | 4 +- vsprojects/buildtests_c.sln | 36 +-- vsprojects/vcxproj/grpc/grpc.vcxproj | 14 +- vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 32 +-- .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj | 12 +- .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 28 +- .../test/http_parser_test/http_parser_test.vcxproj | 199 +++++++++++++ .../http_parser_test.vcxproj.filters | 21 ++ .../httpcli_format_request_test.vcxproj | 2 +- .../httpcli_format_request_test.vcxproj.filters | 8 +- .../httpcli_parser_test.vcxproj | 199 ------------- .../httpcli_parser_test.vcxproj.filters | 21 -- 57 files changed, 2605 insertions(+), 2370 deletions(-) create mode 100644 src/core/http/format_request.c create mode 100644 src/core/http/format_request.h create mode 100644 src/core/http/httpcli.c create mode 100644 src/core/http/httpcli.h create mode 100644 src/core/http/httpcli_security_connector.c create mode 100644 src/core/http/parser.c create mode 100644 src/core/http/parser.h delete mode 100644 src/core/httpcli/format_request.c delete mode 100644 src/core/httpcli/format_request.h delete mode 100644 src/core/httpcli/httpcli.c delete mode 100644 src/core/httpcli/httpcli.h delete mode 100644 src/core/httpcli/httpcli_security_connector.c delete mode 100644 src/core/httpcli/parser.c delete mode 100644 src/core/httpcli/parser.h create mode 100644 test/core/http/format_request_test.c create mode 100644 test/core/http/httpcli_test.c create mode 100644 test/core/http/httpscli_test.c create mode 100644 test/core/http/parser_test.c create mode 100755 test/core/http/test_server.py delete mode 100644 test/core/httpcli/format_request_test.c delete mode 100644 test/core/httpcli/httpcli_test.c delete mode 100644 test/core/httpcli/httpscli_test.c delete mode 100644 test/core/httpcli/parser_test.c delete mode 100755 test/core/httpcli/test_server.py create mode 100644 vsprojects/vcxproj/test/http_parser_test/http_parser_test.vcxproj create mode 100644 vsprojects/vcxproj/test/http_parser_test/http_parser_test.vcxproj.filters delete mode 100644 vsprojects/vcxproj/test/httpcli_parser_test/httpcli_parser_test.vcxproj delete mode 100644 vsprojects/vcxproj/test/httpcli_parser_test/httpcli_parser_test.vcxproj.filters (limited to 'src') diff --git a/BUILD b/BUILD index 2c2cce76c4..4ca2c250a0 100644 --- a/BUILD +++ b/BUILD @@ -190,9 +190,9 @@ cc_library( "src/core/compression/algorithm_metadata.h", "src/core/compression/message_compress.h", "src/core/debug/trace.h", - "src/core/httpcli/format_request.h", - "src/core/httpcli/httpcli.h", - "src/core/httpcli/parser.h", + "src/core/http/format_request.h", + "src/core/http/httpcli.h", + "src/core/http/parser.h", "src/core/iomgr/closure.h", "src/core/iomgr/endpoint.h", "src/core/iomgr/endpoint_pair.h", @@ -331,9 +331,9 @@ cc_library( "src/core/compression/compression_algorithm.c", "src/core/compression/message_compress.c", "src/core/debug/trace.c", - "src/core/httpcli/format_request.c", - "src/core/httpcli/httpcli.c", - "src/core/httpcli/parser.c", + "src/core/http/format_request.c", + "src/core/http/httpcli.c", + "src/core/http/parser.c", "src/core/iomgr/closure.c", "src/core/iomgr/endpoint.c", "src/core/iomgr/endpoint_pair_posix.c", @@ -429,7 +429,7 @@ cc_library( "src/core/transport/static_metadata.c", "src/core/transport/transport.c", "src/core/transport/transport_op_string.c", - "src/core/httpcli/httpcli_security_connector.c", + "src/core/http/httpcli_security_connector.c", "src/core/security/b64.c", "src/core/security/client_auth_filter.c", "src/core/security/credentials.c", @@ -562,9 +562,9 @@ cc_library( "src/core/compression/algorithm_metadata.h", "src/core/compression/message_compress.h", "src/core/debug/trace.h", - "src/core/httpcli/format_request.h", - "src/core/httpcli/httpcli.h", - "src/core/httpcli/parser.h", + "src/core/http/format_request.h", + "src/core/http/httpcli.h", + "src/core/http/parser.h", "src/core/iomgr/closure.h", "src/core/iomgr/endpoint.h", "src/core/iomgr/endpoint_pair.h", @@ -690,9 +690,9 @@ cc_library( "src/core/compression/compression_algorithm.c", "src/core/compression/message_compress.c", "src/core/debug/trace.c", - "src/core/httpcli/format_request.c", - "src/core/httpcli/httpcli.c", - "src/core/httpcli/parser.c", + "src/core/http/format_request.c", + "src/core/http/httpcli.c", + "src/core/http/parser.c", "src/core/iomgr/closure.c", "src/core/iomgr/endpoint.c", "src/core/iomgr/endpoint_pair_posix.c", @@ -1390,9 +1390,9 @@ objc_library( "src/core/compression/compression_algorithm.c", "src/core/compression/message_compress.c", "src/core/debug/trace.c", - "src/core/httpcli/format_request.c", - "src/core/httpcli/httpcli.c", - "src/core/httpcli/parser.c", + "src/core/http/format_request.c", + "src/core/http/httpcli.c", + "src/core/http/parser.c", "src/core/iomgr/closure.c", "src/core/iomgr/endpoint.c", "src/core/iomgr/endpoint_pair_posix.c", @@ -1488,7 +1488,7 @@ objc_library( "src/core/transport/static_metadata.c", "src/core/transport/transport.c", "src/core/transport/transport_op_string.c", - "src/core/httpcli/httpcli_security_connector.c", + "src/core/http/httpcli_security_connector.c", "src/core/security/b64.c", "src/core/security/client_auth_filter.c", "src/core/security/credentials.c", @@ -1566,9 +1566,9 @@ objc_library( "src/core/compression/algorithm_metadata.h", "src/core/compression/message_compress.h", "src/core/debug/trace.h", - "src/core/httpcli/format_request.h", - "src/core/httpcli/httpcli.h", - "src/core/httpcli/parser.h", + "src/core/http/format_request.h", + "src/core/http/httpcli.h", + "src/core/http/parser.h", "src/core/iomgr/closure.h", "src/core/iomgr/endpoint.h", "src/core/iomgr/endpoint_pair.h", diff --git a/Makefile b/Makefile index 0e2b8905b0..aaa2d79f8f 100644 --- a/Makefile +++ b/Makefile @@ -927,8 +927,8 @@ grpc_security_connector_test: $(BINDIR)/$(CONFIG)/grpc_security_connector_test grpc_verify_jwt: $(BINDIR)/$(CONFIG)/grpc_verify_jwt hpack_parser_test: $(BINDIR)/$(CONFIG)/hpack_parser_test hpack_table_test: $(BINDIR)/$(CONFIG)/hpack_table_test +http_parser_test: $(BINDIR)/$(CONFIG)/http_parser_test httpcli_format_request_test: $(BINDIR)/$(CONFIG)/httpcli_format_request_test -httpcli_parser_test: $(BINDIR)/$(CONFIG)/httpcli_parser_test httpcli_test: $(BINDIR)/$(CONFIG)/httpcli_test httpscli_test: $(BINDIR)/$(CONFIG)/httpscli_test init_test: $(BINDIR)/$(CONFIG)/init_test @@ -1236,8 +1236,8 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/grpc_security_connector_test \ $(BINDIR)/$(CONFIG)/hpack_parser_test \ $(BINDIR)/$(CONFIG)/hpack_table_test \ + $(BINDIR)/$(CONFIG)/http_parser_test \ $(BINDIR)/$(CONFIG)/httpcli_format_request_test \ - $(BINDIR)/$(CONFIG)/httpcli_parser_test \ $(BINDIR)/$(CONFIG)/httpcli_test \ $(BINDIR)/$(CONFIG)/httpscli_test \ $(BINDIR)/$(CONFIG)/init_test \ @@ -1522,10 +1522,10 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/hpack_parser_test || ( echo test hpack_parser_test failed ; exit 1 ) $(E) "[RUN] Testing hpack_table_test" $(Q) $(BINDIR)/$(CONFIG)/hpack_table_test || ( echo test hpack_table_test failed ; exit 1 ) + $(E) "[RUN] Testing http_parser_test" + $(Q) $(BINDIR)/$(CONFIG)/http_parser_test || ( echo test http_parser_test failed ; exit 1 ) $(E) "[RUN] Testing httpcli_format_request_test" $(Q) $(BINDIR)/$(CONFIG)/httpcli_format_request_test || ( echo test httpcli_format_request_test failed ; exit 1 ) - $(E) "[RUN] Testing httpcli_parser_test" - $(Q) $(BINDIR)/$(CONFIG)/httpcli_parser_test || ( echo test httpcli_parser_test failed ; exit 1 ) $(E) "[RUN] Testing httpcli_test" $(Q) $(BINDIR)/$(CONFIG)/httpcli_test || ( echo test httpcli_test failed ; exit 1 ) $(E) "[RUN] Testing httpscli_test" @@ -2437,9 +2437,9 @@ LIBGRPC_SRC = \ src/core/compression/compression_algorithm.c \ src/core/compression/message_compress.c \ src/core/debug/trace.c \ - src/core/httpcli/format_request.c \ - src/core/httpcli/httpcli.c \ - src/core/httpcli/parser.c \ + src/core/http/format_request.c \ + src/core/http/httpcli.c \ + src/core/http/parser.c \ src/core/iomgr/closure.c \ src/core/iomgr/endpoint.c \ src/core/iomgr/endpoint_pair_posix.c \ @@ -2535,7 +2535,7 @@ LIBGRPC_SRC = \ src/core/transport/static_metadata.c \ src/core/transport/transport.c \ src/core/transport/transport_op_string.c \ - src/core/httpcli/httpcli_security_connector.c \ + src/core/http/httpcli_security_connector.c \ src/core/security/b64.c \ src/core/security/client_auth_filter.c \ src/core/security/credentials.c \ @@ -2797,9 +2797,9 @@ LIBGRPC_UNSECURE_SRC = \ src/core/compression/compression_algorithm.c \ src/core/compression/message_compress.c \ src/core/debug/trace.c \ - src/core/httpcli/format_request.c \ - src/core/httpcli/httpcli.c \ - src/core/httpcli/parser.c \ + src/core/http/format_request.c \ + src/core/http/httpcli.c \ + src/core/http/parser.c \ src/core/iomgr/closure.c \ src/core/iomgr/endpoint.c \ src/core/iomgr/endpoint_pair_posix.c \ @@ -7757,72 +7757,72 @@ endif endif -HTTPCLI_FORMAT_REQUEST_TEST_SRC = \ - test/core/httpcli/format_request_test.c \ +HTTP_PARSER_TEST_SRC = \ + test/core/http/parser_test.c \ -HTTPCLI_FORMAT_REQUEST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HTTPCLI_FORMAT_REQUEST_TEST_SRC)))) +HTTP_PARSER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HTTP_PARSER_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/httpcli_format_request_test: openssl_dep_error +$(BINDIR)/$(CONFIG)/http_parser_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_parser_test: $(HTTP_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_format_request_test + $(Q) $(LD) $(LDFLAGS) $(HTTP_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_parser_test endif -$(OBJDIR)/$(CONFIG)/test/core/httpcli/format_request_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS:.o=.dep) +deps_http_parser_test: $(HTTP_PARSER_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS:.o=.dep) +-include $(HTTP_PARSER_TEST_OBJS:.o=.dep) endif endif -HTTPCLI_PARSER_TEST_SRC = \ - test/core/httpcli/parser_test.c \ +HTTPCLI_FORMAT_REQUEST_TEST_SRC = \ + test/core/http/format_request_test.c \ -HTTPCLI_PARSER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HTTPCLI_PARSER_TEST_SRC)))) +HTTPCLI_FORMAT_REQUEST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HTTPCLI_FORMAT_REQUEST_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/httpcli_parser_test: openssl_dep_error +$(BINDIR)/$(CONFIG)/httpcli_format_request_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/httpcli_parser_test: $(HTTPCLI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_parser_test + $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_format_request_test endif -$(OBJDIR)/$(CONFIG)/test/core/httpcli/parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/format_request_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_httpcli_parser_test: $(HTTPCLI_PARSER_TEST_OBJS:.o=.dep) +deps_httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(HTTPCLI_PARSER_TEST_OBJS:.o=.dep) +-include $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS:.o=.dep) endif endif HTTPCLI_TEST_SRC = \ - test/core/httpcli/httpcli_test.c \ + test/core/http/httpcli_test.c \ HTTPCLI_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HTTPCLI_TEST_SRC)))) ifeq ($(NO_SECURE),true) @@ -7842,7 +7842,7 @@ $(BINDIR)/$(CONFIG)/httpcli_test: $(HTTPCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgr endif -$(OBJDIR)/$(CONFIG)/test/core/httpcli/httpcli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/httpcli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_httpcli_test: $(HTTPCLI_TEST_OBJS:.o=.dep) @@ -7854,7 +7854,7 @@ endif HTTPSCLI_TEST_SRC = \ - test/core/httpcli/httpscli_test.c \ + test/core/http/httpscli_test.c \ HTTPSCLI_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HTTPSCLI_TEST_SRC)))) ifeq ($(NO_SECURE),true) @@ -7874,7 +7874,7 @@ $(BINDIR)/$(CONFIG)/httpscli_test: $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/lib endif -$(OBJDIR)/$(CONFIG)/test/core/httpcli/httpscli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/httpscli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_httpscli_test: $(HTTPSCLI_TEST_OBJS:.o=.dep) @@ -13378,7 +13378,7 @@ ifneq ($(OPENSSL_DEP),) # This is to ensure the embedded OpenSSL is built beforehand, properly # installing headers to their final destination on the drive. We need this # otherwise parallel compilation will fail if a source is compiled first. -src/core/httpcli/httpcli_security_connector.c: $(OPENSSL_DEP) +src/core/http/httpcli_security_connector.c: $(OPENSSL_DEP) src/core/security/b64.c: $(OPENSSL_DEP) src/core/security/client_auth_filter.c: $(OPENSSL_DEP) src/core/security/credentials.c: $(OPENSSL_DEP) diff --git a/binding.gyp b/binding.gyp index c16697786a..8f3382a19a 100644 --- a/binding.gyp +++ b/binding.gyp @@ -592,9 +592,9 @@ 'src/core/compression/compression_algorithm.c', 'src/core/compression/message_compress.c', 'src/core/debug/trace.c', - 'src/core/httpcli/format_request.c', - 'src/core/httpcli/httpcli.c', - 'src/core/httpcli/parser.c', + 'src/core/http/format_request.c', + 'src/core/http/httpcli.c', + 'src/core/http/parser.c', 'src/core/iomgr/closure.c', 'src/core/iomgr/endpoint.c', 'src/core/iomgr/endpoint_pair_posix.c', @@ -690,7 +690,7 @@ 'src/core/transport/static_metadata.c', 'src/core/transport/transport.c', 'src/core/transport/transport_op_string.c', - 'src/core/httpcli/httpcli_security_connector.c', + 'src/core/http/httpcli_security_connector.c', 'src/core/security/b64.c', 'src/core/security/client_auth_filter.c', 'src/core/security/credentials.c', diff --git a/build.yaml b/build.yaml index 9773490776..6b35e6fe71 100644 --- a/build.yaml +++ b/build.yaml @@ -280,9 +280,9 @@ filegroups: - src/core/compression/algorithm_metadata.h - src/core/compression/message_compress.h - src/core/debug/trace.h - - src/core/httpcli/format_request.h - - src/core/httpcli/httpcli.h - - src/core/httpcli/parser.h + - src/core/http/format_request.h + - src/core/http/httpcli.h + - src/core/http/parser.h - src/core/iomgr/closure.h - src/core/iomgr/endpoint.h - src/core/iomgr/endpoint_pair.h @@ -401,9 +401,9 @@ filegroups: - src/core/compression/compression_algorithm.c - src/core/compression/message_compress.c - src/core/debug/trace.c - - src/core/httpcli/format_request.c - - src/core/httpcli/httpcli.c - - src/core/httpcli/parser.c + - src/core/http/format_request.c + - src/core/http/httpcli.c + - src/core/http/parser.c - src/core/iomgr/closure.c - src/core/iomgr/endpoint.c - src/core/iomgr/endpoint_pair_posix.c @@ -524,7 +524,7 @@ filegroups: - src/core/tsi/transport_security.h - src/core/tsi/transport_security_interface.h src: - - src/core/httpcli/httpcli_security_connector.c + - src/core/http/httpcli_security_connector.c - src/core/security/b64.c - src/core/security/client_auth_filter.c - src/core/security/credentials.c @@ -1560,21 +1560,21 @@ targets: - grpc - gpr_test_util - gpr -- name: httpcli_format_request_test +- name: http_parser_test build: test language: c src: - - test/core/httpcli/format_request_test.c + - test/core/http/parser_test.c deps: - grpc_test_util - grpc - gpr_test_util - gpr -- name: httpcli_parser_test +- name: httpcli_format_request_test build: test language: c src: - - test/core/httpcli/parser_test.c + - test/core/http/format_request_test.c deps: - grpc_test_util - grpc @@ -1585,7 +1585,7 @@ targets: build: test language: c src: - - test/core/httpcli/httpcli_test.c + - test/core/http/httpcli_test.c deps: - grpc_test_util - grpc @@ -1600,7 +1600,7 @@ targets: build: test language: c src: - - test/core/httpcli/httpscli_test.c + - test/core/http/httpscli_test.c deps: - grpc_test_util - grpc diff --git a/config.m4 b/config.m4 index 2d42c405ec..e8ee56f210 100644 --- a/config.m4 +++ b/config.m4 @@ -114,9 +114,9 @@ if test "$PHP_GRPC" != "no"; then src/core/compression/compression_algorithm.c \ src/core/compression/message_compress.c \ src/core/debug/trace.c \ - src/core/httpcli/format_request.c \ - src/core/httpcli/httpcli.c \ - src/core/httpcli/parser.c \ + src/core/http/format_request.c \ + src/core/http/httpcli.c \ + src/core/http/parser.c \ src/core/iomgr/closure.c \ src/core/iomgr/endpoint.c \ src/core/iomgr/endpoint_pair_posix.c \ @@ -212,7 +212,7 @@ if test "$PHP_GRPC" != "no"; then src/core/transport/static_metadata.c \ src/core/transport/transport.c \ src/core/transport/transport_op_string.c \ - src/core/httpcli/httpcli_security_connector.c \ + src/core/http/httpcli_security_connector.c \ src/core/security/b64.c \ src/core/security/client_auth_filter.c \ src/core/security/credentials.c \ @@ -551,7 +551,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/client_config/resolvers) PHP_ADD_BUILD_DIR($ext_builddir/src/core/compression) PHP_ADD_BUILD_DIR($ext_builddir/src/core/debug) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/httpcli) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/http) PHP_ADD_BUILD_DIR($ext_builddir/src/core/iomgr) PHP_ADD_BUILD_DIR($ext_builddir/src/core/json) PHP_ADD_BUILD_DIR($ext_builddir/src/core/profiling) diff --git a/gRPC.podspec b/gRPC.podspec index 65f24a658c..0187d11aa4 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -194,9 +194,9 @@ Pod::Spec.new do |s| 'src/core/compression/algorithm_metadata.h', 'src/core/compression/message_compress.h', 'src/core/debug/trace.h', - 'src/core/httpcli/format_request.h', - 'src/core/httpcli/httpcli.h', - 'src/core/httpcli/parser.h', + 'src/core/http/format_request.h', + 'src/core/http/httpcli.h', + 'src/core/http/parser.h', 'src/core/iomgr/closure.h', 'src/core/iomgr/endpoint.h', 'src/core/iomgr/endpoint_pair.h', @@ -348,9 +348,9 @@ Pod::Spec.new do |s| 'src/core/compression/compression_algorithm.c', 'src/core/compression/message_compress.c', 'src/core/debug/trace.c', - 'src/core/httpcli/format_request.c', - 'src/core/httpcli/httpcli.c', - 'src/core/httpcli/parser.c', + 'src/core/http/format_request.c', + 'src/core/http/httpcli.c', + 'src/core/http/parser.c', 'src/core/iomgr/closure.c', 'src/core/iomgr/endpoint.c', 'src/core/iomgr/endpoint_pair_posix.c', @@ -446,7 +446,7 @@ Pod::Spec.new do |s| 'src/core/transport/static_metadata.c', 'src/core/transport/transport.c', 'src/core/transport/transport_op_string.c', - 'src/core/httpcli/httpcli_security_connector.c', + 'src/core/http/httpcli_security_connector.c', 'src/core/security/b64.c', 'src/core/security/client_auth_filter.c', 'src/core/security/credentials.c', @@ -522,9 +522,9 @@ Pod::Spec.new do |s| 'src/core/compression/algorithm_metadata.h', 'src/core/compression/message_compress.h', 'src/core/debug/trace.h', - 'src/core/httpcli/format_request.h', - 'src/core/httpcli/httpcli.h', - 'src/core/httpcli/parser.h', + 'src/core/http/format_request.h', + 'src/core/http/httpcli.h', + 'src/core/http/parser.h', 'src/core/iomgr/closure.h', 'src/core/iomgr/endpoint.h', 'src/core/iomgr/endpoint_pair.h', diff --git a/grpc.gemspec b/grpc.gemspec index 0873286e21..c897ccd551 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -190,9 +190,9 @@ Gem::Specification.new do |s| s.files += %w( src/core/compression/algorithm_metadata.h ) s.files += %w( src/core/compression/message_compress.h ) s.files += %w( src/core/debug/trace.h ) - s.files += %w( src/core/httpcli/format_request.h ) - s.files += %w( src/core/httpcli/httpcli.h ) - s.files += %w( src/core/httpcli/parser.h ) + s.files += %w( src/core/http/format_request.h ) + s.files += %w( src/core/http/httpcli.h ) + s.files += %w( src/core/http/parser.h ) s.files += %w( src/core/iomgr/closure.h ) s.files += %w( src/core/iomgr/endpoint.h ) s.files += %w( src/core/iomgr/endpoint_pair.h ) @@ -331,9 +331,9 @@ Gem::Specification.new do |s| s.files += %w( src/core/compression/compression_algorithm.c ) s.files += %w( src/core/compression/message_compress.c ) s.files += %w( src/core/debug/trace.c ) - s.files += %w( src/core/httpcli/format_request.c ) - s.files += %w( src/core/httpcli/httpcli.c ) - s.files += %w( src/core/httpcli/parser.c ) + s.files += %w( src/core/http/format_request.c ) + s.files += %w( src/core/http/httpcli.c ) + s.files += %w( src/core/http/parser.c ) s.files += %w( src/core/iomgr/closure.c ) s.files += %w( src/core/iomgr/endpoint.c ) s.files += %w( src/core/iomgr/endpoint_pair_posix.c ) @@ -429,7 +429,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/transport/static_metadata.c ) s.files += %w( src/core/transport/transport.c ) s.files += %w( src/core/transport/transport_op_string.c ) - s.files += %w( src/core/httpcli/httpcli_security_connector.c ) + s.files += %w( src/core/http/httpcli_security_connector.c ) s.files += %w( src/core/security/b64.c ) s.files += %w( src/core/security/client_auth_filter.c ) s.files += %w( src/core/security/credentials.c ) diff --git a/package.json b/package.json index bc15183c93..3fb0799fd3 100644 --- a/package.json +++ b/package.json @@ -132,9 +132,9 @@ "src/core/compression/algorithm_metadata.h", "src/core/compression/message_compress.h", "src/core/debug/trace.h", - "src/core/httpcli/format_request.h", - "src/core/httpcli/httpcli.h", - "src/core/httpcli/parser.h", + "src/core/http/format_request.h", + "src/core/http/httpcli.h", + "src/core/http/parser.h", "src/core/iomgr/closure.h", "src/core/iomgr/endpoint.h", "src/core/iomgr/endpoint_pair.h", @@ -273,9 +273,9 @@ "src/core/compression/compression_algorithm.c", "src/core/compression/message_compress.c", "src/core/debug/trace.c", - "src/core/httpcli/format_request.c", - "src/core/httpcli/httpcli.c", - "src/core/httpcli/parser.c", + "src/core/http/format_request.c", + "src/core/http/httpcli.c", + "src/core/http/parser.c", "src/core/iomgr/closure.c", "src/core/iomgr/endpoint.c", "src/core/iomgr/endpoint_pair_posix.c", @@ -371,7 +371,7 @@ "src/core/transport/static_metadata.c", "src/core/transport/transport.c", "src/core/transport/transport_op_string.c", - "src/core/httpcli/httpcli_security_connector.c", + "src/core/http/httpcli_security_connector.c", "src/core/security/b64.c", "src/core/security/client_auth_filter.c", "src/core/security/credentials.c", diff --git a/package.xml b/package.xml index 95bc835602..cf11e0e450 100644 --- a/package.xml +++ b/package.xml @@ -194,9 +194,9 @@ - - - + + + @@ -335,9 +335,9 @@ - - - + + + @@ -433,7 +433,7 @@ - + diff --git a/src/core/http/format_request.c b/src/core/http/format_request.c new file mode 100644 index 0000000000..60179297bf --- /dev/null +++ b/src/core/http/format_request.c @@ -0,0 +1,120 @@ +/* + * + * Copyright 2015-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/http/format_request.h" + +#include +#include +#include + +#include "src/core/support/string.h" +#include +#include +#include +#include + +static void fill_common_header(const grpc_httpcli_request *request, + gpr_strvec *buf) { + size_t i; + gpr_strvec_add(buf, gpr_strdup(request->http.path)); + gpr_strvec_add(buf, gpr_strdup(" HTTP/1.0\r\n")); + /* just in case some crazy server really expects HTTP/1.1 */ + gpr_strvec_add(buf, gpr_strdup("Host: ")); + gpr_strvec_add(buf, gpr_strdup(request->host)); + gpr_strvec_add(buf, gpr_strdup("\r\n")); + gpr_strvec_add(buf, gpr_strdup("Connection: close\r\n")); + gpr_strvec_add(buf, + gpr_strdup("User-Agent: " GRPC_HTTPCLI_USER_AGENT "\r\n")); + /* user supplied headers */ + for (i = 0; i < request->http.hdr_count; i++) { + gpr_strvec_add(buf, gpr_strdup(request->http.hdrs[i].key)); + gpr_strvec_add(buf, gpr_strdup(": ")); + gpr_strvec_add(buf, gpr_strdup(request->http.hdrs[i].value)); + gpr_strvec_add(buf, gpr_strdup("\r\n")); + } +} + +gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request) { + gpr_strvec out; + char *flat; + size_t flat_len; + + gpr_strvec_init(&out); + gpr_strvec_add(&out, gpr_strdup("GET ")); + fill_common_header(request, &out); + gpr_strvec_add(&out, gpr_strdup("\r\n")); + + flat = gpr_strvec_flatten(&out, &flat_len); + gpr_strvec_destroy(&out); + + return gpr_slice_new(flat, flat_len, gpr_free); +} + +gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, + const char *body_bytes, + size_t body_size) { + gpr_strvec out; + char *tmp; + size_t out_len; + size_t i; + + gpr_strvec_init(&out); + + gpr_strvec_add(&out, gpr_strdup("POST ")); + fill_common_header(request, &out); + if (body_bytes) { + uint8_t has_content_type = 0; + for (i = 0; i < request->http.hdr_count; i++) { + if (strcmp(request->http.hdrs[i].key, "Content-Type") == 0) { + has_content_type = 1; + break; + } + } + if (!has_content_type) { + gpr_strvec_add(&out, gpr_strdup("Content-Type: text/plain\r\n")); + } + gpr_asprintf(&tmp, "Content-Length: %lu\r\n", (unsigned long)body_size); + gpr_strvec_add(&out, tmp); + } + gpr_strvec_add(&out, gpr_strdup("\r\n")); + tmp = gpr_strvec_flatten(&out, &out_len); + gpr_strvec_destroy(&out); + + if (body_bytes) { + tmp = gpr_realloc(tmp, out_len + body_size); + memcpy(tmp + out_len, body_bytes, body_size); + out_len += body_size; + } + + return gpr_slice_new(tmp, out_len, gpr_free); +} diff --git a/src/core/http/format_request.h b/src/core/http/format_request.h new file mode 100644 index 0000000000..49593b695c --- /dev/null +++ b/src/core/http/format_request.h @@ -0,0 +1,45 @@ +/* + * + * Copyright 2015-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_HTTP_FORMAT_REQUEST_H +#define GRPC_CORE_HTTP_FORMAT_REQUEST_H + +#include "src/core/http/httpcli.h" +#include + +gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request); +gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, + const char *body_bytes, + size_t body_size); + +#endif /* GRPC_CORE_HTTP_FORMAT_REQUEST_H */ diff --git a/src/core/http/httpcli.c b/src/core/http/httpcli.c new file mode 100644 index 0000000000..1c0d3336ea --- /dev/null +++ b/src/core/http/httpcli.c @@ -0,0 +1,293 @@ +/* + * + * Copyright 2015-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/http/httpcli.h" +#include "src/core/iomgr/sockaddr.h" + +#include + +#include +#include +#include + +#include "src/core/http/format_request.h" +#include "src/core/http/parser.h" +#include "src/core/iomgr/endpoint.h" +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/tcp_client.h" +#include "src/core/support/string.h" + +typedef struct { + gpr_slice request_text; + grpc_http_parser parser; + grpc_resolved_addresses *addresses; + size_t next_address; + grpc_endpoint *ep; + char *host; + char *ssl_host_override; + gpr_timespec deadline; + int have_read_byte; + const grpc_httpcli_handshaker *handshaker; + grpc_httpcli_response_cb on_response; + void *user_data; + grpc_httpcli_context *context; + grpc_pollset *pollset; + grpc_iomgr_object iomgr_obj; + gpr_slice_buffer incoming; + gpr_slice_buffer outgoing; + grpc_closure on_read; + grpc_closure done_write; + grpc_closure connected; +} internal_request; + +static grpc_httpcli_get_override g_get_override = NULL; +static grpc_httpcli_post_override g_post_override = NULL; + +static void plaintext_handshake(grpc_exec_ctx *exec_ctx, void *arg, + grpc_endpoint *endpoint, const char *host, + void (*on_done)(grpc_exec_ctx *exec_ctx, + void *arg, + grpc_endpoint *endpoint)) { + on_done(exec_ctx, arg, endpoint); +} + +const grpc_httpcli_handshaker grpc_httpcli_plaintext = {"http", + plaintext_handshake}; + +void grpc_httpcli_context_init(grpc_httpcli_context *context) { + context->pollset_set = grpc_pollset_set_create(); +} + +void grpc_httpcli_context_destroy(grpc_httpcli_context *context) { + grpc_pollset_set_destroy(context->pollset_set); +} + +static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req); + +static void finish(grpc_exec_ctx *exec_ctx, internal_request *req, + int success) { + grpc_pollset_set_del_pollset(exec_ctx, req->context->pollset_set, + req->pollset); + req->on_response(exec_ctx, req->user_data, + success ? &req->parser.http.response : NULL); + grpc_http_parser_destroy(&req->parser); + if (req->addresses != NULL) { + grpc_resolved_addresses_destroy(req->addresses); + } + if (req->ep != NULL) { + grpc_endpoint_destroy(exec_ctx, req->ep); + } + gpr_slice_unref(req->request_text); + gpr_free(req->host); + gpr_free(req->ssl_host_override); + grpc_iomgr_unregister_object(&req->iomgr_obj); + gpr_slice_buffer_destroy(&req->incoming); + gpr_slice_buffer_destroy(&req->outgoing); + gpr_free(req); +} + +static void on_read(grpc_exec_ctx *exec_ctx, void *user_data, bool success); + +static void do_read(grpc_exec_ctx *exec_ctx, internal_request *req) { + grpc_endpoint_read(exec_ctx, req->ep, &req->incoming, &req->on_read); +} + +static void on_read(grpc_exec_ctx *exec_ctx, void *user_data, bool success) { + internal_request *req = user_data; + size_t i; + + for (i = 0; i < req->incoming.count; i++) { + if (GPR_SLICE_LENGTH(req->incoming.slices[i])) { + req->have_read_byte = 1; + if (!grpc_http_parser_parse(&req->parser, req->incoming.slices[i])) { + finish(exec_ctx, req, 0); + return; + } + } + } + + if (success) { + do_read(exec_ctx, req); + } else if (!req->have_read_byte) { + next_address(exec_ctx, req); + } else { + int parse_success = grpc_http_parser_eof(&req->parser); + if (parse_success && (req->parser.type != GRPC_HTTP_RESPONSE)) { + parse_success = 0; + } + finish(exec_ctx, req, parse_success); + } +} + +static void on_written(grpc_exec_ctx *exec_ctx, internal_request *req) { + do_read(exec_ctx, req); +} + +static void done_write(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + internal_request *req = arg; + if (success) { + on_written(exec_ctx, req); + } else { + next_address(exec_ctx, req); + } +} + +static void start_write(grpc_exec_ctx *exec_ctx, internal_request *req) { + gpr_slice_ref(req->request_text); + gpr_slice_buffer_add(&req->outgoing, req->request_text); + grpc_endpoint_write(exec_ctx, req->ep, &req->outgoing, &req->done_write); +} + +static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, + grpc_endpoint *ep) { + internal_request *req = arg; + + if (!ep) { + next_address(exec_ctx, req); + return; + } + + req->ep = ep; + start_write(exec_ctx, req); +} + +static void on_connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + internal_request *req = arg; + + if (!req->ep) { + next_address(exec_ctx, req); + return; + } + req->handshaker->handshake( + exec_ctx, req, req->ep, + req->ssl_host_override ? req->ssl_host_override : req->host, + on_handshake_done); +} + +static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req) { + grpc_resolved_address *addr; + if (req->next_address == req->addresses->naddrs) { + finish(exec_ctx, req, 0); + return; + } + addr = &req->addresses->addrs[req->next_address++]; + grpc_closure_init(&req->connected, on_connected, req); + grpc_tcp_client_connect( + exec_ctx, &req->connected, &req->ep, req->context->pollset_set, + (struct sockaddr *)&addr->addr, addr->len, req->deadline); +} + +static void on_resolved(grpc_exec_ctx *exec_ctx, void *arg, + grpc_resolved_addresses *addresses) { + internal_request *req = arg; + if (!addresses) { + finish(exec_ctx, req, 0); + return; + } + req->addresses = addresses; + req->next_address = 0; + next_address(exec_ctx, req); +} + +static void internal_request_begin( + grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, + grpc_pollset *pollset, const grpc_httpcli_request *request, + gpr_timespec deadline, grpc_httpcli_response_cb on_response, + void *user_data, const char *name, gpr_slice request_text) { + internal_request *req = gpr_malloc(sizeof(internal_request)); + memset(req, 0, sizeof(*req)); + req->request_text = request_text; + grpc_http_parser_init(&req->parser); + req->on_response = on_response; + req->user_data = user_data; + req->deadline = deadline; + req->handshaker = + request->handshaker ? request->handshaker : &grpc_httpcli_plaintext; + req->context = context; + req->pollset = pollset; + grpc_closure_init(&req->on_read, on_read, req); + grpc_closure_init(&req->done_write, done_write, req); + gpr_slice_buffer_init(&req->incoming); + gpr_slice_buffer_init(&req->outgoing); + grpc_iomgr_register_object(&req->iomgr_obj, name); + req->host = gpr_strdup(request->host); + req->ssl_host_override = gpr_strdup(request->ssl_host_override); + + grpc_pollset_set_add_pollset(exec_ctx, req->context->pollset_set, + req->pollset); + grpc_resolve_address(request->host, req->handshaker->default_port, + on_resolved, req); +} + +void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, + grpc_pollset *pollset, + const grpc_httpcli_request *request, + gpr_timespec deadline, + grpc_httpcli_response_cb on_response, void *user_data) { + char *name; + if (g_get_override && + g_get_override(exec_ctx, request, deadline, on_response, user_data)) { + return; + } + gpr_asprintf(&name, "HTTP:GET:%s:%s", request->host, request->http.path); + internal_request_begin(exec_ctx, context, pollset, request, deadline, + on_response, user_data, name, + grpc_httpcli_format_get_request(request)); + gpr_free(name); +} + +void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, + grpc_pollset *pollset, + const grpc_httpcli_request *request, + const char *body_bytes, size_t body_size, + gpr_timespec deadline, + grpc_httpcli_response_cb on_response, void *user_data) { + char *name; + if (g_post_override && + g_post_override(exec_ctx, request, body_bytes, body_size, deadline, + on_response, user_data)) { + return; + } + gpr_asprintf(&name, "HTTP:POST:%s:%s", request->host, request->http.path); + internal_request_begin( + exec_ctx, context, pollset, request, deadline, on_response, user_data, + name, grpc_httpcli_format_post_request(request, body_bytes, body_size)); + gpr_free(name); +} + +void grpc_httpcli_set_override(grpc_httpcli_get_override get, + grpc_httpcli_post_override post) { + g_get_override = get; + g_post_override = post; +} diff --git a/src/core/http/httpcli.h b/src/core/http/httpcli.h new file mode 100644 index 0000000000..0bf4f2f445 --- /dev/null +++ b/src/core/http/httpcli.h @@ -0,0 +1,144 @@ +/* + * + * Copyright 2015-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_HTTP_HTTPCLI_H +#define GRPC_CORE_HTTP_HTTPCLI_H + +#include + +#include + +#include "src/core/http/parser.h" +#include "src/core/iomgr/endpoint.h" +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/pollset_set.h" + +/* User agent this library reports */ +#define GRPC_HTTPCLI_USER_AGENT "grpc-httpcli/0.0" + +/* Tracks in-progress http requests + TODO(ctiller): allow caching and capturing multiple requests for the + same content and combining them */ +typedef struct grpc_httpcli_context { + grpc_pollset_set *pollset_set; +} grpc_httpcli_context; + +typedef struct { + const char *default_port; + void (*handshake)(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *endpoint, + const char *host, + void (*on_done)(grpc_exec_ctx *exec_ctx, void *arg, + grpc_endpoint *endpoint)); +} grpc_httpcli_handshaker; + +extern const grpc_httpcli_handshaker grpc_httpcli_plaintext; +extern const grpc_httpcli_handshaker grpc_httpcli_ssl; + +/* A request */ +typedef struct grpc_httpcli_request { + /* The host name to connect to */ + char *host; + /* The host to verify in the SSL handshake (or NULL) */ + char *ssl_host_override; + /* The main part of the request + The following headers are supplied automatically and MUST NOT be set here: + Host, Connection, User-Agent */ + grpc_http_request http; + /* handshaker to use ssl for the request */ + const grpc_httpcli_handshaker *handshaker; +} grpc_httpcli_request; + +/* Expose the parser response type as a httpcli response too */ +typedef struct grpc_http_response grpc_httpcli_response; + +/* Callback for grpc_httpcli_get and grpc_httpcli_post. */ +typedef void (*grpc_httpcli_response_cb)(grpc_exec_ctx *exec_ctx, + void *user_data, + const grpc_http_response *response); + +void grpc_httpcli_context_init(grpc_httpcli_context *context); +void grpc_httpcli_context_destroy(grpc_httpcli_context *context); + +/* Asynchronously perform a HTTP GET. + 'context' specifies the http context under which to do the get + 'pollset' indicates a grpc_pollset that is interested in the result + of the get - work on this pollset may be used to progress the get + operation + 'request' contains request parameters - these are caller owned and can be + destroyed once the call returns + 'deadline' contains a deadline for the request (or gpr_inf_future) + 'on_response' is a callback to report results to (and 'user_data' is a user + supplied pointer to pass to said call) */ +void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, + grpc_pollset *pollset, + const grpc_httpcli_request *request, + gpr_timespec deadline, + grpc_httpcli_response_cb on_response, void *user_data); + +/* Asynchronously perform a HTTP POST. + 'context' specifies the http context under which to do the post + 'pollset' indicates a grpc_pollset that is interested in the result + of the post - work on this pollset may be used to progress the post + operation + 'request' contains request parameters - these are caller owned and can be + destroyed once the call returns + 'body_bytes' and 'body_size' specify the payload for the post. + When there is no body, pass in NULL as body_bytes. + 'deadline' contains a deadline for the request (or gpr_inf_future) + 'em' points to a caller owned event manager that must be alive for the + lifetime of the request + 'on_response' is a callback to report results to (and 'user_data' is a user + supplied pointer to pass to said call) + Does not support ?var1=val1&var2=val2 in the path. */ +void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, + grpc_pollset *pollset, + const grpc_httpcli_request *request, + const char *body_bytes, size_t body_size, + gpr_timespec deadline, + grpc_httpcli_response_cb on_response, void *user_data); + +/* override functions return 1 if they handled the request, 0 otherwise */ +typedef int (*grpc_httpcli_get_override)(grpc_exec_ctx *exec_ctx, + const grpc_httpcli_request *request, + gpr_timespec deadline, + grpc_httpcli_response_cb on_response, + void *user_data); +typedef int (*grpc_httpcli_post_override)( + grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, + const char *body_bytes, size_t body_size, gpr_timespec deadline, + grpc_httpcli_response_cb on_response, void *user_data); + +void grpc_httpcli_set_override(grpc_httpcli_get_override get, + grpc_httpcli_post_override post); + +#endif /* GRPC_CORE_HTTP_HTTPCLI_H */ diff --git a/src/core/http/httpcli_security_connector.c b/src/core/http/httpcli_security_connector.c new file mode 100644 index 0000000000..ce82701089 --- /dev/null +++ b/src/core/http/httpcli_security_connector.c @@ -0,0 +1,188 @@ +/* + * + * Copyright 2015-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/http/httpcli.h" + +#include + +#include "src/core/security/handshake.h" +#include "src/core/support/string.h" +#include +#include +#include +#include "src/core/tsi/ssl_transport_security.h" + +typedef struct { + grpc_channel_security_connector base; + tsi_ssl_handshaker_factory *handshaker_factory; + char *secure_peer_name; +} grpc_httpcli_ssl_channel_security_connector; + +static void httpcli_ssl_destroy(grpc_security_connector *sc) { + grpc_httpcli_ssl_channel_security_connector *c = + (grpc_httpcli_ssl_channel_security_connector *)sc; + if (c->handshaker_factory != NULL) { + tsi_ssl_handshaker_factory_destroy(c->handshaker_factory); + } + if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name); + gpr_free(sc); +} + +static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, + grpc_channel_security_connector *sc, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *user_data) { + grpc_httpcli_ssl_channel_security_connector *c = + (grpc_httpcli_ssl_channel_security_connector *)sc; + tsi_result result = TSI_OK; + tsi_handshaker *handshaker; + if (c->handshaker_factory == NULL) { + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); + return; + } + result = tsi_ssl_handshaker_factory_create_handshaker( + c->handshaker_factory, c->secure_peer_name, &handshaker); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); + } else { + grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true, + nonsecure_endpoint, cb, user_data); + } +} + +static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx, + grpc_security_connector *sc, tsi_peer peer, + grpc_security_peer_check_cb cb, + void *user_data) { + grpc_httpcli_ssl_channel_security_connector *c = + (grpc_httpcli_ssl_channel_security_connector *)sc; + grpc_security_status status = GRPC_SECURITY_OK; + + /* Check the peer name. */ + if (c->secure_peer_name != NULL && + !tsi_ssl_peer_matches_name(&peer, c->secure_peer_name)) { + gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", + c->secure_peer_name); + status = GRPC_SECURITY_ERROR; + } + cb(exec_ctx, user_data, status, NULL); + tsi_peer_destruct(&peer); +} + +static grpc_security_connector_vtable httpcli_ssl_vtable = { + httpcli_ssl_destroy, httpcli_ssl_check_peer}; + +static grpc_security_status httpcli_ssl_channel_security_connector_create( + const unsigned char *pem_root_certs, size_t pem_root_certs_size, + const char *secure_peer_name, grpc_channel_security_connector **sc) { + tsi_result result = TSI_OK; + grpc_httpcli_ssl_channel_security_connector *c; + + if (secure_peer_name != NULL && pem_root_certs == NULL) { + gpr_log(GPR_ERROR, + "Cannot assert a secure peer name without a trust root."); + return GRPC_SECURITY_ERROR; + } + + c = gpr_malloc(sizeof(grpc_httpcli_ssl_channel_security_connector)); + memset(c, 0, sizeof(grpc_httpcli_ssl_channel_security_connector)); + + gpr_ref_init(&c->base.base.refcount, 1); + c->base.base.vtable = &httpcli_ssl_vtable; + if (secure_peer_name != NULL) { + c->secure_peer_name = gpr_strdup(secure_peer_name); + } + result = tsi_create_ssl_client_handshaker_factory( + NULL, 0, NULL, 0, pem_root_certs, pem_root_certs_size, NULL, NULL, NULL, + 0, &c->handshaker_factory); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + httpcli_ssl_destroy(&c->base.base); + *sc = NULL; + return GRPC_SECURITY_ERROR; + } + c->base.do_handshake = httpcli_ssl_do_handshake; + *sc = &c->base; + return GRPC_SECURITY_OK; +} + +/* handshaker */ + +typedef struct { + void (*func)(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *endpoint); + void *arg; +} on_done_closure; + +static void on_secure_transport_setup_done(grpc_exec_ctx *exec_ctx, void *rp, + grpc_security_status status, + grpc_endpoint *secure_endpoint, + grpc_auth_context *auth_context) { + on_done_closure *c = rp; + if (status != GRPC_SECURITY_OK) { + gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status); + c->func(exec_ctx, c->arg, NULL); + } else { + c->func(exec_ctx, c->arg, secure_endpoint); + } + gpr_free(c); +} + +static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg, + grpc_endpoint *tcp, const char *host, + void (*on_done)(grpc_exec_ctx *exec_ctx, void *arg, + grpc_endpoint *endpoint)) { + grpc_channel_security_connector *sc = NULL; + const unsigned char *pem_root_certs = NULL; + on_done_closure *c = gpr_malloc(sizeof(*c)); + size_t pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs); + if (pem_root_certs == NULL || pem_root_certs_size == 0) { + gpr_log(GPR_ERROR, "Could not get default pem root certs."); + on_done(exec_ctx, arg, NULL); + gpr_free(c); + return; + } + c->func = on_done; + c->arg = arg; + GPR_ASSERT(httpcli_ssl_channel_security_connector_create( + pem_root_certs, pem_root_certs_size, host, &sc) == + GRPC_SECURITY_OK); + grpc_channel_security_connector_do_handshake( + exec_ctx, sc, tcp, on_secure_transport_setup_done, c); + GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); +} + +const grpc_httpcli_handshaker grpc_httpcli_ssl = {"https", ssl_handshake}; diff --git a/src/core/http/parser.c b/src/core/http/parser.c new file mode 100644 index 0000000000..ebec8a5157 --- /dev/null +++ b/src/core/http/parser.c @@ -0,0 +1,313 @@ +/* + * + * Copyright 2015-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/http/parser.h" + +#include + +#include +#include +#include + +static char *buf2str(void *buffer, size_t length) { + char *out = gpr_malloc(length + 1); + memcpy(out, buffer, length); + out[length] = 0; + return out; +} + +static int handle_response_line(grpc_http_parser *parser) { + uint8_t *beg = parser->cur_line; + uint8_t *cur = beg; + uint8_t *end = beg + parser->cur_line_length; + + if (cur == end || *cur++ != 'H') goto error; + if (cur == end || *cur++ != 'T') goto error; + if (cur == end || *cur++ != 'T') goto error; + if (cur == end || *cur++ != 'P') goto error; + if (cur == end || *cur++ != '/') goto error; + if (cur == end || *cur++ != '1') goto error; + if (cur == end || *cur++ != '.') goto error; + if (cur == end || *cur < '0' || *cur++ > '1') goto error; + if (cur == end || *cur++ != ' ') goto error; + if (cur == end || *cur < '1' || *cur++ > '9') goto error; + if (cur == end || *cur < '0' || *cur++ > '9') goto error; + if (cur == end || *cur < '0' || *cur++ > '9') goto error; + parser->http.response.status = + (cur[-3] - '0') * 100 + (cur[-2] - '0') * 10 + (cur[-1] - '0'); + if (cur == end || *cur++ != ' ') goto error; + + /* we don't really care about the status code message */ + + return 1; + +error: + gpr_log(GPR_ERROR, "Failed parsing response line"); + return 0; +} + +static int handle_request_line(grpc_http_parser *parser) { + uint8_t *beg = parser->cur_line; + uint8_t *cur = beg; + uint8_t *end = beg + parser->cur_line_length; + uint8_t vers_major = 0; + uint8_t vers_minor = 0; + + while (cur != end && *cur++ != ' ') + ; + if (cur == end) goto error; + parser->http.request.method = buf2str(beg, (size_t)(cur - beg - 1)); + + beg = cur; + while (cur != end && *cur++ != ' ') + ; + if (cur == end) goto error; + parser->http.request.path = buf2str(beg, (size_t)(cur - beg - 1)); + + if (cur == end || *cur++ != 'H') goto error; + if (cur == end || *cur++ != 'T') goto error; + if (cur == end || *cur++ != 'T') goto error; + if (cur == end || *cur++ != 'P') goto error; + if (cur == end || *cur++ != '/') goto error; + vers_major = (uint8_t)(*cur++ - '1' + 1); + ++cur; + if (cur == end) goto error; + vers_minor = (uint8_t)(*cur++ - '1' + 1); + + if (vers_major == 1) { + if (vers_minor == 0) { + parser->http.request.version = GRPC_HTTP_HTTP10; + } else if (vers_minor == 1) { + parser->http.request.version = GRPC_HTTP_HTTP11; + } else { + goto error; + } + } else if (vers_major == 2) { + if (vers_minor == 0) { + parser->http.request.version = GRPC_HTTP_HTTP20; + } else { + goto error; + } + } else { + goto error; + } + + return 1; + +error: + gpr_log(GPR_ERROR, "Failed parsing request line"); + return 0; +} + +static int handle_first_line(grpc_http_parser *parser) { + if (parser->cur_line[0] == 'H') { + parser->type = GRPC_HTTP_RESPONSE; + return handle_response_line(parser); + } else { + parser->type = GRPC_HTTP_REQUEST; + return handle_request_line(parser); + } +} + +static int add_header(grpc_http_parser *parser) { + uint8_t *beg = parser->cur_line; + uint8_t *cur = beg; + uint8_t *end = beg + parser->cur_line_length; + size_t *hdr_count = NULL; + grpc_http_header **hdrs = NULL; + grpc_http_header hdr = {NULL, NULL}; + + GPR_ASSERT(cur != end); + + if (*cur == ' ' || *cur == '\t') { + gpr_log(GPR_ERROR, "Continued header lines not supported yet"); + goto error; + } + + while (cur != end && *cur != ':') { + cur++; + } + if (cur == end) { + gpr_log(GPR_ERROR, "Didn't find ':' in header string"); + goto error; + } + GPR_ASSERT(cur >= beg); + hdr.key = buf2str(beg, (size_t)(cur - beg)); + cur++; /* skip : */ + + while (cur != end && (*cur == ' ' || *cur == '\t')) { + cur++; + } + GPR_ASSERT(end - cur >= 2); + hdr.value = buf2str(cur, (size_t)(end - cur) - 2); + + if (parser->type == GRPC_HTTP_RESPONSE) { + hdr_count = &parser->http.response.hdr_count; + hdrs = &parser->http.response.hdrs; + } else if (parser->type == GRPC_HTTP_REQUEST) { + hdr_count = &parser->http.request.hdr_count; + hdrs = &parser->http.request.hdrs; + } else { + return 0; + } + + if (*hdr_count == parser->hdr_capacity) { + parser->hdr_capacity = + GPR_MAX(parser->hdr_capacity + 1, parser->hdr_capacity * 3 / 2); + *hdrs = gpr_realloc(*hdrs, parser->hdr_capacity * sizeof(**hdrs)); + } + (*hdrs)[(*hdr_count)++] = hdr; + return 1; + +error: + gpr_free(hdr.key); + gpr_free(hdr.value); + return 0; +} + +static int finish_line(grpc_http_parser *parser) { + switch (parser->state) { + case GRPC_HTTP_FIRST_LINE: + if (!handle_first_line(parser)) { + return 0; + } + parser->state = GRPC_HTTP_HEADERS; + break; + case GRPC_HTTP_HEADERS: + if (parser->cur_line_length == 2) { + parser->state = GRPC_HTTP_BODY; + break; + } + if (!add_header(parser)) { + return 0; + } + break; + case GRPC_HTTP_BODY: + GPR_UNREACHABLE_CODE(return 0); + } + + parser->cur_line_length = 0; + return 1; +} + +static int addbyte_body(grpc_http_parser *parser, uint8_t byte) { + size_t *body_length = NULL; + char **body = NULL; + + if (parser->type == GRPC_HTTP_RESPONSE) { + body_length = &parser->http.response.body_length; + body = &parser->http.response.body; + } else if (parser->type == GRPC_HTTP_REQUEST) { + body_length = &parser->http.request.body_length; + body = &parser->http.request.body; + } else { + return 0; + } + + if (*body_length == parser->body_capacity) { + parser->body_capacity = GPR_MAX(8, parser->body_capacity * 3 / 2); + *body = gpr_realloc((void *)*body, parser->body_capacity); + } + (*body)[*body_length] = (char)byte; + (*body_length)++; + + return 1; +} + +static int addbyte(grpc_http_parser *parser, uint8_t byte) { + switch (parser->state) { + case GRPC_HTTP_FIRST_LINE: + case GRPC_HTTP_HEADERS: + if (parser->cur_line_length >= GRPC_HTTP_PARSER_MAX_HEADER_LENGTH) { + gpr_log(GPR_ERROR, "HTTP client max line length (%d) exceeded", + GRPC_HTTP_PARSER_MAX_HEADER_LENGTH); + return 0; + } + parser->cur_line[parser->cur_line_length] = byte; + parser->cur_line_length++; + if (parser->cur_line_length >= 2 && + parser->cur_line[parser->cur_line_length - 2] == '\r' && + parser->cur_line[parser->cur_line_length - 1] == '\n') { + return finish_line(parser); + } else { + return 1; + } + GPR_UNREACHABLE_CODE(return 0); + case GRPC_HTTP_BODY: + return addbyte_body(parser, byte); + } + GPR_UNREACHABLE_CODE(return 0); +} + +void grpc_http_parser_init(grpc_http_parser *parser) { + memset(parser, 0, sizeof(*parser)); + parser->state = GRPC_HTTP_FIRST_LINE; + parser->type = GRPC_HTTP_UNKNOWN; +} + +void grpc_http_parser_destroy(grpc_http_parser *parser) { + size_t i; + if (parser->type == GRPC_HTTP_RESPONSE) { + gpr_free(parser->http.response.body); + for (i = 0; i < parser->http.response.hdr_count; i++) { + gpr_free(parser->http.response.hdrs[i].key); + gpr_free(parser->http.response.hdrs[i].value); + } + gpr_free(parser->http.response.hdrs); + } else if (parser->type == GRPC_HTTP_REQUEST) { + gpr_free(parser->http.request.body); + for (i = 0; i < parser->http.request.hdr_count; i++) { + gpr_free(parser->http.request.hdrs[i].key); + gpr_free(parser->http.request.hdrs[i].value); + } + gpr_free(parser->http.request.hdrs); + gpr_free(parser->http.request.method); + gpr_free(parser->http.request.path); + } +} + +int grpc_http_parser_parse(grpc_http_parser *parser, gpr_slice slice) { + size_t i; + + for (i = 0; i < GPR_SLICE_LENGTH(slice); i++) { + if (!addbyte(parser, GPR_SLICE_START_PTR(slice)[i])) { + return 0; + } + } + + return 1; +} + +int grpc_http_parser_eof(grpc_http_parser *parser) { + return parser->state == GRPC_HTTP_BODY; +} diff --git a/src/core/http/parser.h b/src/core/http/parser.h new file mode 100644 index 0000000000..39517e485a --- /dev/null +++ b/src/core/http/parser.h @@ -0,0 +1,116 @@ +/* + * + * Copyright 2015-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_HTTP_PARSER_H +#define GRPC_CORE_HTTP_PARSER_H + +#include +#include + +/* Maximum length of a header string of the form 'Key: Value\r\n' */ +#define GRPC_HTTP_PARSER_MAX_HEADER_LENGTH 4096 + +/* A single header to be passed in a request */ +typedef struct grpc_http_header { + char *key; + char *value; +} grpc_http_header; + +typedef enum { + GRPC_HTTP_FIRST_LINE, + GRPC_HTTP_HEADERS, + GRPC_HTTP_BODY +} grpc_http_parser_state; + +typedef enum { + GRPC_HTTP_HTTP10, + GRPC_HTTP_HTTP11, + GRPC_HTTP_HTTP20, +} grpc_http_version; + +typedef enum { + GRPC_HTTP_RESPONSE, + GRPC_HTTP_REQUEST, + GRPC_HTTP_UNKNOWN +} grpc_http_type; + +/* A request */ +typedef struct grpc_http_request { + /* Method of the request (e.g. GET, POST) */ + char *method; + /* The path of the resource to fetch */ + char *path; + /* HTTP version to use */ + grpc_http_version version; + /* Headers attached to the request */ + size_t hdr_count; + grpc_http_header *hdrs; + /* Body: length and contents; contents are NOT null-terminated */ + size_t body_length; + char *body; +} grpc_http_request; + +/* A response */ +typedef struct grpc_http_response { + /* HTTP status code */ + int status; + /* Headers: count and key/values */ + size_t hdr_count; + grpc_http_header *hdrs; + /* Body: length and contents; contents are NOT null-terminated */ + size_t body_length; + char *body; +} grpc_http_response; + +typedef struct { + grpc_http_parser_state state; + grpc_http_type type; + + union { + grpc_http_response response; + grpc_http_request request; + } http; + size_t body_capacity; + size_t hdr_capacity; + + uint8_t cur_line[GRPC_HTTP_PARSER_MAX_HEADER_LENGTH]; + size_t cur_line_length; +} grpc_http_parser; + +void grpc_http_parser_init(grpc_http_parser *parser); +void grpc_http_parser_destroy(grpc_http_parser *parser); + +int grpc_http_parser_parse(grpc_http_parser *parser, gpr_slice slice); +int grpc_http_parser_eof(grpc_http_parser *parser); + +#endif /* GRPC_CORE_HTTP_PARSER_H */ diff --git a/src/core/httpcli/format_request.c b/src/core/httpcli/format_request.c deleted file mode 100644 index 04f2a2d99a..0000000000 --- a/src/core/httpcli/format_request.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * - * Copyright 2015, 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/httpcli/format_request.h" - -#include -#include -#include - -#include "src/core/support/string.h" -#include -#include -#include -#include - -static void fill_common_header(const grpc_httpcli_request *request, - gpr_strvec *buf) { - size_t i; - gpr_strvec_add(buf, gpr_strdup(request->path)); - gpr_strvec_add(buf, gpr_strdup(" HTTP/1.0\r\n")); - /* just in case some crazy server really expects HTTP/1.1 */ - gpr_strvec_add(buf, gpr_strdup("Host: ")); - gpr_strvec_add(buf, gpr_strdup(request->host)); - gpr_strvec_add(buf, gpr_strdup("\r\n")); - gpr_strvec_add(buf, gpr_strdup("Connection: close\r\n")); - gpr_strvec_add(buf, - gpr_strdup("User-Agent: " GRPC_HTTPCLI_USER_AGENT "\r\n")); - /* user supplied headers */ - for (i = 0; i < request->hdr_count; i++) { - gpr_strvec_add(buf, gpr_strdup(request->hdrs[i].key)); - gpr_strvec_add(buf, gpr_strdup(": ")); - gpr_strvec_add(buf, gpr_strdup(request->hdrs[i].value)); - gpr_strvec_add(buf, gpr_strdup("\r\n")); - } -} - -gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request) { - gpr_strvec out; - char *flat; - size_t flat_len; - - gpr_strvec_init(&out); - gpr_strvec_add(&out, gpr_strdup("GET ")); - fill_common_header(request, &out); - gpr_strvec_add(&out, gpr_strdup("\r\n")); - - flat = gpr_strvec_flatten(&out, &flat_len); - gpr_strvec_destroy(&out); - - return gpr_slice_new(flat, flat_len, gpr_free); -} - -gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, - const char *body_bytes, - size_t body_size) { - gpr_strvec out; - char *tmp; - size_t out_len; - size_t i; - - gpr_strvec_init(&out); - - gpr_strvec_add(&out, gpr_strdup("POST ")); - fill_common_header(request, &out); - if (body_bytes) { - uint8_t has_content_type = 0; - for (i = 0; i < request->hdr_count; i++) { - if (strcmp(request->hdrs[i].key, "Content-Type") == 0) { - has_content_type = 1; - break; - } - } - if (!has_content_type) { - gpr_strvec_add(&out, gpr_strdup("Content-Type: text/plain\r\n")); - } - gpr_asprintf(&tmp, "Content-Length: %lu\r\n", (unsigned long)body_size); - gpr_strvec_add(&out, tmp); - } - gpr_strvec_add(&out, gpr_strdup("\r\n")); - tmp = gpr_strvec_flatten(&out, &out_len); - gpr_strvec_destroy(&out); - - if (body_bytes) { - tmp = gpr_realloc(tmp, out_len + body_size); - memcpy(tmp + out_len, body_bytes, body_size); - out_len += body_size; - } - - return gpr_slice_new(tmp, out_len, gpr_free); -} diff --git a/src/core/httpcli/format_request.h b/src/core/httpcli/format_request.h deleted file mode 100644 index eb47cc90ca..0000000000 --- a/src/core/httpcli/format_request.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Copyright 2015-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_HTTPCLI_FORMAT_REQUEST_H -#define GRPC_CORE_HTTPCLI_FORMAT_REQUEST_H - -#include "src/core/httpcli/httpcli.h" -#include - -gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request); -gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, - const char *body_bytes, - size_t body_size); - -#endif /* GRPC_CORE_HTTPCLI_FORMAT_REQUEST_H */ diff --git a/src/core/httpcli/httpcli.c b/src/core/httpcli/httpcli.c deleted file mode 100644 index 1219c444c7..0000000000 --- a/src/core/httpcli/httpcli.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * - * Copyright 2015-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/httpcli/httpcli.h" -#include "src/core/iomgr/sockaddr.h" - -#include - -#include -#include -#include - -#include "src/core/httpcli/format_request.h" -#include "src/core/httpcli/parser.h" -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/support/string.h" - -typedef struct { - gpr_slice request_text; - grpc_httpcli_parser parser; - grpc_resolved_addresses *addresses; - size_t next_address; - grpc_endpoint *ep; - char *host; - char *ssl_host_override; - gpr_timespec deadline; - int have_read_byte; - const grpc_httpcli_handshaker *handshaker; - grpc_httpcli_response_cb on_response; - void *user_data; - grpc_httpcli_context *context; - grpc_pollset *pollset; - grpc_iomgr_object iomgr_obj; - gpr_slice_buffer incoming; - gpr_slice_buffer outgoing; - grpc_closure on_read; - grpc_closure done_write; - grpc_closure connected; -} internal_request; - -static grpc_httpcli_get_override g_get_override = NULL; -static grpc_httpcli_post_override g_post_override = NULL; - -static void plaintext_handshake(grpc_exec_ctx *exec_ctx, void *arg, - grpc_endpoint *endpoint, const char *host, - void (*on_done)(grpc_exec_ctx *exec_ctx, - void *arg, - grpc_endpoint *endpoint)) { - on_done(exec_ctx, arg, endpoint); -} - -const grpc_httpcli_handshaker grpc_httpcli_plaintext = {"http", - plaintext_handshake}; - -void grpc_httpcli_context_init(grpc_httpcli_context *context) { - context->pollset_set = grpc_pollset_set_create(); -} - -void grpc_httpcli_context_destroy(grpc_httpcli_context *context) { - grpc_pollset_set_destroy(context->pollset_set); -} - -static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req); - -static void finish(grpc_exec_ctx *exec_ctx, internal_request *req, - int success) { - grpc_pollset_set_del_pollset(exec_ctx, req->context->pollset_set, - req->pollset); - req->on_response(exec_ctx, req->user_data, success ? &req->parser.r : NULL); - grpc_httpcli_parser_destroy(&req->parser); - if (req->addresses != NULL) { - grpc_resolved_addresses_destroy(req->addresses); - } - if (req->ep != NULL) { - grpc_endpoint_destroy(exec_ctx, req->ep); - } - gpr_slice_unref(req->request_text); - gpr_free(req->host); - gpr_free(req->ssl_host_override); - grpc_iomgr_unregister_object(&req->iomgr_obj); - gpr_slice_buffer_destroy(&req->incoming); - gpr_slice_buffer_destroy(&req->outgoing); - gpr_free(req); -} - -static void on_read(grpc_exec_ctx *exec_ctx, void *user_data, bool success); - -static void do_read(grpc_exec_ctx *exec_ctx, internal_request *req) { - grpc_endpoint_read(exec_ctx, req->ep, &req->incoming, &req->on_read); -} - -static void on_read(grpc_exec_ctx *exec_ctx, void *user_data, bool success) { - internal_request *req = user_data; - size_t i; - - for (i = 0; i < req->incoming.count; i++) { - if (GPR_SLICE_LENGTH(req->incoming.slices[i])) { - req->have_read_byte = 1; - if (!grpc_httpcli_parser_parse(&req->parser, req->incoming.slices[i])) { - finish(exec_ctx, req, 0); - return; - } - } - } - - if (success) { - do_read(exec_ctx, req); - } else if (!req->have_read_byte) { - next_address(exec_ctx, req); - } else { - finish(exec_ctx, req, grpc_httpcli_parser_eof(&req->parser)); - } -} - -static void on_written(grpc_exec_ctx *exec_ctx, internal_request *req) { - do_read(exec_ctx, req); -} - -static void done_write(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - internal_request *req = arg; - if (success) { - on_written(exec_ctx, req); - } else { - next_address(exec_ctx, req); - } -} - -static void start_write(grpc_exec_ctx *exec_ctx, internal_request *req) { - gpr_slice_ref(req->request_text); - gpr_slice_buffer_add(&req->outgoing, req->request_text); - grpc_endpoint_write(exec_ctx, req->ep, &req->outgoing, &req->done_write); -} - -static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, - grpc_endpoint *ep) { - internal_request *req = arg; - - if (!ep) { - next_address(exec_ctx, req); - return; - } - - req->ep = ep; - start_write(exec_ctx, req); -} - -static void on_connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - internal_request *req = arg; - - if (!req->ep) { - next_address(exec_ctx, req); - return; - } - req->handshaker->handshake( - exec_ctx, req, req->ep, - req->ssl_host_override ? req->ssl_host_override : req->host, - on_handshake_done); -} - -static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req) { - grpc_resolved_address *addr; - if (req->next_address == req->addresses->naddrs) { - finish(exec_ctx, req, 0); - return; - } - addr = &req->addresses->addrs[req->next_address++]; - grpc_closure_init(&req->connected, on_connected, req); - grpc_tcp_client_connect( - exec_ctx, &req->connected, &req->ep, req->context->pollset_set, - (struct sockaddr *)&addr->addr, addr->len, req->deadline); -} - -static void on_resolved(grpc_exec_ctx *exec_ctx, void *arg, - grpc_resolved_addresses *addresses) { - internal_request *req = arg; - if (!addresses) { - finish(exec_ctx, req, 0); - return; - } - req->addresses = addresses; - req->next_address = 0; - next_address(exec_ctx, req); -} - -static void internal_request_begin( - grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, - grpc_pollset *pollset, const grpc_httpcli_request *request, - gpr_timespec deadline, grpc_httpcli_response_cb on_response, - void *user_data, const char *name, gpr_slice request_text) { - internal_request *req = gpr_malloc(sizeof(internal_request)); - memset(req, 0, sizeof(*req)); - req->request_text = request_text; - grpc_httpcli_parser_init(&req->parser); - req->on_response = on_response; - req->user_data = user_data; - req->deadline = deadline; - req->handshaker = - request->handshaker ? request->handshaker : &grpc_httpcli_plaintext; - req->context = context; - req->pollset = pollset; - grpc_closure_init(&req->on_read, on_read, req); - grpc_closure_init(&req->done_write, done_write, req); - gpr_slice_buffer_init(&req->incoming); - gpr_slice_buffer_init(&req->outgoing); - grpc_iomgr_register_object(&req->iomgr_obj, name); - req->host = gpr_strdup(request->host); - req->ssl_host_override = gpr_strdup(request->ssl_host_override); - - grpc_pollset_set_add_pollset(exec_ctx, req->context->pollset_set, - req->pollset); - grpc_resolve_address(request->host, req->handshaker->default_port, - on_resolved, req); -} - -void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, - grpc_pollset *pollset, - const grpc_httpcli_request *request, - gpr_timespec deadline, - grpc_httpcli_response_cb on_response, void *user_data) { - char *name; - if (g_get_override && - g_get_override(exec_ctx, request, deadline, on_response, user_data)) { - return; - } - gpr_asprintf(&name, "HTTP:GET:%s:%s", request->host, request->path); - internal_request_begin(exec_ctx, context, pollset, request, deadline, - on_response, user_data, name, - grpc_httpcli_format_get_request(request)); - gpr_free(name); -} - -void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, - grpc_pollset *pollset, - const grpc_httpcli_request *request, - const char *body_bytes, size_t body_size, - gpr_timespec deadline, - grpc_httpcli_response_cb on_response, void *user_data) { - char *name; - if (g_post_override && - g_post_override(exec_ctx, request, body_bytes, body_size, deadline, - on_response, user_data)) { - return; - } - gpr_asprintf(&name, "HTTP:POST:%s:%s", request->host, request->path); - internal_request_begin( - exec_ctx, context, pollset, request, deadline, on_response, user_data, - name, grpc_httpcli_format_post_request(request, body_bytes, body_size)); - gpr_free(name); -} - -void grpc_httpcli_set_override(grpc_httpcli_get_override get, - grpc_httpcli_post_override post) { - g_get_override = get; - g_post_override = post; -} diff --git a/src/core/httpcli/httpcli.h b/src/core/httpcli/httpcli.h deleted file mode 100644 index 1fe5782657..0000000000 --- a/src/core/httpcli/httpcli.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * - * Copyright 2015-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_HTTPCLI_HTTPCLI_H -#define GRPC_CORE_HTTPCLI_HTTPCLI_H - -#include - -#include - -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/pollset_set.h" - -/* User agent this library reports */ -#define GRPC_HTTPCLI_USER_AGENT "grpc-httpcli/0.0" -/* Maximum length of a header string of the form 'Key: Value\r\n' */ -#define GRPC_HTTPCLI_MAX_HEADER_LENGTH 4096 - -/* A single header to be passed in a request */ -typedef struct grpc_httpcli_header { - char *key; - char *value; -} grpc_httpcli_header; - -/* Tracks in-progress http requests - TODO(ctiller): allow caching and capturing multiple requests for the - same content and combining them */ -typedef struct grpc_httpcli_context { - grpc_pollset_set *pollset_set; -} grpc_httpcli_context; - -typedef struct { - const char *default_port; - void (*handshake)(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *endpoint, - const char *host, - void (*on_done)(grpc_exec_ctx *exec_ctx, void *arg, - grpc_endpoint *endpoint)); -} grpc_httpcli_handshaker; - -extern const grpc_httpcli_handshaker grpc_httpcli_plaintext; -extern const grpc_httpcli_handshaker grpc_httpcli_ssl; - -/* A request */ -typedef struct grpc_httpcli_request { - /* The host name to connect to */ - char *host; - /* The host to verify in the SSL handshake (or NULL) */ - char *ssl_host_override; - /* The path of the resource to fetch */ - char *path; - /* Additional headers: count and key/values; the following are supplied - automatically and MUST NOT be set here: - Host, Connection, User-Agent */ - size_t hdr_count; - grpc_httpcli_header *hdrs; - /* handshaker to use ssl for the request */ - const grpc_httpcli_handshaker *handshaker; -} grpc_httpcli_request; - -/* A response */ -typedef struct grpc_httpcli_response { - /* HTTP status code */ - int status; - /* Headers: count and key/values */ - size_t hdr_count; - grpc_httpcli_header *hdrs; - /* Body: length and contents; contents are NOT null-terminated */ - size_t body_length; - char *body; -} grpc_httpcli_response; - -/* Callback for grpc_httpcli_get and grpc_httpcli_post. */ -typedef void (*grpc_httpcli_response_cb)(grpc_exec_ctx *exec_ctx, - void *user_data, - const grpc_httpcli_response *response); - -void grpc_httpcli_context_init(grpc_httpcli_context *context); -void grpc_httpcli_context_destroy(grpc_httpcli_context *context); - -/* Asynchronously perform a HTTP GET. - 'context' specifies the http context under which to do the get - 'pollset' indicates a grpc_pollset that is interested in the result - of the get - work on this pollset may be used to progress the get - operation - 'request' contains request parameters - these are caller owned and can be - destroyed once the call returns - 'deadline' contains a deadline for the request (or gpr_inf_future) - 'on_response' is a callback to report results to (and 'user_data' is a user - supplied pointer to pass to said call) */ -void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, - grpc_pollset *pollset, - const grpc_httpcli_request *request, - gpr_timespec deadline, - grpc_httpcli_response_cb on_response, void *user_data); - -/* Asynchronously perform a HTTP POST. - 'context' specifies the http context under which to do the post - 'pollset' indicates a grpc_pollset that is interested in the result - of the post - work on this pollset may be used to progress the post - operation - 'request' contains request parameters - these are caller owned and can be - destroyed once the call returns - 'body_bytes' and 'body_size' specify the payload for the post. - When there is no body, pass in NULL as body_bytes. - 'deadline' contains a deadline for the request (or gpr_inf_future) - 'em' points to a caller owned event manager that must be alive for the - lifetime of the request - 'on_response' is a callback to report results to (and 'user_data' is a user - supplied pointer to pass to said call) - Does not support ?var1=val1&var2=val2 in the path. */ -void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, - grpc_pollset *pollset, - const grpc_httpcli_request *request, - const char *body_bytes, size_t body_size, - gpr_timespec deadline, - grpc_httpcli_response_cb on_response, void *user_data); - -/* override functions return 1 if they handled the request, 0 otherwise */ -typedef int (*grpc_httpcli_get_override)(grpc_exec_ctx *exec_ctx, - const grpc_httpcli_request *request, - gpr_timespec deadline, - grpc_httpcli_response_cb on_response, - void *user_data); -typedef int (*grpc_httpcli_post_override)( - grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - const char *body_bytes, size_t body_size, gpr_timespec deadline, - grpc_httpcli_response_cb on_response, void *user_data); - -void grpc_httpcli_set_override(grpc_httpcli_get_override get, - grpc_httpcli_post_override post); - -#endif /* GRPC_CORE_HTTPCLI_HTTPCLI_H */ diff --git a/src/core/httpcli/httpcli_security_connector.c b/src/core/httpcli/httpcli_security_connector.c deleted file mode 100644 index 156961a377..0000000000 --- a/src/core/httpcli/httpcli_security_connector.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * - * Copyright 2015-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/httpcli/httpcli.h" - -#include - -#include "src/core/security/handshake.h" -#include "src/core/support/string.h" -#include -#include -#include -#include "src/core/tsi/ssl_transport_security.h" - -typedef struct { - grpc_channel_security_connector base; - tsi_ssl_handshaker_factory *handshaker_factory; - char *secure_peer_name; -} grpc_httpcli_ssl_channel_security_connector; - -static void httpcli_ssl_destroy(grpc_security_connector *sc) { - grpc_httpcli_ssl_channel_security_connector *c = - (grpc_httpcli_ssl_channel_security_connector *)sc; - if (c->handshaker_factory != NULL) { - tsi_ssl_handshaker_factory_destroy(c->handshaker_factory); - } - if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name); - gpr_free(sc); -} - -static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, - grpc_channel_security_connector *sc, - grpc_endpoint *nonsecure_endpoint, - grpc_security_handshake_done_cb cb, - void *user_data) { - grpc_httpcli_ssl_channel_security_connector *c = - (grpc_httpcli_ssl_channel_security_connector *)sc; - tsi_result result = TSI_OK; - tsi_handshaker *handshaker; - if (c->handshaker_factory == NULL) { - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); - return; - } - result = tsi_ssl_handshaker_factory_create_handshaker( - c->handshaker_factory, c->secure_peer_name, &handshaker); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); - } else { - grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true, - nonsecure_endpoint, cb, user_data); - } -} - -static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx, - grpc_security_connector *sc, tsi_peer peer, - grpc_security_peer_check_cb cb, - void *user_data) { - grpc_httpcli_ssl_channel_security_connector *c = - (grpc_httpcli_ssl_channel_security_connector *)sc; - grpc_security_status status = GRPC_SECURITY_OK; - - /* Check the peer name. */ - if (c->secure_peer_name != NULL && - !tsi_ssl_peer_matches_name(&peer, c->secure_peer_name)) { - gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", - c->secure_peer_name); - status = GRPC_SECURITY_ERROR; - } - cb(exec_ctx, user_data, status, NULL); - tsi_peer_destruct(&peer); -} - -static grpc_security_connector_vtable httpcli_ssl_vtable = { - httpcli_ssl_destroy, httpcli_ssl_check_peer}; - -static grpc_security_status httpcli_ssl_channel_security_connector_create( - const unsigned char *pem_root_certs, size_t pem_root_certs_size, - const char *secure_peer_name, grpc_channel_security_connector **sc) { - tsi_result result = TSI_OK; - grpc_httpcli_ssl_channel_security_connector *c; - - if (secure_peer_name != NULL && pem_root_certs == NULL) { - gpr_log(GPR_ERROR, - "Cannot assert a secure peer name without a trust root."); - return GRPC_SECURITY_ERROR; - } - - c = gpr_malloc(sizeof(grpc_httpcli_ssl_channel_security_connector)); - memset(c, 0, sizeof(grpc_httpcli_ssl_channel_security_connector)); - - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &httpcli_ssl_vtable; - if (secure_peer_name != NULL) { - c->secure_peer_name = gpr_strdup(secure_peer_name); - } - result = tsi_create_ssl_client_handshaker_factory( - NULL, 0, NULL, 0, pem_root_certs, pem_root_certs_size, NULL, NULL, NULL, - 0, &c->handshaker_factory); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - httpcli_ssl_destroy(&c->base.base); - *sc = NULL; - return GRPC_SECURITY_ERROR; - } - c->base.do_handshake = httpcli_ssl_do_handshake; - *sc = &c->base; - return GRPC_SECURITY_OK; -} - -/* handshaker */ - -typedef struct { - void (*func)(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *endpoint); - void *arg; -} on_done_closure; - -static void on_secure_transport_setup_done(grpc_exec_ctx *exec_ctx, void *rp, - grpc_security_status status, - grpc_endpoint *secure_endpoint, - grpc_auth_context *auth_context) { - on_done_closure *c = rp; - if (status != GRPC_SECURITY_OK) { - gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status); - c->func(exec_ctx, c->arg, NULL); - } else { - c->func(exec_ctx, c->arg, secure_endpoint); - } - gpr_free(c); -} - -static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg, - grpc_endpoint *tcp, const char *host, - void (*on_done)(grpc_exec_ctx *exec_ctx, void *arg, - grpc_endpoint *endpoint)) { - grpc_channel_security_connector *sc = NULL; - const unsigned char *pem_root_certs = NULL; - on_done_closure *c = gpr_malloc(sizeof(*c)); - size_t pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs); - if (pem_root_certs == NULL || pem_root_certs_size == 0) { - gpr_log(GPR_ERROR, "Could not get default pem root certs."); - on_done(exec_ctx, arg, NULL); - gpr_free(c); - return; - } - c->func = on_done; - c->arg = arg; - GPR_ASSERT(httpcli_ssl_channel_security_connector_create( - pem_root_certs, pem_root_certs_size, host, &sc) == - GRPC_SECURITY_OK); - grpc_channel_security_connector_do_handshake( - exec_ctx, sc, tcp, on_secure_transport_setup_done, c); - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); -} - -const grpc_httpcli_handshaker grpc_httpcli_ssl = {"https", ssl_handshake}; diff --git a/src/core/httpcli/parser.c b/src/core/httpcli/parser.c deleted file mode 100644 index c314f025a0..0000000000 --- a/src/core/httpcli/parser.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * - * Copyright 2015, 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/httpcli/parser.h" - -#include - -#include -#include -#include - -static int handle_response_line(grpc_httpcli_parser *parser) { - uint8_t *beg = parser->cur_line; - uint8_t *cur = beg; - uint8_t *end = beg + parser->cur_line_length; - - if (cur == end || *cur++ != 'H') goto error; - if (cur == end || *cur++ != 'T') goto error; - if (cur == end || *cur++ != 'T') goto error; - if (cur == end || *cur++ != 'P') goto error; - if (cur == end || *cur++ != '/') goto error; - if (cur == end || *cur++ != '1') goto error; - if (cur == end || *cur++ != '.') goto error; - if (cur == end || *cur < '0' || *cur++ > '1') goto error; - if (cur == end || *cur++ != ' ') goto error; - if (cur == end || *cur < '1' || *cur++ > '9') goto error; - if (cur == end || *cur < '0' || *cur++ > '9') goto error; - if (cur == end || *cur < '0' || *cur++ > '9') goto error; - parser->r.status = - (cur[-3] - '0') * 100 + (cur[-2] - '0') * 10 + (cur[-1] - '0'); - if (cur == end || *cur++ != ' ') goto error; - - /* we don't really care about the status code message */ - - return 1; - -error: - gpr_log(GPR_ERROR, "Failed parsing response line"); - return 0; -} - -static char *buf2str(void *buffer, size_t length) { - char *out = gpr_malloc(length + 1); - memcpy(out, buffer, length); - out[length] = 0; - return out; -} - -static int add_header(grpc_httpcli_parser *parser) { - uint8_t *beg = parser->cur_line; - uint8_t *cur = beg; - uint8_t *end = beg + parser->cur_line_length; - grpc_httpcli_header hdr = {NULL, NULL}; - - GPR_ASSERT(cur != end); - - if (*cur == ' ' || *cur == '\t') { - gpr_log(GPR_ERROR, "Continued header lines not supported yet"); - goto error; - } - - while (cur != end && *cur != ':') { - cur++; - } - if (cur == end) { - gpr_log(GPR_ERROR, "Didn't find ':' in header string"); - goto error; - } - GPR_ASSERT(cur >= beg); - hdr.key = buf2str(beg, (size_t)(cur - beg)); - cur++; /* skip : */ - - while (cur != end && (*cur == ' ' || *cur == '\t')) { - cur++; - } - GPR_ASSERT(end - cur >= 2); - hdr.value = buf2str(cur, (size_t)(end - cur) - 2); - - if (parser->r.hdr_count == parser->hdr_capacity) { - parser->hdr_capacity = - GPR_MAX(parser->hdr_capacity + 1, parser->hdr_capacity * 3 / 2); - parser->r.hdrs = gpr_realloc( - parser->r.hdrs, parser->hdr_capacity * sizeof(*parser->r.hdrs)); - } - parser->r.hdrs[parser->r.hdr_count++] = hdr; - return 1; - -error: - gpr_free(hdr.key); - gpr_free(hdr.value); - return 0; -} - -static int finish_line(grpc_httpcli_parser *parser) { - switch (parser->state) { - case GRPC_HTTPCLI_INITIAL_RESPONSE: - if (!handle_response_line(parser)) { - return 0; - } - parser->state = GRPC_HTTPCLI_HEADERS; - break; - case GRPC_HTTPCLI_HEADERS: - if (parser->cur_line_length == 2) { - parser->state = GRPC_HTTPCLI_BODY; - break; - } - if (!add_header(parser)) { - return 0; - } - break; - case GRPC_HTTPCLI_BODY: - GPR_UNREACHABLE_CODE(return 0); - } - - parser->cur_line_length = 0; - return 1; -} - -static int addbyte(grpc_httpcli_parser *parser, uint8_t byte) { - switch (parser->state) { - case GRPC_HTTPCLI_INITIAL_RESPONSE: - case GRPC_HTTPCLI_HEADERS: - if (parser->cur_line_length >= GRPC_HTTPCLI_MAX_HEADER_LENGTH) { - gpr_log(GPR_ERROR, "HTTP client max line length (%d) exceeded", - GRPC_HTTPCLI_MAX_HEADER_LENGTH); - return 0; - } - parser->cur_line[parser->cur_line_length] = byte; - parser->cur_line_length++; - if (parser->cur_line_length >= 2 && - parser->cur_line[parser->cur_line_length - 2] == '\r' && - parser->cur_line[parser->cur_line_length - 1] == '\n') { - return finish_line(parser); - } else { - return 1; - } - GPR_UNREACHABLE_CODE(return 0); - case GRPC_HTTPCLI_BODY: - if (parser->r.body_length == parser->body_capacity) { - parser->body_capacity = GPR_MAX(8, parser->body_capacity * 3 / 2); - parser->r.body = - gpr_realloc((void *)parser->r.body, parser->body_capacity); - } - parser->r.body[parser->r.body_length] = (char)byte; - parser->r.body_length++; - return 1; - } - GPR_UNREACHABLE_CODE(return 0); -} - -void grpc_httpcli_parser_init(grpc_httpcli_parser *parser) { - memset(parser, 0, sizeof(*parser)); - parser->state = GRPC_HTTPCLI_INITIAL_RESPONSE; - parser->r.status = 500; -} - -void grpc_httpcli_parser_destroy(grpc_httpcli_parser *parser) { - size_t i; - gpr_free(parser->r.body); - for (i = 0; i < parser->r.hdr_count; i++) { - gpr_free(parser->r.hdrs[i].key); - gpr_free(parser->r.hdrs[i].value); - } - gpr_free(parser->r.hdrs); -} - -int grpc_httpcli_parser_parse(grpc_httpcli_parser *parser, gpr_slice slice) { - size_t i; - - for (i = 0; i < GPR_SLICE_LENGTH(slice); i++) { - if (!addbyte(parser, GPR_SLICE_START_PTR(slice)[i])) { - return 0; - } - } - - return 1; -} - -int grpc_httpcli_parser_eof(grpc_httpcli_parser *parser) { - return parser->state == GRPC_HTTPCLI_BODY; -} diff --git a/src/core/httpcli/parser.h b/src/core/httpcli/parser.h deleted file mode 100644 index cd4a737245..0000000000 --- a/src/core/httpcli/parser.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * Copyright 2015-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_HTTPCLI_PARSER_H -#define GRPC_CORE_HTTPCLI_PARSER_H - -#include "src/core/httpcli/httpcli.h" -#include -#include - -typedef enum { - GRPC_HTTPCLI_INITIAL_RESPONSE, - GRPC_HTTPCLI_HEADERS, - GRPC_HTTPCLI_BODY -} grpc_httpcli_parser_state; - -typedef struct { - grpc_httpcli_parser_state state; - - grpc_httpcli_response r; - size_t body_capacity; - size_t hdr_capacity; - - uint8_t cur_line[GRPC_HTTPCLI_MAX_HEADER_LENGTH]; - size_t cur_line_length; -} grpc_httpcli_parser; - -void grpc_httpcli_parser_init(grpc_httpcli_parser* parser); -void grpc_httpcli_parser_destroy(grpc_httpcli_parser* parser); - -int grpc_httpcli_parser_parse(grpc_httpcli_parser* parser, gpr_slice slice); -int grpc_httpcli_parser_eof(grpc_httpcli_parser* parser); - -#endif /* GRPC_CORE_HTTPCLI_PARSER_H */ diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index b4fa616fa7..0ba6d5dd84 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -38,7 +38,8 @@ #include "src/core/channel/channel_args.h" #include "src/core/channel/http_client_filter.h" -#include "src/core/httpcli/httpcli.h" +#include "src/core/http/parser.h" +#include "src/core/http/httpcli.h" #include "src/core/iomgr/executor.h" #include "src/core/json/json.h" #include "src/core/support/string.h" @@ -539,7 +540,7 @@ static void oauth2_token_fetcher_destruct(grpc_call_credentials *creds) { grpc_credentials_status grpc_oauth2_token_fetcher_credentials_parse_server_response( - const grpc_httpcli_response *response, grpc_credentials_md_store **token_md, + const grpc_http_response *response, grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime) { char *null_terminated_body = NULL; char *new_access_token = NULL; @@ -629,7 +630,7 @@ end: static void on_oauth2_token_fetcher_http_response( grpc_exec_ctx *exec_ctx, void *user_data, - const grpc_httpcli_response *response) { + const grpc_http_response *response) { grpc_credentials_metadata_request *r = (grpc_credentials_metadata_request *)user_data; grpc_oauth2_token_fetcher_credentials *c = @@ -706,13 +707,13 @@ static void compute_engine_fetch_oauth2( grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req, grpc_httpcli_context *httpcli_context, grpc_pollset *pollset, grpc_httpcli_response_cb response_cb, gpr_timespec deadline) { - grpc_httpcli_header header = {"Metadata-Flavor", "Google"}; + grpc_http_header header = {"Metadata-Flavor", "Google"}; grpc_httpcli_request request; memset(&request, 0, sizeof(grpc_httpcli_request)); request.host = GRPC_COMPUTE_ENGINE_METADATA_HOST; - request.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH; - request.hdr_count = 1; - request.hdrs = &header; + request.http.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH; + request.http.hdr_count = 1; + request.http.hdrs = &header; grpc_httpcli_get(exec_ctx, httpcli_context, pollset, &request, deadline, response_cb, metadata_req); } @@ -747,8 +748,8 @@ static void refresh_token_fetch_oauth2( grpc_httpcli_response_cb response_cb, gpr_timespec deadline) { grpc_google_refresh_token_credentials *c = (grpc_google_refresh_token_credentials *)metadata_req->creds; - grpc_httpcli_header header = {"Content-Type", - "application/x-www-form-urlencoded"}; + grpc_http_header header = {"Content-Type", + "application/x-www-form-urlencoded"}; grpc_httpcli_request request; char *body = NULL; gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING, @@ -756,9 +757,9 @@ static void refresh_token_fetch_oauth2( c->refresh_token.refresh_token); memset(&request, 0, sizeof(grpc_httpcli_request)); request.host = GRPC_GOOGLE_OAUTH2_SERVICE_HOST; - request.path = GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH; - request.hdr_count = 1; - request.hdrs = &header; + request.http.path = GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH; + request.http.hdr_count = 1; + request.http.hdrs = &header; request.handshaker = &grpc_httpcli_ssl; grpc_httpcli_post(exec_ctx, httpcli_context, pollset, &request, body, strlen(body), deadline, response_cb, metadata_req); diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h index 133aa9d8d9..afac7a5bf2 100644 --- a/src/core/security/credentials.h +++ b/src/core/security/credentials.h @@ -39,11 +39,12 @@ #include #include -#include "src/core/httpcli/httpcli.h" +#include "src/core/http/httpcli.h" +#include "src/core/http/parser.h" #include "src/core/security/json_token.h" #include "src/core/security/security_connector.h" -struct grpc_httpcli_response; +struct grpc_http_response; /* --- Constants. --- */ @@ -207,7 +208,7 @@ grpc_call_credentials *grpc_credentials_contains_type( /* Exposed for testing only. */ grpc_credentials_status grpc_oauth2_token_fetcher_credentials_parse_server_response( - const struct grpc_httpcli_response *response, + const struct grpc_http_response *response, grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime); void grpc_flush_cached_google_default_credentials(void); diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c index 1f4f3e4aa5..3872e86993 100644 --- a/src/core/security/google_default_credentials.c +++ b/src/core/security/google_default_credentials.c @@ -39,7 +39,8 @@ #include #include -#include "src/core/httpcli/httpcli.h" +#include "src/core/http/httpcli.h" +#include "src/core/http/parser.h" #include "src/core/support/env.h" #include "src/core/support/load_file.h" #include "src/core/surface/api_trace.h" @@ -66,14 +67,14 @@ typedef struct { static void on_compute_engine_detection_http_response( grpc_exec_ctx *exec_ctx, void *user_data, - const grpc_httpcli_response *response) { + const grpc_http_response *response) { compute_engine_detector *detector = (compute_engine_detector *)user_data; if (response != NULL && response->status == 200 && response->hdr_count > 0) { /* Internet providers can return a generic response to all requests, so it is necessary to check that metadata header is present also. */ size_t i; for (i = 0; i < response->hdr_count; i++) { - grpc_httpcli_header *header = &response->hdrs[i]; + grpc_http_header *header = &response->hdrs[i]; if (strcmp(header->key, "Metadata-Flavor") == 0 && strcmp(header->value, "Google") == 0) { detector->success = 1; @@ -109,7 +110,7 @@ static int is_stack_running_on_compute_engine(void) { memset(&request, 0, sizeof(grpc_httpcli_request)); request.host = GRPC_COMPUTE_ENGINE_DETECTION_HOST; - request.path = "/"; + request.http.path = "/"; grpc_httpcli_context_init(&context); diff --git a/src/core/security/jwt_verifier.c b/src/core/security/jwt_verifier.c index 928c6c148d..0bb8e05306 100644 --- a/src/core/security/jwt_verifier.c +++ b/src/core/security/jwt_verifier.c @@ -36,7 +36,7 @@ #include #include -#include "src/core/httpcli/httpcli.h" +#include "src/core/http/httpcli.h" #include "src/core/security/b64.h" #include "src/core/tsi/ssl_types.h" @@ -635,11 +635,11 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data, jwks_uri += 8; req.handshaker = &grpc_httpcli_ssl; req.host = gpr_strdup(jwks_uri); - req.path = strchr(jwks_uri, '/'); - if (req.path == NULL) { - req.path = ""; + req.http.path = strchr(jwks_uri, '/'); + if (req.http.path == NULL) { + req.http.path = ""; } else { - *(req.host + (req.path - jwks_uri)) = '\0'; + *(req.host + (req.http.path - jwks_uri)) = '\0'; } grpc_httpcli_get( exec_ctx, &ctx->verifier->http_ctx, ctx->pollset, &req, @@ -725,20 +725,20 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx, req.host = gpr_strdup(mapping->key_url_prefix); path_prefix = strchr(req.host, '/'); if (path_prefix == NULL) { - gpr_asprintf(&req.path, "/%s", iss); + gpr_asprintf(&req.http.path, "/%s", iss); } else { *(path_prefix++) = '\0'; - gpr_asprintf(&req.path, "/%s/%s", path_prefix, iss); + gpr_asprintf(&req.http.path, "/%s/%s", path_prefix, iss); } http_cb = on_keys_retrieved; } else { req.host = gpr_strdup(strstr(iss, "https://") == iss ? iss + 8 : iss); path_prefix = strchr(req.host, '/'); if (path_prefix == NULL) { - req.path = gpr_strdup(GRPC_OPENID_CONFIG_URL_SUFFIX); + req.http.path = gpr_strdup(GRPC_OPENID_CONFIG_URL_SUFFIX); } else { *(path_prefix++) = 0; - gpr_asprintf(&req.path, "/%s%s", path_prefix, + gpr_asprintf(&req.http.path, "/%s%s", path_prefix, GRPC_OPENID_CONFIG_URL_SUFFIX); } http_cb = on_openid_config_retrieved; @@ -749,7 +749,7 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay), http_cb, ctx); gpr_free(req.host); - gpr_free(req.path); + gpr_free(req.http.path); return; error: diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 29506e69bc..ef3d6dd17a 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -108,9 +108,9 @@ CORE_SOURCE_FILES = [ 'src/core/compression/compression_algorithm.c', 'src/core/compression/message_compress.c', 'src/core/debug/trace.c', - 'src/core/httpcli/format_request.c', - 'src/core/httpcli/httpcli.c', - 'src/core/httpcli/parser.c', + 'src/core/http/format_request.c', + 'src/core/http/httpcli.c', + 'src/core/http/parser.c', 'src/core/iomgr/closure.c', 'src/core/iomgr/endpoint.c', 'src/core/iomgr/endpoint_pair_posix.c', @@ -206,7 +206,7 @@ CORE_SOURCE_FILES = [ 'src/core/transport/static_metadata.c', 'src/core/transport/transport.c', 'src/core/transport/transport_op_string.c', - 'src/core/httpcli/httpcli_security_connector.c', + 'src/core/http/httpcli_security_connector.c', 'src/core/security/b64.c', 'src/core/security/client_auth_filter.c', 'src/core/security/credentials.c', diff --git a/test/core/http/format_request_test.c b/test/core/http/format_request_test.c new file mode 100644 index 0000000000..67dfd24803 --- /dev/null +++ b/test/core/http/format_request_test.c @@ -0,0 +1,165 @@ +/* + * + * Copyright 2015-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/http/format_request.h" + +#include + +#include +#include "test/core/util/test_config.h" + +static void test_format_get_request(void) { + grpc_http_header hdr = {"x-yz", "abc"}; + grpc_httpcli_request req; + gpr_slice slice; + + memset(&req, 0, sizeof(req)); + req.host = "example.com"; + req.http.path = "/index.html"; + req.http.hdr_count = 1; + req.http.hdrs = &hdr; + + slice = grpc_httpcli_format_get_request(&req); + + GPR_ASSERT(0 == gpr_slice_str_cmp(slice, + "GET /index.html HTTP/1.0\r\n" + "Host: example.com\r\n" + "Connection: close\r\n" + "User-Agent: " GRPC_HTTPCLI_USER_AGENT + "\r\n" + "x-yz: abc\r\n" + "\r\n")); + + gpr_slice_unref(slice); +} + +static void test_format_post_request(void) { + grpc_http_header hdr = {"x-yz", "abc"}; + grpc_httpcli_request req; + gpr_slice slice; + char body_bytes[] = "fake body"; + size_t body_len = 9; + + memset(&req, 0, sizeof(req)); + req.host = "example.com"; + req.http.path = "/index.html"; + req.http.hdr_count = 1; + req.http.hdrs = &hdr; + + slice = grpc_httpcli_format_post_request(&req, body_bytes, body_len); + + GPR_ASSERT(0 == gpr_slice_str_cmp(slice, + "POST /index.html HTTP/1.0\r\n" + "Host: example.com\r\n" + "Connection: close\r\n" + "User-Agent: " GRPC_HTTPCLI_USER_AGENT + "\r\n" + "x-yz: abc\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 9\r\n" + "\r\n" + "fake body")); + + gpr_slice_unref(slice); +} + +static void test_format_post_request_no_body(void) { + grpc_http_header hdr = {"x-yz", "abc"}; + grpc_httpcli_request req; + gpr_slice slice; + + memset(&req, 0, sizeof(req)); + req.host = "example.com"; + req.http.path = "/index.html"; + req.http.hdr_count = 1; + req.http.hdrs = &hdr; + + slice = grpc_httpcli_format_post_request(&req, NULL, 0); + + GPR_ASSERT(0 == gpr_slice_str_cmp(slice, + "POST /index.html HTTP/1.0\r\n" + "Host: example.com\r\n" + "Connection: close\r\n" + "User-Agent: " GRPC_HTTPCLI_USER_AGENT + "\r\n" + "x-yz: abc\r\n" + "\r\n")); + + gpr_slice_unref(slice); +} + +static void test_format_post_request_content_type_override(void) { + grpc_http_header hdrs[2]; + grpc_httpcli_request req; + gpr_slice slice; + char body_bytes[] = "fake%20body"; + size_t body_len = 11; + + hdrs[0].key = "x-yz"; + hdrs[0].value = "abc"; + hdrs[1].key = "Content-Type"; + hdrs[1].value = "application/x-www-form-urlencoded"; + memset(&req, 0, sizeof(req)); + req.host = "example.com"; + req.http.path = "/index.html"; + req.http.hdr_count = 2; + req.http.hdrs = hdrs; + + slice = grpc_httpcli_format_post_request(&req, body_bytes, body_len); + + GPR_ASSERT(0 == gpr_slice_str_cmp( + slice, + "POST /index.html HTTP/1.0\r\n" + "Host: example.com\r\n" + "Connection: close\r\n" + "User-Agent: " GRPC_HTTPCLI_USER_AGENT + "\r\n" + "x-yz: abc\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Content-Length: 11\r\n" + "\r\n" + "fake%20body")); + + gpr_slice_unref(slice); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + + test_format_get_request(); + test_format_post_request(); + test_format_post_request_no_body(); + test_format_post_request_content_type_override(); + + return 0; +} diff --git a/test/core/http/httpcli_test.c b/test/core/http/httpcli_test.c new file mode 100644 index 0000000000..bdb7a02e9b --- /dev/null +++ b/test/core/http/httpcli_test.c @@ -0,0 +1,200 @@ +/* + * + * Copyright 2015-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/http/httpcli.h" + +#include + +#include +#include +#include +#include +#include +#include +#include "src/core/iomgr/iomgr.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +static int g_done = 0; +static grpc_httpcli_context g_context; +static gpr_mu *g_mu; +static grpc_pollset *g_pollset; + +static gpr_timespec n_seconds_time(int seconds) { + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds); +} + +static void on_finish(grpc_exec_ctx *exec_ctx, void *arg, + const grpc_httpcli_response *response) { + const char *expect = + "Hello world!" + "

This is a test

"; + GPR_ASSERT(arg == (void *)42); + GPR_ASSERT(response); + GPR_ASSERT(response->status == 200); + GPR_ASSERT(response->body_length == strlen(expect)); + GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length)); + gpr_mu_lock(g_mu); + g_done = 1; + grpc_pollset_kick(g_pollset, NULL); + gpr_mu_unlock(g_mu); +} + +static void test_get(int port) { + grpc_httpcli_request req; + char *host; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + g_done = 0; + gpr_log(GPR_INFO, "test_get"); + + gpr_asprintf(&host, "localhost:%d", port); + gpr_log(GPR_INFO, "requesting from %s", host); + + memset(&req, 0, sizeof(req)); + req.host = host; + req.http.path = "/get"; + req.handshaker = &grpc_httpcli_plaintext; + + grpc_httpcli_get(&exec_ctx, &g_context, g_pollset, &req, n_seconds_time(15), + on_finish, (void *)42); + gpr_mu_lock(g_mu); + while (!g_done) { + grpc_pollset_worker *worker = NULL; + grpc_pollset_work(&exec_ctx, g_pollset, &worker, + gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20)); + gpr_mu_unlock(g_mu); + grpc_exec_ctx_finish(&exec_ctx); + gpr_mu_lock(g_mu); + } + gpr_mu_unlock(g_mu); + gpr_free(host); +} + +static void test_post(int port) { + grpc_httpcli_request req; + char *host; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + g_done = 0; + gpr_log(GPR_INFO, "test_post"); + + gpr_asprintf(&host, "localhost:%d", port); + gpr_log(GPR_INFO, "posting to %s", host); + + memset(&req, 0, sizeof(req)); + req.host = host; + req.http.path = "/post"; + req.handshaker = &grpc_httpcli_plaintext; + + grpc_httpcli_post(&exec_ctx, &g_context, g_pollset, &req, "hello", 5, + n_seconds_time(15), on_finish, (void *)42); + gpr_mu_lock(g_mu); + while (!g_done) { + grpc_pollset_worker *worker = NULL; + grpc_pollset_work(&exec_ctx, g_pollset, &worker, + gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20)); + gpr_mu_unlock(g_mu); + grpc_exec_ctx_finish(&exec_ctx); + gpr_mu_lock(g_mu); + } + gpr_mu_unlock(g_mu); + gpr_free(host); +} + +static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool success) { + grpc_pollset_destroy(p); +} + +int main(int argc, char **argv) { + grpc_closure destroyed; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + gpr_subprocess *server; + char *me = argv[0]; + char *lslash = strrchr(me, '/'); + char *args[4]; + int port = grpc_pick_unused_port_or_die(); + int arg_shift = 0; + /* figure out where we are */ + char *root; + if (lslash) { + root = gpr_malloc((size_t)(lslash - me + 1)); + memcpy(root, me, (size_t)(lslash - me)); + root[lslash - me] = 0; + } else { + root = gpr_strdup("."); + } + + GPR_ASSERT(argc <= 2); + if (argc == 2) { + args[0] = gpr_strdup(argv[1]); + } else { + arg_shift = 1; + gpr_asprintf(&args[0], "%s/../../tools/distrib/python_wrapper.sh", root); + gpr_asprintf(&args[1], "%s/../../test/core/http/test_server.py", root); + } + + /* start the server */ + args[1 + arg_shift] = "--port"; + gpr_asprintf(&args[2 + arg_shift], "%d", port); + server = gpr_subprocess_create(3 + arg_shift, (const char **)args); + GPR_ASSERT(server); + gpr_free(args[0]); + if (arg_shift) gpr_free(args[1]); + gpr_free(args[2 + arg_shift]); + gpr_free(root); + + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(5, GPR_TIMESPAN))); + + grpc_test_init(argc, argv); + grpc_init(); + grpc_httpcli_context_init(&g_context); + g_pollset = gpr_malloc(grpc_pollset_size()); + grpc_pollset_init(g_pollset, &g_mu); + + test_get(port); + test_post(port); + + grpc_httpcli_context_destroy(&g_context); + grpc_closure_init(&destroyed, destroy_pollset, g_pollset); + grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed); + grpc_exec_ctx_finish(&exec_ctx); + grpc_shutdown(); + + gpr_free(g_pollset); + + gpr_subprocess_destroy(server); + + return 0; +} diff --git a/test/core/http/httpscli_test.c b/test/core/http/httpscli_test.c new file mode 100644 index 0000000000..21845b6a8e --- /dev/null +++ b/test/core/http/httpscli_test.c @@ -0,0 +1,203 @@ +/* + * + * Copyright 2015-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/http/httpcli.h" + +#include + +#include +#include +#include +#include +#include +#include +#include "src/core/iomgr/iomgr.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +static int g_done = 0; +static grpc_httpcli_context g_context; +static gpr_mu *g_mu; +static grpc_pollset *g_pollset; + +static gpr_timespec n_seconds_time(int seconds) { + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds); +} + +static void on_finish(grpc_exec_ctx *exec_ctx, void *arg, + const grpc_httpcli_response *response) { + const char *expect = + "Hello world!" + "

This is a test

"; + GPR_ASSERT(arg == (void *)42); + GPR_ASSERT(response); + GPR_ASSERT(response->status == 200); + GPR_ASSERT(response->body_length == strlen(expect)); + GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length)); + gpr_mu_lock(g_mu); + g_done = 1; + grpc_pollset_kick(g_pollset, NULL); + gpr_mu_unlock(g_mu); +} + +static void test_get(int port) { + grpc_httpcli_request req; + char *host; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + g_done = 0; + gpr_log(GPR_INFO, "test_get"); + + gpr_asprintf(&host, "localhost:%d", port); + gpr_log(GPR_INFO, "requesting from %s", host); + + memset(&req, 0, sizeof(req)); + req.host = host; + req.ssl_host_override = "foo.test.google.fr"; + req.http.path = "/get"; + req.handshaker = &grpc_httpcli_ssl; + + grpc_httpcli_get(&exec_ctx, &g_context, g_pollset, &req, n_seconds_time(15), + on_finish, (void *)42); + gpr_mu_lock(g_mu); + while (!g_done) { + grpc_pollset_worker *worker = NULL; + grpc_pollset_work(&exec_ctx, g_pollset, &worker, + gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20)); + gpr_mu_unlock(g_mu); + grpc_exec_ctx_finish(&exec_ctx); + gpr_mu_lock(g_mu); + } + gpr_mu_unlock(g_mu); + gpr_free(host); +} + +static void test_post(int port) { + grpc_httpcli_request req; + char *host; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + g_done = 0; + gpr_log(GPR_INFO, "test_post"); + + gpr_asprintf(&host, "localhost:%d", port); + gpr_log(GPR_INFO, "posting to %s", host); + + memset(&req, 0, sizeof(req)); + req.host = host; + req.ssl_host_override = "foo.test.google.fr"; + req.http.path = "/post"; + req.handshaker = &grpc_httpcli_ssl; + + grpc_httpcli_post(&exec_ctx, &g_context, g_pollset, &req, "hello", 5, + n_seconds_time(15), on_finish, (void *)42); + gpr_mu_lock(g_mu); + while (!g_done) { + grpc_pollset_worker *worker = NULL; + grpc_pollset_work(&exec_ctx, g_pollset, &worker, + gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20)); + gpr_mu_unlock(g_mu); + grpc_exec_ctx_finish(&exec_ctx); + gpr_mu_lock(g_mu); + } + gpr_mu_unlock(g_mu); + gpr_free(host); +} + +static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool success) { + grpc_pollset_destroy(p); +} + +int main(int argc, char **argv) { + grpc_closure destroyed; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + gpr_subprocess *server; + char *me = argv[0]; + char *lslash = strrchr(me, '/'); + char *args[5]; + int port = grpc_pick_unused_port_or_die(); + int arg_shift = 0; + /* figure out where we are */ + char *root; + if (lslash) { + root = gpr_malloc((size_t)(lslash - me + 1)); + memcpy(root, me, (size_t)(lslash - me)); + root[lslash - me] = 0; + } else { + root = gpr_strdup("."); + } + + GPR_ASSERT(argc <= 2); + if (argc == 2) { + args[0] = gpr_strdup(argv[1]); + } else { + arg_shift = 1; + gpr_asprintf(&args[0], "%s/../../tools/distrib/python_wrapper.sh", root); + gpr_asprintf(&args[1], "%s/../../test/core/http/test_server.py", root); + } + + /* start the server */ + args[1 + arg_shift] = "--port"; + gpr_asprintf(&args[2 + arg_shift], "%d", port); + args[3 + arg_shift] = "--ssl"; + server = gpr_subprocess_create(4 + arg_shift, (const char **)args); + GPR_ASSERT(server); + gpr_free(args[0]); + if (arg_shift) gpr_free(args[1]); + gpr_free(args[2 + arg_shift]); + gpr_free(root); + + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(5, GPR_TIMESPAN))); + + grpc_test_init(argc, argv); + grpc_init(); + grpc_httpcli_context_init(&g_context); + g_pollset = gpr_malloc(grpc_pollset_size()); + grpc_pollset_init(g_pollset, &g_mu); + + test_get(port); + test_post(port); + + grpc_httpcli_context_destroy(&g_context); + grpc_closure_init(&destroyed, destroy_pollset, g_pollset); + grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed); + grpc_exec_ctx_finish(&exec_ctx); + grpc_shutdown(); + + gpr_free(g_pollset); + + gpr_subprocess_destroy(server); + + return 0; +} diff --git a/test/core/http/parser_test.c b/test/core/http/parser_test.c new file mode 100644 index 0000000000..338a301534 --- /dev/null +++ b/test/core/http/parser_test.c @@ -0,0 +1,260 @@ +/* + * + * Copyright 2015-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/http/parser.h" + +#include +#include + +#include +#include +#include +#include +#include "test/core/util/slice_splitter.h" +#include "test/core/util/test_config.h" + +static void test_request_succeeds(grpc_slice_split_mode split_mode, + char *request, char *expect_method, + grpc_http_version expect_version, + char *expect_path, char *expect_body, ...) { + grpc_http_parser parser; + gpr_slice input_slice = gpr_slice_from_copied_string(request); + size_t num_slices; + size_t i; + gpr_slice *slices; + va_list args; + + grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices); + gpr_slice_unref(input_slice); + + grpc_http_parser_init(&parser); + + for (i = 0; i < num_slices; i++) { + GPR_ASSERT(grpc_http_parser_parse(&parser, slices[i])); + gpr_slice_unref(slices[i]); + } + GPR_ASSERT(grpc_http_parser_eof(&parser)); + + GPR_ASSERT(GRPC_HTTP_REQUEST == parser.type); + GPR_ASSERT(0 == strcmp(expect_method, parser.http.request.method)); + GPR_ASSERT(0 == strcmp(expect_path, parser.http.request.path)); + GPR_ASSERT(expect_version == parser.http.request.version); + + if (expect_body != NULL) { + GPR_ASSERT(strlen(expect_body) == parser.http.request.body_length); + GPR_ASSERT(0 == memcmp(expect_body, parser.http.request.body, + parser.http.request.body_length)); + } else { + GPR_ASSERT(parser.http.request.body_length == 0); + } + + va_start(args, expect_body); + i = 0; + for (;;) { + char *expect_key; + char *expect_value; + expect_key = va_arg(args, char *); + if (!expect_key) break; + GPR_ASSERT(i < parser.http.request.hdr_count); + expect_value = va_arg(args, char *); + GPR_ASSERT(expect_value); + GPR_ASSERT(0 == strcmp(expect_key, parser.http.request.hdrs[i].key)); + GPR_ASSERT(0 == strcmp(expect_value, parser.http.request.hdrs[i].value)); + i++; + } + va_end(args); + GPR_ASSERT(i == parser.http.request.hdr_count); + + grpc_http_parser_destroy(&parser); + gpr_free(slices); +} + +static void test_succeeds(grpc_slice_split_mode split_mode, char *response, + int expect_status, char *expect_body, ...) { + grpc_http_parser parser; + gpr_slice input_slice = gpr_slice_from_copied_string(response); + size_t num_slices; + size_t i; + gpr_slice *slices; + va_list args; + + grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices); + gpr_slice_unref(input_slice); + + grpc_http_parser_init(&parser); + + for (i = 0; i < num_slices; i++) { + GPR_ASSERT(grpc_http_parser_parse(&parser, slices[i])); + gpr_slice_unref(slices[i]); + } + GPR_ASSERT(grpc_http_parser_eof(&parser)); + + GPR_ASSERT(GRPC_HTTP_RESPONSE == parser.type); + GPR_ASSERT(expect_status == parser.http.response.status); + if (expect_body != NULL) { + GPR_ASSERT(strlen(expect_body) == parser.http.response.body_length); + GPR_ASSERT(0 == memcmp(expect_body, parser.http.response.body, + parser.http.response.body_length)); + } else { + GPR_ASSERT(parser.http.response.body_length == 0); + } + + va_start(args, expect_body); + i = 0; + for (;;) { + char *expect_key; + char *expect_value; + expect_key = va_arg(args, char *); + if (!expect_key) break; + GPR_ASSERT(i < parser.http.response.hdr_count); + expect_value = va_arg(args, char *); + GPR_ASSERT(expect_value); + GPR_ASSERT(0 == strcmp(expect_key, parser.http.response.hdrs[i].key)); + GPR_ASSERT(0 == strcmp(expect_value, parser.http.response.hdrs[i].value)); + i++; + } + va_end(args); + GPR_ASSERT(i == parser.http.response.hdr_count); + + grpc_http_parser_destroy(&parser); + gpr_free(slices); +} + +static void test_fails(grpc_slice_split_mode split_mode, char *response) { + grpc_http_parser parser; + gpr_slice input_slice = gpr_slice_from_copied_string(response); + size_t num_slices; + size_t i; + gpr_slice *slices; + int done = 0; + + grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices); + gpr_slice_unref(input_slice); + + grpc_http_parser_init(&parser); + + for (i = 0; i < num_slices; i++) { + if (!done && !grpc_http_parser_parse(&parser, slices[i])) { + done = 1; + } + gpr_slice_unref(slices[i]); + } + if (!done && !grpc_http_parser_eof(&parser)) { + done = 1; + } + GPR_ASSERT(done); + + grpc_http_parser_destroy(&parser); + gpr_free(slices); +} + +int main(int argc, char **argv) { + size_t i; + const grpc_slice_split_mode split_modes[] = {GRPC_SLICE_SPLIT_IDENTITY, + GRPC_SLICE_SPLIT_ONE_BYTE}; + char *tmp1, *tmp2; + + grpc_test_init(argc, argv); + + for (i = 0; i < GPR_ARRAY_SIZE(split_modes); i++) { + test_succeeds(split_modes[i], + "HTTP/1.0 200 OK\r\n" + "xyz: abc\r\n" + "\r\n" + "hello world!", + 200, "hello world!", "xyz", "abc", NULL); + test_succeeds(split_modes[i], + "HTTP/1.0 404 Not Found\r\n" + "\r\n", + 404, NULL, NULL); + test_succeeds(split_modes[i], + "HTTP/1.1 200 OK\r\n" + "xyz: abc\r\n" + "\r\n" + "hello world!", + 200, "hello world!", "xyz", "abc", NULL); + test_request_succeeds(split_modes[i], + "GET / HTTP/1.0\r\n" + "\r\n", + "GET", GRPC_HTTP_HTTP10, "/", NULL, NULL); + test_request_succeeds(split_modes[i], + "GET / HTTP/1.0\r\n" + "\r\n" + "xyz", + "GET", GRPC_HTTP_HTTP10, "/", "xyz", NULL); + test_request_succeeds(split_modes[i], + "GET / HTTP/1.1\r\n" + "\r\n" + "xyz", + "GET", GRPC_HTTP_HTTP11, "/", "xyz", NULL); + test_request_succeeds(split_modes[i], + "GET / HTTP/2.0\r\n" + "\r\n" + "xyz", + "GET", GRPC_HTTP_HTTP20, "/", "xyz", NULL); + test_request_succeeds(split_modes[i], + "GET / HTTP/1.0\r\n" + "xyz: abc\r\n" + "\r\n" + "xyz", + "GET", GRPC_HTTP_HTTP10, "/", "xyz", "xyz", "abc", + NULL); + test_fails(split_modes[i], "HTTP/1.0\r\n"); + test_fails(split_modes[i], "HTTP/1.2\r\n"); + test_fails(split_modes[i], "HTTP/1.0 000 XYX\r\n"); + test_fails(split_modes[i], "HTTP/1.0 200 OK\n"); + test_fails(split_modes[i], "HTTP/1.0 200 OK\r\n"); + test_fails(split_modes[i], "HTTP/1.0 200 OK\r\nFoo x\r\n"); + test_fails(split_modes[i], + "HTTP/1.0 200 OK\r\n" + "xyz: abc\r\n" + " def\r\n" + "\r\n" + "hello world!"); + test_fails(split_modes[i], "GET\r\n"); + test_fails(split_modes[i], "GET /\r\n"); + test_fails(split_modes[i], "GET / HTTP/0.0\r\n"); + test_fails(split_modes[i], "GET / ____/1.0\r\n"); + test_fails(split_modes[i], "GET / HTTP/1.2\r\n"); + + tmp1 = gpr_malloc(2 * GRPC_HTTP_PARSER_MAX_HEADER_LENGTH); + memset(tmp1, 'a', 2 * GRPC_HTTP_PARSER_MAX_HEADER_LENGTH - 1); + tmp1[2 * GRPC_HTTP_PARSER_MAX_HEADER_LENGTH - 1] = 0; + gpr_asprintf(&tmp2, "HTTP/1.0 200 OK\r\nxyz: %s\r\n\r\n", tmp1); + test_fails(split_modes[i], tmp2); + gpr_free(tmp1); + gpr_free(tmp2); + } + + return 0; +} diff --git a/test/core/http/test_server.py b/test/core/http/test_server.py new file mode 100755 index 0000000000..ecde494cc0 --- /dev/null +++ b/test/core/http/test_server.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python2.7 +# Copyright 2015-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. + +"""Server for httpcli_test""" + +import argparse +import BaseHTTPServer +import os +import ssl +import sys + +_PEM = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.pem')) +_KEY = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.key')) +print _PEM +open(_PEM).close() + +argp = argparse.ArgumentParser(description='Server for httpcli_test') +argp.add_argument('-p', '--port', default=10080, type=int) +argp.add_argument('-s', '--ssl', default=False, action='store_true') +args = argp.parse_args() + +print 'server running on port %d' % args.port + +class Handler(BaseHTTPServer.BaseHTTPRequestHandler): + def good(self): + self.send_response(200) + self.send_header('Content-Type', 'text/html') + self.end_headers() + self.wfile.write('Hello world!') + self.wfile.write('

This is a test

') + + def do_GET(self): + if self.path == '/get': + self.good() + + def do_POST(self): + content = self.rfile.read(int(self.headers.getheader('content-length'))) + if self.path == '/post' and content == 'hello': + self.good() + +httpd = BaseHTTPServer.HTTPServer(('localhost', args.port), Handler) +if args.ssl: + httpd.socket = ssl.wrap_socket(httpd.socket, certfile=_PEM, keyfile=_KEY, server_side=True) +httpd.serve_forever() diff --git a/test/core/httpcli/format_request_test.c b/test/core/httpcli/format_request_test.c deleted file mode 100644 index da850049e2..0000000000 --- a/test/core/httpcli/format_request_test.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * - * Copyright 2015, 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/httpcli/format_request.h" - -#include - -#include -#include "test/core/util/test_config.h" - -static void test_format_get_request(void) { - grpc_httpcli_header hdr = {"x-yz", "abc"}; - grpc_httpcli_request req; - gpr_slice slice; - - memset(&req, 0, sizeof(req)); - req.host = "example.com"; - req.path = "/index.html"; - req.hdr_count = 1; - req.hdrs = &hdr; - - slice = grpc_httpcli_format_get_request(&req); - - GPR_ASSERT(0 == gpr_slice_str_cmp(slice, - "GET /index.html HTTP/1.0\r\n" - "Host: example.com\r\n" - "Connection: close\r\n" - "User-Agent: " GRPC_HTTPCLI_USER_AGENT - "\r\n" - "x-yz: abc\r\n" - "\r\n")); - - gpr_slice_unref(slice); -} - -static void test_format_post_request(void) { - grpc_httpcli_header hdr = {"x-yz", "abc"}; - grpc_httpcli_request req; - gpr_slice slice; - char body_bytes[] = "fake body"; - size_t body_len = 9; - - memset(&req, 0, sizeof(req)); - req.host = "example.com"; - req.path = "/index.html"; - req.hdr_count = 1; - req.hdrs = &hdr; - - slice = grpc_httpcli_format_post_request(&req, body_bytes, body_len); - - GPR_ASSERT(0 == gpr_slice_str_cmp(slice, - "POST /index.html HTTP/1.0\r\n" - "Host: example.com\r\n" - "Connection: close\r\n" - "User-Agent: " GRPC_HTTPCLI_USER_AGENT - "\r\n" - "x-yz: abc\r\n" - "Content-Type: text/plain\r\n" - "Content-Length: 9\r\n" - "\r\n" - "fake body")); - - gpr_slice_unref(slice); -} - -static void test_format_post_request_no_body(void) { - grpc_httpcli_header hdr = {"x-yz", "abc"}; - grpc_httpcli_request req; - gpr_slice slice; - - memset(&req, 0, sizeof(req)); - req.host = "example.com"; - req.path = "/index.html"; - req.hdr_count = 1; - req.hdrs = &hdr; - - slice = grpc_httpcli_format_post_request(&req, NULL, 0); - - GPR_ASSERT(0 == gpr_slice_str_cmp(slice, - "POST /index.html HTTP/1.0\r\n" - "Host: example.com\r\n" - "Connection: close\r\n" - "User-Agent: " GRPC_HTTPCLI_USER_AGENT - "\r\n" - "x-yz: abc\r\n" - "\r\n")); - - gpr_slice_unref(slice); -} - -static void test_format_post_request_content_type_override(void) { - grpc_httpcli_header hdrs[2]; - grpc_httpcli_request req; - gpr_slice slice; - char body_bytes[] = "fake%20body"; - size_t body_len = 11; - - hdrs[0].key = "x-yz"; - hdrs[0].value = "abc"; - hdrs[1].key = "Content-Type"; - hdrs[1].value = "application/x-www-form-urlencoded"; - memset(&req, 0, sizeof(req)); - req.host = "example.com"; - req.path = "/index.html"; - req.hdr_count = 2; - req.hdrs = hdrs; - - slice = grpc_httpcli_format_post_request(&req, body_bytes, body_len); - - GPR_ASSERT(0 == gpr_slice_str_cmp( - slice, - "POST /index.html HTTP/1.0\r\n" - "Host: example.com\r\n" - "Connection: close\r\n" - "User-Agent: " GRPC_HTTPCLI_USER_AGENT - "\r\n" - "x-yz: abc\r\n" - "Content-Type: application/x-www-form-urlencoded\r\n" - "Content-Length: 11\r\n" - "\r\n" - "fake%20body")); - - gpr_slice_unref(slice); -} - -int main(int argc, char **argv) { - grpc_test_init(argc, argv); - - test_format_get_request(); - test_format_post_request(); - test_format_post_request_no_body(); - test_format_post_request_content_type_override(); - - return 0; -} diff --git a/test/core/httpcli/httpcli_test.c b/test/core/httpcli/httpcli_test.c deleted file mode 100644 index fbc5d4abe7..0000000000 --- a/test/core/httpcli/httpcli_test.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * - * Copyright 2015-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/httpcli/httpcli.h" - -#include - -#include -#include -#include -#include -#include -#include -#include "src/core/iomgr/iomgr.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -static int g_done = 0; -static grpc_httpcli_context g_context; -static gpr_mu *g_mu; -static grpc_pollset *g_pollset; - -static gpr_timespec n_seconds_time(int seconds) { - return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds); -} - -static void on_finish(grpc_exec_ctx *exec_ctx, void *arg, - const grpc_httpcli_response *response) { - const char *expect = - "Hello world!" - "

This is a test

"; - GPR_ASSERT(arg == (void *)42); - GPR_ASSERT(response); - GPR_ASSERT(response->status == 200); - GPR_ASSERT(response->body_length == strlen(expect)); - GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length)); - gpr_mu_lock(g_mu); - g_done = 1; - grpc_pollset_kick(g_pollset, NULL); - gpr_mu_unlock(g_mu); -} - -static void test_get(int port) { - grpc_httpcli_request req; - char *host; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - g_done = 0; - gpr_log(GPR_INFO, "test_get"); - - gpr_asprintf(&host, "localhost:%d", port); - gpr_log(GPR_INFO, "requesting from %s", host); - - memset(&req, 0, sizeof(req)); - req.host = host; - req.path = "/get"; - req.handshaker = &grpc_httpcli_plaintext; - - grpc_httpcli_get(&exec_ctx, &g_context, g_pollset, &req, n_seconds_time(15), - on_finish, (void *)42); - gpr_mu_lock(g_mu); - while (!g_done) { - grpc_pollset_worker *worker = NULL; - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20)); - gpr_mu_unlock(g_mu); - grpc_exec_ctx_finish(&exec_ctx); - gpr_mu_lock(g_mu); - } - gpr_mu_unlock(g_mu); - gpr_free(host); -} - -static void test_post(int port) { - grpc_httpcli_request req; - char *host; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - g_done = 0; - gpr_log(GPR_INFO, "test_post"); - - gpr_asprintf(&host, "localhost:%d", port); - gpr_log(GPR_INFO, "posting to %s", host); - - memset(&req, 0, sizeof(req)); - req.host = host; - req.path = "/post"; - req.handshaker = &grpc_httpcli_plaintext; - - grpc_httpcli_post(&exec_ctx, &g_context, g_pollset, &req, "hello", 5, - n_seconds_time(15), on_finish, (void *)42); - gpr_mu_lock(g_mu); - while (!g_done) { - grpc_pollset_worker *worker = NULL; - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20)); - gpr_mu_unlock(g_mu); - grpc_exec_ctx_finish(&exec_ctx); - gpr_mu_lock(g_mu); - } - gpr_mu_unlock(g_mu); - gpr_free(host); -} - -static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool success) { - grpc_pollset_destroy(p); -} - -int main(int argc, char **argv) { - grpc_closure destroyed; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - gpr_subprocess *server; - char *me = argv[0]; - char *lslash = strrchr(me, '/'); - char *args[4]; - int port = grpc_pick_unused_port_or_die(); - int arg_shift = 0; - /* figure out where we are */ - char *root; - if (lslash) { - root = gpr_malloc((size_t)(lslash - me + 1)); - memcpy(root, me, (size_t)(lslash - me)); - root[lslash - me] = 0; - } else { - root = gpr_strdup("."); - } - - GPR_ASSERT(argc <= 2); - if (argc == 2) { - args[0] = gpr_strdup(argv[1]); - } else { - arg_shift = 1; - gpr_asprintf(&args[0], "%s/../../tools/distrib/python_wrapper.sh", root); - gpr_asprintf(&args[1], "%s/../../test/core/httpcli/test_server.py", root); - } - - /* start the server */ - args[1 + arg_shift] = "--port"; - gpr_asprintf(&args[2 + arg_shift], "%d", port); - server = gpr_subprocess_create(3 + arg_shift, (const char **)args); - GPR_ASSERT(server); - gpr_free(args[0]); - if (arg_shift) gpr_free(args[1]); - gpr_free(args[2 + arg_shift]); - gpr_free(root); - - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(5, GPR_TIMESPAN))); - - grpc_test_init(argc, argv); - grpc_init(); - grpc_httpcli_context_init(&g_context); - g_pollset = gpr_malloc(grpc_pollset_size()); - grpc_pollset_init(g_pollset, &g_mu); - - test_get(port); - test_post(port); - - grpc_httpcli_context_destroy(&g_context); - grpc_closure_init(&destroyed, destroy_pollset, g_pollset); - grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed); - grpc_exec_ctx_finish(&exec_ctx); - grpc_shutdown(); - - gpr_free(g_pollset); - - gpr_subprocess_destroy(server); - - return 0; -} diff --git a/test/core/httpcli/httpscli_test.c b/test/core/httpcli/httpscli_test.c deleted file mode 100644 index 04c57db286..0000000000 --- a/test/core/httpcli/httpscli_test.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * - * Copyright 2015-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/httpcli/httpcli.h" - -#include - -#include -#include -#include -#include -#include -#include -#include "src/core/iomgr/iomgr.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -static int g_done = 0; -static grpc_httpcli_context g_context; -static gpr_mu *g_mu; -static grpc_pollset *g_pollset; - -static gpr_timespec n_seconds_time(int seconds) { - return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds); -} - -static void on_finish(grpc_exec_ctx *exec_ctx, void *arg, - const grpc_httpcli_response *response) { - const char *expect = - "Hello world!" - "

This is a test

"; - GPR_ASSERT(arg == (void *)42); - GPR_ASSERT(response); - GPR_ASSERT(response->status == 200); - GPR_ASSERT(response->body_length == strlen(expect)); - GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length)); - gpr_mu_lock(g_mu); - g_done = 1; - grpc_pollset_kick(g_pollset, NULL); - gpr_mu_unlock(g_mu); -} - -static void test_get(int port) { - grpc_httpcli_request req; - char *host; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - g_done = 0; - gpr_log(GPR_INFO, "test_get"); - - gpr_asprintf(&host, "localhost:%d", port); - gpr_log(GPR_INFO, "requesting from %s", host); - - memset(&req, 0, sizeof(req)); - req.host = host; - req.ssl_host_override = "foo.test.google.fr"; - req.path = "/get"; - req.handshaker = &grpc_httpcli_ssl; - - grpc_httpcli_get(&exec_ctx, &g_context, g_pollset, &req, n_seconds_time(15), - on_finish, (void *)42); - gpr_mu_lock(g_mu); - while (!g_done) { - grpc_pollset_worker *worker = NULL; - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20)); - gpr_mu_unlock(g_mu); - grpc_exec_ctx_finish(&exec_ctx); - gpr_mu_lock(g_mu); - } - gpr_mu_unlock(g_mu); - gpr_free(host); -} - -static void test_post(int port) { - grpc_httpcli_request req; - char *host; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - g_done = 0; - gpr_log(GPR_INFO, "test_post"); - - gpr_asprintf(&host, "localhost:%d", port); - gpr_log(GPR_INFO, "posting to %s", host); - - memset(&req, 0, sizeof(req)); - req.host = host; - req.ssl_host_override = "foo.test.google.fr"; - req.path = "/post"; - req.handshaker = &grpc_httpcli_ssl; - - grpc_httpcli_post(&exec_ctx, &g_context, g_pollset, &req, "hello", 5, - n_seconds_time(15), on_finish, (void *)42); - gpr_mu_lock(g_mu); - while (!g_done) { - grpc_pollset_worker *worker = NULL; - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20)); - gpr_mu_unlock(g_mu); - grpc_exec_ctx_finish(&exec_ctx); - gpr_mu_lock(g_mu); - } - gpr_mu_unlock(g_mu); - gpr_free(host); -} - -static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool success) { - grpc_pollset_destroy(p); -} - -int main(int argc, char **argv) { - grpc_closure destroyed; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - gpr_subprocess *server; - char *me = argv[0]; - char *lslash = strrchr(me, '/'); - char *args[5]; - int port = grpc_pick_unused_port_or_die(); - int arg_shift = 0; - /* figure out where we are */ - char *root; - if (lslash) { - root = gpr_malloc((size_t)(lslash - me + 1)); - memcpy(root, me, (size_t)(lslash - me)); - root[lslash - me] = 0; - } else { - root = gpr_strdup("."); - } - - GPR_ASSERT(argc <= 2); - if (argc == 2) { - args[0] = gpr_strdup(argv[1]); - } else { - arg_shift = 1; - gpr_asprintf(&args[0], "%s/../../tools/distrib/python_wrapper.sh", root); - gpr_asprintf(&args[1], "%s/../../test/core/httpcli/test_server.py", root); - } - - /* start the server */ - args[1 + arg_shift] = "--port"; - gpr_asprintf(&args[2 + arg_shift], "%d", port); - args[3 + arg_shift] = "--ssl"; - server = gpr_subprocess_create(4 + arg_shift, (const char **)args); - GPR_ASSERT(server); - gpr_free(args[0]); - if (arg_shift) gpr_free(args[1]); - gpr_free(args[2 + arg_shift]); - gpr_free(root); - - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(5, GPR_TIMESPAN))); - - grpc_test_init(argc, argv); - grpc_init(); - grpc_httpcli_context_init(&g_context); - g_pollset = gpr_malloc(grpc_pollset_size()); - grpc_pollset_init(g_pollset, &g_mu); - - test_get(port); - test_post(port); - - grpc_httpcli_context_destroy(&g_context); - grpc_closure_init(&destroyed, destroy_pollset, g_pollset); - grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed); - grpc_exec_ctx_finish(&exec_ctx); - grpc_shutdown(); - - gpr_free(g_pollset); - - gpr_subprocess_destroy(server); - - return 0; -} diff --git a/test/core/httpcli/parser_test.c b/test/core/httpcli/parser_test.c deleted file mode 100644 index a26ddd2821..0000000000 --- a/test/core/httpcli/parser_test.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * - * Copyright 2015, 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/httpcli/parser.h" - -#include -#include - -#include -#include -#include -#include -#include "test/core/util/slice_splitter.h" -#include "test/core/util/test_config.h" - -static void test_succeeds(grpc_slice_split_mode split_mode, char *response, - int expect_status, char *expect_body, ...) { - grpc_httpcli_parser parser; - gpr_slice input_slice = gpr_slice_from_copied_string(response); - size_t num_slices; - size_t i; - gpr_slice *slices; - va_list args; - - grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices); - gpr_slice_unref(input_slice); - - grpc_httpcli_parser_init(&parser); - - for (i = 0; i < num_slices; i++) { - GPR_ASSERT(grpc_httpcli_parser_parse(&parser, slices[i])); - gpr_slice_unref(slices[i]); - } - GPR_ASSERT(grpc_httpcli_parser_eof(&parser)); - - GPR_ASSERT(expect_status == parser.r.status); - if (expect_body != NULL) { - GPR_ASSERT(strlen(expect_body) == parser.r.body_length); - GPR_ASSERT(0 == memcmp(expect_body, parser.r.body, parser.r.body_length)); - } else { - GPR_ASSERT(parser.r.body_length == 0); - } - - va_start(args, expect_body); - i = 0; - for (;;) { - char *expect_key; - char *expect_value; - expect_key = va_arg(args, char *); - if (!expect_key) break; - GPR_ASSERT(i < parser.r.hdr_count); - expect_value = va_arg(args, char *); - GPR_ASSERT(expect_value); - GPR_ASSERT(0 == strcmp(expect_key, parser.r.hdrs[i].key)); - GPR_ASSERT(0 == strcmp(expect_value, parser.r.hdrs[i].value)); - i++; - } - va_end(args); - GPR_ASSERT(i == parser.r.hdr_count); - - grpc_httpcli_parser_destroy(&parser); - gpr_free(slices); -} - -static void test_fails(grpc_slice_split_mode split_mode, char *response) { - grpc_httpcli_parser parser; - gpr_slice input_slice = gpr_slice_from_copied_string(response); - size_t num_slices; - size_t i; - gpr_slice *slices; - int done = 0; - - grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices); - gpr_slice_unref(input_slice); - - grpc_httpcli_parser_init(&parser); - - for (i = 0; i < num_slices; i++) { - if (!done && !grpc_httpcli_parser_parse(&parser, slices[i])) { - done = 1; - } - gpr_slice_unref(slices[i]); - } - if (!done && !grpc_httpcli_parser_eof(&parser)) { - done = 1; - } - GPR_ASSERT(done); - - grpc_httpcli_parser_destroy(&parser); - gpr_free(slices); -} - -int main(int argc, char **argv) { - size_t i; - const grpc_slice_split_mode split_modes[] = {GRPC_SLICE_SPLIT_IDENTITY, - GRPC_SLICE_SPLIT_ONE_BYTE}; - char *tmp1, *tmp2; - - grpc_test_init(argc, argv); - - for (i = 0; i < GPR_ARRAY_SIZE(split_modes); i++) { - test_succeeds(split_modes[i], - "HTTP/1.0 200 OK\r\n" - "xyz: abc\r\n" - "\r\n" - "hello world!", - 200, "hello world!", "xyz", "abc", NULL); - test_succeeds(split_modes[i], - "HTTP/1.0 404 Not Found\r\n" - "\r\n", - 404, NULL, NULL); - test_succeeds(split_modes[i], - "HTTP/1.1 200 OK\r\n" - "xyz: abc\r\n" - "\r\n" - "hello world!", - 200, "hello world!", "xyz", "abc", NULL); - test_fails(split_modes[i], "HTTP/1.0\r\n"); - test_fails(split_modes[i], "HTTP/1.2\r\n"); - test_fails(split_modes[i], "HTTP/1.0 000 XYX\r\n"); - test_fails(split_modes[i], "HTTP/1.0 200 OK\n"); - test_fails(split_modes[i], "HTTP/1.0 200 OK\r\n"); - test_fails(split_modes[i], "HTTP/1.0 200 OK\r\nFoo x\r\n"); - test_fails(split_modes[i], - "HTTP/1.0 200 OK\r\n" - "xyz: abc\r\n" - " def\r\n" - "\r\n" - "hello world!"); - - tmp1 = gpr_malloc(2 * GRPC_HTTPCLI_MAX_HEADER_LENGTH); - memset(tmp1, 'a', 2 * GRPC_HTTPCLI_MAX_HEADER_LENGTH - 1); - tmp1[2 * GRPC_HTTPCLI_MAX_HEADER_LENGTH - 1] = 0; - gpr_asprintf(&tmp2, "HTTP/1.0 200 OK\r\nxyz: %s\r\n\r\n", tmp1); - test_fails(split_modes[i], tmp2); - gpr_free(tmp1); - gpr_free(tmp2); - } - - return 0; -} diff --git a/test/core/httpcli/test_server.py b/test/core/httpcli/test_server.py deleted file mode 100755 index dbbf5ceb3c..0000000000 --- a/test/core/httpcli/test_server.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python2.7 -# Copyright 2015, 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. - -"""Server for httpcli_test""" - -import argparse -import BaseHTTPServer -import os -import ssl -import sys - -_PEM = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.pem')) -_KEY = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.key')) -print _PEM -open(_PEM).close() - -argp = argparse.ArgumentParser(description='Server for httpcli_test') -argp.add_argument('-p', '--port', default=10080, type=int) -argp.add_argument('-s', '--ssl', default=False, action='store_true') -args = argp.parse_args() - -print 'server running on port %d' % args.port - -class Handler(BaseHTTPServer.BaseHTTPRequestHandler): - def good(self): - self.send_response(200) - self.send_header('Content-Type', 'text/html') - self.end_headers() - self.wfile.write('Hello world!') - self.wfile.write('

This is a test

') - - def do_GET(self): - if self.path == '/get': - self.good() - - def do_POST(self): - content = self.rfile.read(int(self.headers.getheader('content-length'))) - if self.path == '/post' and content == 'hello': - self.good() - -httpd = BaseHTTPServer.HTTPServer(('localhost', args.port), Handler) -if args.ssl: - httpd.socket = ssl.wrap_socket(httpd.socket, certfile=_PEM, keyfile=_KEY, server_side=True) -httpd.serve_forever() diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c index 98133ef5e5..fd9ccbf45d 100644 --- a/test/core/security/credentials_test.c +++ b/test/core/security/credentials_test.c @@ -44,7 +44,7 @@ #include #include -#include "src/core/httpcli/httpcli.h" +#include "src/core/http/httpcli.h" #include "src/core/security/json_token.h" #include "src/core/support/env.h" #include "src/core/support/tmpfile.h" @@ -536,12 +536,12 @@ static void validate_compute_engine_http_request( GPR_ASSERT(request->handshaker != &grpc_httpcli_ssl); GPR_ASSERT(strcmp(request->host, "metadata") == 0); GPR_ASSERT( - strcmp(request->path, + strcmp(request->http.path, "/computeMetadata/v1/instance/service-accounts/default/token") == 0); - GPR_ASSERT(request->hdr_count == 1); - GPR_ASSERT(strcmp(request->hdrs[0].key, "Metadata-Flavor") == 0); - GPR_ASSERT(strcmp(request->hdrs[0].value, "Google") == 0); + GPR_ASSERT(request->http.hdr_count == 1); + GPR_ASSERT(strcmp(request->http.hdrs[0].key, "Metadata-Flavor") == 0); + GPR_ASSERT(strcmp(request->http.hdrs[0].value, "Google") == 0); } static int compute_engine_httpcli_get_success_override( @@ -639,11 +639,12 @@ static void validate_refresh_token_http_request( gpr_free(expected_body); GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl); GPR_ASSERT(strcmp(request->host, GRPC_GOOGLE_OAUTH2_SERVICE_HOST) == 0); - GPR_ASSERT(strcmp(request->path, GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH) == 0); - GPR_ASSERT(request->hdr_count == 1); - GPR_ASSERT(strcmp(request->hdrs[0].key, "Content-Type") == 0); GPR_ASSERT( - strcmp(request->hdrs[0].value, "application/x-www-form-urlencoded") == 0); + strcmp(request->http.path, GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH) == 0); + GPR_ASSERT(request->http.hdr_count == 1); + GPR_ASSERT(strcmp(request->http.hdrs[0].key, "Content-Type") == 0); + GPR_ASSERT(strcmp(request->http.hdrs[0].value, + "application/x-www-form-urlencoded") == 0); } static int refresh_token_httpcli_post_success( @@ -898,12 +899,12 @@ static int default_creds_gce_detection_httpcli_get_success_override( gpr_timespec deadline, grpc_httpcli_response_cb on_response, void *user_data) { grpc_httpcli_response response = http_response(200, ""); - grpc_httpcli_header header; + grpc_http_header header; header.key = "Metadata-Flavor"; header.value = "Google"; response.hdr_count = 1; response.hdrs = &header; - GPR_ASSERT(strcmp(request->path, "/") == 0); + GPR_ASSERT(strcmp(request->http.path, "/") == 0); GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); on_response(exec_ctx, user_data, &response); return 1; @@ -961,7 +962,7 @@ static int default_creds_gce_detection_httpcli_get_failure_override( void *user_data) { /* No magic header. */ grpc_httpcli_response response = http_response(200, ""); - GPR_ASSERT(strcmp(request->path, "/") == 0); + GPR_ASSERT(strcmp(request->http.path, "/") == 0); GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); on_response(exec_ctx, user_data, &response); return 1; diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c index f6ec9e12ef..d2f8d1d182 100644 --- a/test/core/security/jwt_verifier_test.c +++ b/test/core/security/jwt_verifier_test.c @@ -35,7 +35,7 @@ #include -#include "src/core/httpcli/httpcli.h" +#include "src/core/http/httpcli.h" #include "src/core/security/b64.h" #include "src/core/security/json_token.h" #include "test/core/util/test_config.h" @@ -288,7 +288,7 @@ static int httpcli_get_google_keys_for_email( grpc_httpcli_response response = http_response(200, good_google_email_keys()); GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl); GPR_ASSERT(strcmp(request->host, "www.googleapis.com") == 0); - GPR_ASSERT(strcmp(request->path, + GPR_ASSERT(strcmp(request->http.path, "/robot/v1/metadata/x509/" "777-abaslkan11hlb6nmim3bpspl31ud@developer." "gserviceaccount.com") == 0); @@ -336,7 +336,7 @@ static int httpcli_get_custom_keys_for_email( grpc_httpcli_response response = http_response(200, gpr_strdup(good_jwk_set)); GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl); GPR_ASSERT(strcmp(request->host, "keys.bar.com") == 0); - GPR_ASSERT(strcmp(request->path, "/jwk/foo@bar.com") == 0); + GPR_ASSERT(strcmp(request->http.path, "/jwk/foo@bar.com") == 0); on_response(exec_ctx, user_data, &response); gpr_free(response.body); return 1; @@ -372,7 +372,7 @@ static int httpcli_get_jwk_set(grpc_exec_ctx *exec_ctx, grpc_httpcli_response response = http_response(200, gpr_strdup(good_jwk_set)); GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl); GPR_ASSERT(strcmp(request->host, "www.googleapis.com") == 0); - GPR_ASSERT(strcmp(request->path, "/oauth2/v3/certs") == 0); + GPR_ASSERT(strcmp(request->http.path, "/oauth2/v3/certs") == 0); on_response(exec_ctx, user_data, &response); gpr_free(response.body); return 1; @@ -387,7 +387,7 @@ static int httpcli_get_openid_config(grpc_exec_ctx *exec_ctx, http_response(200, gpr_strdup(good_openid_config)); GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl); GPR_ASSERT(strcmp(request->host, "accounts.google.com") == 0); - GPR_ASSERT(strcmp(request->path, GRPC_OPENID_CONFIG_URL_SUFFIX) == 0); + GPR_ASSERT(strcmp(request->http.path, GRPC_OPENID_CONFIG_URL_SUFFIX) == 0); grpc_httpcli_set_override(httpcli_get_jwk_set, httpcli_post_should_not_be_called); on_response(exec_ctx, user_data, &response); diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c index 5c0b2717cb..d211016267 100644 --- a/test/core/util/port_posix.c +++ b/test/core/util/port_posix.c @@ -49,6 +49,7 @@ #include #include +#include "src/core/http/httpcli.h" #include "src/core/support/env.h" #include "test/core/util/port_server_client.h" diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c index 653ecb2709..c7b9d63109 100644 --- a/test/core/util/port_server_client.c +++ b/test/core/util/port_server_client.c @@ -47,7 +47,7 @@ #include #include -#include "src/core/httpcli/httpcli.h" +#include "src/core/http/httpcli.h" typedef struct freereq { gpr_mu *mu; @@ -91,7 +91,7 @@ void grpc_free_port_using_server(char *server, int port) { req.host = server; gpr_asprintf(&path, "/drop/%d", port); - req.path = path; + req.http.path = path; grpc_httpcli_context_init(&context); grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req, @@ -150,7 +150,7 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg, GPR_TIMESPAN))); pr->retries++; req.host = pr->server; - req.path = "/get"; + req.http.path = "/get"; grpc_httpcli_get(exec_ctx, pr->ctx, pr->pollset, &req, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server, pr); @@ -189,7 +189,7 @@ int grpc_pick_port_using_server(char *server) { pr.ctx = &context; req.host = server; - req.path = "/get"; + req.http.path = "/get"; grpc_httpcli_context_init(&context); grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req, diff --git a/test/core/util/port_windows.c b/test/core/util/port_windows.c index a810683440..77125dde75 100644 --- a/test/core/util/port_windows.c +++ b/test/core/util/port_windows.c @@ -47,6 +47,7 @@ #include #include "src/core/support/env.h" +#include "src/core/http/httpcli.h" #include "src/core/iomgr/sockaddr_utils.h" #include "test/core/util/port_server_client.h" diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 694fd2820b..5b41e04216 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -806,9 +806,9 @@ src/core/client_config/uri_parser.h \ src/core/compression/algorithm_metadata.h \ src/core/compression/message_compress.h \ src/core/debug/trace.h \ -src/core/httpcli/format_request.h \ -src/core/httpcli/httpcli.h \ -src/core/httpcli/parser.h \ +src/core/http/format_request.h \ +src/core/http/httpcli.h \ +src/core/http/parser.h \ src/core/iomgr/closure.h \ src/core/iomgr/endpoint.h \ src/core/iomgr/endpoint_pair.h \ @@ -947,9 +947,9 @@ src/core/client_config/uri_parser.c \ src/core/compression/compression_algorithm.c \ src/core/compression/message_compress.c \ src/core/debug/trace.c \ -src/core/httpcli/format_request.c \ -src/core/httpcli/httpcli.c \ -src/core/httpcli/parser.c \ +src/core/http/format_request.c \ +src/core/http/httpcli.c \ +src/core/http/parser.c \ src/core/iomgr/closure.c \ src/core/iomgr/endpoint.c \ src/core/iomgr/endpoint_pair_posix.c \ @@ -1045,7 +1045,7 @@ src/core/transport/metadata_batch.c \ src/core/transport/static_metadata.c \ src/core/transport/transport.c \ src/core/transport/transport_op_string.c \ -src/core/httpcli/httpcli_security_connector.c \ +src/core/http/httpcli_security_connector.c \ src/core/security/b64.c \ src/core/security/client_auth_filter.c \ src/core/security/credentials.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 3b787d680a..f206120d93 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -923,9 +923,9 @@ ], "headers": [], "language": "c", - "name": "httpcli_format_request_test", + "name": "http_parser_test", "src": [ - "test/core/httpcli/format_request_test.c" + "test/core/http/parser_test.c" ], "third_party": false, "type": "target" @@ -939,9 +939,9 @@ ], "headers": [], "language": "c", - "name": "httpcli_parser_test", + "name": "httpcli_format_request_test", "src": [ - "test/core/httpcli/parser_test.c" + "test/core/http/format_request_test.c" ], "third_party": false, "type": "target" @@ -957,7 +957,7 @@ "language": "c", "name": "httpcli_test", "src": [ - "test/core/httpcli/httpcli_test.c" + "test/core/http/httpcli_test.c" ], "third_party": false, "type": "target" @@ -973,7 +973,7 @@ "language": "c", "name": "httpscli_test", "src": [ - "test/core/httpcli/httpscli_test.c" + "test/core/http/httpscli_test.c" ], "third_party": false, "type": "target" @@ -3960,9 +3960,9 @@ "src/core/compression/algorithm_metadata.h", "src/core/compression/message_compress.h", "src/core/debug/trace.h", - "src/core/httpcli/format_request.h", - "src/core/httpcli/httpcli.h", - "src/core/httpcli/parser.h", + "src/core/http/format_request.h", + "src/core/http/httpcli.h", + "src/core/http/parser.h", "src/core/iomgr/closure.h", "src/core/iomgr/endpoint.h", "src/core/iomgr/endpoint_pair.h", @@ -4157,13 +4157,13 @@ "src/core/compression/message_compress.h", "src/core/debug/trace.c", "src/core/debug/trace.h", - "src/core/httpcli/format_request.c", - "src/core/httpcli/format_request.h", - "src/core/httpcli/httpcli.c", - "src/core/httpcli/httpcli.h", - "src/core/httpcli/httpcli_security_connector.c", - "src/core/httpcli/parser.c", - "src/core/httpcli/parser.h", + "src/core/http/format_request.c", + "src/core/http/format_request.h", + "src/core/http/httpcli.c", + "src/core/http/httpcli.h", + "src/core/http/httpcli_security_connector.c", + "src/core/http/parser.c", + "src/core/http/parser.h", "src/core/iomgr/closure.c", "src/core/iomgr/closure.h", "src/core/iomgr/endpoint.c", @@ -4584,9 +4584,9 @@ "src/core/compression/algorithm_metadata.h", "src/core/compression/message_compress.h", "src/core/debug/trace.h", - "src/core/httpcli/format_request.h", - "src/core/httpcli/httpcli.h", - "src/core/httpcli/parser.h", + "src/core/http/format_request.h", + "src/core/http/httpcli.h", + "src/core/http/parser.h", "src/core/iomgr/closure.h", "src/core/iomgr/endpoint.h", "src/core/iomgr/endpoint_pair.h", @@ -4766,12 +4766,12 @@ "src/core/compression/message_compress.h", "src/core/debug/trace.c", "src/core/debug/trace.h", - "src/core/httpcli/format_request.c", - "src/core/httpcli/format_request.h", - "src/core/httpcli/httpcli.c", - "src/core/httpcli/httpcli.h", - "src/core/httpcli/parser.c", - "src/core/httpcli/parser.h", + "src/core/http/format_request.c", + "src/core/http/format_request.h", + "src/core/http/httpcli.c", + "src/core/http/httpcli.h", + "src/core/http/parser.c", + "src/core/http/parser.h", "src/core/iomgr/closure.c", "src/core/iomgr/closure.h", "src/core/iomgr/endpoint.c", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 34006b19f2..5f72b8c582 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -1094,7 +1094,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "httpcli_format_request_test", + "name": "http_parser_test", "platforms": [ "linux", "mac", @@ -1115,7 +1115,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "httpcli_parser_test", + "name": "httpcli_format_request_test", "platforms": [ "linux", "mac", diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln index 86f42ee632..96dc4eb107 100644 --- a/vsprojects/buildtests_c.sln +++ b/vsprojects/buildtests_c.sln @@ -663,7 +663,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hpack_table_test", "vcxproj {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpcli_format_request_test", "vcxproj\test\httpcli_format_request_test\httpcli_format_request_test.vcxproj", "{A43C3292-CAE7-1B8C-A5FD-52D9E3DCFD82}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "http_parser_test", "vcxproj\test\http_parser_test\http_parser_test.vcxproj", "{49D7E690-BDA1-5236-1ABF-3D81C1559DF7}" ProjectSection(myProperties) = preProject lib = "False" EndProjectSection @@ -674,7 +674,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpcli_format_request_test {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpcli_parser_test", "vcxproj\test\httpcli_parser_test\httpcli_parser_test.vcxproj", "{B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpcli_format_request_test", "vcxproj\test\httpcli_format_request_test\httpcli_format_request_test.vcxproj", "{A43C3292-CAE7-1B8C-A5FD-52D9E3DCFD82}" ProjectSection(myProperties) = preProject lib = "False" EndProjectSection @@ -2405,6 +2405,22 @@ Global {FF2CEE6D-850F-E22C-53A0-8C5912B14B20}.Release-DLL|Win32.Build.0 = Release|Win32 {FF2CEE6D-850F-E22C-53A0-8C5912B14B20}.Release-DLL|x64.ActiveCfg = Release|x64 {FF2CEE6D-850F-E22C-53A0-8C5912B14B20}.Release-DLL|x64.Build.0 = Release|x64 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Debug|Win32.ActiveCfg = Debug|Win32 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Debug|x64.ActiveCfg = Debug|x64 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Release|Win32.ActiveCfg = Release|Win32 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Release|x64.ActiveCfg = Release|x64 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Debug|Win32.Build.0 = Debug|Win32 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Debug|x64.Build.0 = Debug|x64 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Release|Win32.Build.0 = Release|Win32 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Release|x64.Build.0 = Release|x64 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Debug-DLL|Win32.Build.0 = Debug|Win32 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Debug-DLL|x64.ActiveCfg = Debug|x64 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Debug-DLL|x64.Build.0 = Debug|x64 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Release-DLL|Win32.ActiveCfg = Release|Win32 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Release-DLL|Win32.Build.0 = Release|Win32 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Release-DLL|x64.ActiveCfg = Release|x64 + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7}.Release-DLL|x64.Build.0 = Release|x64 {A43C3292-CAE7-1B8C-A5FD-52D9E3DCFD82}.Debug|Win32.ActiveCfg = Debug|Win32 {A43C3292-CAE7-1B8C-A5FD-52D9E3DCFD82}.Debug|x64.ActiveCfg = Debug|x64 {A43C3292-CAE7-1B8C-A5FD-52D9E3DCFD82}.Release|Win32.ActiveCfg = Release|Win32 @@ -2421,22 +2437,6 @@ Global {A43C3292-CAE7-1B8C-A5FD-52D9E3DCFD82}.Release-DLL|Win32.Build.0 = Release|Win32 {A43C3292-CAE7-1B8C-A5FD-52D9E3DCFD82}.Release-DLL|x64.ActiveCfg = Release|x64 {A43C3292-CAE7-1B8C-A5FD-52D9E3DCFD82}.Release-DLL|x64.Build.0 = Release|x64 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Debug|Win32.ActiveCfg = Debug|Win32 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Debug|x64.ActiveCfg = Debug|x64 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Release|Win32.ActiveCfg = Release|Win32 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Release|x64.ActiveCfg = Release|x64 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Debug|Win32.Build.0 = Debug|Win32 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Debug|x64.Build.0 = Debug|x64 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Release|Win32.Build.0 = Release|Win32 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Release|x64.Build.0 = Release|x64 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Debug-DLL|Win32.Build.0 = Debug|Win32 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Debug-DLL|x64.ActiveCfg = Debug|x64 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Debug-DLL|x64.Build.0 = Debug|x64 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Release-DLL|Win32.ActiveCfg = Release|Win32 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Release-DLL|Win32.Build.0 = Release|Win32 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Release-DLL|x64.ActiveCfg = Release|x64 - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848}.Release-DLL|x64.Build.0 = Release|x64 {117CA7AD-C42B-9217-6C95-42A801777BC5}.Debug|Win32.ActiveCfg = Debug|Win32 {117CA7AD-C42B-9217-6C95-42A801777BC5}.Debug|x64.ActiveCfg = Debug|x64 {117CA7AD-C42B-9217-6C95-42A801777BC5}.Release|Win32.ActiveCfg = Release|Win32 diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index 30726ff5e9..353f642b06 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -315,9 +315,9 @@ - - - + + + @@ -492,11 +492,11 @@
- + - + - + @@ -688,7 +688,7 @@ - + diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index 26ef8aa781..f433f3694e 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -103,14 +103,14 @@ src\core\debug - - src\core\httpcli + + src\core\http - - src\core\httpcli + + src\core\http - - src\core\httpcli + + src\core\http src\core\iomgr @@ -397,8 +397,8 @@ src\core\transport - - src\core\httpcli + + src\core\http src\core\security @@ -629,14 +629,14 @@ src\core\debug - - src\core\httpcli + + src\core\http - - src\core\httpcli + + src\core\http - - src\core\httpcli + + src\core\http src\core\iomgr @@ -992,8 +992,8 @@ {1da7ef8a-a06d-5499-b3de-19fee4a4214d} - - {a9bc00ad-835f-c625-c6d9-6a1324f98b9f} + + {404fdb9e-a69c-81d4-035b-465c826115a9} {1baf3894-af37-e647-bdbc-95dc17ed0073} diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index 1939396e1a..c2ece63578 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -305,9 +305,9 @@ - - - + + + @@ -470,11 +470,11 @@ - + - + - + diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index 6075961030..2193d999f0 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -106,14 +106,14 @@ src\core\debug - - src\core\httpcli + + src\core\http - - src\core\httpcli + + src\core\http - - src\core\httpcli + + src\core\http src\core\iomgr @@ -566,14 +566,14 @@ src\core\debug - - src\core\httpcli + + src\core\http - - src\core\httpcli + + src\core\http - - src\core\httpcli + + src\core\http src\core\iomgr @@ -887,8 +887,8 @@ {6d8d5774-7291-554d-fafa-583463cd3fd9} - - {1ba3a245-47e7-89b5-b0c9-aca758bd0277} + + {46faed8e-5cd4-98b0-05ed-ff2ac7bc2d46} {a9df8b24-ecea-ff6d-8999-d8fa54cd70bf} diff --git a/vsprojects/vcxproj/test/http_parser_test/http_parser_test.vcxproj b/vsprojects/vcxproj/test/http_parser_test/http_parser_test.vcxproj new file mode 100644 index 0000000000..bd5cf1212c --- /dev/null +++ b/vsprojects/vcxproj/test/http_parser_test/http_parser_test.vcxproj @@ -0,0 +1,199 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {49D7E690-BDA1-5236-1ABF-3D81C1559DF7} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + http_parser_test + static + Debug + static + Debug + + + http_parser_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/http_parser_test/http_parser_test.vcxproj.filters b/vsprojects/vcxproj/test/http_parser_test/http_parser_test.vcxproj.filters new file mode 100644 index 0000000000..4353c3b61f --- /dev/null +++ b/vsprojects/vcxproj/test/http_parser_test/http_parser_test.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + test\core\http + + + + + + {1d07f09d-a0ec-d684-3589-bff02afbe830} + + + {eedab59d-9f19-9172-cf0e-83a839217afc} + + + {1fcac48f-3718-00ea-6c0c-aafa1a4de528} + + + + diff --git a/vsprojects/vcxproj/test/httpcli_format_request_test/httpcli_format_request_test.vcxproj b/vsprojects/vcxproj/test/httpcli_format_request_test/httpcli_format_request_test.vcxproj index 97f14f6c8e..5515349b9b 100644 --- a/vsprojects/vcxproj/test/httpcli_format_request_test/httpcli_format_request_test.vcxproj +++ b/vsprojects/vcxproj/test/httpcli_format_request_test/httpcli_format_request_test.vcxproj @@ -158,7 +158,7 @@ - + diff --git a/vsprojects/vcxproj/test/httpcli_format_request_test/httpcli_format_request_test.vcxproj.filters b/vsprojects/vcxproj/test/httpcli_format_request_test/httpcli_format_request_test.vcxproj.filters index c54ded579b..6f941f4361 100644 --- a/vsprojects/vcxproj/test/httpcli_format_request_test/httpcli_format_request_test.vcxproj.filters +++ b/vsprojects/vcxproj/test/httpcli_format_request_test/httpcli_format_request_test.vcxproj.filters @@ -1,8 +1,8 @@ - - test\core\httpcli + + test\core\http @@ -13,8 +13,8 @@ {f033cf49-b830-5698-3989-6ec75817333b} - - {75330e6a-521e-5f90-defd-652a4591dbe9} + + {51615bc9-b61d-8d7d-9abb-5409276c04ec} diff --git a/vsprojects/vcxproj/test/httpcli_parser_test/httpcli_parser_test.vcxproj b/vsprojects/vcxproj/test/httpcli_parser_test/httpcli_parser_test.vcxproj deleted file mode 100644 index 6f976309c5..0000000000 --- a/vsprojects/vcxproj/test/httpcli_parser_test/httpcli_parser_test.vcxproj +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {B6F60D1C-D4F3-0F1A-4A2F-9134629B7848} - true - $(SolutionDir)IntDir\$(MSBuildProjectName)\ - - - - v100 - - - v110 - - - v120 - - - v140 - - - Application - true - Unicode - - - Application - false - true - Unicode - - - - - - - - - - - - - - httpcli_parser_test - static - Debug - static - Debug - - - httpcli_parser_test - static - Release - static - Release - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDebug - true - None - false - - - Console - true - false - - - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDebug - true - None - false - - - Console - true - false - - - - - - NotUsing - Level3 - MaxSpeed - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - true - true - MultiThreaded - true - None - false - - - Console - true - false - true - true - - - - - - NotUsing - Level3 - MaxSpeed - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - true - true - MultiThreaded - true - None - false - - - Console - true - false - true - true - - - - - - - - - - {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} - - - {29D16885-7228-4C31-81ED-5F9187C7F2A9} - - - {EAB0A629-17A9-44DB-B5FF-E91A721FE037} - - - {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} - - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - diff --git a/vsprojects/vcxproj/test/httpcli_parser_test/httpcli_parser_test.vcxproj.filters b/vsprojects/vcxproj/test/httpcli_parser_test/httpcli_parser_test.vcxproj.filters deleted file mode 100644 index 1cdc32fb85..0000000000 --- a/vsprojects/vcxproj/test/httpcli_parser_test/httpcli_parser_test.vcxproj.filters +++ /dev/null @@ -1,21 +0,0 @@ - - - - - test\core\httpcli - - - - - - {f3562e8b-3020-c79a-4e3b-c895f9e49f44} - - - {db527686-b5c7-68df-a106-bd919f60742a} - - - {8e60d460-93de-c6e1-b67b-bfae71bd9bca} - - - - -- cgit v1.2.3 From b7921c7b4ae55edb61eee309e0898d4b720f424e Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 23 Mar 2016 10:16:45 -0700 Subject: resolve comments --- src/core/iomgr/tcp_server_posix.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c index 8f23ddff34..9903c1ace9 100644 --- a/src/core/iomgr/tcp_server_posix.c +++ b/src/core/iomgr/tcp_server_posix.c @@ -490,13 +490,11 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, addr_len = sizeof(wild6); fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode); sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index); - if (fd >= 0 && - (dsmode == GRPC_DSMODE_DUALSTACK || dsmode == GRPC_DSMODE_IPV4)) { + if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) { goto done; } if (sp != NULL) { ++fd_index; - sp2 = sp; } /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */ if (port == 0 && sp != NULL) { @@ -515,6 +513,7 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, addr = (struct sockaddr *)&addr4_copy; addr_len = sizeof(addr4_copy); } + sp2 = sp; sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index); if (sp2 != NULL && sp != NULL) { sp2->sibling = sp; @@ -526,8 +525,6 @@ done: gpr_free(allocated_addr); if (sp != NULL) { return sp->port; - } else if (sp2 != NULL) { - return sp2->port; } else { return -1; } -- cgit v1.2.3 From 9e3e0ab57ba978974069ab61d0fdbaf7f7e01136 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 23 Mar 2016 11:18:15 -0700 Subject: Added generic service client and server to Node perf tests --- src/node/performance/benchmark_client.js | 60 +++++++++++++++++++++-------- src/node/performance/benchmark_server.js | 34 +++++++++++++--- src/node/performance/generic_service.js | 46 ++++++++++++++++++++++ src/node/performance/worker_service_impl.js | 25 +++++++++--- 4 files changed, 137 insertions(+), 28 deletions(-) create mode 100644 src/node/performance/generic_service.js (limited to 'src') diff --git a/src/node/performance/benchmark_client.js b/src/node/performance/benchmark_client.js index 620aecde97..80bec0b73e 100644 --- a/src/node/performance/benchmark_client.js +++ b/src/node/performance/benchmark_client.js @@ -45,6 +45,9 @@ var EventEmitter = require('events'); var _ = require('lodash'); var PoissonProcess = require('poisson-process'); var Histogram = require('./histogram'); + +var genericService = require('./generic_service'); + var grpc = require('../../../'); var serviceProto = grpc.load({ root: __dirname + '/../../..', @@ -104,10 +107,14 @@ function BenchmarkClient(server_targets, channels, histogram_params, } this.clients = []; + var GenericClient = grpc.makeGenericClientConstructor(genericService); + this.genericClients = []; for (var i = 0; i < channels; i++) { this.clients[i] = new serviceProto.BenchmarkService( server_targets[i % server_targets.length], creds, options); + this.genericClients[i] = new GenericClient( + server_targets[i % server_targets.length], creds, options); } this.histogram = new Histogram(histogram_params.resolution, @@ -130,9 +137,11 @@ util.inherits(BenchmarkClient, EventEmitter); * 'STREAMING' * @param {number} req_size The size of the payload to send with each request * @param {number} resp_size The size of payload to request be sent in responses + * @param {boolean} generic Indicates that the generic (non-proto) clients + * should be used */ BenchmarkClient.prototype.startClosedLoop = function( - outstanding_rpcs_per_channel, rpc_type, req_size, resp_size) { + outstanding_rpcs_per_channel, rpc_type, req_size, resp_size, generic) { var self = this; self.running = true; @@ -141,12 +150,20 @@ BenchmarkClient.prototype.startClosedLoop = function( var makeCall; - var argument = { - response_size: resp_size, - payload: { - body: zeroBuffer(req_size) - } - }; + var argument; + var client_list; + if (generic) { + argument = zeroBuffer(req_size); + client_list = self.genericClients; + } else { + argument = { + response_size: resp_size, + payload: { + body: zeroBuffer(req_size) + } + }; + client_list = self.clients; + } if (rpc_type == 'UNARY') { makeCall = function(client) { @@ -195,7 +212,7 @@ BenchmarkClient.prototype.startClosedLoop = function( }; } - _.each(self.clients, function(client) { + _.each(client_list, function(client) { _.times(outstanding_rpcs_per_channel, function() { makeCall(client); }); @@ -213,9 +230,12 @@ BenchmarkClient.prototype.startClosedLoop = function( * @param {number} req_size The size of the payload to send with each request * @param {number} resp_size The size of payload to request be sent in responses * @param {number} offered_load The load parameter for the Poisson process + * @param {boolean} generic Indicates that the generic (non-proto) clients + * should be used */ BenchmarkClient.prototype.startPoisson = function( - outstanding_rpcs_per_channel, rpc_type, req_size, resp_size, offered_load) { + outstanding_rpcs_per_channel, rpc_type, req_size, resp_size, offered_load, + generic) { var self = this; self.running = true; @@ -224,12 +244,20 @@ BenchmarkClient.prototype.startPoisson = function( var makeCall; - var argument = { - response_size: resp_size, - payload: { - body: zeroBuffer(req_size) - } - }; + var argument; + var client_list; + if (generic) { + argument = zeroBuffer(req_size); + client_list = self.genericClients; + } else { + argument = { + response_size: resp_size, + payload: { + body: zeroBuffer(req_size) + } + }; + client_list = self.clients; + } if (rpc_type == 'UNARY') { makeCall = function(client, poisson) { @@ -282,7 +310,7 @@ BenchmarkClient.prototype.startPoisson = function( var averageIntervalMs = (1 / offered_load) * 1000; - _.each(self.clients, function(client) { + _.each(client_list, function(client) { _.times(outstanding_rpcs_per_channel, function() { var p = PoissonProcess.create(averageIntervalMs, function() { makeCall(client, p); diff --git a/src/node/performance/benchmark_server.js b/src/node/performance/benchmark_server.js index e48acd48f5..b1b0bd12ab 100644 --- a/src/node/performance/benchmark_server.js +++ b/src/node/performance/benchmark_server.js @@ -41,6 +41,8 @@ var fs = require('fs'); var path = require('path'); +var genericService = require('./generic_service'); + var grpc = require('../../../'); var serviceProto = grpc.load({ root: __dirname + '/../../..', @@ -84,14 +86,28 @@ function streamingCall(call) { }); } +function makeStreamingGenericCall(response_size) { + var response = zeroBuffer(response_size); + return function streamingGenericCall(call) { + call.on('data', function(value) { + call.write(response); + }); + call.on('end', function() { + call.end(); + }); + }; +} + /** * BenchmarkServer class. Constructed based on parameters from the driver and * stores statistics. * @param {string} host The host to serve on * @param {number} port The port to listen to - * @param {tls} Indicates whether TLS should be used + * @param {boolean} tls Indicates whether TLS should be used + * @param {boolean} generic Indicates whether to use the generic service + * @param {number=} response_size The response size for the generic service */ -function BenchmarkServer(host, port, tls) { +function BenchmarkServer(host, port, tls, generic, response_size) { var server_creds; var host_override; if (tls) { @@ -109,10 +125,16 @@ function BenchmarkServer(host, port, tls) { var server = new grpc.Server(); this.port = server.bind(host + ':' + port, server_creds); - server.addProtoService(serviceProto.BenchmarkService.service, { - unaryCall: unaryCall, - streamingCall: streamingCall - }); + if (generic) { + server.addService(genericService, { + streamingCall: makeStreamingGenericCall(response_size) + }); + } else { + server.addProtoService(serviceProto.BenchmarkService.service, { + unaryCall: unaryCall, + streamingCall: streamingCall + }); + } this.server = server; } diff --git a/src/node/performance/generic_service.js b/src/node/performance/generic_service.js new file mode 100644 index 0000000000..614434da4f --- /dev/null +++ b/src/node/performance/generic_service.js @@ -0,0 +1,46 @@ +/* + * + * 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. + * + */ + +var _ = require('loadsh'); + +module.exports = { + 'streamingCall' : { + path: '/grpc.testing/BenchmarkService', + requestStream: true, + responseStream: true, + requestSerialize: _.identity, + requestDeserialize: _.identity, + responseSerialize: _.identity, + responseDeserialize: _.identity + } +}; diff --git a/src/node/performance/worker_service_impl.js b/src/node/performance/worker_service_impl.js index 1439249878..2c4651370f 100644 --- a/src/node/performance/worker_service_impl.js +++ b/src/node/performance/worker_service_impl.js @@ -56,18 +56,31 @@ exports.runClient = function runClient(call) { client.on('error', function(error) { call.emit('error', error); }); + var req_size, resp_size, generic; + switch (setup.payload_config.payload) { + case 'bytebuf_params': + req_size = setup.payload_config.bytebuf_params.req_size; + resp_size = setup.payload_config.bytebuf_params.resp_size; + generic = true; + break; + case 'simple_params': + req_size = setup.payload_config.simple_params.req_size; + resp_size = setup.payload_config.simple_params.resp_size; + generic = false; + break; + default: + call.emit('error', new Error('Unsupported PayloadConfig type' + + setup.payload_config.payload)); + } switch (setup.load_params.load) { case 'closed_loop': client.startClosedLoop(setup.outstanding_rpcs_per_channel, - setup.rpc_type, - setup.payload_config.simple_params.req_size, - setup.payload_config.simple_params.resp_size); + setup.rpc_type, req_size, resp_size, generic); break; case 'poisson': client.startPoisson(setup.outstanding_rpcs_per_channel, - setup.rpc_type, setup.payload_config.req_size, - setup.payload_config.resp_size, - setup.load_params.poisson.offered_load); + setup.rpc_type, req_size, resp_size, + setup.load_params.poisson.offered_load, generic); break; default: call.emit('error', new Error('Unsupported LoadParams type' + -- cgit v1.2.3 From 8447b88f8c0aa2f4d035e1bf3a5b6bddfa7c6b4f Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 23 Mar 2016 13:55:55 -0700 Subject: Address code review comments --- src/proto/grpc/testing/metrics.proto | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/proto/grpc/testing/metrics.proto b/src/proto/grpc/testing/metrics.proto index 4485d3a53b..0cc4b60239 100644 --- a/src/proto/grpc/testing/metrics.proto +++ b/src/proto/grpc/testing/metrics.proto @@ -1,4 +1,3 @@ - // Copyright 2015, Google Inc. // All rights reserved. // @@ -28,12 +27,17 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// An integration test service that covers all the method signature permutations -// of unary/streaming requests/responses. +// Contains the definitions for a metrics service and the type of metrics +// exposed by the service. +// +// Currently, 'Gauge' (i.e a metric that represents the measured value of +// something at an instant of time) is the only metric type supported by the +// service. syntax = "proto3"; package grpc.testing; +// Reponse message containing the gauge name and value message GaugeResponse { string name = 1; oneof value { @@ -43,11 +47,18 @@ message GaugeResponse { } } -message GaugeRequest { string name = 1; } +// Request message containing the gauge name +message GaugeRequest { + string name = 1; +} message EmptyMessage {} service MetricsService { + // Returns the values of all the gauges that are currently being maintained by + // the service rpc GetAllGauges(EmptyMessage) returns (stream GaugeResponse); + + // Returns the value of one gauge rpc GetGauge(GaugeRequest) returns (GaugeResponse); } -- cgit v1.2.3 From e9b3af85d9198012c84b3b18d1c25aa1099bf36e Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 23 Mar 2016 14:21:25 -0700 Subject: Fixed import --- src/node/performance/generic_service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/node/performance/generic_service.js b/src/node/performance/generic_service.js index 614434da4f..ce09cc4336 100644 --- a/src/node/performance/generic_service.js +++ b/src/node/performance/generic_service.js @@ -31,7 +31,7 @@ * */ -var _ = require('loadsh'); +var _ = require('lodash'); module.exports = { 'streamingCall' : { -- cgit v1.2.3 From 294c5d8d115f11c68c29820224d5f3c6b820450d Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 23 Mar 2016 14:28:53 -0700 Subject: Address review feedback --- src/node/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/node/README.md b/src/node/README.md index 6b832e581c..6148dd53c1 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -21,7 +21,7 @@ npm install grpc 1. Clone [the grpc Git Repository](https://github.com/grpc/grpc). 2. Run `npm install` from the repository root. - - **Note:** On Windows, this might fail due to [issue# 4932](https:\github.com\nodejs\node\issues\4932) in which case, you will see something like the following in `npm install`'s output (towards the very beginning): + - **Note:** On Windows, this might fail due to a [nodejs issue](nodejs/node#4932) in which case, you will see something like the following in `npm install`'s output (towards the very beginning): ``` .. -- cgit v1.2.3 From 26cbe1ef8ca19eaacca58ddd2d4c56ae1ff27a23 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 23 Mar 2016 14:30:23 -0700 Subject: Fix broken link --- src/node/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/node/README.md b/src/node/README.md index 6148dd53c1..f3bb1f5fa1 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -21,7 +21,7 @@ npm install grpc 1. Clone [the grpc Git Repository](https://github.com/grpc/grpc). 2. Run `npm install` from the repository root. - - **Note:** On Windows, this might fail due to a [nodejs issue](nodejs/node#4932) in which case, you will see something like the following in `npm install`'s output (towards the very beginning): + - **Note:** On Windows, this might fail due to a [nodejs issue](https:\github.com\nodejs\node\issues\4932) in which case, you will see something like the following in `npm install`'s output (towards the very beginning): ``` .. -- cgit v1.2.3 From b5a1ff5a4dfd0c4415d890175ad92ce355c34b67 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 23 Mar 2016 14:36:46 -0700 Subject: Try fixing the link again --- src/node/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/node/README.md b/src/node/README.md index f3bb1f5fa1..16dc906319 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -21,7 +21,7 @@ npm install grpc 1. Clone [the grpc Git Repository](https://github.com/grpc/grpc). 2. Run `npm install` from the repository root. - - **Note:** On Windows, this might fail due to a [nodejs issue](https:\github.com\nodejs\node\issues\4932) in which case, you will see something like the following in `npm install`'s output (towards the very beginning): + - **Note:** On Windows, this might fail due to nodejs/node#4932 in which case, you will see something like the following in `npm install`'s output (towards the very beginning): ``` .. -- cgit v1.2.3 From e7964dd7bb1b978e05f6b7ddb854e5e61f9ed1bf Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 23 Mar 2016 14:59:41 -0700 Subject: Fix the link again: Third time's a charm! --- src/node/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/node/README.md b/src/node/README.md index 16dc906319..15d4c6d02f 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -21,7 +21,7 @@ npm install grpc 1. Clone [the grpc Git Repository](https://github.com/grpc/grpc). 2. Run `npm install` from the repository root. - - **Note:** On Windows, this might fail due to nodejs/node#4932 in which case, you will see something like the following in `npm install`'s output (towards the very beginning): + - **Note:** On Windows, this might fail due to [nodejs issue #4932](https://github.com/nodejs/node/issues/4932) in which case, you will see something like the following in `npm install`'s output (towards the very beginning): ``` .. -- cgit v1.2.3 From 0cdf04796f57d5dc765e277a2607b954cd8a022d Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 23 Mar 2016 15:36:51 -0700 Subject: Fix Node status code usage to match spec --- src/node/src/server.js | 6 +++--- src/node/test/surface_test.js | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/node/src/server.js b/src/node/src/server.js index 0cf7ba3424..dd0bc12bc9 100644 --- a/src/node/src/server.js +++ b/src/node/src/server.js @@ -339,7 +339,7 @@ function _read(size) { try { deserialized = self.deserialize(data); } catch (e) { - e.code = grpc.status.INVALID_ARGUMENT; + e.code = grpc.status.INTERNAL; self.emit('error', e); return; } @@ -475,7 +475,7 @@ function handleUnary(call, handler, metadata) { try { emitter.request = handler.deserialize(result.read); } catch (e) { - e.code = grpc.status.INVALID_ARGUMENT; + e.code = grpc.status.INTERNAL; handleError(call, e); return; } @@ -516,7 +516,7 @@ function handleServerStreaming(call, handler, metadata) { try { stream.request = handler.deserialize(result.read); } catch (e) { - e.code = grpc.status.INVALID_ARGUMENT; + e.code = grpc.status.INTERNAL; stream.emit('error', e); return; } diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js index 8a232d6fc4..edbfc0a288 100644 --- a/src/node/test/surface_test.js +++ b/src/node/test/surface_test.js @@ -709,14 +709,14 @@ describe('Other conditions', function() { it('should respond correctly to a unary call', function(done) { misbehavingClient.unary(badArg, function(err, data) { assert(err); - assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT); + assert.strictEqual(err.code, grpc.status.INTERNAL); done(); }); }); it('should respond correctly to a client stream', function(done) { var call = misbehavingClient.clientStream(function(err, data) { assert(err); - assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT); + assert.strictEqual(err.code, grpc.status.INTERNAL); done(); }); call.write(badArg); @@ -729,7 +729,7 @@ describe('Other conditions', function() { assert.fail(data, null, 'Unexpected data', '==='); }); call.on('error', function(err) { - assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT); + assert.strictEqual(err.code, grpc.status.INTERNAL); done(); }); }); @@ -739,7 +739,7 @@ describe('Other conditions', function() { assert.fail(data, null, 'Unexpected data', '==='); }); call.on('error', function(err) { - assert.strictEqual(err.code, grpc.status.INVALID_ARGUMENT); + assert.strictEqual(err.code, grpc.status.INTERNAL); done(); }); call.write(badArg); -- cgit v1.2.3 From 739454749b985d62f1ee385c3b20441ce9f5f0bd Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 23 Mar 2016 15:50:56 -0700 Subject: fix copyright --- src/proto/grpc/testing/metrics.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/proto/grpc/testing/metrics.proto b/src/proto/grpc/testing/metrics.proto index 0cc4b60239..df719afd99 100644 --- a/src/proto/grpc/testing/metrics.proto +++ b/src/proto/grpc/testing/metrics.proto @@ -1,4 +1,4 @@ -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without -- cgit v1.2.3 From ae2195667d4bbe24a8b67e5e9b23280211f92d36 Mon Sep 17 00:00:00 2001 From: Leifur Halldor Asgeirsson Date: Tue, 1 Mar 2016 10:35:05 -0500 Subject: fixes to tests for py2/3 syntax compatibility --- src/python/grpcio/tests/_result.py | 2 +- src/python/grpcio/tests/_runner.py | 9 ++-- src/python/grpcio/tests/interop/methods.py | 4 +- .../tests/protoc_plugin/beta_python_plugin_test.py | 54 +++++++++++----------- .../tests/unit/_adapter/_intermediary_low_test.py | 16 ++++--- .../unit/framework/interfaces/base/_control.py | 12 +++-- .../face/_blocking_invocation_inline_service.py | 4 +- ...future_invocation_asynchronous_event_service.py | 4 +- 8 files changed, 60 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/python/grpcio/tests/_result.py b/src/python/grpcio/tests/_result.py index 065153f0c3..18b0f43963 100644 --- a/src/python/grpcio/tests/_result.py +++ b/src/python/grpcio/tests/_result.py @@ -204,7 +204,7 @@ class AugmentedResult(unittest.TestResult): """ case_id = self.id_map(test) self.cases[case_id] = self.cases[case_id].updated( - stdout=stdout, stderr=stderr) + stdout=stdout.decode(), stderr=stderr.decode()) def augmented_results(self, filter): """Convenience method to retrieve filtered case results. diff --git a/src/python/grpcio/tests/_runner.py b/src/python/grpcio/tests/_runner.py index e899154b0b..173a170409 100644 --- a/src/python/grpcio/tests/_runner.py +++ b/src/python/grpcio/tests/_runner.py @@ -42,6 +42,7 @@ import time import unittest import uuid +import six from six import moves from tests import _loader @@ -95,6 +96,8 @@ class CaptureFile(object): Arguments: value (str): What to write to the original file. """ + if six.PY3 and not isinstance(value, six.binary_type): + value = bytes(value, 'ascii') if self._saved_fd is None: os.write(self._redirect_fd, value) else: @@ -171,9 +174,9 @@ class Runner(object): result.stopTestRun() stdout_pipe.write_bypass(result_out.getvalue()) stdout_pipe.write_bypass( - '\ninterrupted stdout:\n{}\n'.format(stdout_pipe.output())) + '\ninterrupted stdout:\n{}\n'.format(stdout_pipe.output().decode())) stderr_pipe.write_bypass( - '\ninterrupted stderr:\n{}\n'.format(stderr_pipe.output())) + '\ninterrupted stderr:\n{}\n'.format(stderr_pipe.output().decode())) os._exit(1) signal.signal(signal.SIGINT, sigint_handler) signal.signal(signal.SIGSEGV, fault_handler) @@ -216,7 +219,7 @@ class Runner(object): sys.stdout.write(result_out.getvalue()) sys.stdout.flush() signal.signal(signal.SIGINT, signal.SIG_DFL) - with open('report.xml', 'w') as report_xml_file: + with open('report.xml', 'wb') as report_xml_file: _result.jenkins_junit_xml(result).write(report_xml_file) return result diff --git a/src/python/grpcio/tests/interop/methods.py b/src/python/grpcio/tests/interop/methods.py index 1f5561c1f0..7f42b4a005 100644 --- a/src/python/grpcio/tests/interop/methods.py +++ b/src/python/grpcio/tests/interop/methods.py @@ -29,6 +29,8 @@ """Implementations of interoperability test methods.""" +from __future__ import print_function + import enum import json import os @@ -208,7 +210,7 @@ def _ping_pong(stub): with stub, _Pipe() as pipe: response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT) - print 'Starting ping-pong with response iterator %s' % response_iterator + print('Starting ping-pong with response iterator %s' % response_iterator) for response_size, payload_size in zip( request_response_sizes, request_payload_sizes): request = messages_pb2.StreamingOutputCallRequest( diff --git a/src/python/grpcio/tests/protoc_plugin/beta_python_plugin_test.py b/src/python/grpcio/tests/protoc_plugin/beta_python_plugin_test.py index ba5b219a88..230ec6487d 100644 --- a/src/python/grpcio/tests/protoc_plugin/beta_python_plugin_test.py +++ b/src/python/grpcio/tests/protoc_plugin/beta_python_plugin_test.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -42,6 +42,8 @@ import threading import time import unittest +from six import moves + from grpc.beta import implementations from grpc.framework.foundation import future from grpc.framework.interfaces.face import face @@ -250,7 +252,7 @@ class PythonPluginTest(unittest.TestCase): def testImportAttributes(self): # check that we can access the generated module and its members. import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) self.assertIsNotNone(getattr(test_pb2, SERVICER_IDENTIFIER, None)) self.assertIsNotNone(getattr(test_pb2, STUB_IDENTIFIER, None)) self.assertIsNotNone(getattr(test_pb2, SERVER_FACTORY_IDENTIFIER, None)) @@ -258,13 +260,13 @@ class PythonPluginTest(unittest.TestCase): def testUpDown(self): import protoc_plugin_test_pb2 as test_pb2 - reload(test_pb2) + moves.reload_module(test_pb2) with _CreateService(test_pb2) as (servicer, stub): request = test_pb2.SimpleRequest(response_size=13) def testUnaryCall(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) with _CreateService(test_pb2) as (methods, stub): request = test_pb2.SimpleRequest(response_size=13) response = stub.UnaryCall(request, test_constants.LONG_TIMEOUT) @@ -273,7 +275,7 @@ class PythonPluginTest(unittest.TestCase): def testUnaryCallFuture(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) request = test_pb2.SimpleRequest(response_size=13) with _CreateService(test_pb2) as (methods, stub): # Check that the call does not block waiting for the server to respond. @@ -286,7 +288,7 @@ class PythonPluginTest(unittest.TestCase): def testUnaryCallFutureExpired(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) with _CreateService(test_pb2) as (methods, stub): request = test_pb2.SimpleRequest(response_size=13) with methods.pause(): @@ -297,7 +299,7 @@ class PythonPluginTest(unittest.TestCase): def testUnaryCallFutureCancelled(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) request = test_pb2.SimpleRequest(response_size=13) with _CreateService(test_pb2) as (methods, stub): with methods.pause(): @@ -307,7 +309,7 @@ class PythonPluginTest(unittest.TestCase): def testUnaryCallFutureFailed(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) request = test_pb2.SimpleRequest(response_size=13) with _CreateService(test_pb2) as (methods, stub): with methods.fail(): @@ -317,20 +319,20 @@ class PythonPluginTest(unittest.TestCase): def testStreamingOutputCall(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) request = _streaming_output_request(test_pb2) with _CreateService(test_pb2) as (methods, stub): responses = stub.StreamingOutputCall( request, test_constants.LONG_TIMEOUT) expected_responses = methods.StreamingOutputCall( request, 'not a real RpcContext!') - for expected_response, response in itertools.izip_longest( + for expected_response, response in moves.zip_longest( expected_responses, responses): self.assertEqual(expected_response, response) def testStreamingOutputCallExpired(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) request = _streaming_output_request(test_pb2) with _CreateService(test_pb2) as (methods, stub): with methods.pause(): @@ -341,7 +343,7 @@ class PythonPluginTest(unittest.TestCase): def testStreamingOutputCallCancelled(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) request = _streaming_output_request(test_pb2) with _CreateService(test_pb2) as (unused_methods, stub): responses = stub.StreamingOutputCall( @@ -353,7 +355,7 @@ class PythonPluginTest(unittest.TestCase): def testStreamingOutputCallFailed(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) request = _streaming_output_request(test_pb2) with _CreateService(test_pb2) as (methods, stub): with methods.fail(): @@ -364,7 +366,7 @@ class PythonPluginTest(unittest.TestCase): def testStreamingInputCall(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) with _CreateService(test_pb2) as (methods, stub): response = stub.StreamingInputCall( _streaming_input_request_iterator(test_pb2), @@ -375,7 +377,7 @@ class PythonPluginTest(unittest.TestCase): def testStreamingInputCallFuture(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) with _CreateService(test_pb2) as (methods, stub): with methods.pause(): response_future = stub.StreamingInputCall.future( @@ -388,7 +390,7 @@ class PythonPluginTest(unittest.TestCase): def testStreamingInputCallFutureExpired(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) with _CreateService(test_pb2) as (methods, stub): with methods.pause(): response_future = stub.StreamingInputCall.future( @@ -401,7 +403,7 @@ class PythonPluginTest(unittest.TestCase): def testStreamingInputCallFutureCancelled(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) with _CreateService(test_pb2) as (methods, stub): with methods.pause(): response_future = stub.StreamingInputCall.future( @@ -414,7 +416,7 @@ class PythonPluginTest(unittest.TestCase): def testStreamingInputCallFutureFailed(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) with _CreateService(test_pb2) as (methods, stub): with methods.fail(): response_future = stub.StreamingInputCall.future( @@ -424,19 +426,19 @@ class PythonPluginTest(unittest.TestCase): def testFullDuplexCall(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) with _CreateService(test_pb2) as (methods, stub): responses = stub.FullDuplexCall( _full_duplex_request_iterator(test_pb2), test_constants.LONG_TIMEOUT) expected_responses = methods.FullDuplexCall( _full_duplex_request_iterator(test_pb2), 'not a real RpcContext!') - for expected_response, response in itertools.izip_longest( + for expected_response, response in moves.zip_longest( expected_responses, responses): self.assertEqual(expected_response, response) def testFullDuplexCallExpired(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) request_iterator = _full_duplex_request_iterator(test_pb2) with _CreateService(test_pb2) as (methods, stub): with methods.pause(): @@ -447,7 +449,7 @@ class PythonPluginTest(unittest.TestCase): def testFullDuplexCallCancelled(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) with _CreateService(test_pb2) as (methods, stub): request_iterator = _full_duplex_request_iterator(test_pb2) responses = stub.FullDuplexCall( @@ -459,7 +461,7 @@ class PythonPluginTest(unittest.TestCase): def testFullDuplexCallFailed(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) request_iterator = _full_duplex_request_iterator(test_pb2) with _CreateService(test_pb2) as (methods, stub): with methods.fail(): @@ -471,7 +473,7 @@ class PythonPluginTest(unittest.TestCase): def testHalfDuplexCall(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) with _CreateService(test_pb2) as (methods, stub): def half_duplex_request_iterator(): request = test_pb2.StreamingOutputCallRequest() @@ -485,13 +487,13 @@ class PythonPluginTest(unittest.TestCase): half_duplex_request_iterator(), test_constants.LONG_TIMEOUT) expected_responses = methods.HalfDuplexCall( half_duplex_request_iterator(), 'not a real RpcContext!') - for check in itertools.izip_longest(expected_responses, responses): + for check in moves.zip_longest(expected_responses, responses): expected_response, response = check self.assertEqual(expected_response, response) def testHalfDuplexCallWedged(self): import protoc_plugin_test_pb2 as test_pb2 # pylint: disable=g-import-not-at-top - reload(test_pb2) + moves.reload_module(test_pb2) condition = threading.Condition() wait_cell = [False] @contextlib.contextmanager diff --git a/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py b/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py index a6fd82388c..06bfc34977 100644 --- a/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py +++ b/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -29,11 +29,13 @@ """Tests for the old '_low'.""" -import Queue import threading import time import unittest +import six +from six.moves import queue + from grpc._adapter import _intermediary_low as _low _STREAM_LENGTH = 300 @@ -67,7 +69,7 @@ class LonelyClientTest(unittest.TestCase): second_event = completion_queue.get(after_deadline) self.assertIsNotNone(second_event) kinds = [event.kind for event in (first_event, second_event)] - self.assertItemsEqual( + six.assertCountEqual(self, (_low.Event.Kind.METADATA_ACCEPTED, _low.Event.Kind.FINISH), kinds) @@ -99,7 +101,7 @@ class EchoTest(unittest.TestCase): self.server = _low.Server(self.server_completion_queue) port = self.server.add_http2_addr('[::]:0') self.server.start() - self.server_events = Queue.Queue() + self.server_events = queue.Queue() self.server_completion_queue_thread = threading.Thread( target=_drive_completion_queue, args=(self.server_completion_queue, self.server_events)) @@ -107,7 +109,7 @@ class EchoTest(unittest.TestCase): self.client_completion_queue = _low.CompletionQueue() self.channel = _low.Channel('%s:%d' % (self.host, port), None) - self.client_events = Queue.Queue() + self.client_events = queue.Queue() self.client_completion_queue_thread = threading.Thread( target=_drive_completion_queue, args=(self.client_completion_queue, self.client_events)) @@ -315,7 +317,7 @@ class CancellationTest(unittest.TestCase): self.server = _low.Server(self.server_completion_queue) port = self.server.add_http2_addr('[::]:0') self.server.start() - self.server_events = Queue.Queue() + self.server_events = queue.Queue() self.server_completion_queue_thread = threading.Thread( target=_drive_completion_queue, args=(self.server_completion_queue, self.server_events)) @@ -323,7 +325,7 @@ class CancellationTest(unittest.TestCase): self.client_completion_queue = _low.CompletionQueue() self.channel = _low.Channel('%s:%d' % (self.host, port), None) - self.client_events = Queue.Queue() + self.client_events = queue.Queue() self.client_completion_queue_thread = threading.Thread( target=_drive_completion_queue, args=(self.client_completion_queue, self.client_events)) diff --git a/src/python/grpcio/tests/unit/framework/interfaces/base/_control.py b/src/python/grpcio/tests/unit/framework/interfaces/base/_control.py index fe69e63995..94bcc1428e 100644 --- a/src/python/grpcio/tests/unit/framework/interfaces/base/_control.py +++ b/src/python/grpcio/tests/unit/framework/interfaces/base/_control.py @@ -29,6 +29,8 @@ """Part of the tests of the base interface of RPC Framework.""" +from __future__ import division + import abc import collections import enum @@ -47,8 +49,8 @@ from tests.unit.framework.interfaces.base import test_interfaces # pylint: disa _GROUP = 'base test cases test group' _METHOD = 'base test cases test method' -_PAYLOAD_RANDOM_SECTION_MAXIMUM_SIZE = test_constants.PAYLOAD_SIZE / 20 -_MINIMUM_PAYLOAD_SIZE = test_constants.PAYLOAD_SIZE / 600 +_PAYLOAD_RANDOM_SECTION_MAXIMUM_SIZE = test_constants.PAYLOAD_SIZE // 20 +_MINIMUM_PAYLOAD_SIZE = test_constants.PAYLOAD_SIZE // 600 def _create_payload(randomness): @@ -59,7 +61,7 @@ def _create_payload(randomness): random_section = bytes( bytearray( randomness.getrandbits(8) for _ in range(random_section_length))) - sevens_section = '\x07' * (length - random_section_length) + sevens_section = b'\x07' * (length - random_section_length) return b''.join(randomness.sample((random_section, sevens_section), 2)) @@ -385,13 +387,13 @@ class _SequenceController(Controller): return request + request def deserialize_request(self, serialized_request): - return serialized_request[:len(serialized_request) / 2] + return serialized_request[:len(serialized_request) // 2] def serialize_response(self, response): return response * 3 def deserialize_response(self, serialized_response): - return serialized_response[2 * len(serialized_response) / 3:] + return serialized_response[2 * len(serialized_response) // 3:] def invocation(self): with self._condition: diff --git a/src/python/grpcio/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py b/src/python/grpcio/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py index 530ba4ff0f..936b87f597 100644 --- a/src/python/grpcio/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py +++ b/src/python/grpcio/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py @@ -29,6 +29,8 @@ """Test code for the Face layer of RPC Framework.""" +from __future__ import division + import abc import itertools import unittest @@ -182,7 +184,7 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest. some_completed_response_futures_iterator = itertools.islice( futures.as_completed(response_futures_to_indices), - test_constants.PARALLELISM / 2) + test_constants.PARALLELISM // 2) for response_future in some_completed_response_futures_iterator: index = response_futures_to_indices[response_future] test_messages.verify(requests[index], response_future.result(), self) diff --git a/src/python/grpcio/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py b/src/python/grpcio/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py index 89f344c289..401b52f614 100644 --- a/src/python/grpcio/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py +++ b/src/python/grpcio/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py @@ -29,6 +29,8 @@ """Test code for the Face layer of RPC Framework.""" +from __future__ import division + import abc import contextlib import itertools @@ -277,7 +279,7 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest. some_completed_response_futures_iterator = itertools.islice( futures.as_completed(response_futures_to_indices), - test_constants.PARALLELISM / 2) + test_constants.PARALLELISM // 2) for response_future in some_completed_response_futures_iterator: index = response_futures_to_indices[response_future] test_messages.verify(requests[index], response_future.result(), self) -- cgit v1.2.3 From 6412479c8952a45bb3906d9e671e505b31163a0d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 25 Mar 2016 09:16:22 -0700 Subject: dont check read_info for writes --- src/core/iomgr/tcp_windows.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/tcp_windows.c b/src/core/iomgr/tcp_windows.c index 038e4158c8..a165e9c79d 100644 --- a/src/core/iomgr/tcp_windows.c +++ b/src/core/iomgr/tcp_windows.c @@ -146,8 +146,8 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, bool success) { grpc_winsocket_callback_info *info = &socket->read_info; if (success) { - if (socket->read_info.wsa_error != 0 && !tcp->shutting_down) { - if (socket->read_info.wsa_error != WSAECONNRESET) { + if (info->wsa_error != 0 && !tcp->shutting_down) { + if (info->wsa_error != WSAECONNRESET) { char *utf8_message = gpr_format_message(info->wsa_error); gpr_log(GPR_ERROR, "ReadFile overlapped error: %s", utf8_message); gpr_free(utf8_message); @@ -306,7 +306,7 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, ok = true; GPR_ASSERT(bytes_sent == tcp->write_slices->length); } else { - if (socket->read_info.wsa_error != WSAECONNRESET) { + if (info->wsa_error != WSAECONNRESET) { char *utf8_message = gpr_format_message(info->wsa_error); gpr_log(GPR_ERROR, "WSASend error: %s", utf8_message); gpr_free(utf8_message); -- cgit v1.2.3 From f40df23eebdc0fb367ea265be98a4f86b6efbc94 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 25 Mar 2016 13:38:14 -0700 Subject: Auto-changes --- include/grpc++/generic/async_generic_service.h | 2 +- include/grpc++/impl/codegen/async_stream.h | 6 +- include/grpc++/impl/codegen/async_unary_call.h | 9 +- include/grpc++/impl/codegen/call.h | 3 +- include/grpc++/impl/codegen/client_unary_call.h | 3 +- include/grpc++/impl/codegen/impl/async_stream.h | 6 +- include/grpc++/impl/codegen/method_handler_impl.h | 18 +- include/grpc++/impl/codegen/rpc_service_method.h | 2 +- include/grpc++/impl/codegen/server_context.h | 6 +- include/grpc++/impl/codegen/server_interface.h | 7 +- include/grpc++/impl/codegen/sync_stream.h | 6 +- include/grpc++/support/byte_buffer.h | 6 +- include/grpc++/support/channel_arguments.h | 4 +- include/grpc++/support/slice.h | 2 +- include/grpc/byte_buffer_reader.h | 2 +- include/grpc/compression.h | 7 +- include/grpc/grpc.h | 32 +-- include/grpc/grpc_security.h | 9 +- include/grpc/impl/codegen/log.h | 2 +- include/grpc/impl/codegen/slice.h | 4 +- include/grpc/impl/codegen/slice_buffer.h | 4 +- include/grpc/impl/codegen/time.h | 4 +- src/core/census/grpc_filter.c | 30 +- src/core/census/grpc_plugin.c | 2 +- src/core/channel/channel_args.c | 2 +- src/core/channel/client_channel.c | 14 +- src/core/channel/compress_filter.c | 15 +- src/core/channel/connected_channel.c | 20 +- src/core/channel/http_client_filter.c | 15 +- src/core/channel/http_server_filter.c | 15 +- src/core/client_config/lb_policies/pick_first.c | 10 +- src/core/client_config/lb_policies/round_robin.c | 10 +- .../client_config/resolvers/zookeeper_resolver.c | 2 +- src/core/client_config/subchannel.c | 16 +- src/core/client_config/subchannel.h | 16 +- src/core/http/format_request.c | 2 +- src/core/http/format_request.h | 2 +- src/core/http/httpcli_security_connector.c | 4 +- src/core/iomgr/endpoint.h | 4 +- src/core/iomgr/endpoint_pair_posix.c | 6 +- src/core/iomgr/endpoint_pair_windows.c | 6 +- src/core/iomgr/fd_posix.h | 4 +- src/core/iomgr/iocp_windows.c | 4 +- src/core/iomgr/iomgr_internal.h | 2 +- src/core/iomgr/iomgr_posix.c | 2 +- src/core/iomgr/iomgr_windows.c | 2 +- src/core/iomgr/pollset_windows.c | 2 +- src/core/iomgr/sockaddr_posix.h | 4 +- src/core/iomgr/sockaddr_win32.h | 2 +- src/core/iomgr/socket_utils_common_posix.c | 12 +- src/core/iomgr/socket_utils_linux.c | 2 +- src/core/iomgr/socket_utils_posix.h | 2 +- src/core/iomgr/socket_windows.c | 2 +- src/core/iomgr/socket_windows.h | 4 +- src/core/iomgr/tcp_client.h | 2 +- src/core/iomgr/tcp_client_windows.c | 6 +- src/core/iomgr/tcp_posix.c | 4 +- src/core/iomgr/tcp_server_posix.c | 10 +- src/core/iomgr/tcp_windows.c | 8 +- src/core/iomgr/timer.h | 4 +- src/core/iomgr/udp_server.c | 12 +- src/core/iomgr/unix_sockets_posix.c | 2 +- src/core/iomgr/wakeup_fd_nospecial.c | 2 +- src/core/iomgr/wakeup_fd_posix.c | 4 +- src/core/iomgr/workqueue.h | 4 +- src/core/json/json_string.c | 2 +- src/core/profiling/basic_timers.c | 2 +- src/core/security/client_auth_filter.c | 6 +- src/core/security/credentials.c | 2 +- src/core/security/credentials.h | 2 +- src/core/security/handshake.c | 4 +- src/core/security/secure_endpoint.c | 11 +- src/core/security/secure_endpoint.h | 2 +- src/core/security/security_context.c | 2 +- src/core/security/server_auth_filter.c | 6 +- src/core/security/server_secure_chttp2.c | 8 +- src/core/statistics/census_log.c | 2 +- src/core/statistics/census_rpc_stats.c | 12 +- src/core/statistics/census_rpc_stats.h | 2 +- src/core/statistics/census_tracing.c | 13 +- src/core/statistics/hash_table.c | 4 +- src/core/statistics/window_stats.c | 6 +- src/core/support/alloc.c | 2 +- src/core/support/cmdline.c | 2 +- src/core/support/cpu_linux.c | 4 +- src/core/support/cpu_posix.c | 2 +- src/core/support/env_posix.c | 2 +- src/core/support/histogram.c | 2 +- src/core/support/host_port.c | 2 +- src/core/support/log_android.c | 4 +- src/core/support/log_linux.c | 6 +- src/core/support/log_posix.c | 6 +- src/core/support/log_win32.c | 6 +- src/core/support/stack_lockfree.c | 4 +- src/core/support/string.h | 2 +- src/core/support/string_posix.c | 2 +- src/core/support/string_win32.c | 2 +- src/core/support/subprocess_posix.c | 6 +- src/core/support/subprocess_windows.c | 2 +- src/core/support/sync.c | 2 +- src/core/support/sync_posix.c | 2 +- src/core/support/thd_posix.c | 6 +- src/core/support/thd_win32.c | 2 +- src/core/support/time.c | 2 +- src/core/support/time_posix.c | 2 +- src/core/support/time_win32.c | 4 +- src/core/surface/alarm.c | 4 +- src/core/surface/api_trace.h | 2 +- src/core/surface/byte_buffer_reader.c | 4 +- src/core/surface/call_log_batch.c | 2 +- src/core/surface/channel.c | 2 +- src/core/surface/channel.h | 2 +- src/core/surface/channel_stack_type.c | 2 +- src/core/surface/completion_queue.h | 2 +- src/core/surface/event_string.c | 2 +- src/core/surface/init.c | 4 +- src/core/surface/init_secure.c | 2 +- src/core/surface/lame_client.c | 21 +- src/core/surface/server.c | 20 +- src/core/surface/server_chttp2.c | 6 +- src/core/surface/surface_trace.h | 2 +- src/core/transport/byte_stream.h | 2 +- src/core/transport/chttp2/bin_encoder.c | 78 +---- src/core/transport/chttp2/frame_data.c | 4 +- src/core/transport/chttp2/frame_data.h | 2 +- src/core/transport/chttp2/frame_goaway.h | 4 +- src/core/transport/chttp2/frame_ping.h | 2 +- src/core/transport/chttp2/frame_rst_stream.h | 2 +- src/core/transport/chttp2/frame_settings.h | 2 +- src/core/transport/chttp2/frame_window_update.h | 2 +- src/core/transport/chttp2/hpack_encoder.h | 6 +- src/core/transport/chttp2/hpack_parser.c | 2 +- src/core/transport/chttp2/hpack_table.h | 2 +- src/core/transport/chttp2/huffsyms.c | 320 +++++---------------- src/core/transport/chttp2/timeout_encoding.h | 2 +- src/core/transport/chttp2_transport.c | 24 +- src/core/transport/metadata.c | 2 +- src/core/transport/static_metadata.c | 107 +++++-- src/core/transport/transport.h | 4 +- src/core/transport/transport_op_string.c | 2 +- src/core/tsi/fake_transport_security.c | 6 +- src/core/tsi/ssl_transport_security.c | 6 +- src/cpp/client/client_context.cc | 6 +- src/cpp/client/insecure_credentials.cc | 4 +- src/cpp/client/secure_credentials.cc | 2 +- src/cpp/client/secure_credentials.h | 2 +- src/cpp/common/core_codegen.h | 2 +- src/cpp/common/create_auth_context.h | 2 +- src/cpp/common/insecure_create_auth_context.cc | 2 +- src/cpp/common/secure_create_auth_context.cc | 2 +- src/cpp/server/server_builder.cc | 4 +- src/cpp/util/time.cc | 2 +- test/core/bad_client/bad_client.c | 8 +- test/core/bad_client/tests/badreq.c | 8 +- test/core/bad_client/tests/connection_prefix.c | 8 +- test/core/bad_client/tests/headers.c | 8 +- .../core/bad_client/tests/initial_settings_frame.c | 8 +- .../bad_client/tests/server_registered_method.c | 2 +- test/core/bad_client/tests/simple_request.c | 8 +- test/core/bad_client/tests/unknown_frame.c | 8 +- test/core/bad_client/tests/window_overflow.c | 17 +- test/core/bad_ssl/bad_ssl_test.c | 4 +- test/core/channel/channel_stack_test.c | 15 +- test/core/client_config/lb_policies_test.c | 23 +- test/core/end2end/cq_verifier.c | 4 +- test/core/end2end/dualstack_socket_test.c | 8 +- test/core/end2end/end2end_nosec_tests.c | 4 +- test/core/end2end/end2end_tests.c | 2 +- test/core/end2end/fixtures/h2_census.c | 12 +- test/core/end2end/fixtures/h2_compress.c | 12 +- test/core/end2end/fixtures/h2_fakesec.c | 8 +- test/core/end2end/fixtures/h2_full+pipe.c | 14 +- test/core/end2end/fixtures/h2_full+trace.c | 14 +- test/core/end2end/fixtures/h2_full.c | 12 +- test/core/end2end/fixtures/h2_oauth2.c | 10 +- test/core/end2end/fixtures/h2_proxy.c | 12 +- test/core/end2end/fixtures/h2_sockpair+trace.c | 12 +- test/core/end2end/fixtures/h2_sockpair.c | 10 +- test/core/end2end/fixtures/h2_sockpair_1byte.c | 12 +- test/core/end2end/fixtures/h2_ssl+poll.c | 2 +- test/core/end2end/fixtures/h2_ssl.c | 2 +- test/core/end2end/fixtures/h2_ssl_proxy.c | 2 +- test/core/end2end/fixtures/h2_uds.c | 14 +- test/core/end2end/invalid_call_argument_test.c | 7 +- test/core/end2end/no_server_test.c | 5 +- test/core/end2end/tests/bad_hostname.c | 8 +- test/core/end2end/tests/binary_metadata.c | 6 +- test/core/end2end/tests/call_creds.c | 10 +- test/core/end2end/tests/cancel_after_accept.c | 6 +- test/core/end2end/tests/cancel_after_client_done.c | 6 +- test/core/end2end/tests/cancel_after_invoke.c | 6 +- test/core/end2end/tests/cancel_before_invoke.c | 6 +- test/core/end2end/tests/cancel_in_a_vacuum.c | 6 +- test/core/end2end/tests/cancel_with_status.c | 8 +- test/core/end2end/tests/compressed_payload.c | 8 +- test/core/end2end/tests/default_host.c | 8 +- test/core/end2end/tests/empty_batch.c | 8 +- test/core/end2end/tests/high_initial_seqno.c | 6 +- test/core/end2end/tests/hpack_size.c | 6 +- test/core/end2end/tests/invoke_large_request.c | 6 +- test/core/end2end/tests/large_metadata.c | 6 +- test/core/end2end/tests/max_concurrent_streams.c | 6 +- test/core/end2end/tests/max_message_length.c | 6 +- test/core/end2end/tests/negative_deadline.c | 8 +- test/core/end2end/tests/no_op.c | 6 +- test/core/end2end/tests/payload.c | 6 +- test/core/end2end/tests/ping_pong_streaming.c | 6 +- test/core/end2end/tests/registered_call.c | 8 +- test/core/end2end/tests/request_with_flags.c | 6 +- test/core/end2end/tests/request_with_payload.c | 6 +- test/core/end2end/tests/server_finishes_request.c | 8 +- test/core/end2end/tests/simple_delayed_request.c | 6 +- test/core/end2end/tests/simple_metadata.c | 6 +- test/core/end2end/tests/simple_request.c | 8 +- test/core/end2end/tests/trailing_metadata.c | 6 +- test/core/fling/fling_stream_test.c | 8 +- test/core/fling/fling_test.c | 2 +- test/core/http/format_request_test.c | 3 +- test/core/iomgr/fd_conservation_posix_test.c | 2 +- test/core/iomgr/resolve_address_test.c | 2 +- test/core/iomgr/timer_list_test.c | 10 +- test/core/iomgr/udp_server_test.c | 6 +- test/core/json/json_rewrite_test.c | 2 +- test/core/json/json_stream_error_test.c | 2 +- test/core/json/json_test.c | 4 +- test/core/network_benchmarks/low_level_ping_pong.c | 2 +- test/core/security/credentials_test.c | 2 +- test/core/security/security_connector_test.c | 2 +- test/core/statistics/census_log_tests.c | 6 +- test/core/statistics/census_stub_test.c | 4 +- test/core/statistics/hash_table_test.c | 26 +- test/core/statistics/rpc_stats_test.c | 6 +- test/core/statistics/trace_test.c | 8 +- test/core/statistics/window_stats_test.c | 2 +- test/core/support/alloc_test.c | 2 +- test/core/support/load_file_test.c | 2 +- test/core/support/sync_test.c | 4 +- test/core/support/thd_test.c | 4 +- test/core/support/time_test.c | 8 +- test/core/support/tls_test.c | 4 +- test/core/support/useful_test.c | 4 +- test/core/surface/byte_buffer_reader_test.c | 4 +- test/core/surface/completion_queue_test.c | 2 +- test/core/transport/chttp2/bin_encoder_test.c | 2 +- test/core/transport/chttp2/hpack_encoder_test.c | 6 +- test/core/transport/chttp2/hpack_table_test.c | 2 +- test/core/util/port_windows.c | 4 +- test/cpp/common/auth_property_iterator_test.cc | 2 +- test/cpp/common/secure_auth_context_test.cc | 4 +- test/cpp/end2end/hybrid_end2end_test.cc | 12 +- test/cpp/end2end/test_service_impl.cc | 7 +- test/cpp/end2end/thread_stress_test.cc | 2 +- test/cpp/interop/client.cc | 4 +- test/cpp/interop/client_helper.cc | 6 +- test/cpp/interop/interop_client.cc | 2 +- test/cpp/interop/interop_client.h | 2 +- test/cpp/interop/interop_test.cc | 6 +- test/cpp/interop/reconnect_interop_client.cc | 10 +- test/cpp/interop/server_helper.h | 4 +- test/cpp/interop/server_main.cc | 14 +- test/cpp/interop/stress_test.cc | 4 +- test/cpp/qps/client_async.cc | 14 +- test/cpp/qps/driver.h | 2 +- test/cpp/qps/perf_db_client.h | 6 +- test/cpp/qps/server_async.cc | 14 +- test/cpp/util/benchmark_config.cc | 2 +- test/cpp/util/byte_buffer_test.cc | 2 +- test/cpp/util/cli_call_test.cc | 4 +- test/cpp/util/grpc_cli.cc | 2 +- test/cpp/util/test_config.cc | 2 +- test/cpp/util/test_credentials_provider.cc | 2 +- test/cpp/util/time_test.cc | 2 +- 272 files changed, 1008 insertions(+), 1052 deletions(-) (limited to 'src') diff --git a/include/grpc++/generic/async_generic_service.h b/include/grpc++/generic/async_generic_service.h index 9ae8391dc4..b87b17ee0d 100644 --- a/include/grpc++/generic/async_generic_service.h +++ b/include/grpc++/generic/async_generic_service.h @@ -34,8 +34,8 @@ #ifndef GRPCXX_GENERIC_ASYNC_GENERIC_SERVICE_H #define GRPCXX_GENERIC_ASYNC_GENERIC_SERVICE_H -#include #include +#include struct grpc_server; diff --git a/include/grpc++/impl/codegen/async_stream.h b/include/grpc++/impl/codegen/async_stream.h index 8f9afe8251..cac345e0dc 100644 --- a/include/grpc++/impl/codegen/async_stream.h +++ b/include/grpc++/impl/codegen/async_stream.h @@ -215,7 +215,8 @@ class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface { CallOpSet write_ops_; CallOpSet writes_done_ops_; CallOpSet finish_ops_; + CallOpClientRecvStatus> + finish_ops_; }; /// Client-side interface for asynchronous bi-directional streaming. @@ -350,7 +351,8 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface, CallOpSet meta_ops_; CallOpSet> read_ops_; CallOpSet finish_ops_; + CallOpServerSendStatus> + finish_ops_; }; template diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h index 9c6dbd5484..1526debf54 100644 --- a/include/grpc++/impl/codegen/async_unary_call.h +++ b/include/grpc++/impl/codegen/async_unary_call.h @@ -101,10 +101,12 @@ class ClientAsyncResponseReader GRPC_FINAL class CallOpSetCollection : public CallOpSetCollectionInterface { public: SneakyCallOpSet init_buf_; + CallOpClientSendClose> + init_buf_; CallOpSet meta_buf_; CallOpSet, - CallOpClientRecvStatus> finish_buf_; + CallOpClientRecvStatus> + finish_buf_; }; std::shared_ptr collection_; }; @@ -159,7 +161,8 @@ class ServerAsyncResponseWriter GRPC_FINAL ServerContext* ctx_; CallOpSet meta_buf_; CallOpSet finish_buf_; + CallOpServerSendStatus> + finish_buf_; }; } // namespace grpc diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h index 03affc2125..50f5a75191 100644 --- a/include/grpc++/impl/codegen/call.h +++ b/include/grpc++/impl/codegen/call.h @@ -280,7 +280,8 @@ class CallOpRecvMessage { if (*status) { got_message = true; *status = SerializationTraits::Deserialize(recv_buf_, message_, - max_message_size).ok(); + max_message_size) + .ok(); } else { got_message = false; g_core_codegen_interface->grpc_byte_buffer_destroy(recv_buf_); diff --git a/include/grpc++/impl/codegen/client_unary_call.h b/include/grpc++/impl/codegen/client_unary_call.h index a2b7d928c3..6c35a95765 100644 --- a/include/grpc++/impl/codegen/client_unary_call.h +++ b/include/grpc++/impl/codegen/client_unary_call.h @@ -56,7 +56,8 @@ Status BlockingUnaryCall(ChannelInterface* channel, const RpcMethod& method, Call call(channel->CreateCall(method, context, &cq)); CallOpSet, - CallOpClientSendClose, CallOpClientRecvStatus> ops; + CallOpClientSendClose, CallOpClientRecvStatus> + ops; Status status = ops.SendMessage(request); if (!status.ok()) { return status; diff --git a/include/grpc++/impl/codegen/impl/async_stream.h b/include/grpc++/impl/codegen/impl/async_stream.h index 413eab7570..95c844723a 100644 --- a/include/grpc++/impl/codegen/impl/async_stream.h +++ b/include/grpc++/impl/codegen/impl/async_stream.h @@ -215,7 +215,8 @@ class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface { CallOpSet write_ops_; CallOpSet writes_done_ops_; CallOpSet finish_ops_; + CallOpClientRecvStatus> + finish_ops_; }; /// Client-side interface for asynchronous bi-directional streaming. @@ -350,7 +351,8 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface, CallOpSet meta_ops_; CallOpSet> read_ops_; CallOpSet finish_ops_; + CallOpServerSendStatus> + finish_ops_; }; template diff --git a/include/grpc++/impl/codegen/method_handler_impl.h b/include/grpc++/impl/codegen/method_handler_impl.h index 3ecca0a406..0ab2ae466a 100644 --- a/include/grpc++/impl/codegen/method_handler_impl.h +++ b/include/grpc++/impl/codegen/method_handler_impl.h @@ -61,7 +61,8 @@ class RpcMethodHandler : public MethodHandler { GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_); CallOpSet ops; + CallOpServerSendStatus> + ops; ops.SendInitialMetadata(param.server_context->initial_metadata_); if (status.ok()) { status = ops.SendMessage(rsp); @@ -74,7 +75,8 @@ class RpcMethodHandler : public MethodHandler { private: // Application provided rpc handler function. std::function func_; + ResponseType*)> + func_; // The class the above handler function lives in. ServiceType* service_; }; @@ -96,7 +98,8 @@ class ClientStreamingHandler : public MethodHandler { GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_); CallOpSet ops; + CallOpServerSendStatus> + ops; ops.SendInitialMetadata(param.server_context->initial_metadata_); if (status.ok()) { status = ops.SendMessage(rsp); @@ -108,7 +111,8 @@ class ClientStreamingHandler : public MethodHandler { private: std::function*, - ResponseType*)> func_; + ResponseType*)> + func_; ServiceType* service_; }; @@ -143,7 +147,8 @@ class ServerStreamingHandler : public MethodHandler { private: std::function*)> func_; + ServerWriter*)> + func_; ServiceType* service_; }; @@ -174,7 +179,8 @@ class BidiStreamingHandler : public MethodHandler { private: std::function*)> func_; + ServerReaderWriter*)> + func_; ServiceType* service_; }; diff --git a/include/grpc++/impl/codegen/rpc_service_method.h b/include/grpc++/impl/codegen/rpc_service_method.h index 6256301677..8b1f026c91 100644 --- a/include/grpc++/impl/codegen/rpc_service_method.h +++ b/include/grpc++/impl/codegen/rpc_service_method.h @@ -40,10 +40,10 @@ #include #include -#include #include #include #include +#include namespace grpc { class ServerContext; diff --git a/include/grpc++/impl/codegen/server_context.h b/include/grpc++/impl/codegen/server_context.h index 91ebe574b1..f8326bc44b 100644 --- a/include/grpc++/impl/codegen/server_context.h +++ b/include/grpc++/impl/codegen/server_context.h @@ -37,12 +37,12 @@ #include #include -#include -#include -#include #include +#include #include #include +#include +#include struct gpr_timespec; struct grpc_metadata; diff --git a/include/grpc++/impl/codegen/server_interface.h b/include/grpc++/impl/codegen/server_interface.h index 7d4ed277ed..908d124df1 100644 --- a/include/grpc++/impl/codegen/server_interface.h +++ b/include/grpc++/impl/codegen/server_interface.h @@ -192,10 +192,11 @@ class ServerInterface : public CallHook { bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE { bool serialization_status = *status && payload_ && - SerializationTraits::Deserialize( - payload_, request_, server_->max_message_size()).ok(); + SerializationTraits::Deserialize(payload_, request_, + server_->max_message_size()) + .ok(); bool ret = RegisteredAsyncRequest::FinalizeResult(tag, status); - *status = serialization_status&&* status; + *status = serialization_status && *status; return ret; } diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h index 5f878469ce..0eabc5fc0f 100644 --- a/include/grpc++/impl/codegen/sync_stream.h +++ b/include/grpc++/impl/codegen/sync_stream.h @@ -123,7 +123,8 @@ class ClientReader GRPC_FINAL : public ClientReaderInterface { ClientContext* context, const W& request) : context_(context), call_(channel->CreateCall(method, context, &cq_)) { CallOpSet ops; + CallOpClientSendClose> + ops; ops.SendInitialMetadata(context->send_initial_metadata_); // TODO(ctiller): don't assert GPR_CODEGEN_ASSERT(ops.SendMessage(request).ok()); @@ -235,7 +236,8 @@ class ClientWriter : public ClientWriterInterface { private: ClientContext* context_; CallOpSet finish_ops_; + CallOpClientRecvStatus> + finish_ops_; CompletionQueue cq_; Call call_; }; diff --git a/include/grpc++/support/byte_buffer.h b/include/grpc++/support/byte_buffer.h index 27307f8fcd..3825518de1 100644 --- a/include/grpc++/support/byte_buffer.h +++ b/include/grpc++/support/byte_buffer.h @@ -34,13 +34,13 @@ #ifndef GRPCXX_SUPPORT_BYTE_BUFFER_H #define GRPCXX_SUPPORT_BYTE_BUFFER_H -#include -#include -#include #include #include #include #include +#include +#include +#include #include diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h index a9ede35f90..8c2f7c71eb 100644 --- a/include/grpc++/support/channel_arguments.h +++ b/include/grpc++/support/channel_arguments.h @@ -34,12 +34,12 @@ #ifndef GRPCXX_SUPPORT_CHANNEL_ARGUMENTS_H #define GRPCXX_SUPPORT_CHANNEL_ARGUMENTS_H -#include #include +#include +#include #include #include -#include namespace grpc { namespace testing { diff --git a/include/grpc++/support/slice.h b/include/grpc++/support/slice.h index 724691a033..6251a8bcde 100644 --- a/include/grpc++/support/slice.h +++ b/include/grpc++/support/slice.h @@ -34,8 +34,8 @@ #ifndef GRPCXX_SUPPORT_SLICE_H #define GRPCXX_SUPPORT_SLICE_H -#include #include +#include namespace grpc { diff --git a/include/grpc/byte_buffer_reader.h b/include/grpc/byte_buffer_reader.h index b0e63a6da2..9a1c6178ab 100644 --- a/include/grpc/byte_buffer_reader.h +++ b/include/grpc/byte_buffer_reader.h @@ -34,8 +34,8 @@ #ifndef GRPC_BYTE_BUFFER_READER_H #define GRPC_BYTE_BUFFER_READER_H -#include #include +#include #ifdef __cplusplus extern "C" { diff --git a/include/grpc/compression.h b/include/grpc/compression.h index 70ba393261..39023ded34 100644 --- a/include/grpc/compression.h +++ b/include/grpc/compression.h @@ -36,8 +36,8 @@ #include -#include #include +#include #ifdef __cplusplus extern "C" { @@ -59,9 +59,8 @@ GRPCAPI int grpc_compression_algorithm_name( * compression algorithms encoded in the \a accepted_encodings bitset. * * It abort()s for unknown levels . */ -GRPCAPI grpc_compression_algorithm -grpc_compression_algorithm_for_level(grpc_compression_level level, - uint32_t accepted_encodings); +GRPCAPI grpc_compression_algorithm grpc_compression_algorithm_for_level( + grpc_compression_level level, uint32_t accepted_encodings); GRPCAPI void grpc_compression_options_init(grpc_compression_options *opts); diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 5113645daf..fe0cf28b3b 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -36,13 +36,13 @@ #include -#include #include -#include -#include #include -#include #include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -154,9 +154,8 @@ GRPCAPI void grpc_alarm_cancel(grpc_alarm *alarm); GRPCAPI void grpc_alarm_destroy(grpc_alarm *alarm); /** Check the connectivity state of a channel. */ -GRPCAPI grpc_connectivity_state -grpc_channel_check_connectivity_state(grpc_channel *channel, - int try_to_connect); +GRPCAPI grpc_connectivity_state grpc_channel_check_connectivity_state( + grpc_channel *channel, int try_to_connect); /** Watch for a change in connectivity state. Once the channel connectivity state is different from last_observed_state, @@ -267,9 +266,10 @@ GRPCAPI grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved); and description passed in. Importantly, this function does not send status nor description to the remote endpoint. */ -GRPCAPI grpc_call_error -grpc_call_cancel_with_status(grpc_call *call, grpc_status_code status, - const char *description, void *reserved); +GRPCAPI grpc_call_error grpc_call_cancel_with_status(grpc_call *call, + grpc_status_code status, + const char *description, + void *reserved); /** Destroy a call. THREAD SAFETY: grpc_call_destroy is thread-compatible */ @@ -283,13 +283,11 @@ GRPCAPI void grpc_call_destroy(grpc_call *call); to \a cq_bound_to_call. Note that \a cq_for_notification must have been registered to the server via \a grpc_server_register_completion_queue. */ -GRPCAPI grpc_call_error -grpc_server_request_call(grpc_server *server, grpc_call **call, - grpc_call_details *details, - grpc_metadata_array *request_metadata, - grpc_completion_queue *cq_bound_to_call, - grpc_completion_queue *cq_for_notification, - void *tag_new); +GRPCAPI grpc_call_error grpc_server_request_call( + grpc_server *server, grpc_call **call, grpc_call_details *details, + grpc_metadata_array *request_metadata, + grpc_completion_queue *cq_bound_to_call, + grpc_completion_queue *cq_for_notification, void *tag_new); /** Registers a method in the server. Methods to this (host, method) pair will not be reported by diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 368d5dda51..f2d04e551a 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -80,9 +80,8 @@ grpc_auth_context_peer_identity(const grpc_auth_context *ctx); /* Finds a property in the context. May return an empty iterator (first _next will return NULL) if no property with this name was found in the context. */ -GRPCAPI grpc_auth_property_iterator -grpc_auth_context_find_properties_by_name(const grpc_auth_context *ctx, - const char *name); +GRPCAPI grpc_auth_property_iterator grpc_auth_context_find_properties_by_name( + const grpc_auth_context *ctx, const char *name); /* Gets the name of the property that indicates the peer identity. Will return NULL if the peer is not authenticated. */ @@ -363,8 +362,8 @@ GRPCAPI int grpc_server_add_secure_http2_port(grpc_server *server, /* Sets a credentials to a call. Can only be called on the client side before grpc_call_start_batch. */ -GRPCAPI grpc_call_error -grpc_call_set_credentials(grpc_call *call, grpc_call_credentials *creds); +GRPCAPI grpc_call_error grpc_call_set_credentials(grpc_call *call, + grpc_call_credentials *creds); /* --- Auth Metadata Processing --- */ diff --git a/include/grpc/impl/codegen/log.h b/include/grpc/impl/codegen/log.h index d6e18e9ca5..afd8c5d4cf 100644 --- a/include/grpc/impl/codegen/log.h +++ b/include/grpc/impl/codegen/log.h @@ -34,8 +34,8 @@ #ifndef GRPC_IMPL_CODEGEN_LOG_H #define GRPC_IMPL_CODEGEN_LOG_H -#include /* for abort() */ #include +#include /* for abort() */ #include diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h index a62fdd087b..03c59e72a0 100644 --- a/include/grpc/impl/codegen/slice.h +++ b/include/grpc/impl/codegen/slice.h @@ -122,8 +122,8 @@ GPRAPI gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)); /* Equivalent to gpr_slice_new, but with a two argument destroy function that also takes the slice length. */ -GPRAPI gpr_slice -gpr_slice_new_with_len(void *p, size_t len, void (*destroy)(void *, size_t)); +GPRAPI gpr_slice gpr_slice_new_with_len(void *p, size_t len, + void (*destroy)(void *, size_t)); /* Equivalent to gpr_slice_new(malloc(len), len, free), but saves one malloc() call. diff --git a/include/grpc/impl/codegen/slice_buffer.h b/include/grpc/impl/codegen/slice_buffer.h index 4fe909ee82..7191878496 100644 --- a/include/grpc/impl/codegen/slice_buffer.h +++ b/include/grpc/impl/codegen/slice_buffer.h @@ -73,8 +73,8 @@ GPRAPI void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_slice slice); slice at the returned index in sb->slices) The implementation MAY decide to concatenate data at the end of a small slice added in this fashion. */ -GPRAPI size_t -gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb, gpr_slice slice); +GPRAPI size_t gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb, + gpr_slice slice); GPRAPI void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *slices, size_t n); /* add a very small (less than 8 bytes) amount of data to the end of a slice diff --git a/include/grpc/impl/codegen/time.h b/include/grpc/impl/codegen/time.h index c22bedfe77..b4f45097c7 100644 --- a/include/grpc/impl/codegen/time.h +++ b/include/grpc/impl/codegen/time.h @@ -88,8 +88,8 @@ GPRAPI void gpr_time_init(void); GPRAPI gpr_timespec gpr_now(gpr_clock_type clock); /* Convert a timespec from one clock to another */ -GPRAPI gpr_timespec -gpr_convert_clock_type(gpr_timespec t, gpr_clock_type target_clock); +GPRAPI gpr_timespec gpr_convert_clock_type(gpr_timespec t, + gpr_clock_type target_clock); /* Return -ve, 0, or +ve according to whether a < b, a == b, or a > b respectively. */ diff --git a/src/core/census/grpc_filter.c b/src/core/census/grpc_filter.c index c8aaf31e2d..11120a28d1 100644 --- a/src/core/census/grpc_filter.c +++ b/src/core/census/grpc_filter.c @@ -172,13 +172,27 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, } const grpc_channel_filter grpc_client_census_filter = { - client_start_transport_op, grpc_channel_next_op, sizeof(call_data), - client_init_call_elem, grpc_call_stack_ignore_set_pollset, - client_destroy_call_elem, sizeof(channel_data), init_channel_elem, - destroy_channel_elem, grpc_call_next_get_peer, "census-client"}; + client_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + client_init_call_elem, + grpc_call_stack_ignore_set_pollset, + client_destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "census-client"}; const grpc_channel_filter grpc_server_census_filter = { - server_start_transport_op, grpc_channel_next_op, sizeof(call_data), - server_init_call_elem, grpc_call_stack_ignore_set_pollset, - server_destroy_call_elem, sizeof(channel_data), init_channel_elem, - destroy_channel_elem, grpc_call_next_get_peer, "census-server"}; + server_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + server_init_call_elem, + grpc_call_stack_ignore_set_pollset, + server_destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "census-server"}; diff --git a/src/core/census/grpc_plugin.c b/src/core/census/grpc_plugin.c index 8d60a5197e..3ca9400f7e 100644 --- a/src/core/census/grpc_plugin.c +++ b/src/core/census/grpc_plugin.c @@ -38,8 +38,8 @@ #include #include "src/core/census/grpc_filter.h" -#include "src/core/surface/channel_init.h" #include "src/core/channel/channel_stack_builder.h" +#include "src/core/surface/channel_init.h" static bool maybe_add_census_filter(grpc_channel_stack_builder *builder, void *arg_must_be_null) { diff --git a/src/core/channel/channel_args.c b/src/core/channel/channel_args.c index bae7a90a01..e0382fa0d9 100644 --- a/src/core/channel/channel_args.c +++ b/src/core/channel/channel_args.c @@ -31,8 +31,8 @@ * */ -#include #include "src/core/channel/channel_args.h" +#include #include "src/core/support/string.h" #include diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index f021a8ae32..ad1ded9ab7 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -431,9 +431,17 @@ static void cc_set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, } const grpc_channel_filter grpc_client_channel_filter = { - cc_start_transport_stream_op, cc_start_transport_op, sizeof(call_data), - init_call_elem, cc_set_pollset, destroy_call_elem, sizeof(channel_data), - init_channel_elem, destroy_channel_elem, cc_get_peer, "client-channel", + cc_start_transport_stream_op, + cc_start_transport_op, + sizeof(call_data), + init_call_elem, + cc_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + cc_get_peer, + "client-channel", }; void grpc_client_channel_set_resolver(grpc_exec_ctx *exec_ctx, diff --git a/src/core/channel/compress_filter.c b/src/core/channel/compress_filter.c index 3e7ca08fd2..6f5a9740ad 100644 --- a/src/core/channel/compress_filter.c +++ b/src/core/channel/compress_filter.c @@ -291,7 +291,14 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) {} const grpc_channel_filter grpc_compress_filter = { - compress_start_transport_stream_op, grpc_channel_next_op, sizeof(call_data), - init_call_elem, grpc_call_stack_ignore_set_pollset, destroy_call_elem, - sizeof(channel_data), init_channel_elem, destroy_channel_elem, - grpc_call_next_get_peer, "compress"}; + compress_start_transport_stream_op, + grpc_channel_next_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "compress"}; diff --git a/src/core/channel/connected_channel.c b/src/core/channel/connected_channel.c index e7ed3ccfeb..df11d54297 100644 --- a/src/core/channel/connected_channel.c +++ b/src/core/channel/connected_channel.c @@ -37,13 +37,13 @@ #include #include -#include "src/core/support/string.h" -#include "src/core/transport/transport.h" -#include "src/core/profiling/timers.h" #include #include #include #include +#include "src/core/profiling/timers.h" +#include "src/core/support/string.h" +#include "src/core/transport/transport.h" #define MAX_BUFFER_LENGTH 8192 @@ -132,9 +132,17 @@ static char *con_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { } static const grpc_channel_filter connected_channel_filter = { - con_start_transport_stream_op, con_start_transport_op, sizeof(call_data), - init_call_elem, set_pollset, destroy_call_elem, sizeof(channel_data), - init_channel_elem, destroy_channel_elem, con_get_peer, "connected", + con_start_transport_stream_op, + con_start_transport_op, + sizeof(call_data), + init_call_elem, + set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + con_get_peer, + "connected", }; static void bind_transport(grpc_channel_stack *channel_stack, diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c index 1aa27208c2..582427daf9 100644 --- a/src/core/channel/http_client_filter.c +++ b/src/core/channel/http_client_filter.c @@ -242,7 +242,14 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, } const grpc_channel_filter grpc_http_client_filter = { - hc_start_transport_op, grpc_channel_next_op, sizeof(call_data), - init_call_elem, grpc_call_stack_ignore_set_pollset, destroy_call_elem, - sizeof(channel_data), init_channel_elem, destroy_channel_elem, - grpc_call_next_get_peer, "http-client"}; + hc_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "http-client"}; diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c index 370f8dbe42..1a2e0c5db3 100644 --- a/src/core/channel/http_server_filter.c +++ b/src/core/channel/http_server_filter.c @@ -227,7 +227,14 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) {} const grpc_channel_filter grpc_http_server_filter = { - hs_start_transport_op, grpc_channel_next_op, sizeof(call_data), - init_call_elem, grpc_call_stack_ignore_set_pollset, destroy_call_elem, - sizeof(channel_data), init_channel_elem, destroy_channel_elem, - grpc_call_next_get_peer, "http-server"}; + hs_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "http-server"}; diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c index 8ed1223d39..2833f112f4 100644 --- a/src/core/client_config/lb_policies/pick_first.c +++ b/src/core/client_config/lb_policies/pick_first.c @@ -378,8 +378,14 @@ void pf_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, } static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = { - pf_destroy, pf_shutdown, pf_pick, pf_cancel_pick, pf_ping_one, pf_exit_idle, - pf_check_connectivity, pf_notify_on_state_change}; + pf_destroy, + pf_shutdown, + pf_pick, + pf_cancel_pick, + pf_ping_one, + pf_exit_idle, + pf_check_connectivity, + pf_notify_on_state_change}; static void pick_first_factory_ref(grpc_lb_policy_factory *factory) {} diff --git a/src/core/client_config/lb_policies/round_robin.c b/src/core/client_config/lb_policies/round_robin.c index 98d9acc75b..114ece6e4d 100644 --- a/src/core/client_config/lb_policies/round_robin.c +++ b/src/core/client_config/lb_policies/round_robin.c @@ -483,8 +483,14 @@ static void rr_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, } static const grpc_lb_policy_vtable round_robin_lb_policy_vtable = { - rr_destroy, rr_shutdown, rr_pick, rr_cancel_pick, rr_ping_one, rr_exit_idle, - rr_check_connectivity, rr_notify_on_state_change}; + rr_destroy, + rr_shutdown, + rr_pick, + rr_cancel_pick, + rr_ping_one, + rr_exit_idle, + rr_check_connectivity, + rr_notify_on_state_change}; static void round_robin_factory_ref(grpc_lb_policy_factory *factory) {} diff --git a/src/core/client_config/resolvers/zookeeper_resolver.c b/src/core/client_config/resolvers/zookeeper_resolver.c index 166738e768..e0e18792a2 100644 --- a/src/core/client_config/resolvers/zookeeper_resolver.c +++ b/src/core/client_config/resolvers/zookeeper_resolver.c @@ -44,9 +44,9 @@ #include "src/core/client_config/lb_policy_registry.h" #include "src/core/client_config/resolver_registry.h" #include "src/core/iomgr/resolve_address.h" +#include "src/core/json/json.h" #include "src/core/support/string.h" #include "src/core/surface/api_trace.h" -#include "src/core/json/json.h" /** Zookeeper session expiration time in milliseconds */ #define GRPC_ZOOKEEPER_SESSION_TIMEOUT 15000 diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index 8f150a8d81..c5cd504929 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -185,8 +185,8 @@ static void connection_destroy(grpc_exec_ctx *exec_ctx, void *arg, gpr_free(c); } -void grpc_connected_subchannel_ref(grpc_connected_subchannel *c - GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { +void grpc_connected_subchannel_ref( + grpc_connected_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { GRPC_CHANNEL_STACK_REF(CHANNEL_STACK_FROM_CONNECTION(c), REF_REASON); } @@ -227,8 +227,8 @@ static gpr_atm ref_mutate(grpc_subchannel *c, gpr_atm delta, return old_val; } -grpc_subchannel *grpc_subchannel_ref(grpc_subchannel *c - GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { +grpc_subchannel *grpc_subchannel_ref( + grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { gpr_atm old_refs; old_refs = ref_mutate(c, (1 << INTERNAL_REF_BITS), 0 REF_MUTATE_PURPOSE("STRONG_REF")); @@ -236,8 +236,8 @@ grpc_subchannel *grpc_subchannel_ref(grpc_subchannel *c return c; } -grpc_subchannel *grpc_subchannel_weak_ref(grpc_subchannel *c - GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { +grpc_subchannel *grpc_subchannel_weak_ref( + grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { gpr_atm old_refs; old_refs = ref_mutate(c, 1, 0 REF_MUTATE_PURPOSE("WEAK_REF")); GPR_ASSERT(old_refs != 0); @@ -626,8 +626,8 @@ static void subchannel_call_destroy(grpc_exec_ctx *exec_ctx, void *call, GPR_TIMER_END("grpc_subchannel_call_unref.destroy", 0); } -void grpc_subchannel_call_ref(grpc_subchannel_call *c - GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { +void grpc_subchannel_call_ref( + grpc_subchannel_call *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); } diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index ef9f2f1d1e..83e1c58a4c 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -83,25 +83,25 @@ typedef struct grpc_subchannel_args grpc_subchannel_args; #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS #endif -grpc_subchannel *grpc_subchannel_ref(grpc_subchannel *channel - GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +grpc_subchannel *grpc_subchannel_ref( + grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); grpc_subchannel *grpc_subchannel_ref_from_weak_ref( grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); void grpc_subchannel_unref(grpc_exec_ctx *exec_ctx, grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -grpc_subchannel *grpc_subchannel_weak_ref(grpc_subchannel *channel - GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +grpc_subchannel *grpc_subchannel_weak_ref( + grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); void grpc_subchannel_weak_unref(grpc_exec_ctx *exec_ctx, grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_connected_subchannel_ref(grpc_connected_subchannel *channel - GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_connected_subchannel_ref( + grpc_connected_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); void grpc_connected_subchannel_unref(grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_call_ref(grpc_subchannel_call *call - GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_call_ref( + grpc_subchannel_call *call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx, grpc_subchannel_call *call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); diff --git a/src/core/http/format_request.c b/src/core/http/format_request.c index 60179297bf..ac9bb8aeb8 100644 --- a/src/core/http/format_request.c +++ b/src/core/http/format_request.c @@ -37,11 +37,11 @@ #include #include -#include "src/core/support/string.h" #include #include #include #include +#include "src/core/support/string.h" static void fill_common_header(const grpc_httpcli_request *request, gpr_strvec *buf) { diff --git a/src/core/http/format_request.h b/src/core/http/format_request.h index 49593b695c..dfd6fadbde 100644 --- a/src/core/http/format_request.h +++ b/src/core/http/format_request.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_HTTP_FORMAT_REQUEST_H #define GRPC_CORE_HTTP_FORMAT_REQUEST_H -#include "src/core/http/httpcli.h" #include +#include "src/core/http/httpcli.h" gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request); gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, diff --git a/src/core/http/httpcli_security_connector.c b/src/core/http/httpcli_security_connector.c index ce82701089..a1a32f7558 100644 --- a/src/core/http/httpcli_security_connector.c +++ b/src/core/http/httpcli_security_connector.c @@ -35,11 +35,11 @@ #include -#include "src/core/security/handshake.h" -#include "src/core/support/string.h" #include #include #include +#include "src/core/security/handshake.h" +#include "src/core/support/string.h" #include "src/core/tsi/ssl_transport_security.h" typedef struct { diff --git a/src/core/iomgr/endpoint.h b/src/core/iomgr/endpoint.h index 788f3ac5bc..b4be852e33 100644 --- a/src/core/iomgr/endpoint.h +++ b/src/core/iomgr/endpoint.h @@ -34,11 +34,11 @@ #ifndef GRPC_CORE_IOMGR_ENDPOINT_H #define GRPC_CORE_IOMGR_ENDPOINT_H -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/pollset_set.h" #include #include #include +#include "src/core/iomgr/pollset.h" +#include "src/core/iomgr/pollset_set.h" /* An endpoint caps a streaming channel between two communicating processes. Examples may be: a tcp socket, , or some shared memory. */ diff --git a/src/core/iomgr/endpoint_pair_posix.c b/src/core/iomgr/endpoint_pair_posix.c index f84b8441df..66d19a486c 100644 --- a/src/core/iomgr/endpoint_pair_posix.c +++ b/src/core/iomgr/endpoint_pair_posix.c @@ -42,14 +42,14 @@ #include #include #include -#include #include +#include -#include "src/core/iomgr/tcp_posix.h" -#include "src/core/support/string.h" #include #include #include +#include "src/core/iomgr/tcp_posix.h" +#include "src/core/support/string.h" static void create_sockets(int sv[2]) { int flags; diff --git a/src/core/iomgr/endpoint_pair_windows.c b/src/core/iomgr/endpoint_pair_windows.c index db9d092dca..13dcee3b59 100644 --- a/src/core/iomgr/endpoint_pair_windows.c +++ b/src/core/iomgr/endpoint_pair_windows.c @@ -34,16 +34,16 @@ #include #ifdef GPR_WINSOCK_SOCKET -#include "src/core/iomgr/sockaddr_utils.h" #include "src/core/iomgr/endpoint_pair.h" +#include "src/core/iomgr/sockaddr_utils.h" #include #include #include -#include "src/core/iomgr/tcp_windows.h" -#include "src/core/iomgr/socket_windows.h" #include +#include "src/core/iomgr/socket_windows.h" +#include "src/core/iomgr/tcp_windows.h" static void create_sockets(SOCKET sv[2]) { SOCKET svr_sock = INVALID_SOCKET; diff --git a/src/core/iomgr/fd_posix.h b/src/core/iomgr/fd_posix.h index a5c8ff1d9a..1993ada79f 100644 --- a/src/core/iomgr/fd_posix.h +++ b/src/core/iomgr/fd_posix.h @@ -34,11 +34,11 @@ #ifndef GRPC_CORE_IOMGR_FD_POSIX_H #define GRPC_CORE_IOMGR_FD_POSIX_H -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/pollset.h" #include #include #include +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/pollset.h" typedef struct grpc_fd grpc_fd; diff --git a/src/core/iomgr/iocp_windows.c b/src/core/iomgr/iocp_windows.c index fa87e5246b..37e277dcc1 100644 --- a/src/core/iomgr/iocp_windows.c +++ b/src/core/iomgr/iocp_windows.c @@ -37,15 +37,15 @@ #include +#include #include #include -#include #include -#include "src/core/iomgr/timer.h" #include "src/core/iomgr/iocp_windows.h" #include "src/core/iomgr/iomgr_internal.h" #include "src/core/iomgr/socket_windows.h" +#include "src/core/iomgr/timer.h" static ULONG g_iocp_kick_token; static OVERLAPPED g_iocp_custom_overlap; diff --git a/src/core/iomgr/iomgr_internal.h b/src/core/iomgr/iomgr_internal.h index d06b068b1c..1cad3182ec 100644 --- a/src/core/iomgr/iomgr_internal.h +++ b/src/core/iomgr/iomgr_internal.h @@ -36,8 +36,8 @@ #include -#include "src/core/iomgr/iomgr.h" #include +#include "src/core/iomgr/iomgr.h" typedef struct grpc_iomgr_object { char *name; diff --git a/src/core/iomgr/iomgr_posix.c b/src/core/iomgr/iomgr_posix.c index fecb7b9760..feb21d331f 100644 --- a/src/core/iomgr/iomgr_posix.c +++ b/src/core/iomgr/iomgr_posix.c @@ -35,9 +35,9 @@ #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/iomgr_posix.h" #include "src/core/debug/trace.h" #include "src/core/iomgr/fd_posix.h" +#include "src/core/iomgr/iomgr_posix.h" #include "src/core/iomgr/tcp_posix.h" void grpc_iomgr_platform_init(void) { diff --git a/src/core/iomgr/iomgr_windows.c b/src/core/iomgr/iomgr_windows.c index 14775516bb..6de41b3c41 100644 --- a/src/core/iomgr/iomgr_windows.c +++ b/src/core/iomgr/iomgr_windows.c @@ -39,9 +39,9 @@ #include -#include "src/core/iomgr/socket_windows.h" #include "src/core/iomgr/iocp_windows.h" #include "src/core/iomgr/iomgr.h" +#include "src/core/iomgr/socket_windows.h" /* Windows' io manager is going to be fully designed using IO completion ports. All of what we're doing here is basically make sure that diff --git a/src/core/iomgr/pollset_windows.c b/src/core/iomgr/pollset_windows.c index c7f30f435f..1a99224c80 100644 --- a/src/core/iomgr/pollset_windows.c +++ b/src/core/iomgr/pollset_windows.c @@ -38,8 +38,8 @@ #include #include -#include "src/core/iomgr/iomgr_internal.h" #include "src/core/iomgr/iocp_windows.h" +#include "src/core/iomgr/iomgr_internal.h" #include "src/core/iomgr/pollset.h" #include "src/core/iomgr/pollset_windows.h" diff --git a/src/core/iomgr/sockaddr_posix.h b/src/core/iomgr/sockaddr_posix.h index e4425ed735..a398096837 100644 --- a/src/core/iomgr/sockaddr_posix.h +++ b/src/core/iomgr/sockaddr_posix.h @@ -35,10 +35,10 @@ #define GRPC_CORE_IOMGR_SOCKADDR_POSIX_H #include +#include +#include #include #include -#include -#include #include #endif /* GRPC_CORE_IOMGR_SOCKADDR_POSIX_H */ diff --git a/src/core/iomgr/sockaddr_win32.h b/src/core/iomgr/sockaddr_win32.h index 7acb8f7f57..bdec72c761 100644 --- a/src/core/iomgr/sockaddr_win32.h +++ b/src/core/iomgr/sockaddr_win32.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_IOMGR_SOCKADDR_WIN32_H #define GRPC_CORE_IOMGR_SOCKADDR_WIN32_H +#include #include #include -#include #endif /* GRPC_CORE_IOMGR_SOCKADDR_WIN32_H */ diff --git a/src/core/iomgr/socket_utils_common_posix.c b/src/core/iomgr/socket_utils_common_posix.c index a9af594700..772a17bd50 100644 --- a/src/core/iomgr/socket_utils_common_posix.c +++ b/src/core/iomgr/socket_utils_common_posix.c @@ -38,23 +38,23 @@ #include "src/core/iomgr/socket_utils_posix.h" #include -#include +#include #include +#include #include #include #include -#include +#include #include +#include #include -#include -#include -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/support/string.h" #include #include #include #include +#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/support/string.h" /* set a socket to non blocking mode */ int grpc_set_socket_nonblocking(int fd, int non_blocking) { diff --git a/src/core/iomgr/socket_utils_linux.c b/src/core/iomgr/socket_utils_linux.c index a87625262b..5b9a236122 100644 --- a/src/core/iomgr/socket_utils_linux.c +++ b/src/core/iomgr/socket_utils_linux.c @@ -37,8 +37,8 @@ #include "src/core/iomgr/socket_utils_posix.h" -#include #include +#include int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int nonblock, int cloexec) { diff --git a/src/core/iomgr/socket_utils_posix.h b/src/core/iomgr/socket_utils_posix.h index b01e28b6f2..3908550380 100644 --- a/src/core/iomgr/socket_utils_posix.h +++ b/src/core/iomgr/socket_utils_posix.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_IOMGR_SOCKET_UTILS_POSIX_H #define GRPC_CORE_IOMGR_SOCKET_UTILS_POSIX_H -#include #include +#include /* a wrapper for accept or accept4 */ int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, diff --git a/src/core/iomgr/socket_windows.c b/src/core/iomgr/socket_windows.c index fafb7b6622..7096d25920 100644 --- a/src/core/iomgr/socket_windows.c +++ b/src/core/iomgr/socket_windows.c @@ -35,8 +35,8 @@ #ifdef GPR_WINSOCK_SOCKET -#include #include +#include #include #include diff --git a/src/core/iomgr/socket_windows.h b/src/core/iomgr/socket_windows.h index 8e50e7a953..6fe3c6e080 100644 --- a/src/core/iomgr/socket_windows.h +++ b/src/core/iomgr/socket_windows.h @@ -37,11 +37,11 @@ #include #include -#include #include +#include -#include "src/core/iomgr/iomgr_internal.h" #include "src/core/iomgr/exec_ctx.h" +#include "src/core/iomgr/iomgr_internal.h" /* This holds the data for an outstanding read or write on a socket. The mutex to protect the concurrent access to that data is the one diff --git a/src/core/iomgr/tcp_client.h b/src/core/iomgr/tcp_client.h index 2e29833b70..c36f8de713 100644 --- a/src/core/iomgr/tcp_client.h +++ b/src/core/iomgr/tcp_client.h @@ -34,10 +34,10 @@ #ifndef GRPC_CORE_IOMGR_TCP_CLIENT_H #define GRPC_CORE_IOMGR_TCP_CLIENT_H +#include #include "src/core/iomgr/endpoint.h" #include "src/core/iomgr/pollset_set.h" #include "src/core/iomgr/sockaddr.h" -#include /* Asynchronously connect to an address (specified as (addr, len)), and call cb with arg and the completed connection when done (or call cb with arg and diff --git a/src/core/iomgr/tcp_client_windows.c b/src/core/iomgr/tcp_client_windows.c index 689c6f7b10..da83f7b79c 100644 --- a/src/core/iomgr/tcp_client_windows.c +++ b/src/core/iomgr/tcp_client_windows.c @@ -43,13 +43,13 @@ #include #include -#include "src/core/iomgr/timer.h" #include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/iomgr/tcp_windows.h" #include "src/core/iomgr/sockaddr.h" #include "src/core/iomgr/sockaddr_utils.h" #include "src/core/iomgr/socket_windows.h" +#include "src/core/iomgr/tcp_client.h" +#include "src/core/iomgr/tcp_windows.h" +#include "src/core/iomgr/timer.h" typedef struct { grpc_closure *on_done; diff --git a/src/core/iomgr/tcp_posix.c b/src/core/iomgr/tcp_posix.c index f74eb3fe51..e8f73811ce 100644 --- a/src/core/iomgr/tcp_posix.c +++ b/src/core/iomgr/tcp_posix.c @@ -297,7 +297,7 @@ static flush_result tcp_flush(grpc_tcp *tcp) { unwind_slice_idx = tcp->outgoing_slice_idx; unwind_byte_idx = tcp->outgoing_byte_idx; for (iov_size = 0; tcp->outgoing_slice_idx != tcp->outgoing_buffer->count && - iov_size != MAX_WRITE_IOVEC; + iov_size != MAX_WRITE_IOVEC; iov_size++) { iov[iov_size].iov_base = GPR_SLICE_START_PTR( @@ -446,7 +446,7 @@ static char *tcp_get_peer(grpc_endpoint *ep) { } static const grpc_endpoint_vtable vtable = { - tcp_read, tcp_write, tcp_add_to_pollset, tcp_add_to_pollset_set, + tcp_read, tcp_write, tcp_add_to_pollset, tcp_add_to_pollset_set, tcp_shutdown, tcp_destroy, tcp_get_peer}; grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size, diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c index 11508044dc..74ee68a6f1 100644 --- a/src/core/iomgr/tcp_server_posix.c +++ b/src/core/iomgr/tcp_server_posix.c @@ -54,6 +54,11 @@ #include #include +#include +#include +#include +#include +#include #include "src/core/iomgr/pollset_posix.h" #include "src/core/iomgr/resolve_address.h" #include "src/core/iomgr/sockaddr_utils.h" @@ -61,11 +66,6 @@ #include "src/core/iomgr/tcp_posix.h" #include "src/core/iomgr/unix_sockets_posix.h" #include "src/core/support/string.h" -#include -#include -#include -#include -#include #define MIN_SAFE_ACCEPT_QUEUE_SIZE 100 diff --git a/src/core/iomgr/tcp_windows.c b/src/core/iomgr/tcp_windows.c index a165e9c79d..9b1db5fa7e 100644 --- a/src/core/iomgr/tcp_windows.c +++ b/src/core/iomgr/tcp_windows.c @@ -44,12 +44,12 @@ #include #include -#include "src/core/iomgr/timer.h" #include "src/core/iomgr/iocp_windows.h" #include "src/core/iomgr/sockaddr.h" #include "src/core/iomgr/sockaddr_utils.h" #include "src/core/iomgr/socket_windows.h" #include "src/core/iomgr/tcp_client.h" +#include "src/core/iomgr/timer.h" static int set_non_block(SOCKET sock) { int status; @@ -382,9 +382,9 @@ static char *win_get_peer(grpc_endpoint *ep) { return gpr_strdup(tcp->peer_string); } -static grpc_endpoint_vtable vtable = {win_read, win_write, win_add_to_pollset, - win_add_to_pollset_set, win_shutdown, - win_destroy, win_get_peer}; +static grpc_endpoint_vtable vtable = { + win_read, win_write, win_add_to_pollset, win_add_to_pollset_set, + win_shutdown, win_destroy, win_get_peer}; grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket, char *peer_string) { grpc_tcp *tcp = (grpc_tcp *)gpr_malloc(sizeof(grpc_tcp)); diff --git a/src/core/iomgr/timer.h b/src/core/iomgr/timer.h index 63505df427..1e2d1cbfbd 100644 --- a/src/core/iomgr/timer.h +++ b/src/core/iomgr/timer.h @@ -34,10 +34,10 @@ #ifndef GRPC_CORE_IOMGR_TIMER_H #define GRPC_CORE_IOMGR_TIMER_H -#include "src/core/iomgr/iomgr.h" -#include "src/core/iomgr/exec_ctx.h" #include #include +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/iomgr/iomgr.h" typedef struct grpc_timer { gpr_timespec deadline; diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c index e7853af58a..174159170f 100644 --- a/src/core/iomgr/udp_server.c +++ b/src/core/iomgr/udp_server.c @@ -54,6 +54,12 @@ #include #include +#include +#include +#include +#include +#include +#include #include "src/core/iomgr/fd_posix.h" #include "src/core/iomgr/pollset_posix.h" #include "src/core/iomgr/resolve_address.h" @@ -61,12 +67,6 @@ #include "src/core/iomgr/socket_utils_posix.h" #include "src/core/iomgr/unix_sockets_posix.h" #include "src/core/support/string.h" -#include -#include -#include -#include -#include -#include #define INIT_PORT_CAP 2 diff --git a/src/core/iomgr/unix_sockets_posix.c b/src/core/iomgr/unix_sockets_posix.c index 480ff613f6..174a7e7abf 100644 --- a/src/core/iomgr/unix_sockets_posix.c +++ b/src/core/iomgr/unix_sockets_posix.c @@ -36,8 +36,8 @@ #ifdef GPR_HAVE_UNIX_SOCKET #include -#include #include +#include #include #include diff --git a/src/core/iomgr/wakeup_fd_nospecial.c b/src/core/iomgr/wakeup_fd_nospecial.c index 78d763c103..1ec3d9b3f7 100644 --- a/src/core/iomgr/wakeup_fd_nospecial.c +++ b/src/core/iomgr/wakeup_fd_nospecial.c @@ -40,8 +40,8 @@ #ifdef GPR_POSIX_NO_SPECIAL_WAKEUP_FD -#include "src/core/iomgr/wakeup_fd_posix.h" #include +#include "src/core/iomgr/wakeup_fd_posix.h" static int check_availability_invalid(void) { return 0; } diff --git a/src/core/iomgr/wakeup_fd_posix.c b/src/core/iomgr/wakeup_fd_posix.c index f40be081b0..c0cfe3129a 100644 --- a/src/core/iomgr/wakeup_fd_posix.c +++ b/src/core/iomgr/wakeup_fd_posix.c @@ -35,9 +35,9 @@ #ifdef GPR_POSIX_WAKEUP_FD -#include "src/core/iomgr/wakeup_fd_posix.h" -#include "src/core/iomgr/wakeup_fd_pipe.h" #include +#include "src/core/iomgr/wakeup_fd_pipe.h" +#include "src/core/iomgr/wakeup_fd_posix.h" static const grpc_wakeup_fd_vtable *wakeup_fd_vtable = NULL; int grpc_allow_specialized_wakeup_fd = 1; diff --git a/src/core/iomgr/workqueue.h b/src/core/iomgr/workqueue.h index 2ba1e5d9a2..2b923ba152 100644 --- a/src/core/iomgr/workqueue.h +++ b/src/core/iomgr/workqueue.h @@ -34,10 +34,10 @@ #ifndef GRPC_CORE_IOMGR_WORKQUEUE_H #define GRPC_CORE_IOMGR_WORKQUEUE_H -#include "src/core/iomgr/iomgr.h" -#include "src/core/iomgr/pollset.h" #include "src/core/iomgr/closure.h" #include "src/core/iomgr/exec_ctx.h" +#include "src/core/iomgr/iomgr.h" +#include "src/core/iomgr/pollset.h" #ifdef GPR_POSIX_SOCKET #include "src/core/iomgr/workqueue_posix.h" diff --git a/src/core/json/json_string.c b/src/core/json/json_string.c index 2bc0b513d5..cb4f76a6b6 100644 --- a/src/core/json/json_string.c +++ b/src/core/json/json_string.c @@ -31,8 +31,8 @@ * */ -#include #include +#include #include #include diff --git a/src/core/profiling/basic_timers.c b/src/core/profiling/basic_timers.c index df32472d1c..0b6f6b78ee 100644 --- a/src/core/profiling/basic_timers.c +++ b/src/core/profiling/basic_timers.c @@ -39,9 +39,9 @@ #include #include -#include #include #include +#include #include typedef enum { BEGIN = '{', END = '}', MARK = '.' } marker_type; diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c index 332d4259d2..e2c23ef98d 100644 --- a/src/core/security/client_auth_filter.c +++ b/src/core/security/client_auth_filter.c @@ -331,6 +331,6 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, const grpc_channel_filter grpc_client_auth_filter = { auth_start_transport_op, grpc_channel_next_op, sizeof(call_data), - init_call_elem, set_pollset, destroy_call_elem, sizeof(channel_data), - init_channel_elem, destroy_channel_elem, grpc_call_next_get_peer, - "client-auth"}; + init_call_elem, set_pollset, destroy_call_elem, + sizeof(channel_data), init_channel_elem, destroy_channel_elem, + grpc_call_next_get_peer, "client-auth"}; diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index 0ba6d5dd84..c8348bc12c 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -38,8 +38,8 @@ #include "src/core/channel/channel_args.h" #include "src/core/channel/http_client_filter.h" -#include "src/core/http/parser.h" #include "src/core/http/httpcli.h" +#include "src/core/http/parser.h" #include "src/core/iomgr/executor.h" #include "src/core/json/json.h" #include "src/core/support/string.h" diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h index afac7a5bf2..bfa7cc71bd 100644 --- a/src/core/security/credentials.h +++ b/src/core/security/credentials.h @@ -34,10 +34,10 @@ #ifndef GRPC_CORE_SECURITY_CREDENTIALS_H #define GRPC_CORE_SECURITY_CREDENTIALS_H -#include "src/core/transport/metadata_batch.h" #include #include #include +#include "src/core/transport/metadata_batch.h" #include "src/core/http/httpcli.h" #include "src/core/http/parser.h" diff --git a/src/core/security/handshake.c b/src/core/security/handshake.c index b5bb6667a7..9fb10a0ecb 100644 --- a/src/core/security/handshake.c +++ b/src/core/security/handshake.c @@ -36,11 +36,11 @@ #include #include -#include "src/core/security/security_context.h" -#include "src/core/security/secure_endpoint.h" #include #include #include +#include "src/core/security/secure_endpoint.h" +#include "src/core/security/security_context.h" #define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256 diff --git a/src/core/security/secure_endpoint.c b/src/core/security/secure_endpoint.c index d11c43be20..58b081dc4a 100644 --- a/src/core/security/secure_endpoint.c +++ b/src/core/security/secure_endpoint.c @@ -32,14 +32,14 @@ */ #include "src/core/security/secure_endpoint.h" -#include "src/core/support/string.h" #include #include -#include #include +#include #include -#include "src/core/tsi/transport_security_interface.h" #include "src/core/debug/trace.h" +#include "src/core/support/string.h" +#include "src/core/tsi/transport_security_interface.h" #define STAGING_BUFFER_SIZE 8192 @@ -354,8 +354,9 @@ static char *endpoint_get_peer(grpc_endpoint *secure_ep) { } static const grpc_endpoint_vtable vtable = { - endpoint_read, endpoint_write, endpoint_add_to_pollset, - endpoint_add_to_pollset_set, endpoint_shutdown, endpoint_destroy, + endpoint_read, endpoint_write, + endpoint_add_to_pollset, endpoint_add_to_pollset_set, + endpoint_shutdown, endpoint_destroy, endpoint_get_peer}; grpc_endpoint *grpc_secure_endpoint_create( diff --git a/src/core/security/secure_endpoint.h b/src/core/security/secure_endpoint.h index 5176ef2059..7368f8424b 100644 --- a/src/core/security/secure_endpoint.h +++ b/src/core/security/secure_endpoint.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_SECURITY_SECURE_ENDPOINT_H #define GRPC_CORE_SECURITY_SECURE_ENDPOINT_H -#include "src/core/iomgr/endpoint.h" #include +#include "src/core/iomgr/endpoint.h" struct tsi_frame_protector; diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index a71b3bc915..f6afc0f633 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -34,9 +34,9 @@ #include #include "src/core/security/security_context.h" +#include "src/core/support/string.h" #include "src/core/surface/api_trace.h" #include "src/core/surface/call.h" -#include "src/core/support/string.h" #include #include diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c index 3d8e5e8d35..f3c411d6d4 100644 --- a/src/core/security/server_auth_filter.c +++ b/src/core/security/server_auth_filter.c @@ -259,6 +259,6 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, const grpc_channel_filter grpc_server_auth_filter = { auth_start_transport_op, grpc_channel_next_op, sizeof(call_data), - init_call_elem, set_pollset, destroy_call_elem, sizeof(channel_data), - init_channel_elem, destroy_channel_elem, grpc_call_next_get_peer, - "server-auth"}; + init_call_elem, set_pollset, destroy_call_elem, + sizeof(channel_data), init_channel_elem, destroy_channel_elem, + grpc_call_next_get_peer, "server-auth"}; diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index 009ec95682..da29ca934b 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -35,6 +35,10 @@ #include +#include +#include +#include +#include #include "src/core/channel/channel_args.h" #include "src/core/channel/http_server_filter.h" #include "src/core/iomgr/endpoint.h" @@ -47,10 +51,6 @@ #include "src/core/surface/api_trace.h" #include "src/core/surface/server.h" #include "src/core/transport/chttp2_transport.h" -#include -#include -#include -#include typedef struct grpc_server_secure_state { grpc_server *server; diff --git a/src/core/statistics/census_log.c b/src/core/statistics/census_log.c index 257ba586a3..6368b09ed9 100644 --- a/src/core/statistics/census_log.c +++ b/src/core/statistics/census_log.c @@ -90,7 +90,6 @@ argument. E.g. cl_block_initialize() will initialize a cl_block. */ #include "src/core/statistics/census_log.h" -#include #include #include #include @@ -98,6 +97,7 @@ #include #include #include +#include /* End of platform specific code */ diff --git a/src/core/statistics/census_rpc_stats.c b/src/core/statistics/census_rpc_stats.c index 524a60793a..01778cd0b0 100644 --- a/src/core/statistics/census_rpc_stats.c +++ b/src/core/statistics/census_rpc_stats.c @@ -33,16 +33,16 @@ #include +#include +#include +#include #include "src/core/statistics/census_interface.h" #include "src/core/statistics/census_rpc_stats.h" -#include "src/core/statistics/hash_table.h" #include "src/core/statistics/census_tracing.h" +#include "src/core/statistics/hash_table.h" #include "src/core/statistics/window_stats.h" #include "src/core/support/murmur_hash.h" #include "src/core/support/string.h" -#include -#include -#include #define NUM_INTERVALS 3 #define MINUTE_INTERVAL 0 @@ -85,8 +85,8 @@ static void delete_key(void *key) { gpr_free(key); } static const census_ht_option ht_opt = { CENSUS_HT_POINTER /* key type */, 1999 /* n_of_buckets */, - simple_hash /* hash function */, cmp_str_keys /* key comparator */, - delete_stats /* data deleter */, delete_key /* key deleter */ + simple_hash /* hash function */, cmp_str_keys /* key comparator */, + delete_stats /* data deleter */, delete_key /* key deleter */ }; static void init_rpc_stats(void *stats) { diff --git a/src/core/statistics/census_rpc_stats.h b/src/core/statistics/census_rpc_stats.h index 4cf17d2e52..f7f220e45f 100644 --- a/src/core/statistics/census_rpc_stats.h +++ b/src/core/statistics/census_rpc_stats.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_STATISTICS_CENSUS_RPC_STATS_H #define GRPC_CORE_STATISTICS_CENSUS_RPC_STATS_H -#include "src/core/statistics/census_interface.h" #include +#include "src/core/statistics/census_interface.h" #ifdef __cplusplus extern "C" { diff --git a/src/core/statistics/census_tracing.c b/src/core/statistics/census_tracing.c index dc0f8a26f5..a7841f5ebd 100644 --- a/src/core/statistics/census_tracing.c +++ b/src/core/statistics/census_tracing.c @@ -31,18 +31,18 @@ * */ -#include "src/core/statistics/census_interface.h" #include "src/core/statistics/census_tracing.h" +#include "src/core/statistics/census_interface.h" #include #include -#include "src/core/statistics/hash_table.h" -#include "src/core/support/string.h" #include #include #include #include +#include "src/core/statistics/hash_table.h" +#include "src/core/support/string.h" void census_trace_obj_destroy(census_trace_obj *obj) { census_trace_annotation *p = obj->annotations; @@ -60,8 +60,11 @@ static void delete_trace_obj(void *obj) { } static const census_ht_option ht_opt = { - CENSUS_HT_UINT64 /* key type */, 571 /* n_of_buckets */, NULL /* hash */, - NULL /* compare_keys */, delete_trace_obj /* delete data */, + CENSUS_HT_UINT64 /* key type */, + 571 /* n_of_buckets */, + NULL /* hash */, + NULL /* compare_keys */, + delete_trace_obj /* delete data */, NULL /* delete key */ }; diff --git a/src/core/statistics/hash_table.c b/src/core/statistics/hash_table.c index 0cadcd4740..26d83c801d 100644 --- a/src/core/statistics/hash_table.c +++ b/src/core/statistics/hash_table.c @@ -33,11 +33,11 @@ #include "src/core/statistics/hash_table.h" -#include #include +#include -#include #include +#include #include #define CENSUS_HT_NUM_BUCKETS 1999 diff --git a/src/core/statistics/window_stats.c b/src/core/statistics/window_stats.c index 3f2940853a..51425a20ee 100644 --- a/src/core/statistics/window_stats.c +++ b/src/core/statistics/window_stats.c @@ -32,13 +32,13 @@ */ #include "src/core/statistics/window_stats.h" -#include -#include -#include #include #include #include #include +#include +#include +#include /* typedefs make typing long names easier. Use cws (for census_window_stats) */ typedef census_window_stats_stat_info cws_stat_info; diff --git a/src/core/support/alloc.c b/src/core/support/alloc.c index b99584bd20..fd9fb8f5e7 100644 --- a/src/core/support/alloc.c +++ b/src/core/support/alloc.c @@ -33,9 +33,9 @@ #include -#include #include #include +#include #include "src/core/profiling/timers.h" static gpr_allocation_functions g_alloc_functions = {malloc, realloc, free}; diff --git a/src/core/support/cmdline.c b/src/core/support/cmdline.c index b517f30b2d..4f1b165d6f 100644 --- a/src/core/support/cmdline.c +++ b/src/core/support/cmdline.c @@ -37,10 +37,10 @@ #include #include -#include "src/core/support/string.h" #include #include #include +#include "src/core/support/string.h" typedef enum { ARGTYPE_INT, ARGTYPE_BOOL, ARGTYPE_STRING } argtype; diff --git a/src/core/support/cpu_linux.c b/src/core/support/cpu_linux.c index 7af6a8f009..d6f7e7d3da 100644 --- a/src/core/support/cpu_linux.c +++ b/src/core/support/cpu_linux.c @@ -39,10 +39,10 @@ #ifdef GPR_CPU_LINUX -#include #include -#include +#include #include +#include #include #include diff --git a/src/core/support/cpu_posix.c b/src/core/support/cpu_posix.c index 8f01c284ca..e508ddd8ca 100644 --- a/src/core/support/cpu_posix.c +++ b/src/core/support/cpu_posix.c @@ -36,8 +36,8 @@ #ifdef GPR_CPU_POSIX #include -#include #include +#include #include #include diff --git a/src/core/support/env_posix.c b/src/core/support/env_posix.c index 1dd2af56bc..68cdf123ac 100644 --- a/src/core/support/env_posix.c +++ b/src/core/support/env_posix.c @@ -41,8 +41,8 @@ #include -#include "src/core/support/string.h" #include +#include "src/core/support/string.h" char *gpr_getenv(const char *name) { char *result = getenv(name); diff --git a/src/core/support/histogram.c b/src/core/support/histogram.c index 20ed2b14b1..7b016bbc78 100644 --- a/src/core/support/histogram.c +++ b/src/core/support/histogram.c @@ -38,8 +38,8 @@ #include #include -#include #include +#include #include /* Histograms are stored with exponentially increasing bucket sizes. diff --git a/src/core/support/host_port.c b/src/core/support/host_port.c index 23f65b1581..f28ed4b0c2 100644 --- a/src/core/support/host_port.c +++ b/src/core/support/host_port.c @@ -35,10 +35,10 @@ #include -#include "src/core/support/string.h" #include #include #include +#include "src/core/support/string.h" int gpr_join_host_port(char **out, const char *host, int port) { if (host[0] != '[' && strchr(host, ':') != NULL) { diff --git a/src/core/support/log_android.c b/src/core/support/log_android.c index 5d0c7d820d..94c8100fd7 100644 --- a/src/core/support/log_android.c +++ b/src/core/support/log_android.c @@ -35,12 +35,12 @@ #ifdef GPR_ANDROID +#include #include #include -#include #include +#include #include -#include static android_LogPriority severity_to_log_priority(gpr_log_severity severity) { switch (severity) { diff --git a/src/core/support/log_linux.c b/src/core/support/log_linux.c index d66b7a3cc0..6d4b63bbe0 100644 --- a/src/core/support/log_linux.c +++ b/src/core/support/log_linux.c @@ -47,12 +47,12 @@ #include #include #include -#include +#include #include +#include #include -#include -#include #include +#include #include static long gettid(void) { return syscall(__NR_gettid); } diff --git a/src/core/support/log_posix.c b/src/core/support/log_posix.c index 3ff171f99c..6ae6320767 100644 --- a/src/core/support/log_posix.c +++ b/src/core/support/log_posix.c @@ -38,12 +38,12 @@ #include #include #include -#include +#include #include -#include #include +#include +#include #include -#include static intptr_t gettid(void) { return (intptr_t)pthread_self(); } diff --git a/src/core/support/log_win32.c b/src/core/support/log_win32.c index e18e667fe5..89ec0917d5 100644 --- a/src/core/support/log_win32.c +++ b/src/core/support/log_win32.c @@ -35,14 +35,14 @@ #ifdef GPR_WIN32 -#include #include +#include #include -#include #include -#include +#include #include +#include #include "src/core/support/string.h" #include "src/core/support/string_win32.h" diff --git a/src/core/support/stack_lockfree.c b/src/core/support/stack_lockfree.c index 9daecd2e18..51d1c42eb4 100644 --- a/src/core/support/stack_lockfree.c +++ b/src/core/support/stack_lockfree.c @@ -36,10 +36,10 @@ #include #include -#include #include #include #include +#include /* The lockfree node structure is a single architecture-level word that allows for an atomic CAS to set it up. */ @@ -67,7 +67,7 @@ typedef union lockfree_node { #define ENTRY_ALIGNMENT_BITS 3 /* make sure that entries aligned to 8-bytes */ #define INVALID_ENTRY_INDEX \ ((1 << 16) - 1) /* reserve this entry as invalid \ - */ + */ struct gpr_stack_lockfree { lockfree_node *entries; diff --git a/src/core/support/string.h b/src/core/support/string.h index a367ed7cd8..8ff16882ab 100644 --- a/src/core/support/string.h +++ b/src/core/support/string.h @@ -37,8 +37,8 @@ #include #include -#include #include +#include #ifdef __cplusplus extern "C" { diff --git a/src/core/support/string_posix.c b/src/core/support/string_posix.c index 25c333db4e..c804ed5ded 100644 --- a/src/core/support/string_posix.c +++ b/src/core/support/string_posix.c @@ -35,8 +35,8 @@ #ifdef GPR_POSIX_STRING -#include #include +#include #include #include diff --git a/src/core/support/string_win32.c b/src/core/support/string_win32.c index 3b1f702cf1..0780907994 100644 --- a/src/core/support/string_win32.c +++ b/src/core/support/string_win32.c @@ -37,8 +37,8 @@ #ifdef GPR_WIN32 -#include #include +#include #include #include diff --git a/src/core/support/subprocess_posix.c b/src/core/support/subprocess_posix.c index 171054e4da..4f4de9298e 100644 --- a/src/core/support/subprocess_posix.c +++ b/src/core/support/subprocess_posix.c @@ -37,15 +37,15 @@ #include -#include #include #include -#include -#include #include +#include #include +#include #include #include +#include #include #include diff --git a/src/core/support/subprocess_windows.c b/src/core/support/subprocess_windows.c index 2b25ef063a..6afbefeb2b 100644 --- a/src/core/support/subprocess_windows.c +++ b/src/core/support/subprocess_windows.c @@ -35,9 +35,9 @@ #ifdef GPR_WINDOWS_SUBPROCESS -#include #include #include +#include #include #include diff --git a/src/core/support/sync.c b/src/core/support/sync.c index 69e3e39c5c..800cf20287 100644 --- a/src/core/support/sync.c +++ b/src/core/support/sync.c @@ -33,9 +33,9 @@ /* Generic implementation of synchronization primitives. */ +#include #include #include -#include /* Number of mutexes to allocate for events, to avoid lock contention. Should be a prime. */ diff --git a/src/core/support/sync_posix.c b/src/core/support/sync_posix.c index d3c483f1b5..be4d0ac1c9 100644 --- a/src/core/support/sync_posix.c +++ b/src/core/support/sync_posix.c @@ -36,10 +36,10 @@ #ifdef GPR_POSIX_SYNC #include -#include #include #include #include +#include #include "src/core/profiling/timers.h" void gpr_mu_init(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_init(mu, NULL) == 0); } diff --git a/src/core/support/thd_posix.c b/src/core/support/thd_posix.c index 653a1c88c1..89832e3ce1 100644 --- a/src/core/support/thd_posix.c +++ b/src/core/support/thd_posix.c @@ -37,13 +37,13 @@ #ifdef GPR_POSIX_SYNC -#include -#include -#include #include #include #include #include +#include +#include +#include struct thd_arg { void (*body)(void *arg); /* body of a thread */ diff --git a/src/core/support/thd_win32.c b/src/core/support/thd_win32.c index a9db180c1b..6deb3140eb 100644 --- a/src/core/support/thd_win32.c +++ b/src/core/support/thd_win32.c @@ -37,10 +37,10 @@ #ifdef GPR_WIN32 -#include #include #include #include +#include #if defined(_MSC_VER) #define thread_local __declspec(thread) diff --git a/src/core/support/time.c b/src/core/support/time.c index 423d12ffc0..0e2c8fcf1a 100644 --- a/src/core/support/time.c +++ b/src/core/support/time.c @@ -33,11 +33,11 @@ /* Generic implementation of time calls. */ +#include #include #include #include #include -#include int gpr_time_cmp(gpr_timespec a, gpr_timespec b) { int cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec); diff --git a/src/core/support/time_posix.c b/src/core/support/time_posix.c index 36d75e7da2..f999e08cb0 100644 --- a/src/core/support/time_posix.c +++ b/src/core/support/time_posix.c @@ -98,9 +98,9 @@ gpr_timespec gpr_now(gpr_clock_type clock_type) { #else /* For some reason Apple's OSes haven't implemented clock_gettime. */ -#include #include #include +#include static double g_time_scale; static uint64_t g_time_start; diff --git a/src/core/support/time_win32.c b/src/core/support/time_win32.c index 8af957e6f4..2c344d3f3b 100644 --- a/src/core/support/time_win32.c +++ b/src/core/support/time_win32.c @@ -39,10 +39,10 @@ #include #include +#include +#include #include #include -#include -#include #include "src/core/support/block_annotate.h" diff --git a/src/core/surface/alarm.c b/src/core/surface/alarm.c index 8169ede065..1085285f95 100644 --- a/src/core/surface/alarm.c +++ b/src/core/surface/alarm.c @@ -31,10 +31,10 @@ * */ -#include "src/core/iomgr/timer.h" -#include "src/core/surface/completion_queue.h" #include #include +#include "src/core/iomgr/timer.h" +#include "src/core/surface/completion_queue.h" struct grpc_alarm { grpc_timer alarm; diff --git a/src/core/surface/api_trace.h b/src/core/surface/api_trace.h index 29a9b2d79c..af53829de4 100644 --- a/src/core/surface/api_trace.h +++ b/src/core/surface/api_trace.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_SURFACE_API_TRACE_H #define GRPC_CORE_SURFACE_API_TRACE_H -#include "src/core/debug/trace.h" #include +#include "src/core/debug/trace.h" extern int grpc_api_trace; diff --git a/src/core/surface/byte_buffer_reader.c b/src/core/surface/byte_buffer_reader.c index 4679854227..edecddbced 100644 --- a/src/core/surface/byte_buffer_reader.c +++ b/src/core/surface/byte_buffer_reader.c @@ -31,15 +31,15 @@ * */ -#include #include +#include +#include #include #include #include #include #include -#include #include "src/core/compression/message_compress.h" diff --git a/src/core/surface/call_log_batch.c b/src/core/surface/call_log_batch.c index 46756f418b..1006a26157 100644 --- a/src/core/surface/call_log_batch.c +++ b/src/core/surface/call_log_batch.c @@ -33,9 +33,9 @@ #include "src/core/surface/call.h" -#include "src/core/support/string.h" #include #include +#include "src/core/support/string.h" static void add_metadata(gpr_strvec *b, const grpc_metadata *md, size_t count) { size_t i; diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c index 964ab34431..0010b64c7d 100644 --- a/src/core/surface/channel.c +++ b/src/core/surface/channel.c @@ -40,12 +40,12 @@ #include #include -#include "src/core/surface/channel_init.h" #include "src/core/client_config/resolver_registry.h" #include "src/core/iomgr/iomgr.h" #include "src/core/support/string.h" #include "src/core/surface/api_trace.h" #include "src/core/surface/call.h" +#include "src/core/surface/channel_init.h" #include "src/core/surface/init.h" #include "src/core/transport/static_metadata.h" diff --git a/src/core/surface/channel.h b/src/core/surface/channel.h index c08988d9e7..6a803ffe23 100644 --- a/src/core/surface/channel.h +++ b/src/core/surface/channel.h @@ -35,8 +35,8 @@ #define GRPC_CORE_SURFACE_CHANNEL_H #include "src/core/channel/channel_stack.h" -#include "src/core/surface/channel_stack_type.h" #include "src/core/client_config/subchannel_factory.h" +#include "src/core/surface/channel_stack_type.h" grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, const grpc_channel_args *args, diff --git a/src/core/surface/channel_stack_type.c b/src/core/surface/channel_stack_type.c index 29bb7704f8..1a6e949ffe 100644 --- a/src/core/surface/channel_stack_type.c +++ b/src/core/surface/channel_stack_type.c @@ -31,9 +31,9 @@ * */ -#include #include "src/core/surface/channel_stack_type.h" #include +#include bool grpc_channel_stack_type_is_client(grpc_channel_stack_type type) { switch (type) { diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h index 07f6d0c8f6..213d89c079 100644 --- a/src/core/surface/completion_queue.h +++ b/src/core/surface/completion_queue.h @@ -36,8 +36,8 @@ /* Internal API for completion queues */ -#include "src/core/iomgr/pollset.h" #include +#include "src/core/iomgr/pollset.h" typedef struct grpc_cq_completion { /** user supplied tag */ diff --git a/src/core/surface/event_string.c b/src/core/surface/event_string.c index 33cd4a43aa..17752715bc 100644 --- a/src/core/surface/event_string.c +++ b/src/core/surface/event_string.c @@ -35,9 +35,9 @@ #include -#include "src/core/support/string.h" #include #include +#include "src/core/support/string.h" static void addhdr(gpr_strvec *buf, grpc_event *ev) { char *tmp; diff --git a/src/core/surface/init.c b/src/core/surface/init.c index 233572a9f3..3c4db3e6cc 100644 --- a/src/core/surface/init.c +++ b/src/core/surface/init.c @@ -42,14 +42,14 @@ /* TODO(ctiller): find another way? - better not to include census here */ #include "src/core/census/grpc_plugin.h" #include "src/core/channel/channel_stack.h" +#include "src/core/channel/client_channel.h" #include "src/core/channel/compress_filter.h" #include "src/core/channel/connected_channel.h" -#include "src/core/channel/client_channel.h" #include "src/core/channel/http_client_filter.h" #include "src/core/channel/http_server_filter.h" -#include "src/core/client_config/lb_policy_registry.h" #include "src/core/client_config/lb_policies/pick_first.h" #include "src/core/client_config/lb_policies/round_robin.h" +#include "src/core/client_config/lb_policy_registry.h" #include "src/core/client_config/resolver_registry.h" #include "src/core/client_config/resolvers/dns_resolver.h" #include "src/core/client_config/resolvers/sockaddr_resolver.h" diff --git a/src/core/surface/init_secure.c b/src/core/surface/init_secure.c index 311dda9864..e0d66a8d46 100644 --- a/src/core/surface/init_secure.c +++ b/src/core/surface/init_secure.c @@ -36,12 +36,12 @@ #include #include -#include "src/core/surface/channel_init.h" #include "src/core/debug/trace.h" #include "src/core/security/auth_filters.h" #include "src/core/security/credentials.h" #include "src/core/security/secure_endpoint.h" #include "src/core/security/security_connector.h" +#include "src/core/surface/channel_init.h" #include "src/core/tsi/transport_security_interface.h" void grpc_security_pre_init(void) { diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c index 58f89946d2..25f3a74349 100644 --- a/src/core/surface/lame_client.c +++ b/src/core/surface/lame_client.c @@ -37,13 +37,13 @@ #include +#include +#include #include "src/core/channel/channel_stack.h" #include "src/core/support/string.h" #include "src/core/surface/api_trace.h" -#include "src/core/surface/channel.h" #include "src/core/surface/call.h" -#include -#include +#include "src/core/surface/channel.h" typedef struct { grpc_linked_mdelem status; @@ -118,10 +118,17 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) {} const grpc_channel_filter grpc_lame_filter = { - lame_start_transport_stream_op, lame_start_transport_op, sizeof(call_data), - init_call_elem, grpc_call_stack_ignore_set_pollset, destroy_call_elem, - sizeof(channel_data), init_channel_elem, destroy_channel_elem, - lame_get_peer, "lame-client", + lame_start_transport_stream_op, + lame_start_transport_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + lame_get_peer, + "lame-client", }; #define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c) + 1)) diff --git a/src/core/surface/server.c b/src/core/surface/server.c index da93474b26..a92f2b3e38 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -754,10 +754,17 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, } const grpc_channel_filter grpc_server_top_filter = { - server_start_transport_stream_op, grpc_channel_next_op, sizeof(call_data), - init_call_elem, grpc_call_stack_ignore_set_pollset, destroy_call_elem, - sizeof(channel_data), init_channel_elem, destroy_channel_elem, - grpc_call_next_get_peer, "server", + server_start_transport_stream_op, + grpc_channel_next_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "server", }; void grpc_server_register_completion_queue(grpc_server *server, @@ -895,7 +902,8 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s, channel = grpc_channel_create(exec_ctx, NULL, args, GRPC_SERVER_CHANNEL, transport); chand = (channel_data *)grpc_channel_stack_element( - grpc_channel_get_channel_stack(channel), 0)->channel_data; + grpc_channel_get_channel_stack(channel), 0) + ->channel_data; chand->server = s; server_ref(s); chand->channel = channel; @@ -916,7 +924,7 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s, method = grpc_mdstr_from_string(rm->method); hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash); for (probes = 0; chand->registered_methods[(hash + probes) % slots] - .server_registered_method != NULL; + .server_registered_method != NULL; probes++) ; if (probes > max_probes) max_probes = probes; diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c index ff2840f655..546760ecfa 100644 --- a/src/core/surface/server_chttp2.c +++ b/src/core/surface/server_chttp2.c @@ -33,15 +33,15 @@ #include +#include +#include +#include #include "src/core/channel/http_server_filter.h" #include "src/core/iomgr/resolve_address.h" #include "src/core/iomgr/tcp_server.h" #include "src/core/surface/api_trace.h" #include "src/core/surface/server.h" #include "src/core/transport/chttp2_transport.h" -#include -#include -#include static void setup_transport(grpc_exec_ctx *exec_ctx, void *server, grpc_transport *transport) { diff --git a/src/core/surface/surface_trace.h b/src/core/surface/surface_trace.h index ed820ebd05..a55a88e44d 100644 --- a/src/core/surface/surface_trace.h +++ b/src/core/surface/surface_trace.h @@ -34,9 +34,9 @@ #ifndef GRPC_CORE_SURFACE_SURFACE_TRACE_H #define GRPC_CORE_SURFACE_SURFACE_TRACE_H +#include #include "src/core/debug/trace.h" #include "src/core/surface/api_trace.h" -#include #define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \ if (grpc_api_trace) { \ diff --git a/src/core/transport/byte_stream.h b/src/core/transport/byte_stream.h index b8d0ade2b5..ab42d07e7e 100644 --- a/src/core/transport/byte_stream.h +++ b/src/core/transport/byte_stream.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_TRANSPORT_BYTE_STREAM_H #define GRPC_CORE_TRANSPORT_BYTE_STREAM_H -#include "src/core/iomgr/exec_ctx.h" #include +#include "src/core/iomgr/exec_ctx.h" /** Internal bit flag for grpc_begin_message's \a flags signaling the use of * compression for the message */ diff --git a/src/core/transport/chttp2/bin_encoder.c b/src/core/transport/chttp2/bin_encoder.c index f26bc7e29b..3d31162499 100644 --- a/src/core/transport/chttp2/bin_encoder.c +++ b/src/core/transport/chttp2/bin_encoder.c @@ -35,8 +35,8 @@ #include -#include "src/core/transport/chttp2/huffsyms.h" #include +#include "src/core/transport/chttp2/huffsyms.h" static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -46,70 +46,18 @@ typedef struct { uint8_t length; } b64_huff_sym; -static const b64_huff_sym huff_alphabet[64] = {{0x21, 6}, - {0x5d, 7}, - {0x5e, 7}, - {0x5f, 7}, - {0x60, 7}, - {0x61, 7}, - {0x62, 7}, - {0x63, 7}, - {0x64, 7}, - {0x65, 7}, - {0x66, 7}, - {0x67, 7}, - {0x68, 7}, - {0x69, 7}, - {0x6a, 7}, - {0x6b, 7}, - {0x6c, 7}, - {0x6d, 7}, - {0x6e, 7}, - {0x6f, 7}, - {0x70, 7}, - {0x71, 7}, - {0x72, 7}, - {0xfc, 8}, - {0x73, 7}, - {0xfd, 8}, - {0x3, 5}, - {0x23, 6}, - {0x4, 5}, - {0x24, 6}, - {0x5, 5}, - {0x25, 6}, - {0x26, 6}, - {0x27, 6}, - {0x6, 5}, - {0x74, 7}, - {0x75, 7}, - {0x28, 6}, - {0x29, 6}, - {0x2a, 6}, - {0x7, 5}, - {0x2b, 6}, - {0x76, 7}, - {0x2c, 6}, - {0x8, 5}, - {0x9, 5}, - {0x2d, 6}, - {0x77, 7}, - {0x78, 7}, - {0x79, 7}, - {0x7a, 7}, - {0x7b, 7}, - {0x0, 5}, - {0x1, 5}, - {0x2, 5}, - {0x19, 6}, - {0x1a, 6}, - {0x1b, 6}, - {0x1c, 6}, - {0x1d, 6}, - {0x1e, 6}, - {0x1f, 6}, - {0x7fb, 11}, - {0x18, 6}}; +static const b64_huff_sym huff_alphabet[64] = { + {0x21, 6}, {0x5d, 7}, {0x5e, 7}, {0x5f, 7}, {0x60, 7}, {0x61, 7}, + {0x62, 7}, {0x63, 7}, {0x64, 7}, {0x65, 7}, {0x66, 7}, {0x67, 7}, + {0x68, 7}, {0x69, 7}, {0x6a, 7}, {0x6b, 7}, {0x6c, 7}, {0x6d, 7}, + {0x6e, 7}, {0x6f, 7}, {0x70, 7}, {0x71, 7}, {0x72, 7}, {0xfc, 8}, + {0x73, 7}, {0xfd, 8}, {0x3, 5}, {0x23, 6}, {0x4, 5}, {0x24, 6}, + {0x5, 5}, {0x25, 6}, {0x26, 6}, {0x27, 6}, {0x6, 5}, {0x74, 7}, + {0x75, 7}, {0x28, 6}, {0x29, 6}, {0x2a, 6}, {0x7, 5}, {0x2b, 6}, + {0x76, 7}, {0x2c, 6}, {0x8, 5}, {0x9, 5}, {0x2d, 6}, {0x77, 7}, + {0x78, 7}, {0x79, 7}, {0x7a, 7}, {0x7b, 7}, {0x0, 5}, {0x1, 5}, + {0x2, 5}, {0x19, 6}, {0x1a, 6}, {0x1b, 6}, {0x1c, 6}, {0x1d, 6}, + {0x1e, 6}, {0x1f, 6}, {0x7fb, 11}, {0x18, 6}}; static const uint8_t tail_xtra[3] = {0, 2, 3}; diff --git a/src/core/transport/chttp2/frame_data.c b/src/core/transport/chttp2/frame_data.c index f9a1af8873..d801ac664f 100644 --- a/src/core/transport/chttp2/frame_data.c +++ b/src/core/transport/chttp2/frame_data.c @@ -35,11 +35,11 @@ #include -#include "src/core/transport/chttp2/internal.h" -#include "src/core/support/string.h" #include #include #include +#include "src/core/support/string.h" +#include "src/core/transport/chttp2/internal.h" #include "src/core/transport/transport.h" grpc_chttp2_parse_error grpc_chttp2_data_parser_init( diff --git a/src/core/transport/chttp2/frame_data.h b/src/core/transport/chttp2/frame_data.h index 92929d5c97..9dbaa60d44 100644 --- a/src/core/transport/chttp2/frame_data.h +++ b/src/core/transport/chttp2/frame_data.h @@ -36,9 +36,9 @@ /* Parser for GRPC streams embedded in DATA frames */ -#include "src/core/iomgr/exec_ctx.h" #include #include +#include "src/core/iomgr/exec_ctx.h" #include "src/core/transport/byte_stream.h" #include "src/core/transport/chttp2/frame.h" diff --git a/src/core/transport/chttp2/frame_goaway.h b/src/core/transport/chttp2/frame_goaway.h index 616287e9ee..b980e47723 100644 --- a/src/core/transport/chttp2/frame_goaway.h +++ b/src/core/transport/chttp2/frame_goaway.h @@ -34,11 +34,11 @@ #ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H #define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" #include #include #include +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/transport/chttp2/frame.h" typedef enum { GRPC_CHTTP2_GOAWAY_LSI0, diff --git a/src/core/transport/chttp2/frame_ping.h b/src/core/transport/chttp2/frame_ping.h index fc4dd7ac58..2412cd7a6f 100644 --- a/src/core/transport/chttp2/frame_ping.h +++ b/src/core/transport/chttp2/frame_ping.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_PING_H #define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_PING_H -#include "src/core/iomgr/exec_ctx.h" #include +#include "src/core/iomgr/exec_ctx.h" #include "src/core/transport/chttp2/frame.h" typedef struct { diff --git a/src/core/transport/chttp2/frame_rst_stream.h b/src/core/transport/chttp2/frame_rst_stream.h index d563a22e24..f725c5d767 100644 --- a/src/core/transport/chttp2/frame_rst_stream.h +++ b/src/core/transport/chttp2/frame_rst_stream.h @@ -35,8 +35,8 @@ #define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H #include -#include "src/core/transport/chttp2/frame.h" #include "src/core/iomgr/exec_ctx.h" +#include "src/core/transport/chttp2/frame.h" typedef struct { uint8_t byte; diff --git a/src/core/transport/chttp2/frame_settings.h b/src/core/transport/chttp2/frame_settings.h index e3c10d3cc5..59dbff9b40 100644 --- a/src/core/transport/chttp2/frame_settings.h +++ b/src/core/transport/chttp2/frame_settings.h @@ -36,8 +36,8 @@ #include #include -#include "src/core/transport/chttp2/frame.h" #include "src/core/iomgr/exec_ctx.h" +#include "src/core/transport/chttp2/frame.h" typedef enum { GRPC_CHTTP2_SPS_ID0, diff --git a/src/core/transport/chttp2/frame_window_update.h b/src/core/transport/chttp2/frame_window_update.h index 0b3712b091..9b7ca3ce63 100644 --- a/src/core/transport/chttp2/frame_window_update.h +++ b/src/core/transport/chttp2/frame_window_update.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H #define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H -#include "src/core/iomgr/exec_ctx.h" #include +#include "src/core/iomgr/exec_ctx.h" #include "src/core/transport/chttp2/frame.h" typedef struct { diff --git a/src/core/transport/chttp2/hpack_encoder.h b/src/core/transport/chttp2/hpack_encoder.h index 90aaf867c5..6d86eb7c83 100644 --- a/src/core/transport/chttp2/hpack_encoder.h +++ b/src/core/transport/chttp2/hpack_encoder.h @@ -34,12 +34,12 @@ #ifndef GRPC_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H #define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H -#include "src/core/transport/chttp2/frame.h" -#include "src/core/transport/metadata.h" -#include "src/core/transport/metadata_batch.h" #include #include #include +#include "src/core/transport/chttp2/frame.h" +#include "src/core/transport/metadata.h" +#include "src/core/transport/metadata_batch.h" #define GRPC_CHTTP2_HPACKC_NUM_FILTERS 256 #define GRPC_CHTTP2_HPACKC_NUM_VALUES 256 diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c index a63c7db1f6..b6e36923cb 100644 --- a/src/core/transport/chttp2/hpack_parser.c +++ b/src/core/transport/chttp2/hpack_parser.c @@ -34,9 +34,9 @@ #include "src/core/transport/chttp2/hpack_parser.h" #include "src/core/transport/chttp2/internal.h" +#include #include #include -#include /* This is here for grpc_is_binary_header * TODO(murgatroid99): Remove this diff --git a/src/core/transport/chttp2/hpack_table.h b/src/core/transport/chttp2/hpack_table.h index 6e1b5e66b5..c984ca35e4 100644 --- a/src/core/transport/chttp2/hpack_table.h +++ b/src/core/transport/chttp2/hpack_table.h @@ -34,9 +34,9 @@ #ifndef GRPC_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H #define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H -#include "src/core/transport/metadata.h" #include #include +#include "src/core/transport/metadata.h" /* HPACK header table */ diff --git a/src/core/transport/chttp2/huffsyms.c b/src/core/transport/chttp2/huffsyms.c index 7b138e9b5d..6f5cf6a2a9 100644 --- a/src/core/transport/chttp2/huffsyms.c +++ b/src/core/transport/chttp2/huffsyms.c @@ -37,261 +37,69 @@ command: :%s/.* \([0-9a-f]\+\) \[ *\([0-9]\+\)\]/{0x\1, \2},/g */ const grpc_chttp2_huffsym grpc_chttp2_huffsyms[GRPC_CHTTP2_NUM_HUFFSYMS] = { - {0x1ff8, 13}, - {0x7fffd8, 23}, - {0xfffffe2, 28}, - {0xfffffe3, 28}, - {0xfffffe4, 28}, - {0xfffffe5, 28}, - {0xfffffe6, 28}, - {0xfffffe7, 28}, - {0xfffffe8, 28}, - {0xffffea, 24}, - {0x3ffffffc, 30}, - {0xfffffe9, 28}, - {0xfffffea, 28}, - {0x3ffffffd, 30}, - {0xfffffeb, 28}, - {0xfffffec, 28}, - {0xfffffed, 28}, - {0xfffffee, 28}, - {0xfffffef, 28}, - {0xffffff0, 28}, - {0xffffff1, 28}, - {0xffffff2, 28}, - {0x3ffffffe, 30}, - {0xffffff3, 28}, - {0xffffff4, 28}, - {0xffffff5, 28}, - {0xffffff6, 28}, - {0xffffff7, 28}, - {0xffffff8, 28}, - {0xffffff9, 28}, - {0xffffffa, 28}, - {0xffffffb, 28}, - {0x14, 6}, - {0x3f8, 10}, - {0x3f9, 10}, - {0xffa, 12}, - {0x1ff9, 13}, - {0x15, 6}, - {0xf8, 8}, - {0x7fa, 11}, - {0x3fa, 10}, - {0x3fb, 10}, - {0xf9, 8}, - {0x7fb, 11}, - {0xfa, 8}, - {0x16, 6}, - {0x17, 6}, - {0x18, 6}, - {0x0, 5}, - {0x1, 5}, - {0x2, 5}, - {0x19, 6}, - {0x1a, 6}, - {0x1b, 6}, - {0x1c, 6}, - {0x1d, 6}, - {0x1e, 6}, - {0x1f, 6}, - {0x5c, 7}, - {0xfb, 8}, - {0x7ffc, 15}, - {0x20, 6}, - {0xffb, 12}, - {0x3fc, 10}, - {0x1ffa, 13}, - {0x21, 6}, - {0x5d, 7}, - {0x5e, 7}, - {0x5f, 7}, - {0x60, 7}, - {0x61, 7}, - {0x62, 7}, - {0x63, 7}, - {0x64, 7}, - {0x65, 7}, - {0x66, 7}, - {0x67, 7}, - {0x68, 7}, - {0x69, 7}, - {0x6a, 7}, - {0x6b, 7}, - {0x6c, 7}, - {0x6d, 7}, - {0x6e, 7}, - {0x6f, 7}, - {0x70, 7}, - {0x71, 7}, - {0x72, 7}, - {0xfc, 8}, - {0x73, 7}, - {0xfd, 8}, - {0x1ffb, 13}, - {0x7fff0, 19}, - {0x1ffc, 13}, - {0x3ffc, 14}, - {0x22, 6}, - {0x7ffd, 15}, - {0x3, 5}, - {0x23, 6}, - {0x4, 5}, - {0x24, 6}, - {0x5, 5}, - {0x25, 6}, - {0x26, 6}, - {0x27, 6}, - {0x6, 5}, - {0x74, 7}, - {0x75, 7}, - {0x28, 6}, - {0x29, 6}, - {0x2a, 6}, - {0x7, 5}, - {0x2b, 6}, - {0x76, 7}, - {0x2c, 6}, - {0x8, 5}, - {0x9, 5}, - {0x2d, 6}, - {0x77, 7}, - {0x78, 7}, - {0x79, 7}, - {0x7a, 7}, - {0x7b, 7}, - {0x7ffe, 15}, - {0x7fc, 11}, - {0x3ffd, 14}, - {0x1ffd, 13}, - {0xffffffc, 28}, - {0xfffe6, 20}, - {0x3fffd2, 22}, - {0xfffe7, 20}, - {0xfffe8, 20}, - {0x3fffd3, 22}, - {0x3fffd4, 22}, - {0x3fffd5, 22}, - {0x7fffd9, 23}, - {0x3fffd6, 22}, - {0x7fffda, 23}, - {0x7fffdb, 23}, - {0x7fffdc, 23}, - {0x7fffdd, 23}, - {0x7fffde, 23}, - {0xffffeb, 24}, - {0x7fffdf, 23}, - {0xffffec, 24}, - {0xffffed, 24}, - {0x3fffd7, 22}, - {0x7fffe0, 23}, - {0xffffee, 24}, - {0x7fffe1, 23}, - {0x7fffe2, 23}, - {0x7fffe3, 23}, - {0x7fffe4, 23}, - {0x1fffdc, 21}, - {0x3fffd8, 22}, - {0x7fffe5, 23}, - {0x3fffd9, 22}, - {0x7fffe6, 23}, - {0x7fffe7, 23}, - {0xffffef, 24}, - {0x3fffda, 22}, - {0x1fffdd, 21}, - {0xfffe9, 20}, - {0x3fffdb, 22}, - {0x3fffdc, 22}, - {0x7fffe8, 23}, - {0x7fffe9, 23}, - {0x1fffde, 21}, - {0x7fffea, 23}, - {0x3fffdd, 22}, - {0x3fffde, 22}, - {0xfffff0, 24}, - {0x1fffdf, 21}, - {0x3fffdf, 22}, - {0x7fffeb, 23}, - {0x7fffec, 23}, - {0x1fffe0, 21}, - {0x1fffe1, 21}, - {0x3fffe0, 22}, - {0x1fffe2, 21}, - {0x7fffed, 23}, - {0x3fffe1, 22}, - {0x7fffee, 23}, - {0x7fffef, 23}, - {0xfffea, 20}, - {0x3fffe2, 22}, - {0x3fffe3, 22}, - {0x3fffe4, 22}, - {0x7ffff0, 23}, - {0x3fffe5, 22}, - {0x3fffe6, 22}, - {0x7ffff1, 23}, - {0x3ffffe0, 26}, - {0x3ffffe1, 26}, - {0xfffeb, 20}, - {0x7fff1, 19}, - {0x3fffe7, 22}, - {0x7ffff2, 23}, - {0x3fffe8, 22}, - {0x1ffffec, 25}, - {0x3ffffe2, 26}, - {0x3ffffe3, 26}, - {0x3ffffe4, 26}, - {0x7ffffde, 27}, - {0x7ffffdf, 27}, - {0x3ffffe5, 26}, - {0xfffff1, 24}, - {0x1ffffed, 25}, - {0x7fff2, 19}, - {0x1fffe3, 21}, - {0x3ffffe6, 26}, - {0x7ffffe0, 27}, - {0x7ffffe1, 27}, - {0x3ffffe7, 26}, - {0x7ffffe2, 27}, - {0xfffff2, 24}, - {0x1fffe4, 21}, - {0x1fffe5, 21}, - {0x3ffffe8, 26}, - {0x3ffffe9, 26}, - {0xffffffd, 28}, - {0x7ffffe3, 27}, - {0x7ffffe4, 27}, - {0x7ffffe5, 27}, - {0xfffec, 20}, - {0xfffff3, 24}, - {0xfffed, 20}, - {0x1fffe6, 21}, - {0x3fffe9, 22}, - {0x1fffe7, 21}, - {0x1fffe8, 21}, - {0x7ffff3, 23}, - {0x3fffea, 22}, - {0x3fffeb, 22}, - {0x1ffffee, 25}, - {0x1ffffef, 25}, - {0xfffff4, 24}, - {0xfffff5, 24}, - {0x3ffffea, 26}, - {0x7ffff4, 23}, - {0x3ffffeb, 26}, - {0x7ffffe6, 27}, - {0x3ffffec, 26}, - {0x3ffffed, 26}, - {0x7ffffe7, 27}, - {0x7ffffe8, 27}, - {0x7ffffe9, 27}, - {0x7ffffea, 27}, - {0x7ffffeb, 27}, - {0xffffffe, 28}, - {0x7ffffec, 27}, - {0x7ffffed, 27}, - {0x7ffffee, 27}, - {0x7ffffef, 27}, - {0x7fffff0, 27}, - {0x3ffffee, 26}, + {0x1ff8, 13}, {0x7fffd8, 23}, {0xfffffe2, 28}, {0xfffffe3, 28}, + {0xfffffe4, 28}, {0xfffffe5, 28}, {0xfffffe6, 28}, {0xfffffe7, 28}, + {0xfffffe8, 28}, {0xffffea, 24}, {0x3ffffffc, 30}, {0xfffffe9, 28}, + {0xfffffea, 28}, {0x3ffffffd, 30}, {0xfffffeb, 28}, {0xfffffec, 28}, + {0xfffffed, 28}, {0xfffffee, 28}, {0xfffffef, 28}, {0xffffff0, 28}, + {0xffffff1, 28}, {0xffffff2, 28}, {0x3ffffffe, 30}, {0xffffff3, 28}, + {0xffffff4, 28}, {0xffffff5, 28}, {0xffffff6, 28}, {0xffffff7, 28}, + {0xffffff8, 28}, {0xffffff9, 28}, {0xffffffa, 28}, {0xffffffb, 28}, + {0x14, 6}, {0x3f8, 10}, {0x3f9, 10}, {0xffa, 12}, + {0x1ff9, 13}, {0x15, 6}, {0xf8, 8}, {0x7fa, 11}, + {0x3fa, 10}, {0x3fb, 10}, {0xf9, 8}, {0x7fb, 11}, + {0xfa, 8}, {0x16, 6}, {0x17, 6}, {0x18, 6}, + {0x0, 5}, {0x1, 5}, {0x2, 5}, {0x19, 6}, + {0x1a, 6}, {0x1b, 6}, {0x1c, 6}, {0x1d, 6}, + {0x1e, 6}, {0x1f, 6}, {0x5c, 7}, {0xfb, 8}, + {0x7ffc, 15}, {0x20, 6}, {0xffb, 12}, {0x3fc, 10}, + {0x1ffa, 13}, {0x21, 6}, {0x5d, 7}, {0x5e, 7}, + {0x5f, 7}, {0x60, 7}, {0x61, 7}, {0x62, 7}, + {0x63, 7}, {0x64, 7}, {0x65, 7}, {0x66, 7}, + {0x67, 7}, {0x68, 7}, {0x69, 7}, {0x6a, 7}, + {0x6b, 7}, {0x6c, 7}, {0x6d, 7}, {0x6e, 7}, + {0x6f, 7}, {0x70, 7}, {0x71, 7}, {0x72, 7}, + {0xfc, 8}, {0x73, 7}, {0xfd, 8}, {0x1ffb, 13}, + {0x7fff0, 19}, {0x1ffc, 13}, {0x3ffc, 14}, {0x22, 6}, + {0x7ffd, 15}, {0x3, 5}, {0x23, 6}, {0x4, 5}, + {0x24, 6}, {0x5, 5}, {0x25, 6}, {0x26, 6}, + {0x27, 6}, {0x6, 5}, {0x74, 7}, {0x75, 7}, + {0x28, 6}, {0x29, 6}, {0x2a, 6}, {0x7, 5}, + {0x2b, 6}, {0x76, 7}, {0x2c, 6}, {0x8, 5}, + {0x9, 5}, {0x2d, 6}, {0x77, 7}, {0x78, 7}, + {0x79, 7}, {0x7a, 7}, {0x7b, 7}, {0x7ffe, 15}, + {0x7fc, 11}, {0x3ffd, 14}, {0x1ffd, 13}, {0xffffffc, 28}, + {0xfffe6, 20}, {0x3fffd2, 22}, {0xfffe7, 20}, {0xfffe8, 20}, + {0x3fffd3, 22}, {0x3fffd4, 22}, {0x3fffd5, 22}, {0x7fffd9, 23}, + {0x3fffd6, 22}, {0x7fffda, 23}, {0x7fffdb, 23}, {0x7fffdc, 23}, + {0x7fffdd, 23}, {0x7fffde, 23}, {0xffffeb, 24}, {0x7fffdf, 23}, + {0xffffec, 24}, {0xffffed, 24}, {0x3fffd7, 22}, {0x7fffe0, 23}, + {0xffffee, 24}, {0x7fffe1, 23}, {0x7fffe2, 23}, {0x7fffe3, 23}, + {0x7fffe4, 23}, {0x1fffdc, 21}, {0x3fffd8, 22}, {0x7fffe5, 23}, + {0x3fffd9, 22}, {0x7fffe6, 23}, {0x7fffe7, 23}, {0xffffef, 24}, + {0x3fffda, 22}, {0x1fffdd, 21}, {0xfffe9, 20}, {0x3fffdb, 22}, + {0x3fffdc, 22}, {0x7fffe8, 23}, {0x7fffe9, 23}, {0x1fffde, 21}, + {0x7fffea, 23}, {0x3fffdd, 22}, {0x3fffde, 22}, {0xfffff0, 24}, + {0x1fffdf, 21}, {0x3fffdf, 22}, {0x7fffeb, 23}, {0x7fffec, 23}, + {0x1fffe0, 21}, {0x1fffe1, 21}, {0x3fffe0, 22}, {0x1fffe2, 21}, + {0x7fffed, 23}, {0x3fffe1, 22}, {0x7fffee, 23}, {0x7fffef, 23}, + {0xfffea, 20}, {0x3fffe2, 22}, {0x3fffe3, 22}, {0x3fffe4, 22}, + {0x7ffff0, 23}, {0x3fffe5, 22}, {0x3fffe6, 22}, {0x7ffff1, 23}, + {0x3ffffe0, 26}, {0x3ffffe1, 26}, {0xfffeb, 20}, {0x7fff1, 19}, + {0x3fffe7, 22}, {0x7ffff2, 23}, {0x3fffe8, 22}, {0x1ffffec, 25}, + {0x3ffffe2, 26}, {0x3ffffe3, 26}, {0x3ffffe4, 26}, {0x7ffffde, 27}, + {0x7ffffdf, 27}, {0x3ffffe5, 26}, {0xfffff1, 24}, {0x1ffffed, 25}, + {0x7fff2, 19}, {0x1fffe3, 21}, {0x3ffffe6, 26}, {0x7ffffe0, 27}, + {0x7ffffe1, 27}, {0x3ffffe7, 26}, {0x7ffffe2, 27}, {0xfffff2, 24}, + {0x1fffe4, 21}, {0x1fffe5, 21}, {0x3ffffe8, 26}, {0x3ffffe9, 26}, + {0xffffffd, 28}, {0x7ffffe3, 27}, {0x7ffffe4, 27}, {0x7ffffe5, 27}, + {0xfffec, 20}, {0xfffff3, 24}, {0xfffed, 20}, {0x1fffe6, 21}, + {0x3fffe9, 22}, {0x1fffe7, 21}, {0x1fffe8, 21}, {0x7ffff3, 23}, + {0x3fffea, 22}, {0x3fffeb, 22}, {0x1ffffee, 25}, {0x1ffffef, 25}, + {0xfffff4, 24}, {0xfffff5, 24}, {0x3ffffea, 26}, {0x7ffff4, 23}, + {0x3ffffeb, 26}, {0x7ffffe6, 27}, {0x3ffffec, 26}, {0x3ffffed, 26}, + {0x7ffffe7, 27}, {0x7ffffe8, 27}, {0x7ffffe9, 27}, {0x7ffffea, 27}, + {0x7ffffeb, 27}, {0xffffffe, 28}, {0x7ffffec, 27}, {0x7ffffed, 27}, + {0x7ffffee, 27}, {0x7ffffef, 27}, {0x7fffff0, 27}, {0x3ffffee, 26}, {0x3fffffff, 30}, }; diff --git a/src/core/transport/chttp2/timeout_encoding.h b/src/core/transport/chttp2/timeout_encoding.h index 81bae8e936..f8e25226eb 100644 --- a/src/core/transport/chttp2/timeout_encoding.h +++ b/src/core/transport/chttp2/timeout_encoding.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H #define GRPC_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H -#include "src/core/support/string.h" #include +#include "src/core/support/string.h" #define GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1) diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index b16768d06e..b45bf31997 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -1398,8 +1398,8 @@ static void recv_data(grpc_exec_ctx *exec_ctx, void *tp, bool success) { gpr_mu_unlock(&t->mu); GPR_TIMER_BEGIN("recv_data.parse", 0); for (; i < t->read_buffer.count && - grpc_chttp2_perform_read(exec_ctx, transport_parsing, - t->read_buffer.slices[i]); + grpc_chttp2_perform_read(exec_ctx, transport_parsing, + t->read_buffer.slices[i]); i++) ; GPR_TIMER_END("recv_data.parse", 0); @@ -1474,9 +1474,10 @@ static void connectivity_state_set( grpc_connectivity_state state, const char *reason) { GRPC_CHTTP2_IF_TRACING( gpr_log(GPR_DEBUG, "set connectivity_state=%d", state)); - grpc_connectivity_state_set(exec_ctx, &TRANSPORT_FROM_GLOBAL(transport_global) - ->channel_callback.state_tracker, - state, reason); + grpc_connectivity_state_set( + exec_ctx, + &TRANSPORT_FROM_GLOBAL(transport_global)->channel_callback.state_tracker, + state, reason); } /******************************************************************************* @@ -1756,10 +1757,15 @@ static char *chttp2_get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *t) { return gpr_strdup(((grpc_chttp2_transport *)t)->peer_string); } -static const grpc_transport_vtable vtable = { - sizeof(grpc_chttp2_stream), "chttp2", init_stream, set_pollset, - perform_stream_op, perform_transport_op, destroy_stream, destroy_transport, - chttp2_get_peer}; +static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), + "chttp2", + init_stream, + set_pollset, + perform_stream_op, + perform_transport_op, + destroy_stream, + destroy_transport, + chttp2_get_peer}; grpc_transport *grpc_create_chttp2_transport( grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args, diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c index 807ae071a3..7ed28feca8 100644 --- a/src/core/transport/metadata.c +++ b/src/core/transport/metadata.c @@ -44,12 +44,12 @@ #include #include +#include "src/core/iomgr/iomgr_internal.h" #include "src/core/profiling/timers.h" #include "src/core/support/murmur_hash.h" #include "src/core/support/string.h" #include "src/core/transport/chttp2/bin_encoder.h" #include "src/core/transport/static_metadata.h" -#include "src/core/iomgr/iomgr_internal.h" /* There are two kinds of mdelem and mdstr instances. * Static instances are declared in static_metadata.{h,c} and diff --git a/src/core/transport/static_metadata.c b/src/core/transport/static_metadata.c index 84abb59e99..30bbb89880 100644 --- a/src/core/transport/static_metadata.c +++ b/src/core/transport/static_metadata.c @@ -66,24 +66,95 @@ const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] = 82, 83, 84, 35, 85, 35, 86, 35, 87, 35, 88, 35}; const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = { - "0", "1", "2", "200", "204", "206", "304", "400", "404", "500", "accept", - "accept-charset", "accept-encoding", "accept-language", "accept-ranges", - "access-control-allow-origin", "age", "allow", "application/grpc", - ":authority", "authorization", "cache-control", "census-bin", - "census-binary-bin", "content-disposition", "content-encoding", - "content-language", "content-length", "content-location", "content-range", - "content-type", "cookie", "date", "deflate", "deflate,gzip", "", "etag", - "expect", "expires", "from", "GET", "grpc", "grpc-accept-encoding", - "grpc-encoding", "grpc-internal-encoding-request", "grpc-message", - "grpc-status", "grpc-timeout", "gzip", "gzip, deflate", "host", "http", - "https", "identity", "identity,deflate", "identity,deflate,gzip", - "identity,gzip", "if-match", "if-modified-since", "if-none-match", - "if-range", "if-unmodified-since", "last-modified", "link", "location", - "max-forwards", ":method", ":path", "POST", "proxy-authenticate", - "proxy-authorization", "range", "referer", "refresh", "retry-after", - ":scheme", "server", "set-cookie", "/", "/index.html", ":status", - "strict-transport-security", "te", "trailers", "transfer-encoding", - "user-agent", "vary", "via", "www-authenticate"}; + "0", + "1", + "2", + "200", + "204", + "206", + "304", + "400", + "404", + "500", + "accept", + "accept-charset", + "accept-encoding", + "accept-language", + "accept-ranges", + "access-control-allow-origin", + "age", + "allow", + "application/grpc", + ":authority", + "authorization", + "cache-control", + "census-bin", + "census-binary-bin", + "content-disposition", + "content-encoding", + "content-language", + "content-length", + "content-location", + "content-range", + "content-type", + "cookie", + "date", + "deflate", + "deflate,gzip", + "", + "etag", + "expect", + "expires", + "from", + "GET", + "grpc", + "grpc-accept-encoding", + "grpc-encoding", + "grpc-internal-encoding-request", + "grpc-message", + "grpc-status", + "grpc-timeout", + "gzip", + "gzip, deflate", + "host", + "http", + "https", + "identity", + "identity,deflate", + "identity,deflate,gzip", + "identity,gzip", + "if-match", + "if-modified-since", + "if-none-match", + "if-range", + "if-unmodified-since", + "last-modified", + "link", + "location", + "max-forwards", + ":method", + ":path", + "POST", + "proxy-authenticate", + "proxy-authorization", + "range", + "referer", + "refresh", + "retry-after", + ":scheme", + "server", + "set-cookie", + "/", + "/index.html", + ":status", + "strict-transport-security", + "te", + "trailers", + "transfer-encoding", + "user-agent", + "vary", + "via", + "www-authenticate"}; const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 29, 26, 30, 28, 32, 27, 31}; diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h index 0f068dcb38..f43e56f23c 100644 --- a/src/core/transport/transport.h +++ b/src/core/transport/transport.h @@ -36,11 +36,11 @@ #include +#include "src/core/channel/context.h" #include "src/core/iomgr/pollset.h" #include "src/core/iomgr/pollset_set.h" -#include "src/core/transport/metadata_batch.h" #include "src/core/transport/byte_stream.h" -#include "src/core/channel/context.h" +#include "src/core/transport/metadata_batch.h" /* forward declarations */ typedef struct grpc_transport grpc_transport; diff --git a/src/core/transport/transport_op_string.c b/src/core/transport/transport_op_string.c index 98b51afc88..08eda360c6 100644 --- a/src/core/transport/transport_op_string.c +++ b/src/core/transport/transport_op_string.c @@ -37,10 +37,10 @@ #include #include -#include "src/core/support/string.h" #include #include #include +#include "src/core/support/string.h" /* These routines are here to facilitate debugging - they produce string representations of various transport data structures */ diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c index 72ac32a171..7a9eb87470 100644 --- a/src/core/tsi/fake_transport_security.c +++ b/src/core/tsi/fake_transport_security.c @@ -493,8 +493,10 @@ static void fake_handshaker_destroy(tsi_handshaker *self) { static const tsi_handshaker_vtable handshaker_vtable = { fake_handshaker_get_bytes_to_send_to_peer, - fake_handshaker_process_bytes_from_peer, fake_handshaker_get_result, - fake_handshaker_extract_peer, fake_handshaker_create_frame_protector, + fake_handshaker_process_bytes_from_peer, + fake_handshaker_get_result, + fake_handshaker_extract_peer, + fake_handshaker_create_frame_protector, fake_handshaker_destroy, }; diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c index 42d25ca929..8df582609b 100644 --- a/src/core/tsi/ssl_transport_security.c +++ b/src/core/tsi/ssl_transport_security.c @@ -1039,8 +1039,10 @@ static void ssl_handshaker_destroy(tsi_handshaker *self) { static const tsi_handshaker_vtable handshaker_vtable = { ssl_handshaker_get_bytes_to_send_to_peer, - ssl_handshaker_process_bytes_from_peer, ssl_handshaker_get_result, - ssl_handshaker_extract_peer, ssl_handshaker_create_frame_protector, + ssl_handshaker_process_bytes_from_peer, + ssl_handshaker_get_result, + ssl_handshaker_extract_peer, + ssl_handshaker_create_frame_protector, ssl_handshaker_destroy, }; diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc index 73147fd7bb..db636a5456 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -33,13 +33,13 @@ #include +#include +#include +#include #include #include #include #include -#include -#include -#include #include "src/core/channel/compress_filter.h" #include "src/cpp/common/create_auth_context.h" diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 1293203b93..13019a7117 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -33,11 +33,11 @@ #include -#include -#include #include #include #include +#include +#include #include "src/cpp/client/create_channel_internal.h" namespace grpc { diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index c34b840f90..cdc8406f24 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -31,12 +31,12 @@ * */ +#include "src/cpp/client/secure_credentials.h" #include #include #include #include #include "src/cpp/client/create_channel_internal.h" -#include "src/cpp/client/secure_credentials.h" #include "src/cpp/common/secure_auth_context.h" namespace grpc { diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 9e84102154..fd82331a44 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -36,8 +36,8 @@ #include -#include #include +#include #include "src/cpp/server/thread_pool_interface.h" diff --git a/src/cpp/common/core_codegen.h b/src/cpp/common/core_codegen.h index 0d8c6b79f7..e15cb4c34a 100644 --- a/src/cpp/common/core_codegen.h +++ b/src/cpp/common/core_codegen.h @@ -34,8 +34,8 @@ // This file should be compiled as part of grpc++. #include -#include #include +#include namespace grpc { diff --git a/src/cpp/common/create_auth_context.h b/src/cpp/common/create_auth_context.h index 4f3da397ba..387407bfec 100644 --- a/src/cpp/common/create_auth_context.h +++ b/src/cpp/common/create_auth_context.h @@ -32,8 +32,8 @@ */ #include -#include #include +#include namespace grpc { diff --git a/src/cpp/common/insecure_create_auth_context.cc b/src/cpp/common/insecure_create_auth_context.cc index b2e153229a..258f02c2ad 100644 --- a/src/cpp/common/insecure_create_auth_context.cc +++ b/src/cpp/common/insecure_create_auth_context.cc @@ -32,8 +32,8 @@ */ #include -#include #include +#include namespace grpc { diff --git a/src/cpp/common/secure_create_auth_context.cc b/src/cpp/common/secure_create_auth_context.cc index 40bc298b64..51ddea46a3 100644 --- a/src/cpp/common/secure_create_auth_context.cc +++ b/src/cpp/common/secure_create_auth_context.cc @@ -32,9 +32,9 @@ */ #include +#include #include #include -#include #include "src/cpp/common/secure_auth_context.h" namespace grpc { diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 134e5f1d5f..1947d68e3e 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -33,10 +33,10 @@ #include -#include -#include #include #include +#include +#include #include "src/cpp/server/thread_pool_interface.h" namespace grpc { diff --git a/src/cpp/util/time.cc b/src/cpp/util/time.cc index 2685e31ee6..c43d848cc6 100644 --- a/src/cpp/util/time.cc +++ b/src/cpp/util/time.cc @@ -35,8 +35,8 @@ #ifndef GRPC_CXX0X_NO_CHRONO -#include #include +#include using std::chrono::duration_cast; using std::chrono::nanoseconds; diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c index ba1901301c..c7130f9580 100644 --- a/test/core/bad_client/bad_client.c +++ b/test/core/bad_client/bad_client.c @@ -36,9 +36,9 @@ #include "src/core/channel/channel_stack.h" #include "src/core/channel/http_server_filter.h" #include "src/core/iomgr/endpoint_pair.h" +#include "src/core/support/string.h" #include "src/core/surface/completion_queue.h" #include "src/core/surface/server.h" -#include "src/core/support/string.h" #include "src/core/transport/chttp2_transport.h" #include @@ -155,9 +155,9 @@ void grpc_run_bad_client_test(grpc_bad_client_server_side_validator validator, grpc_exec_ctx_finish(&exec_ctx); } grpc_server_shutdown_and_notify(a.server, a.cq, NULL); - GPR_ASSERT(grpc_completion_queue_pluck(a.cq, NULL, - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + a.cq, NULL, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(a.server); grpc_completion_queue_destroy(a.cq); gpr_slice_buffer_destroy(&outgoing); diff --git a/test/core/bad_client/tests/badreq.c b/test/core/bad_client/tests/badreq.c index 6d59d25b92..024a1e7953 100644 --- a/test/core/bad_client/tests/badreq.c +++ b/test/core/bad_client/tests/badreq.c @@ -35,8 +35,8 @@ #include -#include "test/core/end2end/cq_verifier.h" #include "src/core/surface/server.h" +#include "test/core/end2end/cq_verifier.h" #define PFX_STR \ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \ @@ -45,9 +45,9 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq, void *registered_method) { while (grpc_server_has_open_connections(server)) { - GPR_ASSERT(grpc_completion_queue_next(cq, - GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), - NULL).type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(grpc_completion_queue_next( + cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), NULL) + .type == GRPC_QUEUE_TIMEOUT); } } diff --git a/test/core/bad_client/tests/connection_prefix.c b/test/core/bad_client/tests/connection_prefix.c index 66ff8c2936..8d74124b19 100644 --- a/test/core/bad_client/tests/connection_prefix.c +++ b/test/core/bad_client/tests/connection_prefix.c @@ -31,15 +31,15 @@ * */ -#include "test/core/bad_client/bad_client.h" #include "src/core/surface/server.h" +#include "test/core/bad_client/bad_client.h" static void verifier(grpc_server *server, grpc_completion_queue *cq, void *registered_method) { while (grpc_server_has_open_connections(server)) { - GPR_ASSERT(grpc_completion_queue_next(cq, - GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), - NULL).type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(grpc_completion_queue_next( + cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), NULL) + .type == GRPC_QUEUE_TIMEOUT); } } diff --git a/test/core/bad_client/tests/headers.c b/test/core/bad_client/tests/headers.c index 2186a4ffcb..81a07de442 100644 --- a/test/core/bad_client/tests/headers.c +++ b/test/core/bad_client/tests/headers.c @@ -31,8 +31,8 @@ * */ -#include "test/core/bad_client/bad_client.h" #include "src/core/surface/server.h" +#include "test/core/bad_client/bad_client.h" #define PFX_STR \ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \ @@ -41,9 +41,9 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq, void *registered_method) { while (grpc_server_has_open_connections(server)) { - GPR_ASSERT(grpc_completion_queue_next(cq, - GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), - NULL).type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(grpc_completion_queue_next( + cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), NULL) + .type == GRPC_QUEUE_TIMEOUT); } } diff --git a/test/core/bad_client/tests/initial_settings_frame.c b/test/core/bad_client/tests/initial_settings_frame.c index fb6149cc3b..108b0bd398 100644 --- a/test/core/bad_client/tests/initial_settings_frame.c +++ b/test/core/bad_client/tests/initial_settings_frame.c @@ -31,8 +31,8 @@ * */ -#include "test/core/bad_client/bad_client.h" #include "src/core/surface/server.h" +#include "test/core/bad_client/bad_client.h" #define PFX_STR "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" #define ONE_SETTING_HDR "\x00\x00\x06\x04\x00\x00\x00\x00\x00" @@ -40,9 +40,9 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq, void *registered_method) { while (grpc_server_has_open_connections(server)) { - GPR_ASSERT(grpc_completion_queue_next(cq, - GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), - NULL).type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(grpc_completion_queue_next( + cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), NULL) + .type == GRPC_QUEUE_TIMEOUT); } } diff --git a/test/core/bad_client/tests/server_registered_method.c b/test/core/bad_client/tests/server_registered_method.c index dc6ecc51f0..19dfeb3355 100644 --- a/test/core/bad_client/tests/server_registered_method.c +++ b/test/core/bad_client/tests/server_registered_method.c @@ -35,8 +35,8 @@ #include -#include "test/core/end2end/cq_verifier.h" #include "src/core/surface/server.h" +#include "test/core/end2end/cq_verifier.h" #define PFX_STR \ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \ diff --git a/test/core/bad_client/tests/simple_request.c b/test/core/bad_client/tests/simple_request.c index c04319edc5..f90ffea188 100644 --- a/test/core/bad_client/tests/simple_request.c +++ b/test/core/bad_client/tests/simple_request.c @@ -35,8 +35,8 @@ #include -#include "test/core/end2end/cq_verifier.h" #include "src/core/surface/server.h" +#include "test/core/end2end/cq_verifier.h" #define PFX_STR \ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \ @@ -108,9 +108,9 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq, static void failure_verifier(grpc_server *server, grpc_completion_queue *cq, void *registered_method) { while (grpc_server_has_open_connections(server)) { - GPR_ASSERT(grpc_completion_queue_next(cq, - GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), - NULL).type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(grpc_completion_queue_next( + cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), NULL) + .type == GRPC_QUEUE_TIMEOUT); } } diff --git a/test/core/bad_client/tests/unknown_frame.c b/test/core/bad_client/tests/unknown_frame.c index 2ef340eeb5..cc8e2157f2 100644 --- a/test/core/bad_client/tests/unknown_frame.c +++ b/test/core/bad_client/tests/unknown_frame.c @@ -31,8 +31,8 @@ * */ -#include "test/core/bad_client/bad_client.h" #include "src/core/surface/server.h" +#include "test/core/bad_client/bad_client.h" #define PFX_STR \ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \ @@ -41,9 +41,9 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq, void *registered_method) { while (grpc_server_has_open_connections(server)) { - GPR_ASSERT(grpc_completion_queue_next(cq, - GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), - NULL).type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(grpc_completion_queue_next( + cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), NULL) + .type == GRPC_QUEUE_TIMEOUT); } } diff --git a/test/core/bad_client/tests/window_overflow.c b/test/core/bad_client/tests/window_overflow.c index 646d5c5f4c..0ac161097f 100644 --- a/test/core/bad_client/tests/window_overflow.c +++ b/test/core/bad_client/tests/window_overflow.c @@ -60,9 +60,9 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq, void *registered_method) { while (grpc_server_has_open_connections(server)) { - GPR_ASSERT(grpc_completion_queue_next(cq, - GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), - NULL).type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(grpc_completion_queue_next( + cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), NULL) + .type == GRPC_QUEUE_TIMEOUT); } } @@ -90,8 +90,15 @@ int main(int argc, char **argv) { addbuf(PFX_STR, sizeof(PFX_STR) - 1); for (i = 0; i < NUM_FRAMES; i++) { - uint8_t hdr[9] = {(uint8_t)(FRAME_SIZE >> 16), (uint8_t)(FRAME_SIZE >> 8), - (uint8_t)FRAME_SIZE, 0, 0, 0, 0, 0, 1}; + uint8_t hdr[9] = {(uint8_t)(FRAME_SIZE >> 16), + (uint8_t)(FRAME_SIZE >> 8), + (uint8_t)FRAME_SIZE, + 0, + 0, + 0, + 0, + 0, + 1}; addbuf(hdr, sizeof(hdr)); for (j = 0; j < MESSAGES_PER_FRAME; j++) { uint8_t message[5] = {0, 0, 0, 0, 0}; diff --git a/test/core/bad_ssl/bad_ssl_test.c b/test/core/bad_ssl/bad_ssl_test.c index 9daad14b5c..e2babfa114 100644 --- a/test/core/bad_ssl/bad_ssl_test.c +++ b/test/core/bad_ssl/bad_ssl_test.c @@ -31,8 +31,8 @@ * */ -#include #include +#include #include #include @@ -43,8 +43,8 @@ #include #include "src/core/support/env.h" #include "src/core/support/string.h" -#include "test/core/util/port.h" #include "test/core/end2end/cq_verifier.h" +#include "test/core/util/port.h" #include "test/core/util/test_config.h" static void *tag(intptr_t t) { return (void *)t; } diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index e19e9a57ae..c4c288d736 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -92,10 +92,17 @@ static void free_call(grpc_exec_ctx *exec_ctx, void *arg, bool success) { } static void test_create_channel_stack(void) { - const grpc_channel_filter filter = { - call_func, channel_func, sizeof(int), call_init_func, - grpc_call_stack_ignore_set_pollset, call_destroy_func, sizeof(int), - channel_init_func, channel_destroy_func, get_peer, "some_test_filter"}; + const grpc_channel_filter filter = {call_func, + channel_func, + sizeof(int), + call_init_func, + grpc_call_stack_ignore_set_pollset, + call_destroy_func, + sizeof(int), + channel_init_func, + channel_destroy_func, + get_peer, + "some_test_filter"}; const grpc_channel_filter *filters = &filter; grpc_channel_stack *channel_stack; grpc_call_stack *call_stack; diff --git a/test/core/client_config/lb_policies_test.c b/test/core/client_config/lb_policies_test.c index 1ea0c423c1..91fa63ea97 100644 --- a/test/core/client_config/lb_policies_test.c +++ b/test/core/client_config/lb_policies_test.c @@ -139,8 +139,9 @@ static void kill_server(const servers_fixture *f, size_t i) { gpr_log(GPR_INFO, "KILLING SERVER %d", i); GPR_ASSERT(f->servers[i] != NULL); grpc_server_shutdown_and_notify(f->servers[i], f->cq, tag(10000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(10000), n_millis_time(5000), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT( + grpc_completion_queue_pluck(f->cq, tag(10000), n_millis_time(5000), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->servers[i]); f->servers[i] = NULL; } @@ -206,8 +207,8 @@ static void teardown_servers(servers_fixture *f) { if (f->servers[i] == NULL) continue; grpc_server_shutdown_and_notify(f->servers[i], f->cq, tag(10000)); GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(10000), - n_millis_time(5000), - NULL).type == GRPC_OP_COMPLETE); + n_millis_time(5000), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->servers[i]); } grpc_completion_queue_shutdown(f->cq); @@ -304,9 +305,10 @@ static int *perform_request(servers_fixture *f, grpc_channel *client, grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL)); s_idx = -1; - while ((ev = grpc_completion_queue_next( - f->cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10 * RETRY_TIMEOUT), - NULL)).type != GRPC_QUEUE_TIMEOUT) { + while ( + (ev = grpc_completion_queue_next( + f->cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10 * RETRY_TIMEOUT), NULL)) + .type != GRPC_QUEUE_TIMEOUT) { GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); read_tag = ((int)(intptr_t)ev.tag); gpr_log(GPR_DEBUG, "EVENT: success:%d, type:%d, tag:%d iter:%d", @@ -378,9 +380,10 @@ static int *perform_request(servers_fixture *f, grpc_channel *client, } } - GPR_ASSERT(grpc_completion_queue_next( - f->cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(2 * RETRY_TIMEOUT), - NULL).type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT( + grpc_completion_queue_next( + f->cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(2 * RETRY_TIMEOUT), NULL) + .type == GRPC_QUEUE_TIMEOUT); grpc_metadata_array_destroy(&rdata->initial_metadata_recv); grpc_metadata_array_destroy(&rdata->trailing_metadata_recv); diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c index 724d419a7a..59fa6cf74b 100644 --- a/test/core/end2end/cq_verifier.c +++ b/test/core/end2end/cq_verifier.c @@ -37,8 +37,6 @@ #include #include -#include "src/core/surface/event_string.h" -#include "src/core/support/string.h" #include #include #include @@ -46,6 +44,8 @@ #include #include #include +#include "src/core/support/string.h" +#include "src/core/surface/event_string.h" #define ROOT_EXPECTATION 1000 diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c index 58e13a4098..b93149e4c0 100644 --- a/test/core/end2end/dualstack_socket_test.c +++ b/test/core/end2end/dualstack_socket_test.c @@ -39,9 +39,9 @@ #include #include -#include "src/core/support/string.h" #include "src/core/iomgr/resolve_address.h" #include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/support/string.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" @@ -249,9 +249,9 @@ void test_connect(const char *server_host, const char *client_host, int port, /* Destroy server. */ grpc_server_shutdown_and_notify(server, cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(server); grpc_completion_queue_shutdown(cq); drain_cq(cq); diff --git a/test/core/end2end/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c index 17dc190d14..ac6e5a2bc6 100644 --- a/test/core/end2end/end2end_nosec_tests.c +++ b/test/core/end2end/end2end_nosec_tests.c @@ -34,9 +34,9 @@ /* This file is auto-generated */ -#include "test/core/end2end/end2end_tests.h" -#include #include +#include +#include "test/core/end2end/end2end_tests.h" extern void bad_hostname(grpc_end2end_test_config config); extern void binary_metadata(grpc_end2end_test_config config); diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c index 6f2f5aff78..8301107392 100644 --- a/test/core/end2end/end2end_tests.c +++ b/test/core/end2end/end2end_tests.c @@ -35,8 +35,8 @@ /* This file is auto-generated */ #include "test/core/end2end/end2end_tests.h" -#include #include +#include extern void bad_hostname(grpc_end2end_test_config config); extern void binary_metadata(grpc_end2end_test_config config); diff --git a/test/core/end2end/fixtures/h2_census.c b/test/core/end2end/fixtures/h2_census.c index e74c9ae243..ca2222752b 100644 --- a/test/core/end2end/fixtures/h2_census.c +++ b/test/core/end2end/fixtures/h2_census.c @@ -35,6 +35,12 @@ #include +#include +#include +#include +#include +#include +#include #include "src/core/channel/channel_args.h" #include "src/core/channel/client_channel.h" #include "src/core/channel/connected_channel.h" @@ -42,12 +48,6 @@ #include "src/core/surface/channel.h" #include "src/core/surface/server.h" #include "src/core/transport/chttp2_transport.h" -#include -#include -#include -#include -#include -#include #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_compress.c b/test/core/end2end/fixtures/h2_compress.c index fea8a4f751..ea85c34460 100644 --- a/test/core/end2end/fixtures/h2_compress.c +++ b/test/core/end2end/fixtures/h2_compress.c @@ -35,6 +35,12 @@ #include +#include +#include +#include +#include +#include +#include #include "src/core/channel/channel_args.h" #include "src/core/channel/client_channel.h" #include "src/core/channel/connected_channel.h" @@ -42,12 +48,6 @@ #include "src/core/surface/channel.h" #include "src/core/surface/server.h" #include "src/core/transport/chttp2_transport.h" -#include -#include -#include -#include -#include -#include #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_fakesec.c b/test/core/end2end/fixtures/h2_fakesec.c index 2767f1df4a..e8e42089ef 100644 --- a/test/core/end2end/fixtures/h2_fakesec.c +++ b/test/core/end2end/fixtures/h2_fakesec.c @@ -36,14 +36,14 @@ #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/security/credentials.h" #include #include #include -#include "test/core/util/test_config.h" -#include "test/core/util/port.h" +#include "src/core/channel/channel_args.h" +#include "src/core/security/credentials.h" #include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" typedef struct fullstack_secure_fixture_data { char *localaddr; diff --git a/test/core/end2end/fixtures/h2_full+pipe.c b/test/core/end2end/fixtures/h2_full+pipe.c index 4b93581899..2f6402580a 100644 --- a/test/core/end2end/fixtures/h2_full+pipe.c +++ b/test/core/end2end/fixtures/h2_full+pipe.c @@ -35,21 +35,21 @@ #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" #include #include #include #include #include #include +#include "src/core/channel/client_channel.h" +#include "src/core/channel/connected_channel.h" +#include "src/core/channel/http_server_filter.h" +#include "src/core/iomgr/wakeup_fd_posix.h" +#include "src/core/surface/channel.h" +#include "src/core/surface/server.h" +#include "src/core/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -#include "src/core/iomgr/wakeup_fd_posix.h" typedef struct fullstack_fixture_data { char *localaddr; diff --git a/test/core/end2end/fixtures/h2_full+trace.c b/test/core/end2end/fixtures/h2_full+trace.c index 042ee212d7..c84bd72530 100644 --- a/test/core/end2end/fixtures/h2_full+trace.c +++ b/test/core/end2end/fixtures/h2_full+trace.c @@ -35,21 +35,21 @@ #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" #include #include #include #include #include #include +#include "src/core/channel/client_channel.h" +#include "src/core/channel/connected_channel.h" +#include "src/core/channel/http_server_filter.h" +#include "src/core/support/env.h" +#include "src/core/surface/channel.h" +#include "src/core/surface/server.h" +#include "src/core/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -#include "src/core/support/env.h" typedef struct fullstack_fixture_data { char *localaddr; diff --git a/test/core/end2end/fixtures/h2_full.c b/test/core/end2end/fixtures/h2_full.c index ebaa1c6a2c..32af542e50 100644 --- a/test/core/end2end/fixtures/h2_full.c +++ b/test/core/end2end/fixtures/h2_full.c @@ -35,18 +35,18 @@ #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" #include #include #include #include #include #include +#include "src/core/channel/client_channel.h" +#include "src/core/channel/connected_channel.h" +#include "src/core/channel/http_server_filter.h" +#include "src/core/surface/channel.h" +#include "src/core/surface/server.h" +#include "src/core/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_oauth2.c b/test/core/end2end/fixtures/h2_oauth2.c index e2c82917ef..36670f5473 100644 --- a/test/core/end2end/fixtures/h2_oauth2.c +++ b/test/core/end2end/fixtures/h2_oauth2.c @@ -36,15 +36,15 @@ #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/security/credentials.h" #include #include #include -#include "test/core/util/test_config.h" -#include "test/core/util/port.h" +#include "src/core/channel/channel_args.h" +#include "src/core/iomgr/iomgr.h" +#include "src/core/security/credentials.h" #include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" static const char oauth2_md[] = "Bearer aaslkfjs424535asdf"; static const char *client_identity_property_name = "smurf_name"; diff --git a/test/core/end2end/fixtures/h2_proxy.c b/test/core/end2end/fixtures/h2_proxy.c index 8bcc1b6ee0..567220b468 100644 --- a/test/core/end2end/fixtures/h2_proxy.c +++ b/test/core/end2end/fixtures/h2_proxy.c @@ -35,18 +35,18 @@ #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" #include #include #include #include #include #include +#include "src/core/channel/client_channel.h" +#include "src/core/channel/connected_channel.h" +#include "src/core/channel/http_server_filter.h" +#include "src/core/surface/channel.h" +#include "src/core/surface/server.h" +#include "src/core/transport/chttp2_transport.h" #include "test/core/end2end/fixtures/proxy.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.c b/test/core/end2end/fixtures/h2_sockpair+trace.c index 482aa8dba8..33068721fa 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.c +++ b/test/core/end2end/fixtures/h2_sockpair+trace.c @@ -35,22 +35,22 @@ #include +#include +#include +#include +#include +#include #include "src/core/channel/client_channel.h" +#include "src/core/channel/compress_filter.h" #include "src/core/channel/connected_channel.h" #include "src/core/channel/http_client_filter.h" #include "src/core/channel/http_server_filter.h" -#include "src/core/channel/compress_filter.h" #include "src/core/iomgr/endpoint_pair.h" #include "src/core/iomgr/iomgr.h" #include "src/core/support/env.h" #include "src/core/surface/channel.h" #include "src/core/surface/server.h" #include "src/core/transport/chttp2_transport.h" -#include -#include -#include -#include -#include #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_sockpair.c b/test/core/end2end/fixtures/h2_sockpair.c index cf1c4ac2ae..d64c85aea8 100644 --- a/test/core/end2end/fixtures/h2_sockpair.c +++ b/test/core/end2end/fixtures/h2_sockpair.c @@ -35,6 +35,11 @@ #include +#include +#include +#include +#include +#include #include "src/core/channel/client_channel.h" #include "src/core/channel/compress_filter.h" #include "src/core/channel/connected_channel.h" @@ -45,11 +50,6 @@ #include "src/core/surface/channel.h" #include "src/core/surface/server.h" #include "src/core/transport/chttp2_transport.h" -#include -#include -#include -#include -#include #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c index f49938c619..67180a5edb 100644 --- a/test/core/end2end/fixtures/h2_sockpair_1byte.c +++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c @@ -35,21 +35,21 @@ #include +#include +#include +#include +#include +#include #include "src/core/channel/client_channel.h" +#include "src/core/channel/compress_filter.h" #include "src/core/channel/connected_channel.h" #include "src/core/channel/http_client_filter.h" #include "src/core/channel/http_server_filter.h" -#include "src/core/channel/compress_filter.h" #include "src/core/iomgr/endpoint_pair.h" #include "src/core/iomgr/iomgr.h" #include "src/core/surface/channel.h" #include "src/core/surface/server.h" #include "src/core/transport/chttp2_transport.h" -#include -#include -#include -#include -#include #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_ssl+poll.c b/test/core/end2end/fixtures/h2_ssl+poll.c index 66268c77d5..4c3bc64197 100644 --- a/test/core/end2end/fixtures/h2_ssl+poll.c +++ b/test/core/end2end/fixtures/h2_ssl+poll.c @@ -44,8 +44,8 @@ #include "src/core/iomgr/pollset_posix.h" #include "src/core/security/credentials.h" #include "src/core/support/env.h" -#include "src/core/support/tmpfile.h" #include "src/core/support/string.h" +#include "src/core/support/tmpfile.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_ssl.c b/test/core/end2end/fixtures/h2_ssl.c index e21a3477df..6a4e8dcb37 100644 --- a/test/core/end2end/fixtures/h2_ssl.c +++ b/test/core/end2end/fixtures/h2_ssl.c @@ -43,8 +43,8 @@ #include "src/core/channel/channel_args.h" #include "src/core/security/credentials.h" #include "src/core/support/env.h" -#include "src/core/support/tmpfile.h" #include "src/core/support/string.h" +#include "src/core/support/tmpfile.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.c b/test/core/end2end/fixtures/h2_ssl_proxy.c index 6340d3f403..f5fcb91812 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.c +++ b/test/core/end2end/fixtures/h2_ssl_proxy.c @@ -43,8 +43,8 @@ #include "src/core/channel/channel_args.h" #include "src/core/security/credentials.h" #include "src/core/support/env.h" -#include "src/core/support/tmpfile.h" #include "src/core/support/string.h" +#include "src/core/support/tmpfile.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/end2end/fixtures/proxy.h" #include "test/core/util/port.h" diff --git a/test/core/end2end/fixtures/h2_uds.c b/test/core/end2end/fixtures/h2_uds.c index 30928270e5..593cd0d7d5 100644 --- a/test/core/end2end/fixtures/h2_uds.c +++ b/test/core/end2end/fixtures/h2_uds.c @@ -37,13 +37,6 @@ #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/support/string.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" #include #include #include @@ -51,6 +44,13 @@ #include #include #include +#include "src/core/channel/client_channel.h" +#include "src/core/channel/connected_channel.h" +#include "src/core/channel/http_server_filter.h" +#include "src/core/support/string.h" +#include "src/core/surface/channel.h" +#include "src/core/surface/server.h" +#include "src/core/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/invalid_call_argument_test.c b/test/core/end2end/invalid_call_argument_test.c index 2fa1a0a108..ab90c4cf74 100644 --- a/test/core/end2end/invalid_call_argument_test.c +++ b/test/core/end2end/invalid_call_argument_test.c @@ -131,15 +131,16 @@ static void cleanup_test() { grpc_server_shutdown_and_notify(g_state.server, g_state.cq, tag(1000)); GPR_ASSERT(grpc_completion_queue_pluck(g_state.cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(g_state.server); grpc_call_details_destroy(&g_state.call_details); grpc_metadata_array_destroy(&g_state.server_initial_metadata_recv); } grpc_completion_queue_shutdown(g_state.cq); while (grpc_completion_queue_next(g_state.cq, - gpr_inf_future(GPR_CLOCK_REALTIME), - NULL).type != GRPC_QUEUE_SHUTDOWN) + gpr_inf_future(GPR_CLOCK_REALTIME), NULL) + .type != GRPC_QUEUE_SHUTDOWN) ; grpc_completion_queue_destroy(g_state.cq); } diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c index 5c971eac6a..7a5cd2335f 100644 --- a/test/core/end2end/no_server_test.c +++ b/test/core/end2end/no_server_test.c @@ -88,8 +88,9 @@ int main(int argc, char **argv) { GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED); grpc_completion_queue_shutdown(cq); - while (grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), - NULL).type != GRPC_QUEUE_SHUTDOWN) + while ( + grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL) + .type != GRPC_QUEUE_SHUTDOWN) ; grpc_completion_queue_destroy(cq); grpc_call_destroy(call); diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c index 14587389c7..01dd39adaf 100644 --- a/test/core/end2end/tests/bad_hostname.c +++ b/test/core/end2end/tests/bad_hostname.c @@ -36,13 +36,13 @@ #include #include -#include "src/core/support/string.h" #include #include #include #include #include #include +#include "src/core/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; @@ -77,9 +77,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/binary_metadata.c b/test/core/end2end/tests/binary_metadata.c index 4eccd16c4c..54583b09bc 100644 --- a/test/core/end2end/tests/binary_metadata.c +++ b/test/core/end2end/tests/binary_metadata.c @@ -75,9 +75,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/call_creds.c b/test/core/end2end/tests/call_creds.c index c9d4251b68..388810e96b 100644 --- a/test/core/end2end/tests/call_creds.c +++ b/test/core/end2end/tests/call_creds.c @@ -36,15 +36,15 @@ #include #include -#include #include +#include #include #include #include #include -#include "test/core/end2end/cq_verifier.h" #include "src/core/security/credentials.h" #include "src/core/support/string.h" +#include "test/core/end2end/cq_verifier.h" static const char iam_token[] = "token"; static const char iam_selector[] = "selector"; @@ -93,9 +93,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c index 4646bf7bca..08d0ef6e51 100644 --- a/test/core/end2end/tests/cancel_after_accept.c +++ b/test/core/end2end/tests/cancel_after_accept.c @@ -76,9 +76,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/cancel_after_client_done.c b/test/core/end2end/tests/cancel_after_client_done.c index 364598a76a..f85ffad118 100644 --- a/test/core/end2end/tests/cancel_after_client_done.c +++ b/test/core/end2end/tests/cancel_after_client_done.c @@ -76,9 +76,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c index ec0b0dea4c..e7d6e0098a 100644 --- a/test/core/end2end/tests/cancel_after_invoke.c +++ b/test/core/end2end/tests/cancel_after_invoke.c @@ -77,9 +77,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c index 7b432fe87e..a4f47f01fa 100644 --- a/test/core/end2end/tests/cancel_before_invoke.c +++ b/test/core/end2end/tests/cancel_before_invoke.c @@ -75,9 +75,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c index 214ab2b9e8..73a6fc452a 100644 --- a/test/core/end2end/tests/cancel_in_a_vacuum.c +++ b/test/core/end2end/tests/cancel_in_a_vacuum.c @@ -76,9 +76,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c index 1541ca099f..e47eb41896 100644 --- a/test/core/end2end/tests/cancel_with_status.c +++ b/test/core/end2end/tests/cancel_with_status.c @@ -36,13 +36,13 @@ #include #include -#include "src/core/support/string.h" #include #include #include #include #include #include +#include "src/core/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; @@ -77,9 +77,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c index 33b1d8f9fe..c76360ff9b 100644 --- a/test/core/end2end/tests/compressed_payload.c +++ b/test/core/end2end/tests/compressed_payload.c @@ -43,10 +43,10 @@ #include #include -#include "test/core/end2end/cq_verifier.h" #include "src/core/channel/channel_args.h" #include "src/core/channel/compress_filter.h" #include "src/core/surface/call_test_only.h" +#include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; @@ -80,9 +80,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/default_host.c b/test/core/end2end/tests/default_host.c index dc3303436b..e60d3fa471 100644 --- a/test/core/end2end/tests/default_host.c +++ b/test/core/end2end/tests/default_host.c @@ -36,13 +36,13 @@ #include #include -#include "src/core/support/string.h" #include #include #include #include #include #include +#include "src/core/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; @@ -77,9 +77,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c index 24320c0f32..a0672c8583 100644 --- a/test/core/end2end/tests/empty_batch.c +++ b/test/core/end2end/tests/empty_batch.c @@ -36,13 +36,13 @@ #include #include -#include "src/core/support/string.h" #include #include #include #include #include #include +#include "src/core/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; @@ -77,9 +77,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/high_initial_seqno.c b/test/core/end2end/tests/high_initial_seqno.c index 8d16ef5f5e..e7a169cb7f 100644 --- a/test/core/end2end/tests/high_initial_seqno.c +++ b/test/core/end2end/tests/high_initial_seqno.c @@ -79,9 +79,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/hpack_size.c b/test/core/end2end/tests/hpack_size.c index fd4fe3419f..e525956958 100644 --- a/test/core/end2end/tests/hpack_size.c +++ b/test/core/end2end/tests/hpack_size.c @@ -262,9 +262,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c index f0b019821d..28c0e36461 100644 --- a/test/core/end2end/tests/invoke_large_request.c +++ b/test/core/end2end/tests/invoke_large_request.c @@ -73,9 +73,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/large_metadata.c b/test/core/end2end/tests/large_metadata.c index 1b41e89b26..173c20996e 100644 --- a/test/core/end2end/tests/large_metadata.c +++ b/test/core/end2end/tests/large_metadata.c @@ -75,9 +75,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c index d6b2a06f9b..60e9ecd7d8 100644 --- a/test/core/end2end/tests/max_concurrent_streams.c +++ b/test/core/end2end/tests/max_concurrent_streams.c @@ -75,9 +75,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c index 59ab7f476c..00a83ecb33 100644 --- a/test/core/end2end/tests/max_message_length.c +++ b/test/core/end2end/tests/max_message_length.c @@ -75,9 +75,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c index 2109310634..f80f18710e 100644 --- a/test/core/end2end/tests/negative_deadline.c +++ b/test/core/end2end/tests/negative_deadline.c @@ -36,13 +36,13 @@ #include #include -#include "src/core/support/string.h" #include #include #include #include #include #include +#include "src/core/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; @@ -77,9 +77,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c index 4bc1d631d1..9dda569cb9 100644 --- a/test/core/end2end/tests/no_op.c +++ b/test/core/end2end/tests/no_op.c @@ -75,9 +75,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c index bc220cbdc9..e9272b6bce 100644 --- a/test/core/end2end/tests/payload.c +++ b/test/core/end2end/tests/payload.c @@ -75,9 +75,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c index 8351f508c5..ac4e810573 100644 --- a/test/core/end2end/tests/ping_pong_streaming.c +++ b/test/core/end2end/tests/ping_pong_streaming.c @@ -75,9 +75,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c index d9d2b19d12..2a32ee07bd 100644 --- a/test/core/end2end/tests/registered_call.c +++ b/test/core/end2end/tests/registered_call.c @@ -36,13 +36,13 @@ #include #include -#include "src/core/support/string.h" #include #include #include #include #include #include +#include "src/core/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; @@ -77,9 +77,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/request_with_flags.c b/test/core/end2end/tests/request_with_flags.c index 340aba6cdb..e9fa5b500c 100644 --- a/test/core/end2end/tests/request_with_flags.c +++ b/test/core/end2end/tests/request_with_flags.c @@ -76,9 +76,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c index 1aced6a875..9866d39000 100644 --- a/test/core/end2end/tests/request_with_payload.c +++ b/test/core/end2end/tests/request_with_payload.c @@ -75,9 +75,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c index 6bca8d476c..d406dc3054 100644 --- a/test/core/end2end/tests/server_finishes_request.c +++ b/test/core/end2end/tests/server_finishes_request.c @@ -36,13 +36,13 @@ #include #include -#include "src/core/support/string.h" #include #include #include #include #include #include +#include "src/core/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; @@ -77,9 +77,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c index 0afef7503b..bb9d462cef 100644 --- a/test/core/end2end/tests/simple_delayed_request.c +++ b/test/core/end2end/tests/simple_delayed_request.c @@ -63,9 +63,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/simple_metadata.c b/test/core/end2end/tests/simple_metadata.c index c5084a560f..0e214e3770 100644 --- a/test/core/end2end/tests/simple_metadata.c +++ b/test/core/end2end/tests/simple_metadata.c @@ -75,9 +75,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c index 3720cd1631..fd9788d0ba 100644 --- a/test/core/end2end/tests/simple_request.c +++ b/test/core/end2end/tests/simple_request.c @@ -36,13 +36,13 @@ #include #include -#include "src/core/support/string.h" #include #include #include #include #include #include +#include "src/core/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; @@ -77,9 +77,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/end2end/tests/trailing_metadata.c b/test/core/end2end/tests/trailing_metadata.c index 78525e9538..99e1e2264a 100644 --- a/test/core/end2end/tests/trailing_metadata.c +++ b/test/core/end2end/tests/trailing_metadata.c @@ -75,9 +75,9 @@ static void drain_cq(grpc_completion_queue *cq) { static void shutdown_server(grpc_end2end_test_fixture *f) { if (!f->server) return; grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), - NULL).type == GRPC_OP_COMPLETE); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); grpc_server_destroy(f->server); f->server = NULL; } diff --git a/test/core/fling/fling_stream_test.c b/test/core/fling/fling_stream_test.c index 78a73372aa..08b703ff30 100644 --- a/test/core/fling/fling_stream_test.c +++ b/test/core/fling/fling_stream_test.c @@ -35,19 +35,19 @@ #define _POSIX_SOURCE #endif -#include #include -#include -#include #include +#include #include +#include #include #include +#include -#include "src/core/support/string.h" #include #include #include +#include "src/core/support/string.h" #include "test/core/util/port.h" int main(int argc, char **argv) { diff --git a/test/core/fling/fling_test.c b/test/core/fling/fling_test.c index cf43ecfd2d..28c0d75be7 100644 --- a/test/core/fling/fling_test.c +++ b/test/core/fling/fling_test.c @@ -31,8 +31,8 @@ * */ -#include #include +#include #include #include diff --git a/test/core/http/format_request_test.c b/test/core/http/format_request_test.c index 67dfd24803..5e2b709f89 100644 --- a/test/core/http/format_request_test.c +++ b/test/core/http/format_request_test.c @@ -142,8 +142,7 @@ static void test_format_post_request_content_type_override(void) { "POST /index.html HTTP/1.0\r\n" "Host: example.com\r\n" "Connection: close\r\n" - "User-Agent: " GRPC_HTTPCLI_USER_AGENT - "\r\n" + "User-Agent: " GRPC_HTTPCLI_USER_AGENT "\r\n" "x-yz: abc\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "Content-Length: 11\r\n" diff --git a/test/core/iomgr/fd_conservation_posix_test.c b/test/core/iomgr/fd_conservation_posix_test.c index 401bf70a9e..fc983e026a 100644 --- a/test/core/iomgr/fd_conservation_posix_test.c +++ b/test/core/iomgr/fd_conservation_posix_test.c @@ -35,9 +35,9 @@ #include -#include "test/core/util/test_config.h" #include "src/core/iomgr/endpoint_pair.h" #include "src/core/iomgr/iomgr.h" +#include "test/core/util/test_config.h" int main(int argc, char **argv) { int i; diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c index 56ce091a88..2e574b58c3 100644 --- a/test/core/iomgr/resolve_address_test.c +++ b/test/core/iomgr/resolve_address_test.c @@ -32,10 +32,10 @@ */ #include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/executor.h" #include #include #include +#include "src/core/iomgr/executor.h" #include "test/core/util/test_config.h" static gpr_timespec test_deadline(void) { diff --git a/test/core/iomgr/timer_list_test.c b/test/core/iomgr/timer_list_test.c index 7a21fdd5c1..955bf44bb6 100644 --- a/test/core/iomgr/timer_list_test.c +++ b/test/core/iomgr/timer_list_test.c @@ -81,9 +81,8 @@ static void add_test(void) { } GPR_ASSERT(!grpc_timer_check( - &exec_ctx, - gpr_time_add(start, gpr_time_from_millis(600, GPR_TIMESPAN)), - NULL)); + &exec_ctx, gpr_time_add(start, gpr_time_from_millis(600, GPR_TIMESPAN)), + NULL)); grpc_exec_ctx_finish(&exec_ctx); for (i = 0; i < 30; i++) { GPR_ASSERT(cb_called[i][1] == (i < 10)); @@ -101,9 +100,8 @@ static void add_test(void) { } GPR_ASSERT(!grpc_timer_check( - &exec_ctx, - gpr_time_add(start, gpr_time_from_millis(1600, GPR_TIMESPAN)), - NULL)); + &exec_ctx, gpr_time_add(start, gpr_time_from_millis(1600, GPR_TIMESPAN)), + NULL)); for (i = 0; i < 30; i++) { GPR_ASSERT(cb_called[i][1] == (i < 20)); GPR_ASSERT(cb_called[i][0] == 0); diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c index 365b5c002b..042e936456 100644 --- a/test/core/iomgr/udp_server_test.c +++ b/test/core/iomgr/udp_server_test.c @@ -31,18 +31,18 @@ * */ -#include "src/core/iomgr/iomgr.h" -#include "src/core/iomgr/pollset_posix.h" #include "src/core/iomgr/udp_server.h" #include #include #include #include +#include "src/core/iomgr/iomgr.h" +#include "src/core/iomgr/pollset_posix.h" #include "test/core/util/test_config.h" -#include #include #include +#include #include #ifdef GRPC_NEED_UDP diff --git a/test/core/json/json_rewrite_test.c b/test/core/json/json_rewrite_test.c index d99cb0dd03..fc725610b6 100644 --- a/test/core/json/json_rewrite_test.c +++ b/test/core/json/json_rewrite_test.c @@ -35,8 +35,8 @@ #include #include -#include #include +#include #include "test/core/util/test_config.h" #include "src/core/json/json_reader.h" diff --git a/test/core/json/json_stream_error_test.c b/test/core/json/json_stream_error_test.c index 400776759d..11bdb9e554 100644 --- a/test/core/json/json_stream_error_test.c +++ b/test/core/json/json_stream_error_test.c @@ -35,8 +35,8 @@ #include #include -#include #include +#include #include "test/core/util/test_config.h" #include "src/core/json/json_reader.h" diff --git a/test/core/json/json_test.c b/test/core/json/json_test.c index 5add80d753..a5f3e08fa6 100644 --- a/test/core/json/json_test.c +++ b/test/core/json/json_test.c @@ -34,9 +34,9 @@ #include #include -#include #include #include +#include #include "src/core/json/json.h" #include "src/core/support/string.h" @@ -66,7 +66,7 @@ static testing_pair testing_pairs[] = { {"\"\\ud834\\udd1e\"", "\"\\ud834\\udd1e\""}, /* Testing nested empty containers. */ { - " [ [ ] , { } , [ ] ] ", "[[],{},[]]", + " [ [ ] , { } , [ ] ] ", "[[],{},[]]", }, /* Testing escapes and control chars in key strings. */ {" { \"\\u007f\x7f\\n\\r\\\"\\f\\b\\\\a , b\": 1, \"\": 0 } ", diff --git a/test/core/network_benchmarks/low_level_ping_pong.c b/test/core/network_benchmarks/low_level_ping_pong.c index dd1544c27b..a15debe604 100644 --- a/test/core/network_benchmarks/low_level_ping_pong.c +++ b/test/core/network_benchmarks/low_level_ping_pong.c @@ -49,13 +49,13 @@ #endif #include -#include "src/core/iomgr/socket_utils_posix.h" #include #include #include #include #include #include +#include "src/core/iomgr/socket_utils_posix.h" typedef struct fd_pair { int read_fd; diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c index fd9ccbf45d..3a6b9696ab 100644 --- a/test/core/security/credentials_test.c +++ b/test/core/security/credentials_test.c @@ -47,8 +47,8 @@ #include "src/core/http/httpcli.h" #include "src/core/security/json_token.h" #include "src/core/support/env.h" -#include "src/core/support/tmpfile.h" #include "src/core/support/string.h" +#include "src/core/support/tmpfile.h" #include "test/core/util/test_config.h" /* -- Mock channel credentials. -- */ diff --git a/test/core/security/security_connector_test.c b/test/core/security/security_connector_test.c index 609d874fd1..31a56ea723 100644 --- a/test/core/security/security_connector_test.c +++ b/test/core/security/security_connector_test.c @@ -43,8 +43,8 @@ #include "src/core/security/security_connector.h" #include "src/core/security/security_context.h" #include "src/core/support/env.h" -#include "src/core/support/tmpfile.h" #include "src/core/support/string.h" +#include "src/core/support/tmpfile.h" #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security.h" #include "test/core/util/test_config.h" diff --git a/test/core/statistics/census_log_tests.c b/test/core/statistics/census_log_tests.c index 77cc57d4d6..7cbb0c022b 100644 --- a/test/core/statistics/census_log_tests.c +++ b/test/core/statistics/census_log_tests.c @@ -32,9 +32,6 @@ */ #include "src/core/statistics/census_log.h" -#include -#include -#include #include #include #include @@ -42,6 +39,9 @@ #include #include #include +#include +#include +#include #include "test/core/util/test_config.h" /* Fills in 'record' of size 'size'. Each byte in record is filled in with the diff --git a/test/core/statistics/census_stub_test.c b/test/core/statistics/census_stub_test.c index 8e409a3726..6514ac9981 100644 --- a/test/core/statistics/census_stub_test.c +++ b/test/core/statistics/census_stub_test.c @@ -34,10 +34,10 @@ #include #include -#include "src/core/statistics/census_interface.h" -#include "src/core/statistics/census_rpc_stats.h" #include #include +#include "src/core/statistics/census_interface.h" +#include "src/core/statistics/census_rpc_stats.h" #include "test/core/util/test_config.h" /* Tests census noop stubs in a simulated rpc flow */ diff --git a/test/core/statistics/hash_table_test.c b/test/core/statistics/hash_table_test.c index 3b119dbc0c..9b2b683393 100644 --- a/test/core/statistics/hash_table_test.c +++ b/test/core/statistics/hash_table_test.c @@ -37,11 +37,11 @@ #include "src/core/statistics/hash_table.h" -#include "src/core/support/murmur_hash.h" -#include "src/core/support/string.h" #include #include #include +#include "src/core/support/murmur_hash.h" +#include "src/core/support/string.h" #include "test/core/util/test_config.h" static uint64_t hash64(const void *k) { @@ -65,8 +65,8 @@ static void free_data(void *data) { gpr_free(data); } static void test_create_table(void) { /* Create table with uint64 key type */ census_ht *ht = NULL; - census_ht_option ht_options = {CENSUS_HT_UINT64, 1999, NULL, NULL, NULL, - NULL}; + census_ht_option ht_options = { + CENSUS_HT_UINT64, 1999, NULL, NULL, NULL, NULL}; ht = census_ht_create(&ht_options); GPR_ASSERT(ht != NULL); GPR_ASSERT(census_ht_get_size(ht) == 0); @@ -120,8 +120,8 @@ static void test_table_with_int_key(void) { /* Test that there is no memory leak when keys and values are owned by table. */ static void test_value_and_key_deleter(void) { - census_ht_option opt = {CENSUS_HT_POINTER, 7, &hash64, &cmp_str_keys, - &free_data, &free_data}; + census_ht_option opt = {CENSUS_HT_POINTER, 7, &hash64, + &cmp_str_keys, &free_data, &free_data}; census_ht *ht = census_ht_create(&opt); census_ht_key key; char *val = NULL; @@ -185,8 +185,8 @@ static void test_simple_add_and_erase(void) { } static void test_insertion_and_deletion_with_high_collision_rate(void) { - census_ht_option opt = {CENSUS_HT_POINTER, 13, &force_collision, - &cmp_str_keys, NULL, NULL}; + census_ht_option opt = {CENSUS_HT_POINTER, 13, &force_collision, + &cmp_str_keys, NULL, NULL}; census_ht *ht = census_ht_create(&opt); char key_str[1000][GPR_LTOA_MIN_BUFSIZE]; uint64_t val = 0; @@ -209,12 +209,12 @@ static void test_insertion_and_deletion_with_high_collision_rate(void) { } static void test_table_with_string_key(void) { - census_ht_option opt = {CENSUS_HT_POINTER, 7, &hash64, &cmp_str_keys, NULL, - NULL}; + census_ht_option opt = {CENSUS_HT_POINTER, 7, &hash64, + &cmp_str_keys, NULL, NULL}; census_ht *ht = census_ht_create(&opt); - const char *keys[] = {"k1", "a", "000", "apple", - "banana_a_long_long_long_banana", "%$", "111", "foo", - "b"}; + const char *keys[] = { + "k1", "a", "000", "apple", "banana_a_long_long_long_banana", + "%$", "111", "foo", "b"}; const int vals[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; int i = 0; GPR_ASSERT(ht != NULL); diff --git a/test/core/statistics/rpc_stats_test.c b/test/core/statistics/rpc_stats_test.c index b1d8814cfa..1f9c445f26 100644 --- a/test/core/statistics/rpc_stats_test.c +++ b/test/core/statistics/rpc_stats_test.c @@ -33,15 +33,15 @@ #include -#include "src/core/statistics/census_interface.h" -#include "src/core/statistics/census_rpc_stats.h" -#include "src/core/statistics/census_tracing.h" #include #include #include #include #include #include +#include "src/core/statistics/census_interface.h" +#include "src/core/statistics/census_rpc_stats.h" +#include "src/core/statistics/census_tracing.h" #include "test/core/util/test_config.h" /* Ensure all possible state transitions are called without causing problem */ diff --git a/test/core/statistics/trace_test.c b/test/core/statistics/trace_test.c index 75904040ff..8fcef4ac1b 100644 --- a/test/core/statistics/trace_test.c +++ b/test/core/statistics/trace_test.c @@ -31,12 +31,9 @@ * */ -#include #include +#include -#include "src/core/statistics/census_interface.h" -#include "src/core/statistics/census_tracing.h" -#include "src/core/statistics/census_tracing.h" #include #include #include @@ -44,6 +41,9 @@ #include #include #include +#include "src/core/statistics/census_interface.h" +#include "src/core/statistics/census_tracing.h" +#include "src/core/statistics/census_tracing.h" #include "test/core/util/test_config.h" /* Ensure all possible state transitions are called without causing problem */ diff --git a/test/core/statistics/window_stats_test.c b/test/core/statistics/window_stats_test.c index 578138fdd2..b8adb053f3 100644 --- a/test/core/statistics/window_stats_test.c +++ b/test/core/statistics/window_stats_test.c @@ -32,9 +32,9 @@ */ #include "src/core/statistics/window_stats.h" -#include #include #include +#include #include "test/core/util/test_config.h" typedef struct test_stat { diff --git a/test/core/support/alloc_test.c b/test/core/support/alloc_test.c index 6bdba8c390..e2d0c16b41 100644 --- a/test/core/support/alloc_test.c +++ b/test/core/support/alloc_test.c @@ -31,8 +31,8 @@ * */ -#include #include +#include #include "test/core/util/test_config.h" static void *fake_malloc(size_t size) { return (void *)size; } diff --git a/test/core/support/load_file_test.c b/test/core/support/load_file_test.c index 70189b739d..a14fdc656e 100644 --- a/test/core/support/load_file_test.c +++ b/test/core/support/load_file_test.c @@ -39,8 +39,8 @@ #include #include "src/core/support/load_file.h" -#include "src/core/support/tmpfile.h" #include "src/core/support/string.h" +#include "src/core/support/tmpfile.h" #include "test/core/util/test_config.h" #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x) diff --git a/test/core/support/sync_test.c b/test/core/support/sync_test.c index d311eb136a..2121a4c5fa 100644 --- a/test/core/support/sync_test.c +++ b/test/core/support/sync_test.c @@ -33,13 +33,13 @@ /* Test of gpr synchronization support. */ -#include -#include #include #include #include #include #include +#include +#include #include "test/core/util/test_config.h" /* ==================Example use of interface=================== diff --git a/test/core/support/thd_test.c b/test/core/support/thd_test.c index 0c176da2d3..771c5104c8 100644 --- a/test/core/support/thd_test.c +++ b/test/core/support/thd_test.c @@ -33,12 +33,12 @@ /* Test of gpr thread support. */ -#include -#include #include #include #include #include +#include +#include #include "test/core/util/test_config.h" #define NUM_THREADS 300 diff --git a/test/core/support/time_test.c b/test/core/support/time_test.c index 6cc3786df1..643e9eada7 100644 --- a/test/core/support/time_test.c +++ b/test/core/support/time_test.c @@ -33,14 +33,14 @@ /* Test of gpr time support. */ -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include #include "test/core/util/test_config.h" static void to_fp(void *arg, const char *buf, size_t len) { diff --git a/test/core/support/tls_test.c b/test/core/support/tls_test.c index c6fb1a4a26..7b732ee10e 100644 --- a/test/core/support/tls_test.c +++ b/test/core/support/tls_test.c @@ -33,12 +33,12 @@ /* Test of gpr thread local storage support. */ -#include -#include #include #include #include #include +#include +#include #include "test/core/util/test_config.h" #define NUM_THREADS 100 diff --git a/test/core/support/useful_test.c b/test/core/support/useful_test.c index 3665bbf972..7d190228bd 100644 --- a/test/core/support/useful_test.c +++ b/test/core/support/useful_test.c @@ -31,9 +31,9 @@ * */ -#include -#include #include +#include +#include #include "test/core/util/test_config.h" int main(int argc, char **argv) { diff --git a/test/core/surface/byte_buffer_reader_test.c b/test/core/surface/byte_buffer_reader_test.c index c87fbdc897..c7ab22de8e 100644 --- a/test/core/surface/byte_buffer_reader_test.c +++ b/test/core/surface/byte_buffer_reader_test.c @@ -31,10 +31,10 @@ * */ -#include #include -#include +#include #include +#include #include #include diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c index ec49840ba8..7ad5dc0b41 100644 --- a/test/core/surface/completion_queue_test.c +++ b/test/core/surface/completion_queue_test.c @@ -33,12 +33,12 @@ #include "src/core/surface/completion_queue.h" -#include "src/core/iomgr/iomgr.h" #include #include #include #include #include +#include "src/core/iomgr/iomgr.h" #include "test/core/util/test_config.h" #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) diff --git a/test/core/transport/chttp2/bin_encoder_test.c b/test/core/transport/chttp2/bin_encoder_test.c index d1838075be..815b03c535 100644 --- a/test/core/transport/chttp2/bin_encoder_test.c +++ b/test/core/transport/chttp2/bin_encoder_test.c @@ -39,9 +39,9 @@ * TODO(murgatroid99): Remove this */ #include -#include "src/core/support/string.h" #include #include +#include "src/core/support/string.h" static int all_ok = 1; diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c index 4a9d143640..aa1bb460ba 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.c +++ b/test/core/transport/chttp2/hpack_encoder_test.c @@ -35,12 +35,12 @@ #include -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/hpack_parser.h" -#include "src/core/transport/metadata.h" #include #include #include +#include "src/core/support/string.h" +#include "src/core/transport/chttp2/hpack_parser.h" +#include "src/core/transport/metadata.h" #include "test/core/util/parse_hexstring.h" #include "test/core/util/slice_splitter.h" #include "test/core/util/test_config.h" diff --git a/test/core/transport/chttp2/hpack_table_test.c b/test/core/transport/chttp2/hpack_table_test.c index 3c5f2e4e31..4c0fa2e2e7 100644 --- a/test/core/transport/chttp2/hpack_table_test.c +++ b/test/core/transport/chttp2/hpack_table_test.c @@ -33,8 +33,8 @@ #include "src/core/transport/chttp2/hpack_table.h" -#include #include +#include #include #include diff --git a/test/core/util/port_windows.c b/test/core/util/port_windows.c index 77125dde75..4cbedc0aa6 100644 --- a/test/core/util/port_windows.c +++ b/test/core/util/port_windows.c @@ -37,18 +37,18 @@ #include "test/core/util/port.h" +#include #include #include -#include #include #include #include #include -#include "src/core/support/env.h" #include "src/core/http/httpcli.h" #include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/support/env.h" #include "test/core/util/port_server_client.h" #define NUM_RANDOM_PORTS_TO_PICK 100 diff --git a/test/cpp/common/auth_property_iterator_test.cc b/test/cpp/common/auth_property_iterator_test.cc index a629ff5a90..9fe0801cc3 100644 --- a/test/cpp/common/auth_property_iterator_test.cc +++ b/test/cpp/common/auth_property_iterator_test.cc @@ -31,8 +31,8 @@ * */ -#include #include +#include #include #include "src/cpp/common/secure_auth_context.h" #include "test/cpp/util/string_ref_helper.h" diff --git a/test/cpp/common/secure_auth_context_test.cc b/test/cpp/common/secure_auth_context_test.cc index 11de646999..250388f88b 100644 --- a/test/cpp/common/secure_auth_context_test.cc +++ b/test/cpp/common/secure_auth_context_test.cc @@ -31,10 +31,10 @@ * */ -#include +#include "src/cpp/common/secure_auth_context.h" #include +#include #include -#include "src/cpp/common/secure_auth_context.h" #include "test/cpp/util/string_ref_helper.h" extern "C" { diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc index c72e20628f..02043a89d3 100644 --- a/test/cpp/end2end/hybrid_end2end_test.cc +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -356,7 +356,8 @@ TEST_F(HybridEnd2endTest, AsyncEcho) { TEST_F(HybridEnd2endTest, AsyncEchoRequestStream) { EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithAsyncMethod_Echo > service; + EchoTestService::WithAsyncMethod_Echo > + service; SetUpServer(&service, nullptr, nullptr); ResetStub(); std::thread echo_handler_thread( @@ -436,7 +437,8 @@ TEST_F(HybridEnd2endTest, GenericEcho) { TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream) { EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithGenericMethod_Echo > service; + EchoTestService::WithGenericMethod_Echo > + service; AsyncGenericService generic_service; SetUpServer(&service, nullptr, &generic_service); ResetStub(); @@ -453,7 +455,8 @@ TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream) { // Add a second service with one sync method. TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_SyncDupService) { EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithGenericMethod_Echo > service; + EchoTestService::WithGenericMethod_Echo > + service; AsyncGenericService generic_service; TestServiceImplDupPkg dup_service; SetUpServer(&service, &dup_service, &generic_service); @@ -472,7 +475,8 @@ TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_SyncDupService) { // Add a second service with one async method. TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_AsyncDupService) { EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithGenericMethod_Echo > service; + EchoTestService::WithGenericMethod_Echo > + service; AsyncGenericService generic_service; duplicate::EchoTestService::AsyncService dup_service; SetUpServer(&service, &dup_service, &generic_service); diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index fe29c4afe9..2f5dd6d49e 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -129,10 +129,9 @@ Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, if (request->has_param() && request->param().echo_metadata()) { const std::multimap& client_metadata = context->client_metadata(); - for ( - std::multimap::const_iterator iter = - client_metadata.begin(); - iter != client_metadata.end(); ++iter) { + for (std::multimap::const_iterator + iter = client_metadata.begin(); + iter != client_metadata.end(); ++iter) { context->AddTrailingMetadata(ToString(iter->first), ToString(iter->second)); } diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index e246c0b0e2..114d715baa 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -318,7 +318,7 @@ class AsyncClientEnd2endTest : public ::testing::Test { TEST_F(AsyncClientEnd2endTest, ThreadStress) { common_.ResetStub(); - std::vector send_threads, completion_threads; + std::vector send_threads, completion_threads; for (int i = 0; i < kNumAsyncReceiveThreads; ++i) { completion_threads.push_back(new std::thread( &AsyncClientEnd2endTest_ThreadStress_Test::AsyncCompleteRpc, this)); diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index 788adefd24..8b237fe75f 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -35,11 +35,11 @@ #include -#include -#include #include #include #include +#include +#include #include "test/cpp/interop/client_helper.h" #include "test/cpp/interop/interop_client.h" diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc index 5caf0f2d1d..c8b1e505c1 100644 --- a/test/cpp/interop/client_helper.cc +++ b/test/cpp/interop/client_helper.cc @@ -39,13 +39,13 @@ #include #include -#include -#include -#include #include #include #include #include +#include +#include +#include #include "src/cpp/client/secure_credentials.h" #include "test/core/security/oauth2_utils.h" diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 46f6fdac40..514d4fa861 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -48,8 +48,8 @@ #include "src/core/transport/byte_stream.h" #include "src/proto/grpc/testing/empty.grpc.pb.h" -#include "src/proto/grpc/testing/test.grpc.pb.h" #include "src/proto/grpc/testing/messages.grpc.pb.h" +#include "src/proto/grpc/testing/test.grpc.pb.h" #include "test/cpp/interop/client_helper.h" namespace grpc { diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h index 3f57f3c733..e6706b5713 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.h @@ -36,8 +36,8 @@ #include -#include #include +#include #include "src/proto/grpc/testing/messages.grpc.pb.h" #include "src/proto/grpc/testing/test.grpc.pb.h" diff --git a/test/cpp/interop/interop_test.cc b/test/cpp/interop/interop_test.cc index faf6698903..019d6aefd7 100644 --- a/test/cpp/interop/interop_test.cc +++ b/test/cpp/interop/interop_test.cc @@ -35,14 +35,14 @@ #define _POSIX_SOURCE #endif -#include #include -#include -#include #include +#include #include +#include #include #include +#include #include #include diff --git a/test/cpp/interop/reconnect_interop_client.cc b/test/cpp/interop/reconnect_interop_client.cc index 79a60cc860..c668edaceb 100644 --- a/test/cpp/interop/reconnect_interop_client.cc +++ b/test/cpp/interop/reconnect_interop_client.cc @@ -34,16 +34,16 @@ #include #include -#include -#include #include #include #include -#include "test/cpp/util/create_test_channel.h" -#include "test/cpp/util/test_config.h" -#include "src/proto/grpc/testing/test.grpc.pb.h" +#include +#include #include "src/proto/grpc/testing/empty.grpc.pb.h" #include "src/proto/grpc/testing/messages.grpc.pb.h" +#include "src/proto/grpc/testing/test.grpc.pb.h" +#include "test/cpp/util/create_test_channel.h" +#include "test/cpp/util/test_config.h" DEFINE_int32(server_control_port, 0, "Server port for control rpcs."); DEFINE_int32(server_retry_port, 0, "Server port for testing reconnection."); diff --git a/test/cpp/interop/server_helper.h b/test/cpp/interop/server_helper.h index 57337e5239..12865e4032 100644 --- a/test/cpp/interop/server_helper.h +++ b/test/cpp/interop/server_helper.h @@ -36,9 +36,9 @@ #include -#include -#include #include +#include +#include namespace grpc { namespace testing { diff --git a/test/cpp/interop/server_main.cc b/test/cpp/interop/server_main.cc index 18ac35d551..8a718701c3 100644 --- a/test/cpp/interop/server_main.cc +++ b/test/cpp/interop/server_main.cc @@ -40,19 +40,19 @@ #include #include -#include -#include -#include +#include #include #include #include -#include +#include +#include +#include -#include "test/cpp/interop/server_helper.h" -#include "test/cpp/util/test_config.h" -#include "src/proto/grpc/testing/test.grpc.pb.h" #include "src/proto/grpc/testing/empty.grpc.pb.h" #include "src/proto/grpc/testing/messages.grpc.pb.h" +#include "src/proto/grpc/testing/test.grpc.pb.h" +#include "test/cpp/interop/server_helper.h" +#include "test/cpp/util/test_config.h" DEFINE_bool(use_tls, false, "Whether to use tls."); DEFINE_int32(port, 0, "Server port."); diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc index 702354dc87..162f7b3778 100644 --- a/test/cpp/interop/stress_test.cc +++ b/test/cpp/interop/stress_test.cc @@ -43,12 +43,12 @@ #include #include +#include "src/proto/grpc/testing/metrics.grpc.pb.h" +#include "src/proto/grpc/testing/metrics.pb.h" #include "test/cpp/interop/interop_client.h" #include "test/cpp/interop/stress_interop_client.h" #include "test/cpp/util/metrics_server.h" #include "test/cpp/util/test_config.h" -#include "src/proto/grpc/testing/metrics.grpc.pb.h" -#include "src/proto/grpc/testing/metrics.pb.h" extern "C" { extern void gpr_default_log(gpr_log_func_args* args); diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc index 9e9da9909a..dcdb665a9a 100644 --- a/test/cpp/qps/client_async.cc +++ b/test/cpp/qps/client_async.cc @@ -141,7 +141,8 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext { std::function next_issue_; std::function>( BenchmarkService::Stub*, grpc::ClientContext*, const RequestType&, - CompletionQueue*)> start_req_; + CompletionQueue*)> + start_req_; grpc::Status status_; double start_; std::unique_ptr> @@ -359,10 +360,10 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext { State next_state_; std::function callback_; std::function next_issue_; - std::function< - std::unique_ptr>( - BenchmarkService::Stub*, grpc::ClientContext*, CompletionQueue*, - void*)> start_req_; + std::function>( + BenchmarkService::Stub*, grpc::ClientContext*, CompletionQueue*, void*)> + start_req_; grpc::Status status_; double start_; std::unique_ptr> @@ -491,7 +492,8 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext { std::function next_issue_; std::function( grpc::GenericStub*, grpc::ClientContext*, const grpc::string&, - CompletionQueue*, void*)> start_req_; + CompletionQueue*, void*)> + start_req_; grpc::Status status_; double start_; std::unique_ptr stream_; diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h index 3af61f7391..1e2e28029e 100644 --- a/test/cpp/qps/driver.h +++ b/test/cpp/qps/driver.h @@ -36,8 +36,8 @@ #include -#include "test/cpp/qps/histogram.h" #include "src/proto/grpc/testing/control.grpc.pb.h" +#include "test/cpp/qps/histogram.h" namespace grpc { namespace testing { diff --git a/test/cpp/qps/perf_db_client.h b/test/cpp/qps/perf_db_client.h index ece020aa9b..b74c70d86b 100644 --- a/test/cpp/qps/perf_db_client.h +++ b/test/cpp/qps/perf_db_client.h @@ -31,17 +31,17 @@ * */ +#include #include #include #include -#include -#include -#include #include #include #include #include +#include +#include #include "src/proto/grpc/testing/perf_db.grpc.pb.h" namespace grpc { diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index d7b3f76e0e..1bfb07013d 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -387,12 +387,14 @@ static Status ProcessGenericRPC(const PayloadConfig &payload_config, } std::unique_ptr CreateAsyncServer(const ServerConfig &config) { - return std::unique_ptr(new AsyncQpsServerTest< - SimpleRequest, SimpleResponse, BenchmarkService::AsyncService, - grpc::ServerContext>( - config, RegisterBenchmarkService, - &BenchmarkService::AsyncService::RequestUnaryCall, - &BenchmarkService::AsyncService::RequestStreamingCall, ProcessSimpleRPC)); + return std::unique_ptr( + new AsyncQpsServerTest( + config, RegisterBenchmarkService, + &BenchmarkService::AsyncService::RequestUnaryCall, + &BenchmarkService::AsyncService::RequestStreamingCall, + ProcessSimpleRPC)); } std::unique_ptr CreateAsyncGenericServer(const ServerConfig &config) { return std::unique_ptr( diff --git a/test/cpp/util/benchmark_config.cc b/test/cpp/util/benchmark_config.cc index 3c38221b4c..746d3d7ae6 100644 --- a/test/cpp/util/benchmark_config.cc +++ b/test/cpp/util/benchmark_config.cc @@ -31,8 +31,8 @@ * */ -#include #include "test/cpp/util/benchmark_config.h" +#include DEFINE_bool(enable_log_reporter, true, "Enable reporting of benchmark results through GprLog"); diff --git a/test/cpp/util/byte_buffer_test.cc b/test/cpp/util/byte_buffer_test.cc index eb9dabcc2a..bc172e9717 100644 --- a/test/cpp/util/byte_buffer_test.cc +++ b/test/cpp/util/byte_buffer_test.cc @@ -36,8 +36,8 @@ #include #include -#include #include +#include #include namespace grpc { diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc index 5fdf519320..474ac282ce 100644 --- a/test/cpp/util/cli_call_test.cc +++ b/test/cpp/util/cli_call_test.cc @@ -33,18 +33,18 @@ #include "test/cpp/util/cli_call.h" -#include #include #include #include #include #include #include +#include #include +#include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/cpp/util/string_ref_helper.h" using grpc::testing::EchoRequest; diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc index f9b9f0c40a..68cf4114a8 100644 --- a/test/cpp/util/grpc_cli.cc +++ b/test/cpp/util/grpc_cli.cc @@ -65,11 +65,11 @@ #include #include -#include #include #include #include #include +#include #include "test/cpp/util/cli_call.h" #include "test/cpp/util/string_ref_helper.h" diff --git a/test/cpp/util/test_config.cc b/test/cpp/util/test_config.cc index e74f8fb14f..8711746129 100644 --- a/test/cpp/util/test_config.cc +++ b/test/cpp/util/test_config.cc @@ -31,8 +31,8 @@ * */ -#include #include "test/cpp/util/test_config.h" +#include // In some distros, gflags is in the namespace google, and in some others, // in gflags. This hack is enabling us to find both. diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc index e314fd6d75..9c09a73115 100644 --- a/test/cpp/util/test_credentials_provider.cc +++ b/test/cpp/util/test_credentials_provider.cc @@ -36,8 +36,8 @@ #include -#include #include +#include #include "test/core/end2end/data/ssl_test_data.h" diff --git a/test/cpp/util/time_test.cc b/test/cpp/util/time_test.cc index 48c6ce7697..e78c85b43a 100644 --- a/test/cpp/util/time_test.cc +++ b/test/cpp/util/time_test.cc @@ -31,8 +31,8 @@ * */ -#include #include +#include #include using std::chrono::duration_cast; -- cgit v1.2.3 From 2e1903638e13aae7f3d30faf17fb37969f339f59 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 25 Mar 2016 14:33:26 -0700 Subject: Fix copyrights --- include/grpc/byte_buffer_reader.h | 2 +- src/core/iomgr/endpoint_pair_windows.c | 2 +- src/core/iomgr/iomgr_posix.c | 2 +- src/core/iomgr/iomgr_windows.c | 2 +- src/core/iomgr/socket_utils_common_posix.c | 2 +- src/core/iomgr/socket_utils_linux.c | 2 +- src/core/iomgr/socket_windows.c | 2 +- src/core/iomgr/wakeup_fd_nospecial.c | 2 +- src/core/iomgr/wakeup_fd_posix.c | 2 +- src/core/json/json_string.c | 2 +- src/core/profiling/basic_timers.c | 2 +- src/core/statistics/census_log.c | 2 +- src/core/statistics/census_rpc_stats.c | 2 +- src/core/statistics/census_tracing.c | 2 +- src/core/statistics/hash_table.c | 2 +- src/core/statistics/window_stats.c | 2 +- src/core/support/cmdline.c | 2 +- src/core/support/cpu_linux.c | 2 +- src/core/support/env_posix.c | 2 +- src/core/support/histogram.c | 2 +- src/core/support/host_port.c | 2 +- src/core/support/log_android.c | 2 +- src/core/support/log_linux.c | 2 +- src/core/support/log_posix.c | 2 +- src/core/support/string_posix.c | 2 +- src/core/support/subprocess_posix.c | 2 +- src/core/support/thd_posix.c | 2 +- src/core/support/thd_win32.c | 2 +- src/core/surface/byte_buffer_reader.c | 2 +- src/core/surface/call_log_batch.c | 2 +- src/core/surface/event_string.c | 2 +- src/core/transport/chttp2/frame_data.c | 2 +- src/core/transport/chttp2/huffsyms.c | 2 +- src/core/transport/transport_op_string.c | 2 +- src/core/tsi/fake_transport_security.c | 2 +- src/cpp/client/insecure_credentials.cc | 2 +- src/cpp/common/create_auth_context.h | 2 +- src/cpp/common/insecure_create_auth_context.cc | 2 +- src/cpp/common/secure_create_auth_context.cc | 2 +- src/cpp/util/time.cc | 2 +- test/core/bad_client/tests/badreq.c | 2 +- test/core/bad_client/tests/connection_prefix.c | 2 +- test/core/bad_client/tests/headers.c | 2 +- test/core/bad_client/tests/initial_settings_frame.c | 2 +- test/core/bad_client/tests/server_registered_method.c | 2 +- test/core/bad_client/tests/simple_request.c | 2 +- test/core/bad_client/tests/unknown_frame.c | 2 +- test/core/bad_client/tests/window_overflow.c | 2 +- test/core/end2end/cq_verifier.c | 2 +- test/core/end2end/dualstack_socket_test.c | 2 +- test/core/end2end/fixtures/h2_census.c | 2 +- test/core/end2end/fixtures/h2_compress.c | 2 +- test/core/end2end/fixtures/h2_fakesec.c | 2 +- test/core/end2end/fixtures/h2_full+pipe.c | 2 +- test/core/end2end/fixtures/h2_full.c | 2 +- test/core/end2end/fixtures/h2_oauth2.c | 2 +- test/core/end2end/fixtures/h2_proxy.c | 2 +- test/core/end2end/fixtures/h2_uds.c | 2 +- test/core/end2end/no_server_test.c | 2 +- test/core/end2end/tests/bad_hostname.c | 2 +- test/core/end2end/tests/binary_metadata.c | 2 +- test/core/end2end/tests/call_creds.c | 2 +- test/core/end2end/tests/cancel_after_accept.c | 2 +- test/core/end2end/tests/cancel_after_client_done.c | 2 +- test/core/end2end/tests/cancel_after_invoke.c | 2 +- test/core/end2end/tests/cancel_before_invoke.c | 2 +- test/core/end2end/tests/cancel_in_a_vacuum.c | 2 +- test/core/end2end/tests/cancel_with_status.c | 2 +- test/core/end2end/tests/compressed_payload.c | 2 +- test/core/end2end/tests/default_host.c | 2 +- test/core/end2end/tests/empty_batch.c | 2 +- test/core/end2end/tests/high_initial_seqno.c | 2 +- test/core/end2end/tests/hpack_size.c | 2 +- test/core/end2end/tests/invoke_large_request.c | 2 +- test/core/end2end/tests/large_metadata.c | 2 +- test/core/end2end/tests/max_concurrent_streams.c | 2 +- test/core/end2end/tests/max_message_length.c | 2 +- test/core/end2end/tests/negative_deadline.c | 2 +- test/core/end2end/tests/no_op.c | 2 +- test/core/end2end/tests/payload.c | 2 +- test/core/end2end/tests/ping_pong_streaming.c | 2 +- test/core/end2end/tests/registered_call.c | 2 +- test/core/end2end/tests/request_with_flags.c | 2 +- test/core/end2end/tests/request_with_payload.c | 2 +- test/core/end2end/tests/server_finishes_request.c | 2 +- test/core/end2end/tests/simple_delayed_request.c | 2 +- test/core/end2end/tests/simple_request.c | 2 +- test/core/end2end/tests/trailing_metadata.c | 2 +- test/core/fling/fling_stream_test.c | 2 +- test/core/fling/fling_test.c | 2 +- test/core/iomgr/fd_conservation_posix_test.c | 2 +- test/core/iomgr/resolve_address_test.c | 2 +- test/core/json/json_rewrite_test.c | 2 +- test/core/json/json_stream_error_test.c | 2 +- test/core/json/json_test.c | 2 +- test/core/network_benchmarks/low_level_ping_pong.c | 2 +- test/core/statistics/census_stub_test.c | 2 +- test/core/statistics/hash_table_test.c | 2 +- test/core/statistics/rpc_stats_test.c | 2 +- test/core/statistics/trace_test.c | 2 +- test/core/statistics/window_stats_test.c | 2 +- test/core/support/tls_test.c | 2 +- test/core/support/useful_test.c | 2 +- test/core/surface/byte_buffer_reader_test.c | 2 +- test/core/surface/completion_queue_test.c | 2 +- test/core/transport/chttp2/hpack_encoder_test.c | 2 +- test/cpp/common/auth_property_iterator_test.cc | 2 +- test/cpp/common/secure_auth_context_test.cc | 2 +- test/cpp/interop/client_helper.cc | 2 +- test/cpp/interop/interop_test.cc | 2 +- test/cpp/interop/server_helper.h | 2 +- test/cpp/qps/perf_db_client.h | 2 +- test/cpp/util/benchmark_config.cc | 2 +- test/cpp/util/grpc_cli.cc | 2 +- test/cpp/util/test_config.cc | 2 +- tools/dockerfile/grpc_clang_format/Dockerfile | 2 +- 116 files changed, 116 insertions(+), 116 deletions(-) (limited to 'src') diff --git a/include/grpc/byte_buffer_reader.h b/include/grpc/byte_buffer_reader.h index 9a1c6178ab..600bd3810a 100644 --- a/include/grpc/byte_buffer_reader.h +++ b/include/grpc/byte_buffer_reader.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/iomgr/endpoint_pair_windows.c b/src/core/iomgr/endpoint_pair_windows.c index 13dcee3b59..2024f58143 100644 --- a/src/core/iomgr/endpoint_pair_windows.c +++ b/src/core/iomgr/endpoint_pair_windows.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/iomgr/iomgr_posix.c b/src/core/iomgr/iomgr_posix.c index feb21d331f..2f7f34746b 100644 --- a/src/core/iomgr/iomgr_posix.c +++ b/src/core/iomgr/iomgr_posix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/iomgr/iomgr_windows.c b/src/core/iomgr/iomgr_windows.c index 6de41b3c41..2d104130f7 100644 --- a/src/core/iomgr/iomgr_windows.c +++ b/src/core/iomgr/iomgr_windows.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/iomgr/socket_utils_common_posix.c b/src/core/iomgr/socket_utils_common_posix.c index 772a17bd50..570daccc9e 100644 --- a/src/core/iomgr/socket_utils_common_posix.c +++ b/src/core/iomgr/socket_utils_common_posix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/iomgr/socket_utils_linux.c b/src/core/iomgr/socket_utils_linux.c index 5b9a236122..e16885f231 100644 --- a/src/core/iomgr/socket_utils_linux.c +++ b/src/core/iomgr/socket_utils_linux.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/iomgr/socket_windows.c b/src/core/iomgr/socket_windows.c index 7096d25920..b27bb1cfb0 100644 --- a/src/core/iomgr/socket_windows.c +++ b/src/core/iomgr/socket_windows.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/iomgr/wakeup_fd_nospecial.c b/src/core/iomgr/wakeup_fd_nospecial.c index 1ec3d9b3f7..7b2be9ed52 100644 --- a/src/core/iomgr/wakeup_fd_nospecial.c +++ b/src/core/iomgr/wakeup_fd_nospecial.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/iomgr/wakeup_fd_posix.c b/src/core/iomgr/wakeup_fd_posix.c index c0cfe3129a..07778c408e 100644 --- a/src/core/iomgr/wakeup_fd_posix.c +++ b/src/core/iomgr/wakeup_fd_posix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/json/json_string.c b/src/core/json/json_string.c index cb4f76a6b6..d4ebce18e1 100644 --- a/src/core/json/json_string.c +++ b/src/core/json/json_string.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/profiling/basic_timers.c b/src/core/profiling/basic_timers.c index 0b6f6b78ee..3067f52c21 100644 --- a/src/core/profiling/basic_timers.c +++ b/src/core/profiling/basic_timers.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/statistics/census_log.c b/src/core/statistics/census_log.c index 6368b09ed9..3802d1cc7a 100644 --- a/src/core/statistics/census_log.c +++ b/src/core/statistics/census_log.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/statistics/census_rpc_stats.c b/src/core/statistics/census_rpc_stats.c index 01778cd0b0..c78d6fd612 100644 --- a/src/core/statistics/census_rpc_stats.c +++ b/src/core/statistics/census_rpc_stats.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/statistics/census_tracing.c b/src/core/statistics/census_tracing.c index a7841f5ebd..ad82498eba 100644 --- a/src/core/statistics/census_tracing.c +++ b/src/core/statistics/census_tracing.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/statistics/hash_table.c b/src/core/statistics/hash_table.c index 26d83c801d..3ef79c0d7d 100644 --- a/src/core/statistics/hash_table.c +++ b/src/core/statistics/hash_table.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/statistics/window_stats.c b/src/core/statistics/window_stats.c index 51425a20ee..eb296865a0 100644 --- a/src/core/statistics/window_stats.c +++ b/src/core/statistics/window_stats.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/support/cmdline.c b/src/core/support/cmdline.c index 4f1b165d6f..eff46a1655 100644 --- a/src/core/support/cmdline.c +++ b/src/core/support/cmdline.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/support/cpu_linux.c b/src/core/support/cpu_linux.c index d6f7e7d3da..5597df2d03 100644 --- a/src/core/support/cpu_linux.c +++ b/src/core/support/cpu_linux.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/support/env_posix.c b/src/core/support/env_posix.c index 68cdf123ac..256212be76 100644 --- a/src/core/support/env_posix.c +++ b/src/core/support/env_posix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/support/histogram.c b/src/core/support/histogram.c index 7b016bbc78..62227be1a6 100644 --- a/src/core/support/histogram.c +++ b/src/core/support/histogram.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/support/host_port.c b/src/core/support/host_port.c index f28ed4b0c2..31243a7221 100644 --- a/src/core/support/host_port.c +++ b/src/core/support/host_port.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/support/log_android.c b/src/core/support/log_android.c index 94c8100fd7..640c9d7099 100644 --- a/src/core/support/log_android.c +++ b/src/core/support/log_android.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/support/log_linux.c b/src/core/support/log_linux.c index 6d4b63bbe0..e60512c526 100644 --- a/src/core/support/log_linux.c +++ b/src/core/support/log_linux.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/support/log_posix.c b/src/core/support/log_posix.c index 6ae6320767..7429dd0a2c 100644 --- a/src/core/support/log_posix.c +++ b/src/core/support/log_posix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/support/string_posix.c b/src/core/support/string_posix.c index c804ed5ded..a73b3106a5 100644 --- a/src/core/support/string_posix.c +++ b/src/core/support/string_posix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/support/subprocess_posix.c b/src/core/support/subprocess_posix.c index 4f4de9298e..662e7dd999 100644 --- a/src/core/support/subprocess_posix.c +++ b/src/core/support/subprocess_posix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/support/thd_posix.c b/src/core/support/thd_posix.c index 89832e3ce1..4d874d3656 100644 --- a/src/core/support/thd_posix.c +++ b/src/core/support/thd_posix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/support/thd_win32.c b/src/core/support/thd_win32.c index 6deb3140eb..630eb7f625 100644 --- a/src/core/support/thd_win32.c +++ b/src/core/support/thd_win32.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/surface/byte_buffer_reader.c b/src/core/surface/byte_buffer_reader.c index edecddbced..4a418faaed 100644 --- a/src/core/surface/byte_buffer_reader.c +++ b/src/core/surface/byte_buffer_reader.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/surface/call_log_batch.c b/src/core/surface/call_log_batch.c index 1006a26157..044211616c 100644 --- a/src/core/surface/call_log_batch.c +++ b/src/core/surface/call_log_batch.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/surface/event_string.c b/src/core/surface/event_string.c index 17752715bc..85a372b9ad 100644 --- a/src/core/surface/event_string.c +++ b/src/core/surface/event_string.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/transport/chttp2/frame_data.c b/src/core/transport/chttp2/frame_data.c index d801ac664f..6cc6d4eaf2 100644 --- a/src/core/transport/chttp2/frame_data.c +++ b/src/core/transport/chttp2/frame_data.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/transport/chttp2/huffsyms.c b/src/core/transport/chttp2/huffsyms.c index 6f5cf6a2a9..ebc85d3378 100644 --- a/src/core/transport/chttp2/huffsyms.c +++ b/src/core/transport/chttp2/huffsyms.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/transport/transport_op_string.c b/src/core/transport/transport_op_string.c index 08eda360c6..8453412480 100644 --- a/src/core/transport/transport_op_string.c +++ b/src/core/transport/transport_op_string.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c index 7a9eb87470..c0106f7a33 100644 --- a/src/core/tsi/fake_transport_security.c +++ b/src/core/tsi/fake_transport_security.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 13019a7117..efea02995a 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/cpp/common/create_auth_context.h b/src/cpp/common/create_auth_context.h index 387407bfec..c53055503f 100644 --- a/src/cpp/common/create_auth_context.h +++ b/src/cpp/common/create_auth_context.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/cpp/common/insecure_create_auth_context.cc b/src/cpp/common/insecure_create_auth_context.cc index 258f02c2ad..7ec5d9bd12 100644 --- a/src/cpp/common/insecure_create_auth_context.cc +++ b/src/cpp/common/insecure_create_auth_context.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/cpp/common/secure_create_auth_context.cc b/src/cpp/common/secure_create_auth_context.cc index 51ddea46a3..d7cf803fde 100644 --- a/src/cpp/common/secure_create_auth_context.cc +++ b/src/cpp/common/secure_create_auth_context.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/cpp/util/time.cc b/src/cpp/util/time.cc index c43d848cc6..bb5fce389d 100644 --- a/src/cpp/util/time.cc +++ b/src/cpp/util/time.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/bad_client/tests/badreq.c b/test/core/bad_client/tests/badreq.c index 024a1e7953..95d46d5731 100644 --- a/test/core/bad_client/tests/badreq.c +++ b/test/core/bad_client/tests/badreq.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/bad_client/tests/connection_prefix.c b/test/core/bad_client/tests/connection_prefix.c index 8d74124b19..000ecca6c6 100644 --- a/test/core/bad_client/tests/connection_prefix.c +++ b/test/core/bad_client/tests/connection_prefix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/bad_client/tests/headers.c b/test/core/bad_client/tests/headers.c index 81a07de442..4ecdb64139 100644 --- a/test/core/bad_client/tests/headers.c +++ b/test/core/bad_client/tests/headers.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/bad_client/tests/initial_settings_frame.c b/test/core/bad_client/tests/initial_settings_frame.c index 108b0bd398..2104892766 100644 --- a/test/core/bad_client/tests/initial_settings_frame.c +++ b/test/core/bad_client/tests/initial_settings_frame.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/bad_client/tests/server_registered_method.c b/test/core/bad_client/tests/server_registered_method.c index 19dfeb3355..d280804687 100644 --- a/test/core/bad_client/tests/server_registered_method.c +++ b/test/core/bad_client/tests/server_registered_method.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/bad_client/tests/simple_request.c b/test/core/bad_client/tests/simple_request.c index f90ffea188..e535be1527 100644 --- a/test/core/bad_client/tests/simple_request.c +++ b/test/core/bad_client/tests/simple_request.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/bad_client/tests/unknown_frame.c b/test/core/bad_client/tests/unknown_frame.c index cc8e2157f2..729a6d9a75 100644 --- a/test/core/bad_client/tests/unknown_frame.c +++ b/test/core/bad_client/tests/unknown_frame.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/bad_client/tests/window_overflow.c b/test/core/bad_client/tests/window_overflow.c index 0ac161097f..a9117de36a 100644 --- a/test/core/bad_client/tests/window_overflow.c +++ b/test/core/bad_client/tests/window_overflow.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c index 59fa6cf74b..3687f7caf4 100644 --- a/test/core/end2end/cq_verifier.c +++ b/test/core/end2end/cq_verifier.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c index b93149e4c0..77589a7eee 100644 --- a/test/core/end2end/dualstack_socket_test.c +++ b/test/core/end2end/dualstack_socket_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/fixtures/h2_census.c b/test/core/end2end/fixtures/h2_census.c index ca2222752b..4d89a8f8c3 100644 --- a/test/core/end2end/fixtures/h2_census.c +++ b/test/core/end2end/fixtures/h2_census.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/fixtures/h2_compress.c b/test/core/end2end/fixtures/h2_compress.c index ea85c34460..19a2495eaf 100644 --- a/test/core/end2end/fixtures/h2_compress.c +++ b/test/core/end2end/fixtures/h2_compress.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/fixtures/h2_fakesec.c b/test/core/end2end/fixtures/h2_fakesec.c index e8e42089ef..8be8e35b1a 100644 --- a/test/core/end2end/fixtures/h2_fakesec.c +++ b/test/core/end2end/fixtures/h2_fakesec.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/fixtures/h2_full+pipe.c b/test/core/end2end/fixtures/h2_full+pipe.c index 2f6402580a..f2d72f0445 100644 --- a/test/core/end2end/fixtures/h2_full+pipe.c +++ b/test/core/end2end/fixtures/h2_full+pipe.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/fixtures/h2_full.c b/test/core/end2end/fixtures/h2_full.c index 32af542e50..c56d2fc073 100644 --- a/test/core/end2end/fixtures/h2_full.c +++ b/test/core/end2end/fixtures/h2_full.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/fixtures/h2_oauth2.c b/test/core/end2end/fixtures/h2_oauth2.c index 36670f5473..279061b99e 100644 --- a/test/core/end2end/fixtures/h2_oauth2.c +++ b/test/core/end2end/fixtures/h2_oauth2.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/fixtures/h2_proxy.c b/test/core/end2end/fixtures/h2_proxy.c index 567220b468..1e9aa624e3 100644 --- a/test/core/end2end/fixtures/h2_proxy.c +++ b/test/core/end2end/fixtures/h2_proxy.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/fixtures/h2_uds.c b/test/core/end2end/fixtures/h2_uds.c index 593cd0d7d5..3228c055a0 100644 --- a/test/core/end2end/fixtures/h2_uds.c +++ b/test/core/end2end/fixtures/h2_uds.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c index 7a5cd2335f..c1be55df13 100644 --- a/test/core/end2end/no_server_test.c +++ b/test/core/end2end/no_server_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c index 01dd39adaf..fe7a275244 100644 --- a/test/core/end2end/tests/bad_hostname.c +++ b/test/core/end2end/tests/bad_hostname.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/binary_metadata.c b/test/core/end2end/tests/binary_metadata.c index 54583b09bc..a4f4afac65 100644 --- a/test/core/end2end/tests/binary_metadata.c +++ b/test/core/end2end/tests/binary_metadata.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/call_creds.c b/test/core/end2end/tests/call_creds.c index 388810e96b..417f7e82bd 100644 --- a/test/core/end2end/tests/call_creds.c +++ b/test/core/end2end/tests/call_creds.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c index 08d0ef6e51..2025f1191f 100644 --- a/test/core/end2end/tests/cancel_after_accept.c +++ b/test/core/end2end/tests/cancel_after_accept.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/cancel_after_client_done.c b/test/core/end2end/tests/cancel_after_client_done.c index f85ffad118..bc958a6ff3 100644 --- a/test/core/end2end/tests/cancel_after_client_done.c +++ b/test/core/end2end/tests/cancel_after_client_done.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c index e7d6e0098a..5bab10e030 100644 --- a/test/core/end2end/tests/cancel_after_invoke.c +++ b/test/core/end2end/tests/cancel_after_invoke.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c index a4f47f01fa..8c0becd1c8 100644 --- a/test/core/end2end/tests/cancel_before_invoke.c +++ b/test/core/end2end/tests/cancel_before_invoke.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c index 73a6fc452a..7bea7d7e65 100644 --- a/test/core/end2end/tests/cancel_in_a_vacuum.c +++ b/test/core/end2end/tests/cancel_in_a_vacuum.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c index e47eb41896..135bdf026c 100644 --- a/test/core/end2end/tests/cancel_with_status.c +++ b/test/core/end2end/tests/cancel_with_status.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c index c76360ff9b..c9092e3394 100644 --- a/test/core/end2end/tests/compressed_payload.c +++ b/test/core/end2end/tests/compressed_payload.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/default_host.c b/test/core/end2end/tests/default_host.c index e60d3fa471..5455428144 100644 --- a/test/core/end2end/tests/default_host.c +++ b/test/core/end2end/tests/default_host.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c index a0672c8583..53b5ca5e6b 100644 --- a/test/core/end2end/tests/empty_batch.c +++ b/test/core/end2end/tests/empty_batch.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/high_initial_seqno.c b/test/core/end2end/tests/high_initial_seqno.c index e7a169cb7f..72007821c8 100644 --- a/test/core/end2end/tests/high_initial_seqno.c +++ b/test/core/end2end/tests/high_initial_seqno.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/hpack_size.c b/test/core/end2end/tests/hpack_size.c index e525956958..189131870e 100644 --- a/test/core/end2end/tests/hpack_size.c +++ b/test/core/end2end/tests/hpack_size.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c index 28c0e36461..7f03ebbc6f 100644 --- a/test/core/end2end/tests/invoke_large_request.c +++ b/test/core/end2end/tests/invoke_large_request.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/large_metadata.c b/test/core/end2end/tests/large_metadata.c index 173c20996e..4b77974470 100644 --- a/test/core/end2end/tests/large_metadata.c +++ b/test/core/end2end/tests/large_metadata.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c index 60e9ecd7d8..05472bf19e 100644 --- a/test/core/end2end/tests/max_concurrent_streams.c +++ b/test/core/end2end/tests/max_concurrent_streams.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c index 00a83ecb33..2202306325 100644 --- a/test/core/end2end/tests/max_message_length.c +++ b/test/core/end2end/tests/max_message_length.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c index f80f18710e..5de82c9795 100644 --- a/test/core/end2end/tests/negative_deadline.c +++ b/test/core/end2end/tests/negative_deadline.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c index 9dda569cb9..efcd496071 100644 --- a/test/core/end2end/tests/no_op.c +++ b/test/core/end2end/tests/no_op.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c index e9272b6bce..74af28ddc3 100644 --- a/test/core/end2end/tests/payload.c +++ b/test/core/end2end/tests/payload.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c index ac4e810573..7af01497c5 100644 --- a/test/core/end2end/tests/ping_pong_streaming.c +++ b/test/core/end2end/tests/ping_pong_streaming.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c index 2a32ee07bd..4051ded1f8 100644 --- a/test/core/end2end/tests/registered_call.c +++ b/test/core/end2end/tests/registered_call.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/request_with_flags.c b/test/core/end2end/tests/request_with_flags.c index e9fa5b500c..f480009f00 100644 --- a/test/core/end2end/tests/request_with_flags.c +++ b/test/core/end2end/tests/request_with_flags.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c index 9866d39000..07f9993d24 100644 --- a/test/core/end2end/tests/request_with_payload.c +++ b/test/core/end2end/tests/request_with_payload.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c index d406dc3054..a7d1661f56 100644 --- a/test/core/end2end/tests/server_finishes_request.c +++ b/test/core/end2end/tests/server_finishes_request.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c index bb9d462cef..e9f5a38c76 100644 --- a/test/core/end2end/tests/simple_delayed_request.c +++ b/test/core/end2end/tests/simple_delayed_request.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c index fd9788d0ba..a8ed79330d 100644 --- a/test/core/end2end/tests/simple_request.c +++ b/test/core/end2end/tests/simple_request.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/end2end/tests/trailing_metadata.c b/test/core/end2end/tests/trailing_metadata.c index 99e1e2264a..03f4f3e79b 100644 --- a/test/core/end2end/tests/trailing_metadata.c +++ b/test/core/end2end/tests/trailing_metadata.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/fling/fling_stream_test.c b/test/core/fling/fling_stream_test.c index 08b703ff30..ff3d919b05 100644 --- a/test/core/fling/fling_stream_test.c +++ b/test/core/fling/fling_stream_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/fling/fling_test.c b/test/core/fling/fling_test.c index 28c0d75be7..4e16b7f1b4 100644 --- a/test/core/fling/fling_test.c +++ b/test/core/fling/fling_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/iomgr/fd_conservation_posix_test.c b/test/core/iomgr/fd_conservation_posix_test.c index fc983e026a..c38f509b16 100644 --- a/test/core/iomgr/fd_conservation_posix_test.c +++ b/test/core/iomgr/fd_conservation_posix_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c index 2e574b58c3..b2a09978e6 100644 --- a/test/core/iomgr/resolve_address_test.c +++ b/test/core/iomgr/resolve_address_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/json/json_rewrite_test.c b/test/core/json/json_rewrite_test.c index fc725610b6..1916d4b86c 100644 --- a/test/core/json/json_rewrite_test.c +++ b/test/core/json/json_rewrite_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/json/json_stream_error_test.c b/test/core/json/json_stream_error_test.c index 11bdb9e554..3b07fcd38e 100644 --- a/test/core/json/json_stream_error_test.c +++ b/test/core/json/json_stream_error_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/json/json_test.c b/test/core/json/json_test.c index a5f3e08fa6..e9b81e2021 100644 --- a/test/core/json/json_test.c +++ b/test/core/json/json_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/network_benchmarks/low_level_ping_pong.c b/test/core/network_benchmarks/low_level_ping_pong.c index a15debe604..7ed3372d5d 100644 --- a/test/core/network_benchmarks/low_level_ping_pong.c +++ b/test/core/network_benchmarks/low_level_ping_pong.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/statistics/census_stub_test.c b/test/core/statistics/census_stub_test.c index 6514ac9981..e734a34f55 100644 --- a/test/core/statistics/census_stub_test.c +++ b/test/core/statistics/census_stub_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/statistics/hash_table_test.c b/test/core/statistics/hash_table_test.c index 9b2b683393..7ff5bb77ad 100644 --- a/test/core/statistics/hash_table_test.c +++ b/test/core/statistics/hash_table_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/statistics/rpc_stats_test.c b/test/core/statistics/rpc_stats_test.c index 1f9c445f26..3ece3caaf3 100644 --- a/test/core/statistics/rpc_stats_test.c +++ b/test/core/statistics/rpc_stats_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/statistics/trace_test.c b/test/core/statistics/trace_test.c index 8fcef4ac1b..2c64e89ddd 100644 --- a/test/core/statistics/trace_test.c +++ b/test/core/statistics/trace_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/statistics/window_stats_test.c b/test/core/statistics/window_stats_test.c index b8adb053f3..9ed7ee1fac 100644 --- a/test/core/statistics/window_stats_test.c +++ b/test/core/statistics/window_stats_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/support/tls_test.c b/test/core/support/tls_test.c index 7b732ee10e..7b73e5beb7 100644 --- a/test/core/support/tls_test.c +++ b/test/core/support/tls_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/support/useful_test.c b/test/core/support/useful_test.c index 7d190228bd..08a8cc90a9 100644 --- a/test/core/support/useful_test.c +++ b/test/core/support/useful_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/surface/byte_buffer_reader_test.c b/test/core/surface/byte_buffer_reader_test.c index c7ab22de8e..c8aacdb017 100644 --- a/test/core/surface/byte_buffer_reader_test.c +++ b/test/core/surface/byte_buffer_reader_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c index 7ad5dc0b41..4f534de0f6 100644 --- a/test/core/surface/completion_queue_test.c +++ b/test/core/surface/completion_queue_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c index aa1bb460ba..f5de087bac 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.c +++ b/test/core/transport/chttp2/hpack_encoder_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cpp/common/auth_property_iterator_test.cc b/test/cpp/common/auth_property_iterator_test.cc index 9fe0801cc3..4c6dd6039c 100644 --- a/test/cpp/common/auth_property_iterator_test.cc +++ b/test/cpp/common/auth_property_iterator_test.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cpp/common/secure_auth_context_test.cc b/test/cpp/common/secure_auth_context_test.cc index 250388f88b..123d4947e0 100644 --- a/test/cpp/common/secure_auth_context_test.cc +++ b/test/cpp/common/secure_auth_context_test.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc index c8b1e505c1..029b967801 100644 --- a/test/cpp/interop/client_helper.cc +++ b/test/cpp/interop/client_helper.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cpp/interop/interop_test.cc b/test/cpp/interop/interop_test.cc index 019d6aefd7..f0fccf4615 100644 --- a/test/cpp/interop/interop_test.cc +++ b/test/cpp/interop/interop_test.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cpp/interop/server_helper.h b/test/cpp/interop/server_helper.h index 12865e4032..38c2fba9cf 100644 --- a/test/cpp/interop/server_helper.h +++ b/test/cpp/interop/server_helper.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cpp/qps/perf_db_client.h b/test/cpp/qps/perf_db_client.h index b74c70d86b..668083b811 100644 --- a/test/cpp/qps/perf_db_client.h +++ b/test/cpp/qps/perf_db_client.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cpp/util/benchmark_config.cc b/test/cpp/util/benchmark_config.cc index 746d3d7ae6..5c3a4cf35d 100644 --- a/test/cpp/util/benchmark_config.cc +++ b/test/cpp/util/benchmark_config.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc index 68cf4114a8..0b0bc20a35 100644 --- a/test/cpp/util/grpc_cli.cc +++ b/test/cpp/util/grpc_cli.cc @@ -1,6 +1,6 @@ /* - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cpp/util/test_config.cc b/test/cpp/util/test_config.cc index 8711746129..c446ae55c7 100644 --- a/test/cpp/util/test_config.cc +++ b/test/cpp/util/test_config.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/tools/dockerfile/grpc_clang_format/Dockerfile b/tools/dockerfile/grpc_clang_format/Dockerfile index 41239e9c23..be2ffc58cf 100644 --- a/tools/dockerfile/grpc_clang_format/Dockerfile +++ b/tools/dockerfile/grpc_clang_format/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without -- cgit v1.2.3 From 534ce4eb934c02c2f81c61be59964d93990bf6b8 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 21 Mar 2016 14:41:29 -0700 Subject: Fixes --- src/core/iomgr/sockaddr_win32.h | 4 +++- src/core/iomgr/socket_windows.c | 4 +++- src/core/support/stack_lockfree.c | 8 ++++---- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/sockaddr_win32.h b/src/core/iomgr/sockaddr_win32.h index bdec72c761..ef306e3cc3 100644 --- a/src/core/iomgr/sockaddr_win32.h +++ b/src/core/iomgr/sockaddr_win32.h @@ -34,8 +34,10 @@ #ifndef GRPC_CORE_IOMGR_SOCKADDR_WIN32_H #define GRPC_CORE_IOMGR_SOCKADDR_WIN32_H -#include #include #include +// must be included after the above +#include + #endif /* GRPC_CORE_IOMGR_SOCKADDR_WIN32_H */ diff --git a/src/core/iomgr/socket_windows.c b/src/core/iomgr/socket_windows.c index b27bb1cfb0..c1f419e273 100644 --- a/src/core/iomgr/socket_windows.c +++ b/src/core/iomgr/socket_windows.c @@ -35,9 +35,11 @@ #ifdef GPR_WINSOCK_SOCKET -#include #include +// must be included after winsock2.h +#include + #include #include #include diff --git a/src/core/support/stack_lockfree.c b/src/core/support/stack_lockfree.c index 51d1c42eb4..8e0bbfaee8 100644 --- a/src/core/support/stack_lockfree.c +++ b/src/core/support/stack_lockfree.c @@ -64,10 +64,10 @@ typedef union lockfree_node { struct lockfree_node_contents contents; } lockfree_node; -#define ENTRY_ALIGNMENT_BITS 3 /* make sure that entries aligned to 8-bytes */ -#define INVALID_ENTRY_INDEX \ - ((1 << 16) - 1) /* reserve this entry as invalid \ - */ +/* make sure that entries aligned to 8-bytes */ +#define ENTRY_ALIGNMENT_BITS 3 +/* reserve this entry as invalid */ +#define INVALID_ENTRY_INDEX ((1 << 16) - 1) struct gpr_stack_lockfree { lockfree_node *entries; -- cgit v1.2.3 From f23078cbd302d32649537eedda1769c5685228d8 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 25 Mar 2016 17:07:29 -0700 Subject: Stage #1 of core breakup: move everything under lib --- BUILD | 1948 ++++++++++---------- Makefile | 736 ++++---- binding.gyp | 410 ++-- build.yaml | 722 ++++---- config.m4 | 446 ++--- gRPC.podspec | 1006 +++++----- grpc.gemspec | 708 +++---- package.json | 708 +++---- package.xml | 708 +++---- src/core/census/README.md | 76 - src/core/census/aggregation.h | 66 - src/core/census/context.c | 509 ----- src/core/census/grpc_context.c | 53 - src/core/census/grpc_filter.c | 198 -- src/core/census/grpc_filter.h | 44 - src/core/census/grpc_plugin.c | 70 - src/core/census/grpc_plugin.h | 40 - src/core/census/initialize.c | 54 - src/core/census/mlog.c | 600 ------ src/core/census/mlog.h | 95 - src/core/census/operation.c | 63 - src/core/census/placeholders.c | 109 -- src/core/census/rpc_metric_id.h | 51 - src/core/census/tracing.c | 45 - src/core/channel/channel_args.c | 271 --- src/core/channel/channel_args.h | 94 - src/core/channel/channel_stack.c | 262 --- src/core/channel/channel_stack.h | 260 --- src/core/channel/channel_stack_builder.c | 258 --- src/core/channel/channel_stack_builder.h | 155 -- src/core/channel/client_channel.c | 526 ------ src/core/channel/client_channel.h | 63 - src/core/channel/compress_filter.c | 304 --- src/core/channel/compress_filter.h | 65 - src/core/channel/connected_channel.c | 176 -- src/core/channel/connected_channel.h | 42 - src/core/channel/context.h | 49 - src/core/channel/http_client_filter.c | 255 --- src/core/channel/http_client_filter.h | 44 - src/core/channel/http_server_filter.c | 240 --- src/core/channel/http_server_filter.h | 42 - src/core/channel/subchannel_call_holder.c | 259 --- src/core/channel/subchannel_call_holder.h | 97 - src/core/client_config/README.md | 66 - src/core/client_config/client_config.c | 74 - src/core/client_config/client_config.h | 53 - src/core/client_config/connector.c | 55 - src/core/client_config/connector.h | 92 - .../client_config/default_initial_connect_string.c | 39 - src/core/client_config/initial_connect_string.c | 53 - src/core/client_config/initial_connect_string.h | 50 - .../client_config/lb_policies/load_balancer_api.c | 163 -- .../client_config/lb_policies/load_balancer_api.h | 85 - src/core/client_config/lb_policies/pick_first.c | 421 ----- src/core/client_config/lb_policies/pick_first.h | 43 - src/core/client_config/lb_policies/round_robin.c | 542 ------ src/core/client_config/lb_policies/round_robin.h | 46 - src/core/client_config/lb_policy.c | 134 -- src/core/client_config/lb_policy.h | 144 -- src/core/client_config/lb_policy_factory.c | 48 - src/core/client_config/lb_policy_factory.h | 73 - src/core/client_config/lb_policy_registry.c | 88 - src/core/client_config/lb_policy_registry.h | 54 - src/core/client_config/resolver.c | 82 - src/core/client_config/resolver.h | 94 - src/core/client_config/resolver_factory.c | 55 - src/core/client_config/resolver_factory.h | 82 - src/core/client_config/resolver_registry.c | 137 -- src/core/client_config/resolver_registry.h | 65 - src/core/client_config/resolvers/dns_resolver.c | 309 ---- src/core/client_config/resolvers/dns_resolver.h | 42 - .../client_config/resolvers/sockaddr_resolver.c | 372 ---- .../client_config/resolvers/sockaddr_resolver.h | 50 - .../client_config/resolvers/zookeeper_resolver.c | 520 ------ .../client_config/resolvers/zookeeper_resolver.h | 42 - src/core/client_config/subchannel.c | 678 ------- src/core/client_config/subchannel.h | 174 -- src/core/client_config/subchannel_factory.c | 49 - src/core/client_config/subchannel_factory.h | 66 - src/core/client_config/subchannel_index.c | 262 --- src/core/client_config/subchannel_index.h | 77 - src/core/client_config/uri_parser.c | 242 --- src/core/client_config/uri_parser.h | 51 - src/core/compression/algorithm_metadata.h | 53 - src/core/compression/compression_algorithm.c | 203 -- src/core/compression/message_compress.c | 198 -- src/core/compression/message_compress.h | 52 - src/core/debug/trace.c | 136 -- src/core/debug/trace.h | 43 - src/core/http/format_request.c | 120 -- src/core/http/format_request.h | 45 - src/core/http/httpcli.c | 293 --- src/core/http/httpcli.h | 144 -- src/core/http/httpcli_security_connector.c | 188 -- src/core/http/parser.c | 313 ---- src/core/http/parser.h | 116 -- src/core/iomgr/closure.c | 98 - src/core/iomgr/closure.h | 98 - src/core/iomgr/endpoint.c | 67 - src/core/iomgr/endpoint.h | 102 - src/core/iomgr/endpoint_pair.h | 47 - src/core/iomgr/endpoint_pair_posix.c | 83 - src/core/iomgr/endpoint_pair_windows.c | 97 - src/core/iomgr/exec_ctx.c | 151 -- src/core/iomgr/exec_ctx.h | 98 - src/core/iomgr/executor.c | 143 -- src/core/iomgr/executor.h | 53 - src/core/iomgr/fd_posix.c | 454 ----- src/core/iomgr/fd_posix.h | 192 -- src/core/iomgr/iocp_windows.c | 208 --- src/core/iomgr/iocp_windows.h | 63 - src/core/iomgr/iomgr.c | 175 -- src/core/iomgr/iomgr.h | 43 - src/core/iomgr/iomgr_internal.h | 62 - src/core/iomgr/iomgr_posix.c | 52 - src/core/iomgr/iomgr_posix.h | 39 - src/core/iomgr/iomgr_windows.c | 73 - src/core/iomgr/pollset.h | 94 - src/core/iomgr/pollset_multipoller_with_epoll.c | 324 ---- .../iomgr/pollset_multipoller_with_poll_posix.c | 234 --- src/core/iomgr/pollset_posix.c | 633 ------- src/core/iomgr/pollset_posix.h | 153 -- src/core/iomgr/pollset_set.h | 61 - src/core/iomgr/pollset_set_posix.c | 202 -- src/core/iomgr/pollset_set_posix.h | 45 - src/core/iomgr/pollset_set_windows.c | 60 - src/core/iomgr/pollset_set_windows.h | 39 - src/core/iomgr/pollset_windows.c | 240 --- src/core/iomgr/pollset_windows.h | 75 - src/core/iomgr/resolve_address.h | 72 - src/core/iomgr/resolve_address_posix.c | 178 -- src/core/iomgr/resolve_address_windows.c | 169 -- src/core/iomgr/sockaddr.h | 47 - src/core/iomgr/sockaddr_posix.h | 44 - src/core/iomgr/sockaddr_utils.c | 227 --- src/core/iomgr/sockaddr_utils.h | 89 - src/core/iomgr/sockaddr_win32.h | 43 - src/core/iomgr/socket_utils_common_posix.c | 208 --- src/core/iomgr/socket_utils_linux.c | 51 - src/core/iomgr/socket_utils_posix.c | 70 - src/core/iomgr/socket_utils_posix.h | 113 -- src/core/iomgr/socket_windows.c | 100 - src/core/iomgr/socket_windows.h | 111 -- src/core/iomgr/tcp_client.h | 53 - src/core/iomgr/tcp_client_posix.c | 306 --- src/core/iomgr/tcp_client_windows.c | 221 --- src/core/iomgr/tcp_posix.c | 493 ----- src/core/iomgr/tcp_posix.h | 71 - src/core/iomgr/tcp_server.h | 103 -- src/core/iomgr/tcp_server_posix.c | 607 ------ src/core/iomgr/tcp_server_windows.c | 557 ------ src/core/iomgr/tcp_windows.c | 402 ---- src/core/iomgr/tcp_windows.h | 57 - src/core/iomgr/time_averaged_stats.c | 77 - src/core/iomgr/time_averaged_stats.h | 88 - src/core/iomgr/timer.c | 356 ---- src/core/iomgr/timer.h | 108 -- src/core/iomgr/timer_heap.c | 146 -- src/core/iomgr/timer_heap.h | 57 - src/core/iomgr/udp_server.c | 418 ----- src/core/iomgr/udp_server.h | 77 - src/core/iomgr/unix_sockets_posix.c | 103 -- src/core/iomgr/unix_sockets_posix.h | 61 - src/core/iomgr/unix_sockets_posix_noop.c | 61 - src/core/iomgr/wakeup_fd_eventfd.c | 85 - src/core/iomgr/wakeup_fd_nospecial.c | 51 - src/core/iomgr/wakeup_fd_pipe.c | 102 - src/core/iomgr/wakeup_fd_pipe.h | 41 - src/core/iomgr/wakeup_fd_posix.c | 72 - src/core/iomgr/wakeup_fd_posix.h | 101 - src/core/iomgr/workqueue.h | 83 - src/core/iomgr/workqueue_posix.c | 144 -- src/core/iomgr/workqueue_posix.h | 53 - src/core/iomgr/workqueue_windows.c | 40 - src/core/iomgr/workqueue_windows.h | 37 - src/core/json/json.c | 64 - src/core/json/json.h | 88 - src/core/json/json_common.h | 49 - src/core/json/json_reader.c | 659 ------- src/core/json/json_reader.h | 160 -- src/core/json/json_string.c | 379 ---- src/core/json/json_writer.c | 258 --- src/core/json/json_writer.h | 97 - src/core/lib/census/README.md | 76 + src/core/lib/census/aggregation.h | 66 + src/core/lib/census/context.c | 509 +++++ src/core/lib/census/grpc_context.c | 53 + src/core/lib/census/grpc_filter.c | 198 ++ src/core/lib/census/grpc_filter.h | 44 + src/core/lib/census/grpc_plugin.c | 70 + src/core/lib/census/grpc_plugin.h | 40 + src/core/lib/census/initialize.c | 54 + src/core/lib/census/mlog.c | 600 ++++++ src/core/lib/census/mlog.h | 95 + src/core/lib/census/operation.c | 63 + src/core/lib/census/placeholders.c | 109 ++ src/core/lib/census/rpc_metric_id.h | 51 + src/core/lib/census/tracing.c | 45 + src/core/lib/channel/channel_args.c | 271 +++ src/core/lib/channel/channel_args.h | 94 + src/core/lib/channel/channel_stack.c | 262 +++ src/core/lib/channel/channel_stack.h | 260 +++ src/core/lib/channel/channel_stack_builder.c | 258 +++ src/core/lib/channel/channel_stack_builder.h | 155 ++ src/core/lib/channel/client_channel.c | 526 ++++++ src/core/lib/channel/client_channel.h | 63 + src/core/lib/channel/compress_filter.c | 304 +++ src/core/lib/channel/compress_filter.h | 65 + src/core/lib/channel/connected_channel.c | 176 ++ src/core/lib/channel/connected_channel.h | 42 + src/core/lib/channel/context.h | 49 + src/core/lib/channel/http_client_filter.c | 255 +++ src/core/lib/channel/http_client_filter.h | 44 + src/core/lib/channel/http_server_filter.c | 240 +++ src/core/lib/channel/http_server_filter.h | 42 + src/core/lib/channel/subchannel_call_holder.c | 259 +++ src/core/lib/channel/subchannel_call_holder.h | 97 + src/core/lib/client_config/README.md | 66 + src/core/lib/client_config/client_config.c | 74 + src/core/lib/client_config/client_config.h | 53 + src/core/lib/client_config/connector.c | 55 + src/core/lib/client_config/connector.h | 92 + .../client_config/default_initial_connect_string.c | 39 + .../lib/client_config/initial_connect_string.c | 53 + .../lib/client_config/initial_connect_string.h | 50 + .../client_config/lb_policies/load_balancer_api.c | 163 ++ .../client_config/lb_policies/load_balancer_api.h | 85 + .../lib/client_config/lb_policies/pick_first.c | 421 +++++ .../lib/client_config/lb_policies/pick_first.h | 43 + .../lib/client_config/lb_policies/round_robin.c | 542 ++++++ .../lib/client_config/lb_policies/round_robin.h | 46 + src/core/lib/client_config/lb_policy.c | 134 ++ src/core/lib/client_config/lb_policy.h | 144 ++ src/core/lib/client_config/lb_policy_factory.c | 48 + src/core/lib/client_config/lb_policy_factory.h | 73 + src/core/lib/client_config/lb_policy_registry.c | 88 + src/core/lib/client_config/lb_policy_registry.h | 54 + src/core/lib/client_config/resolver.c | 82 + src/core/lib/client_config/resolver.h | 94 + src/core/lib/client_config/resolver_factory.c | 55 + src/core/lib/client_config/resolver_factory.h | 82 + src/core/lib/client_config/resolver_registry.c | 137 ++ src/core/lib/client_config/resolver_registry.h | 65 + .../lib/client_config/resolvers/dns_resolver.c | 309 ++++ .../lib/client_config/resolvers/dns_resolver.h | 42 + .../client_config/resolvers/sockaddr_resolver.c | 372 ++++ .../client_config/resolvers/sockaddr_resolver.h | 50 + .../client_config/resolvers/zookeeper_resolver.c | 520 ++++++ .../client_config/resolvers/zookeeper_resolver.h | 42 + src/core/lib/client_config/subchannel.c | 678 +++++++ src/core/lib/client_config/subchannel.h | 174 ++ src/core/lib/client_config/subchannel_factory.c | 49 + src/core/lib/client_config/subchannel_factory.h | 66 + src/core/lib/client_config/subchannel_index.c | 262 +++ src/core/lib/client_config/subchannel_index.h | 77 + src/core/lib/client_config/uri_parser.c | 242 +++ src/core/lib/client_config/uri_parser.h | 51 + src/core/lib/compression/algorithm_metadata.h | 53 + src/core/lib/compression/compression_algorithm.c | 203 ++ src/core/lib/compression/message_compress.c | 198 ++ src/core/lib/compression/message_compress.h | 52 + src/core/lib/debug/trace.c | 136 ++ src/core/lib/debug/trace.h | 43 + src/core/lib/http/format_request.c | 120 ++ src/core/lib/http/format_request.h | 45 + src/core/lib/http/httpcli.c | 293 +++ src/core/lib/http/httpcli.h | 144 ++ src/core/lib/http/httpcli_security_connector.c | 188 ++ src/core/lib/http/parser.c | 313 ++++ src/core/lib/http/parser.h | 116 ++ src/core/lib/iomgr/closure.c | 98 + src/core/lib/iomgr/closure.h | 98 + src/core/lib/iomgr/endpoint.c | 67 + src/core/lib/iomgr/endpoint.h | 102 + src/core/lib/iomgr/endpoint_pair.h | 47 + src/core/lib/iomgr/endpoint_pair_posix.c | 83 + src/core/lib/iomgr/endpoint_pair_windows.c | 97 + src/core/lib/iomgr/exec_ctx.c | 151 ++ src/core/lib/iomgr/exec_ctx.h | 98 + src/core/lib/iomgr/executor.c | 143 ++ src/core/lib/iomgr/executor.h | 53 + src/core/lib/iomgr/fd_posix.c | 454 +++++ src/core/lib/iomgr/fd_posix.h | 192 ++ src/core/lib/iomgr/iocp_windows.c | 208 +++ src/core/lib/iomgr/iocp_windows.h | 63 + src/core/lib/iomgr/iomgr.c | 175 ++ src/core/lib/iomgr/iomgr.h | 43 + src/core/lib/iomgr/iomgr_internal.h | 62 + src/core/lib/iomgr/iomgr_posix.c | 52 + src/core/lib/iomgr/iomgr_posix.h | 39 + src/core/lib/iomgr/iomgr_windows.c | 73 + src/core/lib/iomgr/pollset.h | 94 + .../lib/iomgr/pollset_multipoller_with_epoll.c | 324 ++++ .../iomgr/pollset_multipoller_with_poll_posix.c | 234 +++ src/core/lib/iomgr/pollset_posix.c | 633 +++++++ src/core/lib/iomgr/pollset_posix.h | 153 ++ src/core/lib/iomgr/pollset_set.h | 61 + src/core/lib/iomgr/pollset_set_posix.c | 202 ++ src/core/lib/iomgr/pollset_set_posix.h | 45 + src/core/lib/iomgr/pollset_set_windows.c | 60 + src/core/lib/iomgr/pollset_set_windows.h | 39 + src/core/lib/iomgr/pollset_windows.c | 240 +++ src/core/lib/iomgr/pollset_windows.h | 75 + src/core/lib/iomgr/resolve_address.h | 72 + src/core/lib/iomgr/resolve_address_posix.c | 178 ++ src/core/lib/iomgr/resolve_address_windows.c | 169 ++ src/core/lib/iomgr/sockaddr.h | 47 + src/core/lib/iomgr/sockaddr_posix.h | 44 + src/core/lib/iomgr/sockaddr_utils.c | 227 +++ src/core/lib/iomgr/sockaddr_utils.h | 89 + src/core/lib/iomgr/sockaddr_win32.h | 43 + src/core/lib/iomgr/socket_utils_common_posix.c | 208 +++ src/core/lib/iomgr/socket_utils_linux.c | 51 + src/core/lib/iomgr/socket_utils_posix.c | 70 + src/core/lib/iomgr/socket_utils_posix.h | 113 ++ src/core/lib/iomgr/socket_windows.c | 100 + src/core/lib/iomgr/socket_windows.h | 111 ++ src/core/lib/iomgr/tcp_client.h | 53 + src/core/lib/iomgr/tcp_client_posix.c | 306 +++ src/core/lib/iomgr/tcp_client_windows.c | 221 +++ src/core/lib/iomgr/tcp_posix.c | 493 +++++ src/core/lib/iomgr/tcp_posix.h | 71 + src/core/lib/iomgr/tcp_server.h | 103 ++ src/core/lib/iomgr/tcp_server_posix.c | 607 ++++++ src/core/lib/iomgr/tcp_server_windows.c | 557 ++++++ src/core/lib/iomgr/tcp_windows.c | 402 ++++ src/core/lib/iomgr/tcp_windows.h | 57 + src/core/lib/iomgr/time_averaged_stats.c | 77 + src/core/lib/iomgr/time_averaged_stats.h | 88 + src/core/lib/iomgr/timer.c | 356 ++++ src/core/lib/iomgr/timer.h | 108 ++ src/core/lib/iomgr/timer_heap.c | 146 ++ src/core/lib/iomgr/timer_heap.h | 57 + src/core/lib/iomgr/udp_server.c | 418 +++++ src/core/lib/iomgr/udp_server.h | 77 + src/core/lib/iomgr/unix_sockets_posix.c | 103 ++ src/core/lib/iomgr/unix_sockets_posix.h | 61 + src/core/lib/iomgr/unix_sockets_posix_noop.c | 61 + src/core/lib/iomgr/wakeup_fd_eventfd.c | 85 + src/core/lib/iomgr/wakeup_fd_nospecial.c | 51 + src/core/lib/iomgr/wakeup_fd_pipe.c | 102 + src/core/lib/iomgr/wakeup_fd_pipe.h | 41 + src/core/lib/iomgr/wakeup_fd_posix.c | 72 + src/core/lib/iomgr/wakeup_fd_posix.h | 101 + src/core/lib/iomgr/workqueue.h | 83 + src/core/lib/iomgr/workqueue_posix.c | 144 ++ src/core/lib/iomgr/workqueue_posix.h | 53 + src/core/lib/iomgr/workqueue_windows.c | 40 + src/core/lib/iomgr/workqueue_windows.h | 37 + src/core/lib/json/json.c | 64 + src/core/lib/json/json.h | 88 + src/core/lib/json/json_common.h | 49 + src/core/lib/json/json_reader.c | 659 +++++++ src/core/lib/json/json_reader.h | 160 ++ src/core/lib/json/json_string.c | 379 ++++ src/core/lib/json/json_writer.c | 258 +++ src/core/lib/json/json_writer.h | 97 + src/core/lib/profiling/basic_timers.c | 274 +++ src/core/lib/profiling/stap_probes.d | 7 + src/core/lib/profiling/stap_timers.c | 65 + src/core/lib/profiling/timers.h | 119 ++ src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c | 119 ++ src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h | 182 ++ src/core/lib/security/auth_filters.h | 42 + src/core/lib/security/b64.c | 233 +++ src/core/lib/security/b64.h | 52 + src/core/lib/security/client_auth_filter.c | 336 ++++ src/core/lib/security/credentials.c | 1281 +++++++++++++ src/core/lib/security/credentials.h | 377 ++++ src/core/lib/security/credentials_metadata.c | 101 + src/core/lib/security/credentials_posix.c | 61 + src/core/lib/security/credentials_win32.c | 61 + src/core/lib/security/google_default_credentials.c | 266 +++ src/core/lib/security/handshake.c | 336 ++++ src/core/lib/security/handshake.h | 51 + src/core/lib/security/json_token.c | 411 +++++ src/core/lib/security/json_token.h | 118 ++ src/core/lib/security/jwt_verifier.c | 843 +++++++++ src/core/lib/security/jwt_verifier.h | 136 ++ src/core/lib/security/secure_endpoint.c | 384 ++++ src/core/lib/security/secure_endpoint.h | 49 + src/core/lib/security/security_connector.c | 812 ++++++++ src/core/lib/security/security_connector.h | 266 +++ src/core/lib/security/security_context.c | 347 ++++ src/core/lib/security/security_context.h | 114 ++ src/core/lib/security/server_auth_filter.c | 264 +++ src/core/lib/security/server_secure_chttp2.c | 264 +++ src/core/lib/statistics/census_init.c | 48 + src/core/lib/statistics/census_interface.h | 76 + src/core/lib/statistics/census_log.c | 603 ++++++ src/core/lib/statistics/census_log.h | 91 + src/core/lib/statistics/census_rpc_stats.c | 253 +++ src/core/lib/statistics/census_rpc_stats.h | 101 + src/core/lib/statistics/census_tracing.c | 241 +++ src/core/lib/statistics/census_tracing.h | 96 + src/core/lib/statistics/hash_table.c | 303 +++ src/core/lib/statistics/hash_table.h | 131 ++ src/core/lib/statistics/window_stats.c | 316 ++++ src/core/lib/statistics/window_stats.h | 173 ++ src/core/lib/support/alloc.c | 90 + src/core/lib/support/avl.c | 288 +++ src/core/lib/support/backoff.c | 76 + src/core/lib/support/backoff.h | 68 + src/core/lib/support/block_annotate.h | 48 + src/core/lib/support/cmdline.c | 347 ++++ src/core/lib/support/cpu_iphone.c | 49 + src/core/lib/support/cpu_linux.c | 78 + src/core/lib/support/cpu_posix.c | 77 + src/core/lib/support/cpu_windows.c | 47 + src/core/lib/support/env.h | 60 + src/core/lib/support/env_linux.c | 89 + src/core/lib/support/env_posix.c | 57 + src/core/lib/support/env_win32.c | 73 + src/core/lib/support/histogram.c | 244 +++ src/core/lib/support/host_port.c | 110 ++ src/core/lib/support/load_file.c | 91 + src/core/lib/support/load_file.h | 55 + src/core/lib/support/log.c | 66 + src/core/lib/support/log_android.c | 87 + src/core/lib/support/log_linux.c | 105 ++ src/core/lib/support/log_posix.c | 102 + src/core/lib/support/log_win32.c | 126 ++ src/core/lib/support/murmur_hash.c | 96 + src/core/lib/support/murmur_hash.h | 44 + src/core/lib/support/slice.c | 343 ++++ src/core/lib/support/slice_buffer.c | 282 +++ src/core/lib/support/stack_lockfree.c | 185 ++ src/core/lib/support/stack_lockfree.h | 53 + src/core/lib/support/string.c | 296 +++ src/core/lib/support/string.h | 121 ++ src/core/lib/support/string_posix.c | 86 + src/core/lib/support/string_win32.c | 109 ++ src/core/lib/support/string_win32.h | 47 + src/core/lib/support/subprocess_posix.c | 112 ++ src/core/lib/support/subprocess_windows.c | 141 ++ src/core/lib/support/sync.c | 127 ++ src/core/lib/support/sync_posix.c | 104 ++ src/core/lib/support/sync_win32.c | 133 ++ src/core/lib/support/thd.c | 64 + src/core/lib/support/thd_internal.h | 39 + src/core/lib/support/thd_posix.c | 94 + src/core/lib/support/thd_win32.c | 117 ++ src/core/lib/support/time.c | 304 +++ src/core/lib/support/time_posix.c | 170 ++ src/core/lib/support/time_precise.c | 89 + src/core/lib/support/time_precise.h | 42 + src/core/lib/support/time_win32.c | 110 ++ src/core/lib/support/tls_pthread.c | 45 + src/core/lib/support/tmpfile.h | 55 + src/core/lib/support/tmpfile_posix.c | 85 + src/core/lib/support/tmpfile_win32.c | 84 + src/core/lib/support/wrap_memcpy.c | 53 + src/core/lib/surface/alarm.c | 84 + src/core/lib/surface/api_trace.c | 36 + src/core/lib/surface/api_trace.h | 65 + src/core/lib/surface/byte_buffer.c | 97 + src/core/lib/surface/byte_buffer_reader.c | 123 ++ src/core/lib/surface/call.c | 1491 +++++++++++++++ src/core/lib/surface/call.h | 116 ++ src/core/lib/surface/call_details.c | 50 + src/core/lib/surface/call_log_batch.c | 118 ++ src/core/lib/surface/call_test_only.h | 64 + src/core/lib/surface/channel.c | 324 ++++ src/core/lib/surface/channel.h | 75 + src/core/lib/surface/channel_connectivity.c | 207 +++ src/core/lib/surface/channel_create.c | 223 +++ src/core/lib/surface/channel_init.c | 146 ++ src/core/lib/surface/channel_init.h | 86 + src/core/lib/surface/channel_ping.c | 79 + src/core/lib/surface/channel_stack_type.c | 54 + src/core/lib/surface/channel_stack_type.h | 58 + src/core/lib/surface/completion_queue.c | 512 +++++ src/core/lib/surface/completion_queue.h | 91 + src/core/lib/surface/event_string.c | 81 + src/core/lib/surface/event_string.h | 42 + src/core/lib/surface/init.c | 239 +++ src/core/lib/surface/init.h | 41 + src/core/lib/surface/init_secure.c | 89 + src/core/lib/surface/init_unsecure.c | 38 + src/core/lib/surface/lame_client.c | 155 ++ src/core/lib/surface/lame_client.h | 41 + src/core/lib/surface/metadata_array.c | 49 + src/core/lib/surface/secure_channel_create.c | 319 ++++ src/core/lib/surface/server.c | 1319 +++++++++++++ src/core/lib/surface/server.h | 62 + src/core/lib/surface/server_chttp2.c | 146 ++ src/core/lib/surface/surface_trace.h | 48 + src/core/lib/surface/validate_metadata.c | 73 + src/core/lib/surface/version.c | 39 + src/core/lib/transport/byte_stream.c | 78 + src/core/lib/transport/byte_stream.h | 89 + src/core/lib/transport/chttp2/alpn.c | 56 + src/core/lib/transport/chttp2/alpn.h | 49 + src/core/lib/transport/chttp2/bin_encoder.c | 233 +++ src/core/lib/transport/chttp2/bin_encoder.h | 54 + src/core/lib/transport/chttp2/frame.h | 69 + src/core/lib/transport/chttp2/frame_data.c | 248 +++ src/core/lib/transport/chttp2/frame_data.h | 101 + src/core/lib/transport/chttp2/frame_goaway.c | 193 ++ src/core/lib/transport/chttp2/frame_goaway.h | 77 + src/core/lib/transport/chttp2/frame_ping.c | 97 + src/core/lib/transport/chttp2/frame_ping.h | 56 + src/core/lib/transport/chttp2/frame_rst_stream.c | 99 + src/core/lib/transport/chttp2/frame_rst_stream.h | 55 + src/core/lib/transport/chttp2/frame_settings.c | 259 +++ src/core/lib/transport/chttp2/frame_settings.h | 103 ++ .../lib/transport/chttp2/frame_window_update.c | 113 ++ .../lib/transport/chttp2/frame_window_update.h | 56 + src/core/lib/transport/chttp2/hpack_encoder.c | 568 ++++++ src/core/lib/transport/chttp2/hpack_encoder.h | 95 + src/core/lib/transport/chttp2/hpack_parser.c | 1449 +++++++++++++++ src/core/lib/transport/chttp2/hpack_parser.h | 116 ++ src/core/lib/transport/chttp2/hpack_table.c | 361 ++++ src/core/lib/transport/chttp2/hpack_table.h | 108 ++ src/core/lib/transport/chttp2/hpack_tables.txt | 66 + src/core/lib/transport/chttp2/http2_errors.h | 56 + src/core/lib/transport/chttp2/huffsyms.c | 105 ++ src/core/lib/transport/chttp2/huffsyms.h | 48 + src/core/lib/transport/chttp2/incoming_metadata.c | 96 + src/core/lib/transport/chttp2/incoming_metadata.h | 60 + src/core/lib/transport/chttp2/internal.h | 780 ++++++++ src/core/lib/transport/chttp2/parsing.c | 866 +++++++++ src/core/lib/transport/chttp2/status_conversion.c | 109 ++ src/core/lib/transport/chttp2/status_conversion.h | 50 + src/core/lib/transport/chttp2/stream_lists.c | 442 +++++ src/core/lib/transport/chttp2/stream_map.c | 197 ++ src/core/lib/transport/chttp2/stream_map.h | 84 + src/core/lib/transport/chttp2/timeout_encoding.c | 188 ++ src/core/lib/transport/chttp2/timeout_encoding.h | 47 + src/core/lib/transport/chttp2/varint.c | 65 + src/core/lib/transport/chttp2/varint.h | 75 + src/core/lib/transport/chttp2/writing.c | 350 ++++ src/core/lib/transport/chttp2_transport.c | 1785 ++++++++++++++++++ src/core/lib/transport/chttp2_transport.h | 51 + src/core/lib/transport/connectivity_state.c | 164 ++ src/core/lib/transport/connectivity_state.h | 85 + src/core/lib/transport/metadata.c | 698 +++++++ src/core/lib/transport/metadata.h | 156 ++ src/core/lib/transport/metadata_batch.c | 194 ++ src/core/lib/transport/metadata_batch.h | 125 ++ src/core/lib/transport/static_metadata.c | 160 ++ src/core/lib/transport/static_metadata.h | 408 ++++ src/core/lib/transport/transport.c | 184 ++ src/core/lib/transport/transport.h | 242 +++ src/core/lib/transport/transport_impl.h | 81 + src/core/lib/transport/transport_op_string.c | 140 ++ src/core/lib/tsi/fake_transport_security.c | 527 ++++++ src/core/lib/tsi/fake_transport_security.h | 61 + src/core/lib/tsi/ssl_transport_security.c | 1536 +++++++++++++++ src/core/lib/tsi/ssl_transport_security.h | 174 ++ src/core/lib/tsi/ssl_types.h | 55 + src/core/lib/tsi/test_creds/README | 62 + src/core/lib/tsi/test_creds/badclient.key | 16 + src/core/lib/tsi/test_creds/badclient.pem | 17 + src/core/lib/tsi/test_creds/badserver.key | 16 + src/core/lib/tsi/test_creds/badserver.pem | 17 + src/core/lib/tsi/test_creds/ca-openssl.cnf | 17 + src/core/lib/tsi/test_creds/ca.key | 16 + src/core/lib/tsi/test_creds/ca.pem | 15 + src/core/lib/tsi/test_creds/client.key | 16 + src/core/lib/tsi/test_creds/client.pem | 14 + src/core/lib/tsi/test_creds/server0.key | 16 + src/core/lib/tsi/test_creds/server0.pem | 14 + src/core/lib/tsi/test_creds/server1-openssl.cnf | 26 + src/core/lib/tsi/test_creds/server1.key | 16 + src/core/lib/tsi/test_creds/server1.pem | 16 + src/core/lib/tsi/transport_security.c | 284 +++ src/core/lib/tsi/transport_security.h | 111 ++ src/core/lib/tsi/transport_security_interface.h | 344 ++++ src/core/profiling/basic_timers.c | 274 --- src/core/profiling/stap_probes.d | 7 - src/core/profiling/stap_timers.c | 65 - src/core/profiling/timers.h | 119 -- src/core/proto/grpc/lb/v0/load_balancer.pb.c | 119 -- src/core/proto/grpc/lb/v0/load_balancer.pb.h | 182 -- src/core/security/auth_filters.h | 42 - src/core/security/b64.c | 233 --- src/core/security/b64.h | 52 - src/core/security/client_auth_filter.c | 336 ---- src/core/security/credentials.c | 1281 ------------- src/core/security/credentials.h | 377 ---- src/core/security/credentials_metadata.c | 101 - src/core/security/credentials_posix.c | 61 - src/core/security/credentials_win32.c | 61 - src/core/security/google_default_credentials.c | 266 --- src/core/security/handshake.c | 336 ---- src/core/security/handshake.h | 51 - src/core/security/json_token.c | 411 ----- src/core/security/json_token.h | 118 -- src/core/security/jwt_verifier.c | 843 --------- src/core/security/jwt_verifier.h | 136 -- src/core/security/secure_endpoint.c | 384 ---- src/core/security/secure_endpoint.h | 49 - src/core/security/security_connector.c | 812 -------- src/core/security/security_connector.h | 266 --- src/core/security/security_context.c | 347 ---- src/core/security/security_context.h | 114 -- src/core/security/server_auth_filter.c | 264 --- src/core/security/server_secure_chttp2.c | 264 --- src/core/statistics/census_init.c | 48 - src/core/statistics/census_interface.h | 76 - src/core/statistics/census_log.c | 603 ------ src/core/statistics/census_log.h | 91 - src/core/statistics/census_rpc_stats.c | 253 --- src/core/statistics/census_rpc_stats.h | 101 - src/core/statistics/census_tracing.c | 241 --- src/core/statistics/census_tracing.h | 96 - src/core/statistics/hash_table.c | 303 --- src/core/statistics/hash_table.h | 131 -- src/core/statistics/window_stats.c | 316 ---- src/core/statistics/window_stats.h | 173 -- src/core/support/alloc.c | 90 - src/core/support/avl.c | 288 --- src/core/support/backoff.c | 76 - src/core/support/backoff.h | 68 - src/core/support/block_annotate.h | 48 - src/core/support/cmdline.c | 347 ---- src/core/support/cpu_iphone.c | 49 - src/core/support/cpu_linux.c | 78 - src/core/support/cpu_posix.c | 77 - src/core/support/cpu_windows.c | 47 - src/core/support/env.h | 60 - src/core/support/env_linux.c | 89 - src/core/support/env_posix.c | 57 - src/core/support/env_win32.c | 73 - src/core/support/histogram.c | 244 --- src/core/support/host_port.c | 110 -- src/core/support/load_file.c | 91 - src/core/support/load_file.h | 55 - src/core/support/log.c | 66 - src/core/support/log_android.c | 87 - src/core/support/log_linux.c | 105 -- src/core/support/log_posix.c | 102 - src/core/support/log_win32.c | 126 -- src/core/support/murmur_hash.c | 96 - src/core/support/murmur_hash.h | 44 - src/core/support/slice.c | 343 ---- src/core/support/slice_buffer.c | 282 --- src/core/support/stack_lockfree.c | 185 -- src/core/support/stack_lockfree.h | 53 - src/core/support/string.c | 296 --- src/core/support/string.h | 121 -- src/core/support/string_posix.c | 86 - src/core/support/string_win32.c | 109 -- src/core/support/string_win32.h | 47 - src/core/support/subprocess_posix.c | 112 -- src/core/support/subprocess_windows.c | 141 -- src/core/support/sync.c | 127 -- src/core/support/sync_posix.c | 104 -- src/core/support/sync_win32.c | 133 -- src/core/support/thd.c | 64 - src/core/support/thd_internal.h | 39 - src/core/support/thd_posix.c | 94 - src/core/support/thd_win32.c | 117 -- src/core/support/time.c | 304 --- src/core/support/time_posix.c | 170 -- src/core/support/time_precise.c | 89 - src/core/support/time_precise.h | 42 - src/core/support/time_win32.c | 110 -- src/core/support/tls_pthread.c | 45 - src/core/support/tmpfile.h | 55 - src/core/support/tmpfile_posix.c | 85 - src/core/support/tmpfile_win32.c | 84 - src/core/support/wrap_memcpy.c | 53 - src/core/surface/alarm.c | 84 - src/core/surface/api_trace.c | 36 - src/core/surface/api_trace.h | 65 - src/core/surface/byte_buffer.c | 97 - src/core/surface/byte_buffer_reader.c | 123 -- src/core/surface/call.c | 1491 --------------- src/core/surface/call.h | 116 -- src/core/surface/call_details.c | 50 - src/core/surface/call_log_batch.c | 118 -- src/core/surface/call_test_only.h | 64 - src/core/surface/channel.c | 324 ---- src/core/surface/channel.h | 75 - src/core/surface/channel_connectivity.c | 207 --- src/core/surface/channel_create.c | 223 --- src/core/surface/channel_init.c | 146 -- src/core/surface/channel_init.h | 86 - src/core/surface/channel_ping.c | 79 - src/core/surface/channel_stack_type.c | 54 - src/core/surface/channel_stack_type.h | 58 - src/core/surface/completion_queue.c | 512 ----- src/core/surface/completion_queue.h | 91 - src/core/surface/event_string.c | 81 - src/core/surface/event_string.h | 42 - src/core/surface/init.c | 239 --- src/core/surface/init.h | 41 - src/core/surface/init_secure.c | 89 - src/core/surface/init_unsecure.c | 38 - src/core/surface/lame_client.c | 155 -- src/core/surface/lame_client.h | 41 - src/core/surface/metadata_array.c | 49 - src/core/surface/secure_channel_create.c | 319 ---- src/core/surface/server.c | 1319 ------------- src/core/surface/server.h | 62 - src/core/surface/server_chttp2.c | 146 -- src/core/surface/surface_trace.h | 48 - src/core/surface/validate_metadata.c | 73 - src/core/surface/version.c | 39 - src/core/transport/byte_stream.c | 78 - src/core/transport/byte_stream.h | 89 - src/core/transport/chttp2/alpn.c | 56 - src/core/transport/chttp2/alpn.h | 49 - src/core/transport/chttp2/bin_encoder.c | 233 --- src/core/transport/chttp2/bin_encoder.h | 54 - src/core/transport/chttp2/frame.h | 69 - src/core/transport/chttp2/frame_data.c | 248 --- src/core/transport/chttp2/frame_data.h | 101 - src/core/transport/chttp2/frame_goaway.c | 193 -- src/core/transport/chttp2/frame_goaway.h | 77 - src/core/transport/chttp2/frame_ping.c | 97 - src/core/transport/chttp2/frame_ping.h | 56 - src/core/transport/chttp2/frame_rst_stream.c | 99 - src/core/transport/chttp2/frame_rst_stream.h | 55 - src/core/transport/chttp2/frame_settings.c | 259 --- src/core/transport/chttp2/frame_settings.h | 103 -- src/core/transport/chttp2/frame_window_update.c | 113 -- src/core/transport/chttp2/frame_window_update.h | 56 - src/core/transport/chttp2/hpack_encoder.c | 568 ------ src/core/transport/chttp2/hpack_encoder.h | 95 - src/core/transport/chttp2/hpack_parser.c | 1449 --------------- src/core/transport/chttp2/hpack_parser.h | 116 -- src/core/transport/chttp2/hpack_table.c | 361 ---- src/core/transport/chttp2/hpack_table.h | 108 -- src/core/transport/chttp2/hpack_tables.txt | 66 - src/core/transport/chttp2/http2_errors.h | 56 - src/core/transport/chttp2/huffsyms.c | 105 -- src/core/transport/chttp2/huffsyms.h | 48 - src/core/transport/chttp2/incoming_metadata.c | 96 - src/core/transport/chttp2/incoming_metadata.h | 60 - src/core/transport/chttp2/internal.h | 780 -------- src/core/transport/chttp2/parsing.c | 866 --------- src/core/transport/chttp2/status_conversion.c | 109 -- src/core/transport/chttp2/status_conversion.h | 50 - src/core/transport/chttp2/stream_lists.c | 442 ----- src/core/transport/chttp2/stream_map.c | 197 -- src/core/transport/chttp2/stream_map.h | 84 - src/core/transport/chttp2/timeout_encoding.c | 188 -- src/core/transport/chttp2/timeout_encoding.h | 47 - src/core/transport/chttp2/varint.c | 65 - src/core/transport/chttp2/varint.h | 75 - src/core/transport/chttp2/writing.c | 350 ---- src/core/transport/chttp2_transport.c | 1785 ------------------ src/core/transport/chttp2_transport.h | 51 - src/core/transport/connectivity_state.c | 164 -- src/core/transport/connectivity_state.h | 85 - src/core/transport/metadata.c | 698 ------- src/core/transport/metadata.h | 156 -- src/core/transport/metadata_batch.c | 194 -- src/core/transport/metadata_batch.h | 125 -- src/core/transport/static_metadata.c | 160 -- src/core/transport/static_metadata.h | 408 ---- src/core/transport/transport.c | 184 -- src/core/transport/transport.h | 242 --- src/core/transport/transport_impl.h | 81 - src/core/transport/transport_op_string.c | 140 -- src/core/tsi/fake_transport_security.c | 527 ------ src/core/tsi/fake_transport_security.h | 61 - src/core/tsi/ssl_transport_security.c | 1536 --------------- src/core/tsi/ssl_transport_security.h | 174 -- src/core/tsi/ssl_types.h | 55 - src/core/tsi/test_creds/README | 62 - src/core/tsi/test_creds/badclient.key | 16 - src/core/tsi/test_creds/badclient.pem | 17 - src/core/tsi/test_creds/badserver.key | 16 - src/core/tsi/test_creds/badserver.pem | 17 - src/core/tsi/test_creds/ca-openssl.cnf | 17 - src/core/tsi/test_creds/ca.key | 16 - src/core/tsi/test_creds/ca.pem | 15 - src/core/tsi/test_creds/client.key | 16 - src/core/tsi/test_creds/client.pem | 14 - src/core/tsi/test_creds/server0.key | 16 - src/core/tsi/test_creds/server0.pem | 14 - src/core/tsi/test_creds/server1-openssl.cnf | 26 - src/core/tsi/test_creds/server1.key | 16 - src/core/tsi/test_creds/server1.pem | 16 - src/core/tsi/transport_security.c | 284 --- src/core/tsi/transport_security.h | 111 -- src/core/tsi/transport_security_interface.h | 344 ---- src/python/grpcio/grpc_core_dependencies.py | 410 ++-- templates/src/core/lib/surface/version.c.template | 41 + templates/src/core/surface/version.c.template | 41 - tools/doxygen/Doxyfile.core.internal | 708 +++---- tools/run_tests/sources_and_headers.json | 1786 +++++++++--------- vsprojects/vcxproj/gpr/gpr.vcxproj | 112 +- vsprojects/vcxproj/gpr/gpr.vcxproj.filters | 235 +-- vsprojects/vcxproj/grpc/grpc.vcxproj | 596 +++--- vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 1275 ++++++------- .../vcxproj/grpc_unsecure/grpc_unsecure.vcxproj | 528 +++--- .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 1131 ++++++------ 792 files changed, 73079 insertions(+), 73070 deletions(-) delete mode 100644 src/core/census/README.md delete mode 100644 src/core/census/aggregation.h delete mode 100644 src/core/census/context.c delete mode 100644 src/core/census/grpc_context.c delete mode 100644 src/core/census/grpc_filter.c delete mode 100644 src/core/census/grpc_filter.h delete mode 100644 src/core/census/grpc_plugin.c delete mode 100644 src/core/census/grpc_plugin.h delete mode 100644 src/core/census/initialize.c delete mode 100644 src/core/census/mlog.c delete mode 100644 src/core/census/mlog.h delete mode 100644 src/core/census/operation.c delete mode 100644 src/core/census/placeholders.c delete mode 100644 src/core/census/rpc_metric_id.h delete mode 100644 src/core/census/tracing.c delete mode 100644 src/core/channel/channel_args.c delete mode 100644 src/core/channel/channel_args.h delete mode 100644 src/core/channel/channel_stack.c delete mode 100644 src/core/channel/channel_stack.h delete mode 100644 src/core/channel/channel_stack_builder.c delete mode 100644 src/core/channel/channel_stack_builder.h delete mode 100644 src/core/channel/client_channel.c delete mode 100644 src/core/channel/client_channel.h delete mode 100644 src/core/channel/compress_filter.c delete mode 100644 src/core/channel/compress_filter.h delete mode 100644 src/core/channel/connected_channel.c delete mode 100644 src/core/channel/connected_channel.h delete mode 100644 src/core/channel/context.h delete mode 100644 src/core/channel/http_client_filter.c delete mode 100644 src/core/channel/http_client_filter.h delete mode 100644 src/core/channel/http_server_filter.c delete mode 100644 src/core/channel/http_server_filter.h delete mode 100644 src/core/channel/subchannel_call_holder.c delete mode 100644 src/core/channel/subchannel_call_holder.h delete mode 100644 src/core/client_config/README.md delete mode 100644 src/core/client_config/client_config.c delete mode 100644 src/core/client_config/client_config.h delete mode 100644 src/core/client_config/connector.c delete mode 100644 src/core/client_config/connector.h delete mode 100644 src/core/client_config/default_initial_connect_string.c delete mode 100644 src/core/client_config/initial_connect_string.c delete mode 100644 src/core/client_config/initial_connect_string.h delete mode 100644 src/core/client_config/lb_policies/load_balancer_api.c delete mode 100644 src/core/client_config/lb_policies/load_balancer_api.h delete mode 100644 src/core/client_config/lb_policies/pick_first.c delete mode 100644 src/core/client_config/lb_policies/pick_first.h delete mode 100644 src/core/client_config/lb_policies/round_robin.c delete mode 100644 src/core/client_config/lb_policies/round_robin.h delete mode 100644 src/core/client_config/lb_policy.c delete mode 100644 src/core/client_config/lb_policy.h delete mode 100644 src/core/client_config/lb_policy_factory.c delete mode 100644 src/core/client_config/lb_policy_factory.h delete mode 100644 src/core/client_config/lb_policy_registry.c delete mode 100644 src/core/client_config/lb_policy_registry.h delete mode 100644 src/core/client_config/resolver.c delete mode 100644 src/core/client_config/resolver.h delete mode 100644 src/core/client_config/resolver_factory.c delete mode 100644 src/core/client_config/resolver_factory.h delete mode 100644 src/core/client_config/resolver_registry.c delete mode 100644 src/core/client_config/resolver_registry.h delete mode 100644 src/core/client_config/resolvers/dns_resolver.c delete mode 100644 src/core/client_config/resolvers/dns_resolver.h delete mode 100644 src/core/client_config/resolvers/sockaddr_resolver.c delete mode 100644 src/core/client_config/resolvers/sockaddr_resolver.h delete mode 100644 src/core/client_config/resolvers/zookeeper_resolver.c delete mode 100644 src/core/client_config/resolvers/zookeeper_resolver.h delete mode 100644 src/core/client_config/subchannel.c delete mode 100644 src/core/client_config/subchannel.h delete mode 100644 src/core/client_config/subchannel_factory.c delete mode 100644 src/core/client_config/subchannel_factory.h delete mode 100644 src/core/client_config/subchannel_index.c delete mode 100644 src/core/client_config/subchannel_index.h delete mode 100644 src/core/client_config/uri_parser.c delete mode 100644 src/core/client_config/uri_parser.h delete mode 100644 src/core/compression/algorithm_metadata.h delete mode 100644 src/core/compression/compression_algorithm.c delete mode 100644 src/core/compression/message_compress.c delete mode 100644 src/core/compression/message_compress.h delete mode 100644 src/core/debug/trace.c delete mode 100644 src/core/debug/trace.h delete mode 100644 src/core/http/format_request.c delete mode 100644 src/core/http/format_request.h delete mode 100644 src/core/http/httpcli.c delete mode 100644 src/core/http/httpcli.h delete mode 100644 src/core/http/httpcli_security_connector.c delete mode 100644 src/core/http/parser.c delete mode 100644 src/core/http/parser.h delete mode 100644 src/core/iomgr/closure.c delete mode 100644 src/core/iomgr/closure.h delete mode 100644 src/core/iomgr/endpoint.c delete mode 100644 src/core/iomgr/endpoint.h delete mode 100644 src/core/iomgr/endpoint_pair.h delete mode 100644 src/core/iomgr/endpoint_pair_posix.c delete mode 100644 src/core/iomgr/endpoint_pair_windows.c delete mode 100644 src/core/iomgr/exec_ctx.c delete mode 100644 src/core/iomgr/exec_ctx.h delete mode 100644 src/core/iomgr/executor.c delete mode 100644 src/core/iomgr/executor.h delete mode 100644 src/core/iomgr/fd_posix.c delete mode 100644 src/core/iomgr/fd_posix.h delete mode 100644 src/core/iomgr/iocp_windows.c delete mode 100644 src/core/iomgr/iocp_windows.h delete mode 100644 src/core/iomgr/iomgr.c delete mode 100644 src/core/iomgr/iomgr.h delete mode 100644 src/core/iomgr/iomgr_internal.h delete mode 100644 src/core/iomgr/iomgr_posix.c delete mode 100644 src/core/iomgr/iomgr_posix.h delete mode 100644 src/core/iomgr/iomgr_windows.c delete mode 100644 src/core/iomgr/pollset.h delete mode 100644 src/core/iomgr/pollset_multipoller_with_epoll.c delete mode 100644 src/core/iomgr/pollset_multipoller_with_poll_posix.c delete mode 100644 src/core/iomgr/pollset_posix.c delete mode 100644 src/core/iomgr/pollset_posix.h delete mode 100644 src/core/iomgr/pollset_set.h delete mode 100644 src/core/iomgr/pollset_set_posix.c delete mode 100644 src/core/iomgr/pollset_set_posix.h delete mode 100644 src/core/iomgr/pollset_set_windows.c delete mode 100644 src/core/iomgr/pollset_set_windows.h delete mode 100644 src/core/iomgr/pollset_windows.c delete mode 100644 src/core/iomgr/pollset_windows.h delete mode 100644 src/core/iomgr/resolve_address.h delete mode 100644 src/core/iomgr/resolve_address_posix.c delete mode 100644 src/core/iomgr/resolve_address_windows.c delete mode 100644 src/core/iomgr/sockaddr.h delete mode 100644 src/core/iomgr/sockaddr_posix.h delete mode 100644 src/core/iomgr/sockaddr_utils.c delete mode 100644 src/core/iomgr/sockaddr_utils.h delete mode 100644 src/core/iomgr/sockaddr_win32.h delete mode 100644 src/core/iomgr/socket_utils_common_posix.c delete mode 100644 src/core/iomgr/socket_utils_linux.c delete mode 100644 src/core/iomgr/socket_utils_posix.c delete mode 100644 src/core/iomgr/socket_utils_posix.h delete mode 100644 src/core/iomgr/socket_windows.c delete mode 100644 src/core/iomgr/socket_windows.h delete mode 100644 src/core/iomgr/tcp_client.h delete mode 100644 src/core/iomgr/tcp_client_posix.c delete mode 100644 src/core/iomgr/tcp_client_windows.c delete mode 100644 src/core/iomgr/tcp_posix.c delete mode 100644 src/core/iomgr/tcp_posix.h delete mode 100644 src/core/iomgr/tcp_server.h delete mode 100644 src/core/iomgr/tcp_server_posix.c delete mode 100644 src/core/iomgr/tcp_server_windows.c delete mode 100644 src/core/iomgr/tcp_windows.c delete mode 100644 src/core/iomgr/tcp_windows.h delete mode 100644 src/core/iomgr/time_averaged_stats.c delete mode 100644 src/core/iomgr/time_averaged_stats.h delete mode 100644 src/core/iomgr/timer.c delete mode 100644 src/core/iomgr/timer.h delete mode 100644 src/core/iomgr/timer_heap.c delete mode 100644 src/core/iomgr/timer_heap.h delete mode 100644 src/core/iomgr/udp_server.c delete mode 100644 src/core/iomgr/udp_server.h delete mode 100644 src/core/iomgr/unix_sockets_posix.c delete mode 100644 src/core/iomgr/unix_sockets_posix.h delete mode 100644 src/core/iomgr/unix_sockets_posix_noop.c delete mode 100644 src/core/iomgr/wakeup_fd_eventfd.c delete mode 100644 src/core/iomgr/wakeup_fd_nospecial.c delete mode 100644 src/core/iomgr/wakeup_fd_pipe.c delete mode 100644 src/core/iomgr/wakeup_fd_pipe.h delete mode 100644 src/core/iomgr/wakeup_fd_posix.c delete mode 100644 src/core/iomgr/wakeup_fd_posix.h delete mode 100644 src/core/iomgr/workqueue.h delete mode 100644 src/core/iomgr/workqueue_posix.c delete mode 100644 src/core/iomgr/workqueue_posix.h delete mode 100644 src/core/iomgr/workqueue_windows.c delete mode 100644 src/core/iomgr/workqueue_windows.h delete mode 100644 src/core/json/json.c delete mode 100644 src/core/json/json.h delete mode 100644 src/core/json/json_common.h delete mode 100644 src/core/json/json_reader.c delete mode 100644 src/core/json/json_reader.h delete mode 100644 src/core/json/json_string.c delete mode 100644 src/core/json/json_writer.c delete mode 100644 src/core/json/json_writer.h create mode 100644 src/core/lib/census/README.md create mode 100644 src/core/lib/census/aggregation.h create mode 100644 src/core/lib/census/context.c create mode 100644 src/core/lib/census/grpc_context.c create mode 100644 src/core/lib/census/grpc_filter.c create mode 100644 src/core/lib/census/grpc_filter.h create mode 100644 src/core/lib/census/grpc_plugin.c create mode 100644 src/core/lib/census/grpc_plugin.h create mode 100644 src/core/lib/census/initialize.c create mode 100644 src/core/lib/census/mlog.c create mode 100644 src/core/lib/census/mlog.h create mode 100644 src/core/lib/census/operation.c create mode 100644 src/core/lib/census/placeholders.c create mode 100644 src/core/lib/census/rpc_metric_id.h create mode 100644 src/core/lib/census/tracing.c create mode 100644 src/core/lib/channel/channel_args.c create mode 100644 src/core/lib/channel/channel_args.h create mode 100644 src/core/lib/channel/channel_stack.c create mode 100644 src/core/lib/channel/channel_stack.h create mode 100644 src/core/lib/channel/channel_stack_builder.c create mode 100644 src/core/lib/channel/channel_stack_builder.h create mode 100644 src/core/lib/channel/client_channel.c create mode 100644 src/core/lib/channel/client_channel.h create mode 100644 src/core/lib/channel/compress_filter.c create mode 100644 src/core/lib/channel/compress_filter.h create mode 100644 src/core/lib/channel/connected_channel.c create mode 100644 src/core/lib/channel/connected_channel.h create mode 100644 src/core/lib/channel/context.h create mode 100644 src/core/lib/channel/http_client_filter.c create mode 100644 src/core/lib/channel/http_client_filter.h create mode 100644 src/core/lib/channel/http_server_filter.c create mode 100644 src/core/lib/channel/http_server_filter.h create mode 100644 src/core/lib/channel/subchannel_call_holder.c create mode 100644 src/core/lib/channel/subchannel_call_holder.h create mode 100644 src/core/lib/client_config/README.md create mode 100644 src/core/lib/client_config/client_config.c create mode 100644 src/core/lib/client_config/client_config.h create mode 100644 src/core/lib/client_config/connector.c create mode 100644 src/core/lib/client_config/connector.h create mode 100644 src/core/lib/client_config/default_initial_connect_string.c create mode 100644 src/core/lib/client_config/initial_connect_string.c create mode 100644 src/core/lib/client_config/initial_connect_string.h create mode 100644 src/core/lib/client_config/lb_policies/load_balancer_api.c create mode 100644 src/core/lib/client_config/lb_policies/load_balancer_api.h create mode 100644 src/core/lib/client_config/lb_policies/pick_first.c create mode 100644 src/core/lib/client_config/lb_policies/pick_first.h create mode 100644 src/core/lib/client_config/lb_policies/round_robin.c create mode 100644 src/core/lib/client_config/lb_policies/round_robin.h create mode 100644 src/core/lib/client_config/lb_policy.c create mode 100644 src/core/lib/client_config/lb_policy.h create mode 100644 src/core/lib/client_config/lb_policy_factory.c create mode 100644 src/core/lib/client_config/lb_policy_factory.h create mode 100644 src/core/lib/client_config/lb_policy_registry.c create mode 100644 src/core/lib/client_config/lb_policy_registry.h create mode 100644 src/core/lib/client_config/resolver.c create mode 100644 src/core/lib/client_config/resolver.h create mode 100644 src/core/lib/client_config/resolver_factory.c create mode 100644 src/core/lib/client_config/resolver_factory.h create mode 100644 src/core/lib/client_config/resolver_registry.c create mode 100644 src/core/lib/client_config/resolver_registry.h create mode 100644 src/core/lib/client_config/resolvers/dns_resolver.c create mode 100644 src/core/lib/client_config/resolvers/dns_resolver.h create mode 100644 src/core/lib/client_config/resolvers/sockaddr_resolver.c create mode 100644 src/core/lib/client_config/resolvers/sockaddr_resolver.h create mode 100644 src/core/lib/client_config/resolvers/zookeeper_resolver.c create mode 100644 src/core/lib/client_config/resolvers/zookeeper_resolver.h create mode 100644 src/core/lib/client_config/subchannel.c create mode 100644 src/core/lib/client_config/subchannel.h create mode 100644 src/core/lib/client_config/subchannel_factory.c create mode 100644 src/core/lib/client_config/subchannel_factory.h create mode 100644 src/core/lib/client_config/subchannel_index.c create mode 100644 src/core/lib/client_config/subchannel_index.h create mode 100644 src/core/lib/client_config/uri_parser.c create mode 100644 src/core/lib/client_config/uri_parser.h create mode 100644 src/core/lib/compression/algorithm_metadata.h create mode 100644 src/core/lib/compression/compression_algorithm.c create mode 100644 src/core/lib/compression/message_compress.c create mode 100644 src/core/lib/compression/message_compress.h create mode 100644 src/core/lib/debug/trace.c create mode 100644 src/core/lib/debug/trace.h create mode 100644 src/core/lib/http/format_request.c create mode 100644 src/core/lib/http/format_request.h create mode 100644 src/core/lib/http/httpcli.c create mode 100644 src/core/lib/http/httpcli.h create mode 100644 src/core/lib/http/httpcli_security_connector.c create mode 100644 src/core/lib/http/parser.c create mode 100644 src/core/lib/http/parser.h create mode 100644 src/core/lib/iomgr/closure.c create mode 100644 src/core/lib/iomgr/closure.h create mode 100644 src/core/lib/iomgr/endpoint.c create mode 100644 src/core/lib/iomgr/endpoint.h create mode 100644 src/core/lib/iomgr/endpoint_pair.h create mode 100644 src/core/lib/iomgr/endpoint_pair_posix.c create mode 100644 src/core/lib/iomgr/endpoint_pair_windows.c create mode 100644 src/core/lib/iomgr/exec_ctx.c create mode 100644 src/core/lib/iomgr/exec_ctx.h create mode 100644 src/core/lib/iomgr/executor.c create mode 100644 src/core/lib/iomgr/executor.h create mode 100644 src/core/lib/iomgr/fd_posix.c create mode 100644 src/core/lib/iomgr/fd_posix.h create mode 100644 src/core/lib/iomgr/iocp_windows.c create mode 100644 src/core/lib/iomgr/iocp_windows.h create mode 100644 src/core/lib/iomgr/iomgr.c create mode 100644 src/core/lib/iomgr/iomgr.h create mode 100644 src/core/lib/iomgr/iomgr_internal.h create mode 100644 src/core/lib/iomgr/iomgr_posix.c create mode 100644 src/core/lib/iomgr/iomgr_posix.h create mode 100644 src/core/lib/iomgr/iomgr_windows.c create mode 100644 src/core/lib/iomgr/pollset.h create mode 100644 src/core/lib/iomgr/pollset_multipoller_with_epoll.c create mode 100644 src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c create mode 100644 src/core/lib/iomgr/pollset_posix.c create mode 100644 src/core/lib/iomgr/pollset_posix.h create mode 100644 src/core/lib/iomgr/pollset_set.h create mode 100644 src/core/lib/iomgr/pollset_set_posix.c create mode 100644 src/core/lib/iomgr/pollset_set_posix.h create mode 100644 src/core/lib/iomgr/pollset_set_windows.c create mode 100644 src/core/lib/iomgr/pollset_set_windows.h create mode 100644 src/core/lib/iomgr/pollset_windows.c create mode 100644 src/core/lib/iomgr/pollset_windows.h create mode 100644 src/core/lib/iomgr/resolve_address.h create mode 100644 src/core/lib/iomgr/resolve_address_posix.c create mode 100644 src/core/lib/iomgr/resolve_address_windows.c create mode 100644 src/core/lib/iomgr/sockaddr.h create mode 100644 src/core/lib/iomgr/sockaddr_posix.h create mode 100644 src/core/lib/iomgr/sockaddr_utils.c create mode 100644 src/core/lib/iomgr/sockaddr_utils.h create mode 100644 src/core/lib/iomgr/sockaddr_win32.h create mode 100644 src/core/lib/iomgr/socket_utils_common_posix.c create mode 100644 src/core/lib/iomgr/socket_utils_linux.c create mode 100644 src/core/lib/iomgr/socket_utils_posix.c create mode 100644 src/core/lib/iomgr/socket_utils_posix.h create mode 100644 src/core/lib/iomgr/socket_windows.c create mode 100644 src/core/lib/iomgr/socket_windows.h create mode 100644 src/core/lib/iomgr/tcp_client.h create mode 100644 src/core/lib/iomgr/tcp_client_posix.c create mode 100644 src/core/lib/iomgr/tcp_client_windows.c create mode 100644 src/core/lib/iomgr/tcp_posix.c create mode 100644 src/core/lib/iomgr/tcp_posix.h create mode 100644 src/core/lib/iomgr/tcp_server.h create mode 100644 src/core/lib/iomgr/tcp_server_posix.c create mode 100644 src/core/lib/iomgr/tcp_server_windows.c create mode 100644 src/core/lib/iomgr/tcp_windows.c create mode 100644 src/core/lib/iomgr/tcp_windows.h create mode 100644 src/core/lib/iomgr/time_averaged_stats.c create mode 100644 src/core/lib/iomgr/time_averaged_stats.h create mode 100644 src/core/lib/iomgr/timer.c create mode 100644 src/core/lib/iomgr/timer.h create mode 100644 src/core/lib/iomgr/timer_heap.c create mode 100644 src/core/lib/iomgr/timer_heap.h create mode 100644 src/core/lib/iomgr/udp_server.c create mode 100644 src/core/lib/iomgr/udp_server.h create mode 100644 src/core/lib/iomgr/unix_sockets_posix.c create mode 100644 src/core/lib/iomgr/unix_sockets_posix.h create mode 100644 src/core/lib/iomgr/unix_sockets_posix_noop.c create mode 100644 src/core/lib/iomgr/wakeup_fd_eventfd.c create mode 100644 src/core/lib/iomgr/wakeup_fd_nospecial.c create mode 100644 src/core/lib/iomgr/wakeup_fd_pipe.c create mode 100644 src/core/lib/iomgr/wakeup_fd_pipe.h create mode 100644 src/core/lib/iomgr/wakeup_fd_posix.c create mode 100644 src/core/lib/iomgr/wakeup_fd_posix.h create mode 100644 src/core/lib/iomgr/workqueue.h create mode 100644 src/core/lib/iomgr/workqueue_posix.c create mode 100644 src/core/lib/iomgr/workqueue_posix.h create mode 100644 src/core/lib/iomgr/workqueue_windows.c create mode 100644 src/core/lib/iomgr/workqueue_windows.h create mode 100644 src/core/lib/json/json.c create mode 100644 src/core/lib/json/json.h create mode 100644 src/core/lib/json/json_common.h create mode 100644 src/core/lib/json/json_reader.c create mode 100644 src/core/lib/json/json_reader.h create mode 100644 src/core/lib/json/json_string.c create mode 100644 src/core/lib/json/json_writer.c create mode 100644 src/core/lib/json/json_writer.h create mode 100644 src/core/lib/profiling/basic_timers.c create mode 100644 src/core/lib/profiling/stap_probes.d create mode 100644 src/core/lib/profiling/stap_timers.c create mode 100644 src/core/lib/profiling/timers.h create mode 100644 src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c create mode 100644 src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h create mode 100644 src/core/lib/security/auth_filters.h create mode 100644 src/core/lib/security/b64.c create mode 100644 src/core/lib/security/b64.h create mode 100644 src/core/lib/security/client_auth_filter.c create mode 100644 src/core/lib/security/credentials.c create mode 100644 src/core/lib/security/credentials.h create mode 100644 src/core/lib/security/credentials_metadata.c create mode 100644 src/core/lib/security/credentials_posix.c create mode 100644 src/core/lib/security/credentials_win32.c create mode 100644 src/core/lib/security/google_default_credentials.c create mode 100644 src/core/lib/security/handshake.c create mode 100644 src/core/lib/security/handshake.h create mode 100644 src/core/lib/security/json_token.c create mode 100644 src/core/lib/security/json_token.h create mode 100644 src/core/lib/security/jwt_verifier.c create mode 100644 src/core/lib/security/jwt_verifier.h create mode 100644 src/core/lib/security/secure_endpoint.c create mode 100644 src/core/lib/security/secure_endpoint.h create mode 100644 src/core/lib/security/security_connector.c create mode 100644 src/core/lib/security/security_connector.h create mode 100644 src/core/lib/security/security_context.c create mode 100644 src/core/lib/security/security_context.h create mode 100644 src/core/lib/security/server_auth_filter.c create mode 100644 src/core/lib/security/server_secure_chttp2.c create mode 100644 src/core/lib/statistics/census_init.c create mode 100644 src/core/lib/statistics/census_interface.h create mode 100644 src/core/lib/statistics/census_log.c create mode 100644 src/core/lib/statistics/census_log.h create mode 100644 src/core/lib/statistics/census_rpc_stats.c create mode 100644 src/core/lib/statistics/census_rpc_stats.h create mode 100644 src/core/lib/statistics/census_tracing.c create mode 100644 src/core/lib/statistics/census_tracing.h create mode 100644 src/core/lib/statistics/hash_table.c create mode 100644 src/core/lib/statistics/hash_table.h create mode 100644 src/core/lib/statistics/window_stats.c create mode 100644 src/core/lib/statistics/window_stats.h create mode 100644 src/core/lib/support/alloc.c create mode 100644 src/core/lib/support/avl.c create mode 100644 src/core/lib/support/backoff.c create mode 100644 src/core/lib/support/backoff.h create mode 100644 src/core/lib/support/block_annotate.h create mode 100644 src/core/lib/support/cmdline.c create mode 100644 src/core/lib/support/cpu_iphone.c create mode 100644 src/core/lib/support/cpu_linux.c create mode 100644 src/core/lib/support/cpu_posix.c create mode 100644 src/core/lib/support/cpu_windows.c create mode 100644 src/core/lib/support/env.h create mode 100644 src/core/lib/support/env_linux.c create mode 100644 src/core/lib/support/env_posix.c create mode 100644 src/core/lib/support/env_win32.c create mode 100644 src/core/lib/support/histogram.c create mode 100644 src/core/lib/support/host_port.c create mode 100644 src/core/lib/support/load_file.c create mode 100644 src/core/lib/support/load_file.h create mode 100644 src/core/lib/support/log.c create mode 100644 src/core/lib/support/log_android.c create mode 100644 src/core/lib/support/log_linux.c create mode 100644 src/core/lib/support/log_posix.c create mode 100644 src/core/lib/support/log_win32.c create mode 100644 src/core/lib/support/murmur_hash.c create mode 100644 src/core/lib/support/murmur_hash.h create mode 100644 src/core/lib/support/slice.c create mode 100644 src/core/lib/support/slice_buffer.c create mode 100644 src/core/lib/support/stack_lockfree.c create mode 100644 src/core/lib/support/stack_lockfree.h create mode 100644 src/core/lib/support/string.c create mode 100644 src/core/lib/support/string.h create mode 100644 src/core/lib/support/string_posix.c create mode 100644 src/core/lib/support/string_win32.c create mode 100644 src/core/lib/support/string_win32.h create mode 100644 src/core/lib/support/subprocess_posix.c create mode 100644 src/core/lib/support/subprocess_windows.c create mode 100644 src/core/lib/support/sync.c create mode 100644 src/core/lib/support/sync_posix.c create mode 100644 src/core/lib/support/sync_win32.c create mode 100644 src/core/lib/support/thd.c create mode 100644 src/core/lib/support/thd_internal.h create mode 100644 src/core/lib/support/thd_posix.c create mode 100644 src/core/lib/support/thd_win32.c create mode 100644 src/core/lib/support/time.c create mode 100644 src/core/lib/support/time_posix.c create mode 100644 src/core/lib/support/time_precise.c create mode 100644 src/core/lib/support/time_precise.h create mode 100644 src/core/lib/support/time_win32.c create mode 100644 src/core/lib/support/tls_pthread.c create mode 100644 src/core/lib/support/tmpfile.h create mode 100644 src/core/lib/support/tmpfile_posix.c create mode 100644 src/core/lib/support/tmpfile_win32.c create mode 100644 src/core/lib/support/wrap_memcpy.c create mode 100644 src/core/lib/surface/alarm.c create mode 100644 src/core/lib/surface/api_trace.c create mode 100644 src/core/lib/surface/api_trace.h create mode 100644 src/core/lib/surface/byte_buffer.c create mode 100644 src/core/lib/surface/byte_buffer_reader.c create mode 100644 src/core/lib/surface/call.c create mode 100644 src/core/lib/surface/call.h create mode 100644 src/core/lib/surface/call_details.c create mode 100644 src/core/lib/surface/call_log_batch.c create mode 100644 src/core/lib/surface/call_test_only.h create mode 100644 src/core/lib/surface/channel.c create mode 100644 src/core/lib/surface/channel.h create mode 100644 src/core/lib/surface/channel_connectivity.c create mode 100644 src/core/lib/surface/channel_create.c create mode 100644 src/core/lib/surface/channel_init.c create mode 100644 src/core/lib/surface/channel_init.h create mode 100644 src/core/lib/surface/channel_ping.c create mode 100644 src/core/lib/surface/channel_stack_type.c create mode 100644 src/core/lib/surface/channel_stack_type.h create mode 100644 src/core/lib/surface/completion_queue.c create mode 100644 src/core/lib/surface/completion_queue.h create mode 100644 src/core/lib/surface/event_string.c create mode 100644 src/core/lib/surface/event_string.h create mode 100644 src/core/lib/surface/init.c create mode 100644 src/core/lib/surface/init.h create mode 100644 src/core/lib/surface/init_secure.c create mode 100644 src/core/lib/surface/init_unsecure.c create mode 100644 src/core/lib/surface/lame_client.c create mode 100644 src/core/lib/surface/lame_client.h create mode 100644 src/core/lib/surface/metadata_array.c create mode 100644 src/core/lib/surface/secure_channel_create.c create mode 100644 src/core/lib/surface/server.c create mode 100644 src/core/lib/surface/server.h create mode 100644 src/core/lib/surface/server_chttp2.c create mode 100644 src/core/lib/surface/surface_trace.h create mode 100644 src/core/lib/surface/validate_metadata.c create mode 100644 src/core/lib/surface/version.c create mode 100644 src/core/lib/transport/byte_stream.c create mode 100644 src/core/lib/transport/byte_stream.h create mode 100644 src/core/lib/transport/chttp2/alpn.c create mode 100644 src/core/lib/transport/chttp2/alpn.h create mode 100644 src/core/lib/transport/chttp2/bin_encoder.c create mode 100644 src/core/lib/transport/chttp2/bin_encoder.h create mode 100644 src/core/lib/transport/chttp2/frame.h create mode 100644 src/core/lib/transport/chttp2/frame_data.c create mode 100644 src/core/lib/transport/chttp2/frame_data.h create mode 100644 src/core/lib/transport/chttp2/frame_goaway.c create mode 100644 src/core/lib/transport/chttp2/frame_goaway.h create mode 100644 src/core/lib/transport/chttp2/frame_ping.c create mode 100644 src/core/lib/transport/chttp2/frame_ping.h create mode 100644 src/core/lib/transport/chttp2/frame_rst_stream.c create mode 100644 src/core/lib/transport/chttp2/frame_rst_stream.h create mode 100644 src/core/lib/transport/chttp2/frame_settings.c create mode 100644 src/core/lib/transport/chttp2/frame_settings.h create mode 100644 src/core/lib/transport/chttp2/frame_window_update.c create mode 100644 src/core/lib/transport/chttp2/frame_window_update.h create mode 100644 src/core/lib/transport/chttp2/hpack_encoder.c create mode 100644 src/core/lib/transport/chttp2/hpack_encoder.h create mode 100644 src/core/lib/transport/chttp2/hpack_parser.c create mode 100644 src/core/lib/transport/chttp2/hpack_parser.h create mode 100644 src/core/lib/transport/chttp2/hpack_table.c create mode 100644 src/core/lib/transport/chttp2/hpack_table.h create mode 100644 src/core/lib/transport/chttp2/hpack_tables.txt create mode 100644 src/core/lib/transport/chttp2/http2_errors.h create mode 100644 src/core/lib/transport/chttp2/huffsyms.c create mode 100644 src/core/lib/transport/chttp2/huffsyms.h create mode 100644 src/core/lib/transport/chttp2/incoming_metadata.c create mode 100644 src/core/lib/transport/chttp2/incoming_metadata.h create mode 100644 src/core/lib/transport/chttp2/internal.h create mode 100644 src/core/lib/transport/chttp2/parsing.c create mode 100644 src/core/lib/transport/chttp2/status_conversion.c create mode 100644 src/core/lib/transport/chttp2/status_conversion.h create mode 100644 src/core/lib/transport/chttp2/stream_lists.c create mode 100644 src/core/lib/transport/chttp2/stream_map.c create mode 100644 src/core/lib/transport/chttp2/stream_map.h create mode 100644 src/core/lib/transport/chttp2/timeout_encoding.c create mode 100644 src/core/lib/transport/chttp2/timeout_encoding.h create mode 100644 src/core/lib/transport/chttp2/varint.c create mode 100644 src/core/lib/transport/chttp2/varint.h create mode 100644 src/core/lib/transport/chttp2/writing.c create mode 100644 src/core/lib/transport/chttp2_transport.c create mode 100644 src/core/lib/transport/chttp2_transport.h create mode 100644 src/core/lib/transport/connectivity_state.c create mode 100644 src/core/lib/transport/connectivity_state.h create mode 100644 src/core/lib/transport/metadata.c create mode 100644 src/core/lib/transport/metadata.h create mode 100644 src/core/lib/transport/metadata_batch.c create mode 100644 src/core/lib/transport/metadata_batch.h create mode 100644 src/core/lib/transport/static_metadata.c create mode 100644 src/core/lib/transport/static_metadata.h create mode 100644 src/core/lib/transport/transport.c create mode 100644 src/core/lib/transport/transport.h create mode 100644 src/core/lib/transport/transport_impl.h create mode 100644 src/core/lib/transport/transport_op_string.c create mode 100644 src/core/lib/tsi/fake_transport_security.c create mode 100644 src/core/lib/tsi/fake_transport_security.h create mode 100644 src/core/lib/tsi/ssl_transport_security.c create mode 100644 src/core/lib/tsi/ssl_transport_security.h create mode 100644 src/core/lib/tsi/ssl_types.h create mode 100644 src/core/lib/tsi/test_creds/README create mode 100644 src/core/lib/tsi/test_creds/badclient.key create mode 100644 src/core/lib/tsi/test_creds/badclient.pem create mode 100644 src/core/lib/tsi/test_creds/badserver.key create mode 100644 src/core/lib/tsi/test_creds/badserver.pem create mode 100644 src/core/lib/tsi/test_creds/ca-openssl.cnf create mode 100644 src/core/lib/tsi/test_creds/ca.key create mode 100644 src/core/lib/tsi/test_creds/ca.pem create mode 100644 src/core/lib/tsi/test_creds/client.key create mode 100644 src/core/lib/tsi/test_creds/client.pem create mode 100644 src/core/lib/tsi/test_creds/server0.key create mode 100644 src/core/lib/tsi/test_creds/server0.pem create mode 100644 src/core/lib/tsi/test_creds/server1-openssl.cnf create mode 100644 src/core/lib/tsi/test_creds/server1.key create mode 100644 src/core/lib/tsi/test_creds/server1.pem create mode 100644 src/core/lib/tsi/transport_security.c create mode 100644 src/core/lib/tsi/transport_security.h create mode 100644 src/core/lib/tsi/transport_security_interface.h delete mode 100644 src/core/profiling/basic_timers.c delete mode 100644 src/core/profiling/stap_probes.d delete mode 100644 src/core/profiling/stap_timers.c delete mode 100644 src/core/profiling/timers.h delete mode 100644 src/core/proto/grpc/lb/v0/load_balancer.pb.c delete mode 100644 src/core/proto/grpc/lb/v0/load_balancer.pb.h delete mode 100644 src/core/security/auth_filters.h delete mode 100644 src/core/security/b64.c delete mode 100644 src/core/security/b64.h delete mode 100644 src/core/security/client_auth_filter.c delete mode 100644 src/core/security/credentials.c delete mode 100644 src/core/security/credentials.h delete mode 100644 src/core/security/credentials_metadata.c delete mode 100644 src/core/security/credentials_posix.c delete mode 100644 src/core/security/credentials_win32.c delete mode 100644 src/core/security/google_default_credentials.c delete mode 100644 src/core/security/handshake.c delete mode 100644 src/core/security/handshake.h delete mode 100644 src/core/security/json_token.c delete mode 100644 src/core/security/json_token.h delete mode 100644 src/core/security/jwt_verifier.c delete mode 100644 src/core/security/jwt_verifier.h delete mode 100644 src/core/security/secure_endpoint.c delete mode 100644 src/core/security/secure_endpoint.h delete mode 100644 src/core/security/security_connector.c delete mode 100644 src/core/security/security_connector.h delete mode 100644 src/core/security/security_context.c delete mode 100644 src/core/security/security_context.h delete mode 100644 src/core/security/server_auth_filter.c delete mode 100644 src/core/security/server_secure_chttp2.c delete mode 100644 src/core/statistics/census_init.c delete mode 100644 src/core/statistics/census_interface.h delete mode 100644 src/core/statistics/census_log.c delete mode 100644 src/core/statistics/census_log.h delete mode 100644 src/core/statistics/census_rpc_stats.c delete mode 100644 src/core/statistics/census_rpc_stats.h delete mode 100644 src/core/statistics/census_tracing.c delete mode 100644 src/core/statistics/census_tracing.h delete mode 100644 src/core/statistics/hash_table.c delete mode 100644 src/core/statistics/hash_table.h delete mode 100644 src/core/statistics/window_stats.c delete mode 100644 src/core/statistics/window_stats.h delete mode 100644 src/core/support/alloc.c delete mode 100644 src/core/support/avl.c delete mode 100644 src/core/support/backoff.c delete mode 100644 src/core/support/backoff.h delete mode 100644 src/core/support/block_annotate.h delete mode 100644 src/core/support/cmdline.c delete mode 100644 src/core/support/cpu_iphone.c delete mode 100644 src/core/support/cpu_linux.c delete mode 100644 src/core/support/cpu_posix.c delete mode 100644 src/core/support/cpu_windows.c delete mode 100644 src/core/support/env.h delete mode 100644 src/core/support/env_linux.c delete mode 100644 src/core/support/env_posix.c delete mode 100644 src/core/support/env_win32.c delete mode 100644 src/core/support/histogram.c delete mode 100644 src/core/support/host_port.c delete mode 100644 src/core/support/load_file.c delete mode 100644 src/core/support/load_file.h delete mode 100644 src/core/support/log.c delete mode 100644 src/core/support/log_android.c delete mode 100644 src/core/support/log_linux.c delete mode 100644 src/core/support/log_posix.c delete mode 100644 src/core/support/log_win32.c delete mode 100644 src/core/support/murmur_hash.c delete mode 100644 src/core/support/murmur_hash.h delete mode 100644 src/core/support/slice.c delete mode 100644 src/core/support/slice_buffer.c delete mode 100644 src/core/support/stack_lockfree.c delete mode 100644 src/core/support/stack_lockfree.h delete mode 100644 src/core/support/string.c delete mode 100644 src/core/support/string.h delete mode 100644 src/core/support/string_posix.c delete mode 100644 src/core/support/string_win32.c delete mode 100644 src/core/support/string_win32.h delete mode 100644 src/core/support/subprocess_posix.c delete mode 100644 src/core/support/subprocess_windows.c delete mode 100644 src/core/support/sync.c delete mode 100644 src/core/support/sync_posix.c delete mode 100644 src/core/support/sync_win32.c delete mode 100644 src/core/support/thd.c delete mode 100644 src/core/support/thd_internal.h delete mode 100644 src/core/support/thd_posix.c delete mode 100644 src/core/support/thd_win32.c delete mode 100644 src/core/support/time.c delete mode 100644 src/core/support/time_posix.c delete mode 100644 src/core/support/time_precise.c delete mode 100644 src/core/support/time_precise.h delete mode 100644 src/core/support/time_win32.c delete mode 100644 src/core/support/tls_pthread.c delete mode 100644 src/core/support/tmpfile.h delete mode 100644 src/core/support/tmpfile_posix.c delete mode 100644 src/core/support/tmpfile_win32.c delete mode 100644 src/core/support/wrap_memcpy.c delete mode 100644 src/core/surface/alarm.c delete mode 100644 src/core/surface/api_trace.c delete mode 100644 src/core/surface/api_trace.h delete mode 100644 src/core/surface/byte_buffer.c delete mode 100644 src/core/surface/byte_buffer_reader.c delete mode 100644 src/core/surface/call.c delete mode 100644 src/core/surface/call.h delete mode 100644 src/core/surface/call_details.c delete mode 100644 src/core/surface/call_log_batch.c delete mode 100644 src/core/surface/call_test_only.h delete mode 100644 src/core/surface/channel.c delete mode 100644 src/core/surface/channel.h delete mode 100644 src/core/surface/channel_connectivity.c delete mode 100644 src/core/surface/channel_create.c delete mode 100644 src/core/surface/channel_init.c delete mode 100644 src/core/surface/channel_init.h delete mode 100644 src/core/surface/channel_ping.c delete mode 100644 src/core/surface/channel_stack_type.c delete mode 100644 src/core/surface/channel_stack_type.h delete mode 100644 src/core/surface/completion_queue.c delete mode 100644 src/core/surface/completion_queue.h delete mode 100644 src/core/surface/event_string.c delete mode 100644 src/core/surface/event_string.h delete mode 100644 src/core/surface/init.c delete mode 100644 src/core/surface/init.h delete mode 100644 src/core/surface/init_secure.c delete mode 100644 src/core/surface/init_unsecure.c delete mode 100644 src/core/surface/lame_client.c delete mode 100644 src/core/surface/lame_client.h delete mode 100644 src/core/surface/metadata_array.c delete mode 100644 src/core/surface/secure_channel_create.c delete mode 100644 src/core/surface/server.c delete mode 100644 src/core/surface/server.h delete mode 100644 src/core/surface/server_chttp2.c delete mode 100644 src/core/surface/surface_trace.h delete mode 100644 src/core/surface/validate_metadata.c delete mode 100644 src/core/surface/version.c delete mode 100644 src/core/transport/byte_stream.c delete mode 100644 src/core/transport/byte_stream.h delete mode 100644 src/core/transport/chttp2/alpn.c delete mode 100644 src/core/transport/chttp2/alpn.h delete mode 100644 src/core/transport/chttp2/bin_encoder.c delete mode 100644 src/core/transport/chttp2/bin_encoder.h delete mode 100644 src/core/transport/chttp2/frame.h delete mode 100644 src/core/transport/chttp2/frame_data.c delete mode 100644 src/core/transport/chttp2/frame_data.h delete mode 100644 src/core/transport/chttp2/frame_goaway.c delete mode 100644 src/core/transport/chttp2/frame_goaway.h delete mode 100644 src/core/transport/chttp2/frame_ping.c delete mode 100644 src/core/transport/chttp2/frame_ping.h delete mode 100644 src/core/transport/chttp2/frame_rst_stream.c delete mode 100644 src/core/transport/chttp2/frame_rst_stream.h delete mode 100644 src/core/transport/chttp2/frame_settings.c delete mode 100644 src/core/transport/chttp2/frame_settings.h delete mode 100644 src/core/transport/chttp2/frame_window_update.c delete mode 100644 src/core/transport/chttp2/frame_window_update.h delete mode 100644 src/core/transport/chttp2/hpack_encoder.c delete mode 100644 src/core/transport/chttp2/hpack_encoder.h delete mode 100644 src/core/transport/chttp2/hpack_parser.c delete mode 100644 src/core/transport/chttp2/hpack_parser.h delete mode 100644 src/core/transport/chttp2/hpack_table.c delete mode 100644 src/core/transport/chttp2/hpack_table.h delete mode 100644 src/core/transport/chttp2/hpack_tables.txt delete mode 100644 src/core/transport/chttp2/http2_errors.h delete mode 100644 src/core/transport/chttp2/huffsyms.c delete mode 100644 src/core/transport/chttp2/huffsyms.h delete mode 100644 src/core/transport/chttp2/incoming_metadata.c delete mode 100644 src/core/transport/chttp2/incoming_metadata.h delete mode 100644 src/core/transport/chttp2/internal.h delete mode 100644 src/core/transport/chttp2/parsing.c delete mode 100644 src/core/transport/chttp2/status_conversion.c delete mode 100644 src/core/transport/chttp2/status_conversion.h delete mode 100644 src/core/transport/chttp2/stream_lists.c delete mode 100644 src/core/transport/chttp2/stream_map.c delete mode 100644 src/core/transport/chttp2/stream_map.h delete mode 100644 src/core/transport/chttp2/timeout_encoding.c delete mode 100644 src/core/transport/chttp2/timeout_encoding.h delete mode 100644 src/core/transport/chttp2/varint.c delete mode 100644 src/core/transport/chttp2/varint.h delete mode 100644 src/core/transport/chttp2/writing.c delete mode 100644 src/core/transport/chttp2_transport.c delete mode 100644 src/core/transport/chttp2_transport.h delete mode 100644 src/core/transport/connectivity_state.c delete mode 100644 src/core/transport/connectivity_state.h delete mode 100644 src/core/transport/metadata.c delete mode 100644 src/core/transport/metadata.h delete mode 100644 src/core/transport/metadata_batch.c delete mode 100644 src/core/transport/metadata_batch.h delete mode 100644 src/core/transport/static_metadata.c delete mode 100644 src/core/transport/static_metadata.h delete mode 100644 src/core/transport/transport.c delete mode 100644 src/core/transport/transport.h delete mode 100644 src/core/transport/transport_impl.h delete mode 100644 src/core/transport/transport_op_string.c delete mode 100644 src/core/tsi/fake_transport_security.c delete mode 100644 src/core/tsi/fake_transport_security.h delete mode 100644 src/core/tsi/ssl_transport_security.c delete mode 100644 src/core/tsi/ssl_transport_security.h delete mode 100644 src/core/tsi/ssl_types.h delete mode 100644 src/core/tsi/test_creds/README delete mode 100644 src/core/tsi/test_creds/badclient.key delete mode 100644 src/core/tsi/test_creds/badclient.pem delete mode 100644 src/core/tsi/test_creds/badserver.key delete mode 100644 src/core/tsi/test_creds/badserver.pem delete mode 100644 src/core/tsi/test_creds/ca-openssl.cnf delete mode 100644 src/core/tsi/test_creds/ca.key delete mode 100644 src/core/tsi/test_creds/ca.pem delete mode 100644 src/core/tsi/test_creds/client.key delete mode 100644 src/core/tsi/test_creds/client.pem delete mode 100644 src/core/tsi/test_creds/server0.key delete mode 100644 src/core/tsi/test_creds/server0.pem delete mode 100644 src/core/tsi/test_creds/server1-openssl.cnf delete mode 100644 src/core/tsi/test_creds/server1.key delete mode 100644 src/core/tsi/test_creds/server1.pem delete mode 100644 src/core/tsi/transport_security.c delete mode 100644 src/core/tsi/transport_security.h delete mode 100644 src/core/tsi/transport_security_interface.h create mode 100644 templates/src/core/lib/surface/version.c.template delete mode 100644 templates/src/core/surface/version.c.template (limited to 'src') diff --git a/BUILD b/BUILD index 7f8d8a423e..ef78f44508 100644 --- a/BUILD +++ b/BUILD @@ -44,62 +44,62 @@ package(default_visibility = ["//visibility:public"]) cc_library( name = "gpr", srcs = [ - "src/core/profiling/timers.h", - "src/core/support/backoff.h", - "src/core/support/block_annotate.h", - "src/core/support/env.h", - "src/core/support/load_file.h", - "src/core/support/murmur_hash.h", - "src/core/support/stack_lockfree.h", - "src/core/support/string.h", - "src/core/support/string_win32.h", - "src/core/support/thd_internal.h", - "src/core/support/time_precise.h", - "src/core/support/tmpfile.h", - "src/core/profiling/basic_timers.c", - "src/core/profiling/stap_timers.c", - "src/core/support/alloc.c", - "src/core/support/avl.c", - "src/core/support/backoff.c", - "src/core/support/cmdline.c", - "src/core/support/cpu_iphone.c", - "src/core/support/cpu_linux.c", - "src/core/support/cpu_posix.c", - "src/core/support/cpu_windows.c", - "src/core/support/env_linux.c", - "src/core/support/env_posix.c", - "src/core/support/env_win32.c", - "src/core/support/histogram.c", - "src/core/support/host_port.c", - "src/core/support/load_file.c", - "src/core/support/log.c", - "src/core/support/log_android.c", - "src/core/support/log_linux.c", - "src/core/support/log_posix.c", - "src/core/support/log_win32.c", - "src/core/support/murmur_hash.c", - "src/core/support/slice.c", - "src/core/support/slice_buffer.c", - "src/core/support/stack_lockfree.c", - "src/core/support/string.c", - "src/core/support/string_posix.c", - "src/core/support/string_win32.c", - "src/core/support/subprocess_posix.c", - "src/core/support/subprocess_windows.c", - "src/core/support/sync.c", - "src/core/support/sync_posix.c", - "src/core/support/sync_win32.c", - "src/core/support/thd.c", - "src/core/support/thd_posix.c", - "src/core/support/thd_win32.c", - "src/core/support/time.c", - "src/core/support/time_posix.c", - "src/core/support/time_precise.c", - "src/core/support/time_win32.c", - "src/core/support/tls_pthread.c", - "src/core/support/tmpfile_posix.c", - "src/core/support/tmpfile_win32.c", - "src/core/support/wrap_memcpy.c", + "src/core/lib/profiling/timers.h", + "src/core/lib/support/backoff.h", + "src/core/lib/support/block_annotate.h", + "src/core/lib/support/env.h", + "src/core/lib/support/load_file.h", + "src/core/lib/support/murmur_hash.h", + "src/core/lib/support/stack_lockfree.h", + "src/core/lib/support/string.h", + "src/core/lib/support/string_win32.h", + "src/core/lib/support/thd_internal.h", + "src/core/lib/support/time_precise.h", + "src/core/lib/support/tmpfile.h", + "src/core/lib/profiling/basic_timers.c", + "src/core/lib/profiling/stap_timers.c", + "src/core/lib/support/alloc.c", + "src/core/lib/support/avl.c", + "src/core/lib/support/backoff.c", + "src/core/lib/support/cmdline.c", + "src/core/lib/support/cpu_iphone.c", + "src/core/lib/support/cpu_linux.c", + "src/core/lib/support/cpu_posix.c", + "src/core/lib/support/cpu_windows.c", + "src/core/lib/support/env_linux.c", + "src/core/lib/support/env_posix.c", + "src/core/lib/support/env_win32.c", + "src/core/lib/support/histogram.c", + "src/core/lib/support/host_port.c", + "src/core/lib/support/load_file.c", + "src/core/lib/support/log.c", + "src/core/lib/support/log_android.c", + "src/core/lib/support/log_linux.c", + "src/core/lib/support/log_posix.c", + "src/core/lib/support/log_win32.c", + "src/core/lib/support/murmur_hash.c", + "src/core/lib/support/slice.c", + "src/core/lib/support/slice_buffer.c", + "src/core/lib/support/stack_lockfree.c", + "src/core/lib/support/string.c", + "src/core/lib/support/string_posix.c", + "src/core/lib/support/string_win32.c", + "src/core/lib/support/subprocess_posix.c", + "src/core/lib/support/subprocess_windows.c", + "src/core/lib/support/sync.c", + "src/core/lib/support/sync_posix.c", + "src/core/lib/support/sync_win32.c", + "src/core/lib/support/thd.c", + "src/core/lib/support/thd_posix.c", + "src/core/lib/support/thd_win32.c", + "src/core/lib/support/time.c", + "src/core/lib/support/time_posix.c", + "src/core/lib/support/time_precise.c", + "src/core/lib/support/time_win32.c", + "src/core/lib/support/tls_pthread.c", + "src/core/lib/support/tmpfile_posix.c", + "src/core/lib/support/tmpfile_win32.c", + "src/core/lib/support/wrap_memcpy.c", ], hdrs = [ "include/grpc/support/alloc.h", @@ -157,308 +157,308 @@ cc_library( cc_library( name = "grpc", srcs = [ - "src/core/census/grpc_filter.h", - "src/core/census/grpc_plugin.h", - "src/core/channel/channel_args.h", - "src/core/channel/channel_stack.h", - "src/core/channel/channel_stack_builder.h", - "src/core/channel/client_channel.h", - "src/core/channel/compress_filter.h", - "src/core/channel/connected_channel.h", - "src/core/channel/context.h", - "src/core/channel/http_client_filter.h", - "src/core/channel/http_server_filter.h", - "src/core/channel/subchannel_call_holder.h", - "src/core/client_config/client_config.h", - "src/core/client_config/connector.h", - "src/core/client_config/initial_connect_string.h", - "src/core/client_config/lb_policies/load_balancer_api.h", - "src/core/client_config/lb_policies/pick_first.h", - "src/core/client_config/lb_policies/round_robin.h", - "src/core/client_config/lb_policy.h", - "src/core/client_config/lb_policy_factory.h", - "src/core/client_config/lb_policy_registry.h", - "src/core/client_config/resolver.h", - "src/core/client_config/resolver_factory.h", - "src/core/client_config/resolver_registry.h", - "src/core/client_config/resolvers/dns_resolver.h", - "src/core/client_config/resolvers/sockaddr_resolver.h", - "src/core/client_config/subchannel.h", - "src/core/client_config/subchannel_factory.h", - "src/core/client_config/subchannel_index.h", - "src/core/client_config/uri_parser.h", - "src/core/compression/algorithm_metadata.h", - "src/core/compression/message_compress.h", - "src/core/debug/trace.h", - "src/core/http/format_request.h", - "src/core/http/httpcli.h", - "src/core/http/parser.h", - "src/core/iomgr/closure.h", - "src/core/iomgr/endpoint.h", - "src/core/iomgr/endpoint_pair.h", - "src/core/iomgr/exec_ctx.h", - "src/core/iomgr/executor.h", - "src/core/iomgr/fd_posix.h", - "src/core/iomgr/iocp_windows.h", - "src/core/iomgr/iomgr.h", - "src/core/iomgr/iomgr_internal.h", - "src/core/iomgr/iomgr_posix.h", - "src/core/iomgr/pollset.h", - "src/core/iomgr/pollset_posix.h", - "src/core/iomgr/pollset_set.h", - "src/core/iomgr/pollset_set_posix.h", - "src/core/iomgr/pollset_set_windows.h", - "src/core/iomgr/pollset_windows.h", - "src/core/iomgr/resolve_address.h", - "src/core/iomgr/sockaddr.h", - "src/core/iomgr/sockaddr_posix.h", - "src/core/iomgr/sockaddr_utils.h", - "src/core/iomgr/sockaddr_win32.h", - "src/core/iomgr/socket_utils_posix.h", - "src/core/iomgr/socket_windows.h", - "src/core/iomgr/tcp_client.h", - "src/core/iomgr/tcp_posix.h", - "src/core/iomgr/tcp_server.h", - "src/core/iomgr/tcp_windows.h", - "src/core/iomgr/time_averaged_stats.h", - "src/core/iomgr/timer.h", - "src/core/iomgr/timer_heap.h", - "src/core/iomgr/udp_server.h", - "src/core/iomgr/unix_sockets_posix.h", - "src/core/iomgr/wakeup_fd_pipe.h", - "src/core/iomgr/wakeup_fd_posix.h", - "src/core/iomgr/workqueue.h", - "src/core/iomgr/workqueue_posix.h", - "src/core/iomgr/workqueue_windows.h", - "src/core/json/json.h", - "src/core/json/json_common.h", - "src/core/json/json_reader.h", - "src/core/json/json_writer.h", - "src/core/proto/grpc/lb/v0/load_balancer.pb.h", - "src/core/statistics/census_interface.h", - "src/core/statistics/census_rpc_stats.h", - "src/core/surface/api_trace.h", - "src/core/surface/call.h", - "src/core/surface/call_test_only.h", - "src/core/surface/channel.h", - "src/core/surface/channel_init.h", - "src/core/surface/channel_stack_type.h", - "src/core/surface/completion_queue.h", - "src/core/surface/event_string.h", - "src/core/surface/init.h", - "src/core/surface/lame_client.h", - "src/core/surface/server.h", - "src/core/surface/surface_trace.h", - "src/core/transport/byte_stream.h", - "src/core/transport/chttp2/alpn.h", - "src/core/transport/chttp2/bin_encoder.h", - "src/core/transport/chttp2/frame.h", - "src/core/transport/chttp2/frame_data.h", - "src/core/transport/chttp2/frame_goaway.h", - "src/core/transport/chttp2/frame_ping.h", - "src/core/transport/chttp2/frame_rst_stream.h", - "src/core/transport/chttp2/frame_settings.h", - "src/core/transport/chttp2/frame_window_update.h", - "src/core/transport/chttp2/hpack_encoder.h", - "src/core/transport/chttp2/hpack_parser.h", - "src/core/transport/chttp2/hpack_table.h", - "src/core/transport/chttp2/http2_errors.h", - "src/core/transport/chttp2/huffsyms.h", - "src/core/transport/chttp2/incoming_metadata.h", - "src/core/transport/chttp2/internal.h", - "src/core/transport/chttp2/status_conversion.h", - "src/core/transport/chttp2/stream_map.h", - "src/core/transport/chttp2/timeout_encoding.h", - "src/core/transport/chttp2/varint.h", - "src/core/transport/chttp2_transport.h", - "src/core/transport/connectivity_state.h", - "src/core/transport/metadata.h", - "src/core/transport/metadata_batch.h", - "src/core/transport/static_metadata.h", - "src/core/transport/transport.h", - "src/core/transport/transport_impl.h", - "src/core/security/auth_filters.h", - "src/core/security/b64.h", - "src/core/security/credentials.h", - "src/core/security/handshake.h", - "src/core/security/json_token.h", - "src/core/security/jwt_verifier.h", - "src/core/security/secure_endpoint.h", - "src/core/security/security_connector.h", - "src/core/security/security_context.h", - "src/core/tsi/fake_transport_security.h", - "src/core/tsi/ssl_transport_security.h", - "src/core/tsi/ssl_types.h", - "src/core/tsi/transport_security.h", - "src/core/tsi/transport_security_interface.h", - "src/core/census/aggregation.h", - "src/core/census/mlog.h", - "src/core/census/rpc_metric_id.h", + "src/core/lib/census/grpc_filter.h", + "src/core/lib/census/grpc_plugin.h", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/client_channel.h", + "src/core/lib/channel/compress_filter.h", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/http_client_filter.h", + "src/core/lib/channel/http_server_filter.h", + "src/core/lib/channel/subchannel_call_holder.h", + "src/core/lib/client_config/client_config.h", + "src/core/lib/client_config/connector.h", + "src/core/lib/client_config/initial_connect_string.h", + "src/core/lib/client_config/lb_policies/load_balancer_api.h", + "src/core/lib/client_config/lb_policies/pick_first.h", + "src/core/lib/client_config/lb_policies/round_robin.h", + "src/core/lib/client_config/lb_policy.h", + "src/core/lib/client_config/lb_policy_factory.h", + "src/core/lib/client_config/lb_policy_registry.h", + "src/core/lib/client_config/resolver.h", + "src/core/lib/client_config/resolver_factory.h", + "src/core/lib/client_config/resolver_registry.h", + "src/core/lib/client_config/resolvers/dns_resolver.h", + "src/core/lib/client_config/resolvers/sockaddr_resolver.h", + "src/core/lib/client_config/subchannel.h", + "src/core/lib/client_config/subchannel_factory.h", + "src/core/lib/client_config/subchannel_index.h", + "src/core/lib/client_config/uri_parser.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/message_compress.h", + "src/core/lib/debug/trace.h", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/fd_posix.h", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_posix.h", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_posix.h", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_win32.h", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/iomgr/workqueue.h", + "src/core/lib/iomgr/workqueue_posix.h", + "src/core/lib/iomgr/workqueue_windows.h", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_writer.h", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h", + "src/core/lib/statistics/census_interface.h", + "src/core/lib/statistics/census_rpc_stats.h", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.h", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/server.h", + "src/core/lib/surface/surface_trace.h", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/chttp2/alpn.h", + "src/core/lib/transport/chttp2/bin_encoder.h", + "src/core/lib/transport/chttp2/frame.h", + "src/core/lib/transport/chttp2/frame_data.h", + "src/core/lib/transport/chttp2/frame_goaway.h", + "src/core/lib/transport/chttp2/frame_ping.h", + "src/core/lib/transport/chttp2/frame_rst_stream.h", + "src/core/lib/transport/chttp2/frame_settings.h", + "src/core/lib/transport/chttp2/frame_window_update.h", + "src/core/lib/transport/chttp2/hpack_encoder.h", + "src/core/lib/transport/chttp2/hpack_parser.h", + "src/core/lib/transport/chttp2/hpack_table.h", + "src/core/lib/transport/chttp2/http2_errors.h", + "src/core/lib/transport/chttp2/huffsyms.h", + "src/core/lib/transport/chttp2/incoming_metadata.h", + "src/core/lib/transport/chttp2/internal.h", + "src/core/lib/transport/chttp2/status_conversion.h", + "src/core/lib/transport/chttp2/stream_map.h", + "src/core/lib/transport/chttp2/timeout_encoding.h", + "src/core/lib/transport/chttp2/varint.h", + "src/core/lib/transport/chttp2_transport.h", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", + "src/core/lib/security/auth_filters.h", + "src/core/lib/security/b64.h", + "src/core/lib/security/credentials.h", + "src/core/lib/security/handshake.h", + "src/core/lib/security/json_token.h", + "src/core/lib/security/jwt_verifier.h", + "src/core/lib/security/secure_endpoint.h", + "src/core/lib/security/security_connector.h", + "src/core/lib/security/security_context.h", + "src/core/lib/tsi/fake_transport_security.h", + "src/core/lib/tsi/ssl_transport_security.h", + "src/core/lib/tsi/ssl_types.h", + "src/core/lib/tsi/transport_security.h", + "src/core/lib/tsi/transport_security_interface.h", + "src/core/lib/census/aggregation.h", + "src/core/lib/census/mlog.h", + "src/core/lib/census/rpc_metric_id.h", "third_party/nanopb/pb.h", "third_party/nanopb/pb_common.h", "third_party/nanopb/pb_decode.h", "third_party/nanopb/pb_encode.h", - "src/core/census/grpc_context.c", - "src/core/census/grpc_filter.c", - "src/core/census/grpc_plugin.c", - "src/core/channel/channel_args.c", - "src/core/channel/channel_stack.c", - "src/core/channel/channel_stack_builder.c", - "src/core/channel/client_channel.c", - "src/core/channel/compress_filter.c", - "src/core/channel/connected_channel.c", - "src/core/channel/http_client_filter.c", - "src/core/channel/http_server_filter.c", - "src/core/channel/subchannel_call_holder.c", - "src/core/client_config/client_config.c", - "src/core/client_config/connector.c", - "src/core/client_config/default_initial_connect_string.c", - "src/core/client_config/initial_connect_string.c", - "src/core/client_config/lb_policies/load_balancer_api.c", - "src/core/client_config/lb_policies/pick_first.c", - "src/core/client_config/lb_policies/round_robin.c", - "src/core/client_config/lb_policy.c", - "src/core/client_config/lb_policy_factory.c", - "src/core/client_config/lb_policy_registry.c", - "src/core/client_config/resolver.c", - "src/core/client_config/resolver_factory.c", - "src/core/client_config/resolver_registry.c", - "src/core/client_config/resolvers/dns_resolver.c", - "src/core/client_config/resolvers/sockaddr_resolver.c", - "src/core/client_config/subchannel.c", - "src/core/client_config/subchannel_factory.c", - "src/core/client_config/subchannel_index.c", - "src/core/client_config/uri_parser.c", - "src/core/compression/compression_algorithm.c", - "src/core/compression/message_compress.c", - "src/core/debug/trace.c", - "src/core/http/format_request.c", - "src/core/http/httpcli.c", - "src/core/http/parser.c", - "src/core/iomgr/closure.c", - "src/core/iomgr/endpoint.c", - "src/core/iomgr/endpoint_pair_posix.c", - "src/core/iomgr/endpoint_pair_windows.c", - "src/core/iomgr/exec_ctx.c", - "src/core/iomgr/executor.c", - "src/core/iomgr/fd_posix.c", - "src/core/iomgr/iocp_windows.c", - "src/core/iomgr/iomgr.c", - "src/core/iomgr/iomgr_posix.c", - "src/core/iomgr/iomgr_windows.c", - "src/core/iomgr/pollset_multipoller_with_epoll.c", - "src/core/iomgr/pollset_multipoller_with_poll_posix.c", - "src/core/iomgr/pollset_posix.c", - "src/core/iomgr/pollset_set_posix.c", - "src/core/iomgr/pollset_set_windows.c", - "src/core/iomgr/pollset_windows.c", - "src/core/iomgr/resolve_address_posix.c", - "src/core/iomgr/resolve_address_windows.c", - "src/core/iomgr/sockaddr_utils.c", - "src/core/iomgr/socket_utils_common_posix.c", - "src/core/iomgr/socket_utils_linux.c", - "src/core/iomgr/socket_utils_posix.c", - "src/core/iomgr/socket_windows.c", - "src/core/iomgr/tcp_client_posix.c", - "src/core/iomgr/tcp_client_windows.c", - "src/core/iomgr/tcp_posix.c", - "src/core/iomgr/tcp_server_posix.c", - "src/core/iomgr/tcp_server_windows.c", - "src/core/iomgr/tcp_windows.c", - "src/core/iomgr/time_averaged_stats.c", - "src/core/iomgr/timer.c", - "src/core/iomgr/timer_heap.c", - "src/core/iomgr/udp_server.c", - "src/core/iomgr/unix_sockets_posix.c", - "src/core/iomgr/unix_sockets_posix_noop.c", - "src/core/iomgr/wakeup_fd_eventfd.c", - "src/core/iomgr/wakeup_fd_nospecial.c", - "src/core/iomgr/wakeup_fd_pipe.c", - "src/core/iomgr/wakeup_fd_posix.c", - "src/core/iomgr/workqueue_posix.c", - "src/core/iomgr/workqueue_windows.c", - "src/core/json/json.c", - "src/core/json/json_reader.c", - "src/core/json/json_string.c", - "src/core/json/json_writer.c", - "src/core/proto/grpc/lb/v0/load_balancer.pb.c", - "src/core/surface/alarm.c", - "src/core/surface/api_trace.c", - "src/core/surface/byte_buffer.c", - "src/core/surface/byte_buffer_reader.c", - "src/core/surface/call.c", - "src/core/surface/call_details.c", - "src/core/surface/call_log_batch.c", - "src/core/surface/channel.c", - "src/core/surface/channel_connectivity.c", - "src/core/surface/channel_create.c", - "src/core/surface/channel_init.c", - "src/core/surface/channel_ping.c", - "src/core/surface/channel_stack_type.c", - "src/core/surface/completion_queue.c", - "src/core/surface/event_string.c", - "src/core/surface/init.c", - "src/core/surface/lame_client.c", - "src/core/surface/metadata_array.c", - "src/core/surface/server.c", - "src/core/surface/server_chttp2.c", - "src/core/surface/validate_metadata.c", - "src/core/surface/version.c", - "src/core/transport/byte_stream.c", - "src/core/transport/chttp2/alpn.c", - "src/core/transport/chttp2/bin_encoder.c", - "src/core/transport/chttp2/frame_data.c", - "src/core/transport/chttp2/frame_goaway.c", - "src/core/transport/chttp2/frame_ping.c", - "src/core/transport/chttp2/frame_rst_stream.c", - "src/core/transport/chttp2/frame_settings.c", - "src/core/transport/chttp2/frame_window_update.c", - "src/core/transport/chttp2/hpack_encoder.c", - "src/core/transport/chttp2/hpack_parser.c", - "src/core/transport/chttp2/hpack_table.c", - "src/core/transport/chttp2/huffsyms.c", - "src/core/transport/chttp2/incoming_metadata.c", - "src/core/transport/chttp2/parsing.c", - "src/core/transport/chttp2/status_conversion.c", - "src/core/transport/chttp2/stream_lists.c", - "src/core/transport/chttp2/stream_map.c", - "src/core/transport/chttp2/timeout_encoding.c", - "src/core/transport/chttp2/varint.c", - "src/core/transport/chttp2/writing.c", - "src/core/transport/chttp2_transport.c", - "src/core/transport/connectivity_state.c", - "src/core/transport/metadata.c", - "src/core/transport/metadata_batch.c", - "src/core/transport/static_metadata.c", - "src/core/transport/transport.c", - "src/core/transport/transport_op_string.c", - "src/core/http/httpcli_security_connector.c", - "src/core/security/b64.c", - "src/core/security/client_auth_filter.c", - "src/core/security/credentials.c", - "src/core/security/credentials_metadata.c", - "src/core/security/credentials_posix.c", - "src/core/security/credentials_win32.c", - "src/core/security/google_default_credentials.c", - "src/core/security/handshake.c", - "src/core/security/json_token.c", - "src/core/security/jwt_verifier.c", - "src/core/security/secure_endpoint.c", - "src/core/security/security_connector.c", - "src/core/security/security_context.c", - "src/core/security/server_auth_filter.c", - "src/core/security/server_secure_chttp2.c", - "src/core/surface/init_secure.c", - "src/core/surface/secure_channel_create.c", - "src/core/tsi/fake_transport_security.c", - "src/core/tsi/ssl_transport_security.c", - "src/core/tsi/transport_security.c", - "src/core/census/context.c", - "src/core/census/initialize.c", - "src/core/census/mlog.c", - "src/core/census/operation.c", - "src/core/census/placeholders.c", - "src/core/census/tracing.c", + "src/core/lib/census/grpc_context.c", + "src/core/lib/census/grpc_filter.c", + "src/core/lib/census/grpc_plugin.c", + "src/core/lib/channel/channel_args.c", + "src/core/lib/channel/channel_stack.c", + "src/core/lib/channel/channel_stack_builder.c", + "src/core/lib/channel/client_channel.c", + "src/core/lib/channel/compress_filter.c", + "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/http_client_filter.c", + "src/core/lib/channel/http_server_filter.c", + "src/core/lib/channel/subchannel_call_holder.c", + "src/core/lib/client_config/client_config.c", + "src/core/lib/client_config/connector.c", + "src/core/lib/client_config/default_initial_connect_string.c", + "src/core/lib/client_config/initial_connect_string.c", + "src/core/lib/client_config/lb_policies/load_balancer_api.c", + "src/core/lib/client_config/lb_policies/pick_first.c", + "src/core/lib/client_config/lb_policies/round_robin.c", + "src/core/lib/client_config/lb_policy.c", + "src/core/lib/client_config/lb_policy_factory.c", + "src/core/lib/client_config/lb_policy_registry.c", + "src/core/lib/client_config/resolver.c", + "src/core/lib/client_config/resolver_factory.c", + "src/core/lib/client_config/resolver_registry.c", + "src/core/lib/client_config/resolvers/dns_resolver.c", + "src/core/lib/client_config/resolvers/sockaddr_resolver.c", + "src/core/lib/client_config/subchannel.c", + "src/core/lib/client_config/subchannel_factory.c", + "src/core/lib/client_config/subchannel_index.c", + "src/core/lib/client_config/uri_parser.c", + "src/core/lib/compression/compression_algorithm.c", + "src/core/lib/compression/message_compress.c", + "src/core/lib/debug/trace.c", + "src/core/lib/http/format_request.c", + "src/core/lib/http/httpcli.c", + "src/core/lib/http/parser.c", + "src/core/lib/iomgr/closure.c", + "src/core/lib/iomgr/endpoint.c", + "src/core/lib/iomgr/endpoint_pair_posix.c", + "src/core/lib/iomgr/endpoint_pair_windows.c", + "src/core/lib/iomgr/exec_ctx.c", + "src/core/lib/iomgr/executor.c", + "src/core/lib/iomgr/fd_posix.c", + "src/core/lib/iomgr/iocp_windows.c", + "src/core/lib/iomgr/iomgr.c", + "src/core/lib/iomgr/iomgr_posix.c", + "src/core/lib/iomgr/iomgr_windows.c", + "src/core/lib/iomgr/pollset_multipoller_with_epoll.c", + "src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c", + "src/core/lib/iomgr/pollset_posix.c", + "src/core/lib/iomgr/pollset_set_posix.c", + "src/core/lib/iomgr/pollset_set_windows.c", + "src/core/lib/iomgr/pollset_windows.c", + "src/core/lib/iomgr/resolve_address_posix.c", + "src/core/lib/iomgr/resolve_address_windows.c", + "src/core/lib/iomgr/sockaddr_utils.c", + "src/core/lib/iomgr/socket_utils_common_posix.c", + "src/core/lib/iomgr/socket_utils_linux.c", + "src/core/lib/iomgr/socket_utils_posix.c", + "src/core/lib/iomgr/socket_windows.c", + "src/core/lib/iomgr/tcp_client_posix.c", + "src/core/lib/iomgr/tcp_client_windows.c", + "src/core/lib/iomgr/tcp_posix.c", + "src/core/lib/iomgr/tcp_server_posix.c", + "src/core/lib/iomgr/tcp_server_windows.c", + "src/core/lib/iomgr/tcp_windows.c", + "src/core/lib/iomgr/time_averaged_stats.c", + "src/core/lib/iomgr/timer.c", + "src/core/lib/iomgr/timer_heap.c", + "src/core/lib/iomgr/udp_server.c", + "src/core/lib/iomgr/unix_sockets_posix.c", + "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_eventfd.c", + "src/core/lib/iomgr/wakeup_fd_nospecial.c", + "src/core/lib/iomgr/wakeup_fd_pipe.c", + "src/core/lib/iomgr/wakeup_fd_posix.c", + "src/core/lib/iomgr/workqueue_posix.c", + "src/core/lib/iomgr/workqueue_windows.c", + "src/core/lib/json/json.c", + "src/core/lib/json/json_reader.c", + "src/core/lib/json/json_string.c", + "src/core/lib/json/json_writer.c", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c", + "src/core/lib/surface/alarm.c", + "src/core/lib/surface/api_trace.c", + "src/core/lib/surface/byte_buffer.c", + "src/core/lib/surface/byte_buffer_reader.c", + "src/core/lib/surface/call.c", + "src/core/lib/surface/call_details.c", + "src/core/lib/surface/call_log_batch.c", + "src/core/lib/surface/channel.c", + "src/core/lib/surface/channel_connectivity.c", + "src/core/lib/surface/channel_create.c", + "src/core/lib/surface/channel_init.c", + "src/core/lib/surface/channel_ping.c", + "src/core/lib/surface/channel_stack_type.c", + "src/core/lib/surface/completion_queue.c", + "src/core/lib/surface/event_string.c", + "src/core/lib/surface/init.c", + "src/core/lib/surface/lame_client.c", + "src/core/lib/surface/metadata_array.c", + "src/core/lib/surface/server.c", + "src/core/lib/surface/server_chttp2.c", + "src/core/lib/surface/validate_metadata.c", + "src/core/lib/surface/version.c", + "src/core/lib/transport/byte_stream.c", + "src/core/lib/transport/chttp2/alpn.c", + "src/core/lib/transport/chttp2/bin_encoder.c", + "src/core/lib/transport/chttp2/frame_data.c", + "src/core/lib/transport/chttp2/frame_goaway.c", + "src/core/lib/transport/chttp2/frame_ping.c", + "src/core/lib/transport/chttp2/frame_rst_stream.c", + "src/core/lib/transport/chttp2/frame_settings.c", + "src/core/lib/transport/chttp2/frame_window_update.c", + "src/core/lib/transport/chttp2/hpack_encoder.c", + "src/core/lib/transport/chttp2/hpack_parser.c", + "src/core/lib/transport/chttp2/hpack_table.c", + "src/core/lib/transport/chttp2/huffsyms.c", + "src/core/lib/transport/chttp2/incoming_metadata.c", + "src/core/lib/transport/chttp2/parsing.c", + "src/core/lib/transport/chttp2/status_conversion.c", + "src/core/lib/transport/chttp2/stream_lists.c", + "src/core/lib/transport/chttp2/stream_map.c", + "src/core/lib/transport/chttp2/timeout_encoding.c", + "src/core/lib/transport/chttp2/varint.c", + "src/core/lib/transport/chttp2/writing.c", + "src/core/lib/transport/chttp2_transport.c", + "src/core/lib/transport/connectivity_state.c", + "src/core/lib/transport/metadata.c", + "src/core/lib/transport/metadata_batch.c", + "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/transport.c", + "src/core/lib/transport/transport_op_string.c", + "src/core/lib/http/httpcli_security_connector.c", + "src/core/lib/security/b64.c", + "src/core/lib/security/client_auth_filter.c", + "src/core/lib/security/credentials.c", + "src/core/lib/security/credentials_metadata.c", + "src/core/lib/security/credentials_posix.c", + "src/core/lib/security/credentials_win32.c", + "src/core/lib/security/google_default_credentials.c", + "src/core/lib/security/handshake.c", + "src/core/lib/security/json_token.c", + "src/core/lib/security/jwt_verifier.c", + "src/core/lib/security/secure_endpoint.c", + "src/core/lib/security/security_connector.c", + "src/core/lib/security/security_context.c", + "src/core/lib/security/server_auth_filter.c", + "src/core/lib/security/server_secure_chttp2.c", + "src/core/lib/surface/init_secure.c", + "src/core/lib/surface/secure_channel_create.c", + "src/core/lib/tsi/fake_transport_security.c", + "src/core/lib/tsi/ssl_transport_security.c", + "src/core/lib/tsi/transport_security.c", + "src/core/lib/census/context.c", + "src/core/lib/census/initialize.c", + "src/core/lib/census/mlog.c", + "src/core/lib/census/operation.c", + "src/core/lib/census/placeholders.c", + "src/core/lib/census/tracing.c", "third_party/nanopb/pb_common.c", "third_party/nanopb/pb_decode.c", "third_party/nanopb/pb_encode.c", @@ -532,274 +532,274 @@ cc_library( cc_library( name = "grpc_unsecure", srcs = [ - "src/core/census/grpc_filter.h", - "src/core/census/grpc_plugin.h", - "src/core/channel/channel_args.h", - "src/core/channel/channel_stack.h", - "src/core/channel/channel_stack_builder.h", - "src/core/channel/client_channel.h", - "src/core/channel/compress_filter.h", - "src/core/channel/connected_channel.h", - "src/core/channel/context.h", - "src/core/channel/http_client_filter.h", - "src/core/channel/http_server_filter.h", - "src/core/channel/subchannel_call_holder.h", - "src/core/client_config/client_config.h", - "src/core/client_config/connector.h", - "src/core/client_config/initial_connect_string.h", - "src/core/client_config/lb_policies/load_balancer_api.h", - "src/core/client_config/lb_policies/pick_first.h", - "src/core/client_config/lb_policies/round_robin.h", - "src/core/client_config/lb_policy.h", - "src/core/client_config/lb_policy_factory.h", - "src/core/client_config/lb_policy_registry.h", - "src/core/client_config/resolver.h", - "src/core/client_config/resolver_factory.h", - "src/core/client_config/resolver_registry.h", - "src/core/client_config/resolvers/dns_resolver.h", - "src/core/client_config/resolvers/sockaddr_resolver.h", - "src/core/client_config/subchannel.h", - "src/core/client_config/subchannel_factory.h", - "src/core/client_config/subchannel_index.h", - "src/core/client_config/uri_parser.h", - "src/core/compression/algorithm_metadata.h", - "src/core/compression/message_compress.h", - "src/core/debug/trace.h", - "src/core/http/format_request.h", - "src/core/http/httpcli.h", - "src/core/http/parser.h", - "src/core/iomgr/closure.h", - "src/core/iomgr/endpoint.h", - "src/core/iomgr/endpoint_pair.h", - "src/core/iomgr/exec_ctx.h", - "src/core/iomgr/executor.h", - "src/core/iomgr/fd_posix.h", - "src/core/iomgr/iocp_windows.h", - "src/core/iomgr/iomgr.h", - "src/core/iomgr/iomgr_internal.h", - "src/core/iomgr/iomgr_posix.h", - "src/core/iomgr/pollset.h", - "src/core/iomgr/pollset_posix.h", - "src/core/iomgr/pollset_set.h", - "src/core/iomgr/pollset_set_posix.h", - "src/core/iomgr/pollset_set_windows.h", - "src/core/iomgr/pollset_windows.h", - "src/core/iomgr/resolve_address.h", - "src/core/iomgr/sockaddr.h", - "src/core/iomgr/sockaddr_posix.h", - "src/core/iomgr/sockaddr_utils.h", - "src/core/iomgr/sockaddr_win32.h", - "src/core/iomgr/socket_utils_posix.h", - "src/core/iomgr/socket_windows.h", - "src/core/iomgr/tcp_client.h", - "src/core/iomgr/tcp_posix.h", - "src/core/iomgr/tcp_server.h", - "src/core/iomgr/tcp_windows.h", - "src/core/iomgr/time_averaged_stats.h", - "src/core/iomgr/timer.h", - "src/core/iomgr/timer_heap.h", - "src/core/iomgr/udp_server.h", - "src/core/iomgr/unix_sockets_posix.h", - "src/core/iomgr/wakeup_fd_pipe.h", - "src/core/iomgr/wakeup_fd_posix.h", - "src/core/iomgr/workqueue.h", - "src/core/iomgr/workqueue_posix.h", - "src/core/iomgr/workqueue_windows.h", - "src/core/json/json.h", - "src/core/json/json_common.h", - "src/core/json/json_reader.h", - "src/core/json/json_writer.h", - "src/core/proto/grpc/lb/v0/load_balancer.pb.h", - "src/core/statistics/census_interface.h", - "src/core/statistics/census_rpc_stats.h", - "src/core/surface/api_trace.h", - "src/core/surface/call.h", - "src/core/surface/call_test_only.h", - "src/core/surface/channel.h", - "src/core/surface/channel_init.h", - "src/core/surface/channel_stack_type.h", - "src/core/surface/completion_queue.h", - "src/core/surface/event_string.h", - "src/core/surface/init.h", - "src/core/surface/lame_client.h", - "src/core/surface/server.h", - "src/core/surface/surface_trace.h", - "src/core/transport/byte_stream.h", - "src/core/transport/chttp2/alpn.h", - "src/core/transport/chttp2/bin_encoder.h", - "src/core/transport/chttp2/frame.h", - "src/core/transport/chttp2/frame_data.h", - "src/core/transport/chttp2/frame_goaway.h", - "src/core/transport/chttp2/frame_ping.h", - "src/core/transport/chttp2/frame_rst_stream.h", - "src/core/transport/chttp2/frame_settings.h", - "src/core/transport/chttp2/frame_window_update.h", - "src/core/transport/chttp2/hpack_encoder.h", - "src/core/transport/chttp2/hpack_parser.h", - "src/core/transport/chttp2/hpack_table.h", - "src/core/transport/chttp2/http2_errors.h", - "src/core/transport/chttp2/huffsyms.h", - "src/core/transport/chttp2/incoming_metadata.h", - "src/core/transport/chttp2/internal.h", - "src/core/transport/chttp2/status_conversion.h", - "src/core/transport/chttp2/stream_map.h", - "src/core/transport/chttp2/timeout_encoding.h", - "src/core/transport/chttp2/varint.h", - "src/core/transport/chttp2_transport.h", - "src/core/transport/connectivity_state.h", - "src/core/transport/metadata.h", - "src/core/transport/metadata_batch.h", - "src/core/transport/static_metadata.h", - "src/core/transport/transport.h", - "src/core/transport/transport_impl.h", - "src/core/census/aggregation.h", - "src/core/census/mlog.h", - "src/core/census/rpc_metric_id.h", + "src/core/lib/census/grpc_filter.h", + "src/core/lib/census/grpc_plugin.h", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/client_channel.h", + "src/core/lib/channel/compress_filter.h", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/http_client_filter.h", + "src/core/lib/channel/http_server_filter.h", + "src/core/lib/channel/subchannel_call_holder.h", + "src/core/lib/client_config/client_config.h", + "src/core/lib/client_config/connector.h", + "src/core/lib/client_config/initial_connect_string.h", + "src/core/lib/client_config/lb_policies/load_balancer_api.h", + "src/core/lib/client_config/lb_policies/pick_first.h", + "src/core/lib/client_config/lb_policies/round_robin.h", + "src/core/lib/client_config/lb_policy.h", + "src/core/lib/client_config/lb_policy_factory.h", + "src/core/lib/client_config/lb_policy_registry.h", + "src/core/lib/client_config/resolver.h", + "src/core/lib/client_config/resolver_factory.h", + "src/core/lib/client_config/resolver_registry.h", + "src/core/lib/client_config/resolvers/dns_resolver.h", + "src/core/lib/client_config/resolvers/sockaddr_resolver.h", + "src/core/lib/client_config/subchannel.h", + "src/core/lib/client_config/subchannel_factory.h", + "src/core/lib/client_config/subchannel_index.h", + "src/core/lib/client_config/uri_parser.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/message_compress.h", + "src/core/lib/debug/trace.h", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/fd_posix.h", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_posix.h", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_posix.h", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_win32.h", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/iomgr/workqueue.h", + "src/core/lib/iomgr/workqueue_posix.h", + "src/core/lib/iomgr/workqueue_windows.h", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_writer.h", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h", + "src/core/lib/statistics/census_interface.h", + "src/core/lib/statistics/census_rpc_stats.h", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.h", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/server.h", + "src/core/lib/surface/surface_trace.h", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/chttp2/alpn.h", + "src/core/lib/transport/chttp2/bin_encoder.h", + "src/core/lib/transport/chttp2/frame.h", + "src/core/lib/transport/chttp2/frame_data.h", + "src/core/lib/transport/chttp2/frame_goaway.h", + "src/core/lib/transport/chttp2/frame_ping.h", + "src/core/lib/transport/chttp2/frame_rst_stream.h", + "src/core/lib/transport/chttp2/frame_settings.h", + "src/core/lib/transport/chttp2/frame_window_update.h", + "src/core/lib/transport/chttp2/hpack_encoder.h", + "src/core/lib/transport/chttp2/hpack_parser.h", + "src/core/lib/transport/chttp2/hpack_table.h", + "src/core/lib/transport/chttp2/http2_errors.h", + "src/core/lib/transport/chttp2/huffsyms.h", + "src/core/lib/transport/chttp2/incoming_metadata.h", + "src/core/lib/transport/chttp2/internal.h", + "src/core/lib/transport/chttp2/status_conversion.h", + "src/core/lib/transport/chttp2/stream_map.h", + "src/core/lib/transport/chttp2/timeout_encoding.h", + "src/core/lib/transport/chttp2/varint.h", + "src/core/lib/transport/chttp2_transport.h", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", + "src/core/lib/census/aggregation.h", + "src/core/lib/census/mlog.h", + "src/core/lib/census/rpc_metric_id.h", "third_party/nanopb/pb.h", "third_party/nanopb/pb_common.h", "third_party/nanopb/pb_decode.h", "third_party/nanopb/pb_encode.h", - "src/core/surface/init_unsecure.c", - "src/core/census/grpc_context.c", - "src/core/census/grpc_filter.c", - "src/core/census/grpc_plugin.c", - "src/core/channel/channel_args.c", - "src/core/channel/channel_stack.c", - "src/core/channel/channel_stack_builder.c", - "src/core/channel/client_channel.c", - "src/core/channel/compress_filter.c", - "src/core/channel/connected_channel.c", - "src/core/channel/http_client_filter.c", - "src/core/channel/http_server_filter.c", - "src/core/channel/subchannel_call_holder.c", - "src/core/client_config/client_config.c", - "src/core/client_config/connector.c", - "src/core/client_config/default_initial_connect_string.c", - "src/core/client_config/initial_connect_string.c", - "src/core/client_config/lb_policies/load_balancer_api.c", - "src/core/client_config/lb_policies/pick_first.c", - "src/core/client_config/lb_policies/round_robin.c", - "src/core/client_config/lb_policy.c", - "src/core/client_config/lb_policy_factory.c", - "src/core/client_config/lb_policy_registry.c", - "src/core/client_config/resolver.c", - "src/core/client_config/resolver_factory.c", - "src/core/client_config/resolver_registry.c", - "src/core/client_config/resolvers/dns_resolver.c", - "src/core/client_config/resolvers/sockaddr_resolver.c", - "src/core/client_config/subchannel.c", - "src/core/client_config/subchannel_factory.c", - "src/core/client_config/subchannel_index.c", - "src/core/client_config/uri_parser.c", - "src/core/compression/compression_algorithm.c", - "src/core/compression/message_compress.c", - "src/core/debug/trace.c", - "src/core/http/format_request.c", - "src/core/http/httpcli.c", - "src/core/http/parser.c", - "src/core/iomgr/closure.c", - "src/core/iomgr/endpoint.c", - "src/core/iomgr/endpoint_pair_posix.c", - "src/core/iomgr/endpoint_pair_windows.c", - "src/core/iomgr/exec_ctx.c", - "src/core/iomgr/executor.c", - "src/core/iomgr/fd_posix.c", - "src/core/iomgr/iocp_windows.c", - "src/core/iomgr/iomgr.c", - "src/core/iomgr/iomgr_posix.c", - "src/core/iomgr/iomgr_windows.c", - "src/core/iomgr/pollset_multipoller_with_epoll.c", - "src/core/iomgr/pollset_multipoller_with_poll_posix.c", - "src/core/iomgr/pollset_posix.c", - "src/core/iomgr/pollset_set_posix.c", - "src/core/iomgr/pollset_set_windows.c", - "src/core/iomgr/pollset_windows.c", - "src/core/iomgr/resolve_address_posix.c", - "src/core/iomgr/resolve_address_windows.c", - "src/core/iomgr/sockaddr_utils.c", - "src/core/iomgr/socket_utils_common_posix.c", - "src/core/iomgr/socket_utils_linux.c", - "src/core/iomgr/socket_utils_posix.c", - "src/core/iomgr/socket_windows.c", - "src/core/iomgr/tcp_client_posix.c", - "src/core/iomgr/tcp_client_windows.c", - "src/core/iomgr/tcp_posix.c", - "src/core/iomgr/tcp_server_posix.c", - "src/core/iomgr/tcp_server_windows.c", - "src/core/iomgr/tcp_windows.c", - "src/core/iomgr/time_averaged_stats.c", - "src/core/iomgr/timer.c", - "src/core/iomgr/timer_heap.c", - "src/core/iomgr/udp_server.c", - "src/core/iomgr/unix_sockets_posix.c", - "src/core/iomgr/unix_sockets_posix_noop.c", - "src/core/iomgr/wakeup_fd_eventfd.c", - "src/core/iomgr/wakeup_fd_nospecial.c", - "src/core/iomgr/wakeup_fd_pipe.c", - "src/core/iomgr/wakeup_fd_posix.c", - "src/core/iomgr/workqueue_posix.c", - "src/core/iomgr/workqueue_windows.c", - "src/core/json/json.c", - "src/core/json/json_reader.c", - "src/core/json/json_string.c", - "src/core/json/json_writer.c", - "src/core/proto/grpc/lb/v0/load_balancer.pb.c", - "src/core/surface/alarm.c", - "src/core/surface/api_trace.c", - "src/core/surface/byte_buffer.c", - "src/core/surface/byte_buffer_reader.c", - "src/core/surface/call.c", - "src/core/surface/call_details.c", - "src/core/surface/call_log_batch.c", - "src/core/surface/channel.c", - "src/core/surface/channel_connectivity.c", - "src/core/surface/channel_create.c", - "src/core/surface/channel_init.c", - "src/core/surface/channel_ping.c", - "src/core/surface/channel_stack_type.c", - "src/core/surface/completion_queue.c", - "src/core/surface/event_string.c", - "src/core/surface/init.c", - "src/core/surface/lame_client.c", - "src/core/surface/metadata_array.c", - "src/core/surface/server.c", - "src/core/surface/server_chttp2.c", - "src/core/surface/validate_metadata.c", - "src/core/surface/version.c", - "src/core/transport/byte_stream.c", - "src/core/transport/chttp2/alpn.c", - "src/core/transport/chttp2/bin_encoder.c", - "src/core/transport/chttp2/frame_data.c", - "src/core/transport/chttp2/frame_goaway.c", - "src/core/transport/chttp2/frame_ping.c", - "src/core/transport/chttp2/frame_rst_stream.c", - "src/core/transport/chttp2/frame_settings.c", - "src/core/transport/chttp2/frame_window_update.c", - "src/core/transport/chttp2/hpack_encoder.c", - "src/core/transport/chttp2/hpack_parser.c", - "src/core/transport/chttp2/hpack_table.c", - "src/core/transport/chttp2/huffsyms.c", - "src/core/transport/chttp2/incoming_metadata.c", - "src/core/transport/chttp2/parsing.c", - "src/core/transport/chttp2/status_conversion.c", - "src/core/transport/chttp2/stream_lists.c", - "src/core/transport/chttp2/stream_map.c", - "src/core/transport/chttp2/timeout_encoding.c", - "src/core/transport/chttp2/varint.c", - "src/core/transport/chttp2/writing.c", - "src/core/transport/chttp2_transport.c", - "src/core/transport/connectivity_state.c", - "src/core/transport/metadata.c", - "src/core/transport/metadata_batch.c", - "src/core/transport/static_metadata.c", - "src/core/transport/transport.c", - "src/core/transport/transport_op_string.c", - "src/core/census/context.c", - "src/core/census/initialize.c", - "src/core/census/mlog.c", - "src/core/census/operation.c", - "src/core/census/placeholders.c", - "src/core/census/tracing.c", + "src/core/lib/surface/init_unsecure.c", + "src/core/lib/census/grpc_context.c", + "src/core/lib/census/grpc_filter.c", + "src/core/lib/census/grpc_plugin.c", + "src/core/lib/channel/channel_args.c", + "src/core/lib/channel/channel_stack.c", + "src/core/lib/channel/channel_stack_builder.c", + "src/core/lib/channel/client_channel.c", + "src/core/lib/channel/compress_filter.c", + "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/http_client_filter.c", + "src/core/lib/channel/http_server_filter.c", + "src/core/lib/channel/subchannel_call_holder.c", + "src/core/lib/client_config/client_config.c", + "src/core/lib/client_config/connector.c", + "src/core/lib/client_config/default_initial_connect_string.c", + "src/core/lib/client_config/initial_connect_string.c", + "src/core/lib/client_config/lb_policies/load_balancer_api.c", + "src/core/lib/client_config/lb_policies/pick_first.c", + "src/core/lib/client_config/lb_policies/round_robin.c", + "src/core/lib/client_config/lb_policy.c", + "src/core/lib/client_config/lb_policy_factory.c", + "src/core/lib/client_config/lb_policy_registry.c", + "src/core/lib/client_config/resolver.c", + "src/core/lib/client_config/resolver_factory.c", + "src/core/lib/client_config/resolver_registry.c", + "src/core/lib/client_config/resolvers/dns_resolver.c", + "src/core/lib/client_config/resolvers/sockaddr_resolver.c", + "src/core/lib/client_config/subchannel.c", + "src/core/lib/client_config/subchannel_factory.c", + "src/core/lib/client_config/subchannel_index.c", + "src/core/lib/client_config/uri_parser.c", + "src/core/lib/compression/compression_algorithm.c", + "src/core/lib/compression/message_compress.c", + "src/core/lib/debug/trace.c", + "src/core/lib/http/format_request.c", + "src/core/lib/http/httpcli.c", + "src/core/lib/http/parser.c", + "src/core/lib/iomgr/closure.c", + "src/core/lib/iomgr/endpoint.c", + "src/core/lib/iomgr/endpoint_pair_posix.c", + "src/core/lib/iomgr/endpoint_pair_windows.c", + "src/core/lib/iomgr/exec_ctx.c", + "src/core/lib/iomgr/executor.c", + "src/core/lib/iomgr/fd_posix.c", + "src/core/lib/iomgr/iocp_windows.c", + "src/core/lib/iomgr/iomgr.c", + "src/core/lib/iomgr/iomgr_posix.c", + "src/core/lib/iomgr/iomgr_windows.c", + "src/core/lib/iomgr/pollset_multipoller_with_epoll.c", + "src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c", + "src/core/lib/iomgr/pollset_posix.c", + "src/core/lib/iomgr/pollset_set_posix.c", + "src/core/lib/iomgr/pollset_set_windows.c", + "src/core/lib/iomgr/pollset_windows.c", + "src/core/lib/iomgr/resolve_address_posix.c", + "src/core/lib/iomgr/resolve_address_windows.c", + "src/core/lib/iomgr/sockaddr_utils.c", + "src/core/lib/iomgr/socket_utils_common_posix.c", + "src/core/lib/iomgr/socket_utils_linux.c", + "src/core/lib/iomgr/socket_utils_posix.c", + "src/core/lib/iomgr/socket_windows.c", + "src/core/lib/iomgr/tcp_client_posix.c", + "src/core/lib/iomgr/tcp_client_windows.c", + "src/core/lib/iomgr/tcp_posix.c", + "src/core/lib/iomgr/tcp_server_posix.c", + "src/core/lib/iomgr/tcp_server_windows.c", + "src/core/lib/iomgr/tcp_windows.c", + "src/core/lib/iomgr/time_averaged_stats.c", + "src/core/lib/iomgr/timer.c", + "src/core/lib/iomgr/timer_heap.c", + "src/core/lib/iomgr/udp_server.c", + "src/core/lib/iomgr/unix_sockets_posix.c", + "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_eventfd.c", + "src/core/lib/iomgr/wakeup_fd_nospecial.c", + "src/core/lib/iomgr/wakeup_fd_pipe.c", + "src/core/lib/iomgr/wakeup_fd_posix.c", + "src/core/lib/iomgr/workqueue_posix.c", + "src/core/lib/iomgr/workqueue_windows.c", + "src/core/lib/json/json.c", + "src/core/lib/json/json_reader.c", + "src/core/lib/json/json_string.c", + "src/core/lib/json/json_writer.c", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c", + "src/core/lib/surface/alarm.c", + "src/core/lib/surface/api_trace.c", + "src/core/lib/surface/byte_buffer.c", + "src/core/lib/surface/byte_buffer_reader.c", + "src/core/lib/surface/call.c", + "src/core/lib/surface/call_details.c", + "src/core/lib/surface/call_log_batch.c", + "src/core/lib/surface/channel.c", + "src/core/lib/surface/channel_connectivity.c", + "src/core/lib/surface/channel_create.c", + "src/core/lib/surface/channel_init.c", + "src/core/lib/surface/channel_ping.c", + "src/core/lib/surface/channel_stack_type.c", + "src/core/lib/surface/completion_queue.c", + "src/core/lib/surface/event_string.c", + "src/core/lib/surface/init.c", + "src/core/lib/surface/lame_client.c", + "src/core/lib/surface/metadata_array.c", + "src/core/lib/surface/server.c", + "src/core/lib/surface/server_chttp2.c", + "src/core/lib/surface/validate_metadata.c", + "src/core/lib/surface/version.c", + "src/core/lib/transport/byte_stream.c", + "src/core/lib/transport/chttp2/alpn.c", + "src/core/lib/transport/chttp2/bin_encoder.c", + "src/core/lib/transport/chttp2/frame_data.c", + "src/core/lib/transport/chttp2/frame_goaway.c", + "src/core/lib/transport/chttp2/frame_ping.c", + "src/core/lib/transport/chttp2/frame_rst_stream.c", + "src/core/lib/transport/chttp2/frame_settings.c", + "src/core/lib/transport/chttp2/frame_window_update.c", + "src/core/lib/transport/chttp2/hpack_encoder.c", + "src/core/lib/transport/chttp2/hpack_parser.c", + "src/core/lib/transport/chttp2/hpack_table.c", + "src/core/lib/transport/chttp2/huffsyms.c", + "src/core/lib/transport/chttp2/incoming_metadata.c", + "src/core/lib/transport/chttp2/parsing.c", + "src/core/lib/transport/chttp2/status_conversion.c", + "src/core/lib/transport/chttp2/stream_lists.c", + "src/core/lib/transport/chttp2/stream_map.c", + "src/core/lib/transport/chttp2/timeout_encoding.c", + "src/core/lib/transport/chttp2/varint.c", + "src/core/lib/transport/chttp2/writing.c", + "src/core/lib/transport/chttp2_transport.c", + "src/core/lib/transport/connectivity_state.c", + "src/core/lib/transport/metadata.c", + "src/core/lib/transport/metadata_batch.c", + "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/transport.c", + "src/core/lib/transport/transport_op_string.c", + "src/core/lib/census/context.c", + "src/core/lib/census/initialize.c", + "src/core/lib/census/mlog.c", + "src/core/lib/census/operation.c", + "src/core/lib/census/placeholders.c", + "src/core/lib/census/tracing.c", "third_party/nanopb/pb_common.c", "third_party/nanopb/pb_decode.c", "third_party/nanopb/pb_encode.c", @@ -834,8 +834,8 @@ cc_library( cc_library( name = "grpc_zookeeper", srcs = [ - "src/core/client_config/resolvers/zookeeper_resolver.h", - "src/core/client_config/resolvers/zookeeper_resolver.c", + "src/core/lib/client_config/resolvers/zookeeper_resolver.h", + "src/core/lib/client_config/resolvers/zookeeper_resolver.c", ], hdrs = [ "include/grpc/grpc_zookeeper.h", @@ -1248,50 +1248,50 @@ cc_library( objc_library( name = "gpr_objc", srcs = [ - "src/core/profiling/basic_timers.c", - "src/core/profiling/stap_timers.c", - "src/core/support/alloc.c", - "src/core/support/avl.c", - "src/core/support/backoff.c", - "src/core/support/cmdline.c", - "src/core/support/cpu_iphone.c", - "src/core/support/cpu_linux.c", - "src/core/support/cpu_posix.c", - "src/core/support/cpu_windows.c", - "src/core/support/env_linux.c", - "src/core/support/env_posix.c", - "src/core/support/env_win32.c", - "src/core/support/histogram.c", - "src/core/support/host_port.c", - "src/core/support/load_file.c", - "src/core/support/log.c", - "src/core/support/log_android.c", - "src/core/support/log_linux.c", - "src/core/support/log_posix.c", - "src/core/support/log_win32.c", - "src/core/support/murmur_hash.c", - "src/core/support/slice.c", - "src/core/support/slice_buffer.c", - "src/core/support/stack_lockfree.c", - "src/core/support/string.c", - "src/core/support/string_posix.c", - "src/core/support/string_win32.c", - "src/core/support/subprocess_posix.c", - "src/core/support/subprocess_windows.c", - "src/core/support/sync.c", - "src/core/support/sync_posix.c", - "src/core/support/sync_win32.c", - "src/core/support/thd.c", - "src/core/support/thd_posix.c", - "src/core/support/thd_win32.c", - "src/core/support/time.c", - "src/core/support/time_posix.c", - "src/core/support/time_precise.c", - "src/core/support/time_win32.c", - "src/core/support/tls_pthread.c", - "src/core/support/tmpfile_posix.c", - "src/core/support/tmpfile_win32.c", - "src/core/support/wrap_memcpy.c", + "src/core/lib/profiling/basic_timers.c", + "src/core/lib/profiling/stap_timers.c", + "src/core/lib/support/alloc.c", + "src/core/lib/support/avl.c", + "src/core/lib/support/backoff.c", + "src/core/lib/support/cmdline.c", + "src/core/lib/support/cpu_iphone.c", + "src/core/lib/support/cpu_linux.c", + "src/core/lib/support/cpu_posix.c", + "src/core/lib/support/cpu_windows.c", + "src/core/lib/support/env_linux.c", + "src/core/lib/support/env_posix.c", + "src/core/lib/support/env_win32.c", + "src/core/lib/support/histogram.c", + "src/core/lib/support/host_port.c", + "src/core/lib/support/load_file.c", + "src/core/lib/support/log.c", + "src/core/lib/support/log_android.c", + "src/core/lib/support/log_linux.c", + "src/core/lib/support/log_posix.c", + "src/core/lib/support/log_win32.c", + "src/core/lib/support/murmur_hash.c", + "src/core/lib/support/slice.c", + "src/core/lib/support/slice_buffer.c", + "src/core/lib/support/stack_lockfree.c", + "src/core/lib/support/string.c", + "src/core/lib/support/string_posix.c", + "src/core/lib/support/string_win32.c", + "src/core/lib/support/subprocess_posix.c", + "src/core/lib/support/subprocess_windows.c", + "src/core/lib/support/sync.c", + "src/core/lib/support/sync_posix.c", + "src/core/lib/support/sync_win32.c", + "src/core/lib/support/thd.c", + "src/core/lib/support/thd_posix.c", + "src/core/lib/support/thd_win32.c", + "src/core/lib/support/time.c", + "src/core/lib/support/time_posix.c", + "src/core/lib/support/time_precise.c", + "src/core/lib/support/time_win32.c", + "src/core/lib/support/tls_pthread.c", + "src/core/lib/support/tmpfile_posix.c", + "src/core/lib/support/tmpfile_win32.c", + "src/core/lib/support/wrap_memcpy.c", ], hdrs = [ "include/grpc/support/alloc.h", @@ -1336,18 +1336,18 @@ objc_library( "include/grpc/impl/codegen/sync_posix.h", "include/grpc/impl/codegen/sync_win32.h", "include/grpc/impl/codegen/time.h", - "src/core/profiling/timers.h", - "src/core/support/backoff.h", - "src/core/support/block_annotate.h", - "src/core/support/env.h", - "src/core/support/load_file.h", - "src/core/support/murmur_hash.h", - "src/core/support/stack_lockfree.h", - "src/core/support/string.h", - "src/core/support/string_win32.h", - "src/core/support/thd_internal.h", - "src/core/support/time_precise.h", - "src/core/support/tmpfile.h", + "src/core/lib/profiling/timers.h", + "src/core/lib/support/backoff.h", + "src/core/lib/support/block_annotate.h", + "src/core/lib/support/env.h", + "src/core/lib/support/load_file.h", + "src/core/lib/support/murmur_hash.h", + "src/core/lib/support/stack_lockfree.h", + "src/core/lib/support/string.h", + "src/core/lib/support/string_win32.h", + "src/core/lib/support/thd_internal.h", + "src/core/lib/support/time_precise.h", + "src/core/lib/support/tmpfile.h", ], includes = [ "include", @@ -1361,167 +1361,167 @@ objc_library( objc_library( name = "grpc_objc", srcs = [ - "src/core/census/grpc_context.c", - "src/core/census/grpc_filter.c", - "src/core/census/grpc_plugin.c", - "src/core/channel/channel_args.c", - "src/core/channel/channel_stack.c", - "src/core/channel/channel_stack_builder.c", - "src/core/channel/client_channel.c", - "src/core/channel/compress_filter.c", - "src/core/channel/connected_channel.c", - "src/core/channel/http_client_filter.c", - "src/core/channel/http_server_filter.c", - "src/core/channel/subchannel_call_holder.c", - "src/core/client_config/client_config.c", - "src/core/client_config/connector.c", - "src/core/client_config/default_initial_connect_string.c", - "src/core/client_config/initial_connect_string.c", - "src/core/client_config/lb_policies/load_balancer_api.c", - "src/core/client_config/lb_policies/pick_first.c", - "src/core/client_config/lb_policies/round_robin.c", - "src/core/client_config/lb_policy.c", - "src/core/client_config/lb_policy_factory.c", - "src/core/client_config/lb_policy_registry.c", - "src/core/client_config/resolver.c", - "src/core/client_config/resolver_factory.c", - "src/core/client_config/resolver_registry.c", - "src/core/client_config/resolvers/dns_resolver.c", - "src/core/client_config/resolvers/sockaddr_resolver.c", - "src/core/client_config/subchannel.c", - "src/core/client_config/subchannel_factory.c", - "src/core/client_config/subchannel_index.c", - "src/core/client_config/uri_parser.c", - "src/core/compression/compression_algorithm.c", - "src/core/compression/message_compress.c", - "src/core/debug/trace.c", - "src/core/http/format_request.c", - "src/core/http/httpcli.c", - "src/core/http/parser.c", - "src/core/iomgr/closure.c", - "src/core/iomgr/endpoint.c", - "src/core/iomgr/endpoint_pair_posix.c", - "src/core/iomgr/endpoint_pair_windows.c", - "src/core/iomgr/exec_ctx.c", - "src/core/iomgr/executor.c", - "src/core/iomgr/fd_posix.c", - "src/core/iomgr/iocp_windows.c", - "src/core/iomgr/iomgr.c", - "src/core/iomgr/iomgr_posix.c", - "src/core/iomgr/iomgr_windows.c", - "src/core/iomgr/pollset_multipoller_with_epoll.c", - "src/core/iomgr/pollset_multipoller_with_poll_posix.c", - "src/core/iomgr/pollset_posix.c", - "src/core/iomgr/pollset_set_posix.c", - "src/core/iomgr/pollset_set_windows.c", - "src/core/iomgr/pollset_windows.c", - "src/core/iomgr/resolve_address_posix.c", - "src/core/iomgr/resolve_address_windows.c", - "src/core/iomgr/sockaddr_utils.c", - "src/core/iomgr/socket_utils_common_posix.c", - "src/core/iomgr/socket_utils_linux.c", - "src/core/iomgr/socket_utils_posix.c", - "src/core/iomgr/socket_windows.c", - "src/core/iomgr/tcp_client_posix.c", - "src/core/iomgr/tcp_client_windows.c", - "src/core/iomgr/tcp_posix.c", - "src/core/iomgr/tcp_server_posix.c", - "src/core/iomgr/tcp_server_windows.c", - "src/core/iomgr/tcp_windows.c", - "src/core/iomgr/time_averaged_stats.c", - "src/core/iomgr/timer.c", - "src/core/iomgr/timer_heap.c", - "src/core/iomgr/udp_server.c", - "src/core/iomgr/unix_sockets_posix.c", - "src/core/iomgr/unix_sockets_posix_noop.c", - "src/core/iomgr/wakeup_fd_eventfd.c", - "src/core/iomgr/wakeup_fd_nospecial.c", - "src/core/iomgr/wakeup_fd_pipe.c", - "src/core/iomgr/wakeup_fd_posix.c", - "src/core/iomgr/workqueue_posix.c", - "src/core/iomgr/workqueue_windows.c", - "src/core/json/json.c", - "src/core/json/json_reader.c", - "src/core/json/json_string.c", - "src/core/json/json_writer.c", - "src/core/proto/grpc/lb/v0/load_balancer.pb.c", - "src/core/surface/alarm.c", - "src/core/surface/api_trace.c", - "src/core/surface/byte_buffer.c", - "src/core/surface/byte_buffer_reader.c", - "src/core/surface/call.c", - "src/core/surface/call_details.c", - "src/core/surface/call_log_batch.c", - "src/core/surface/channel.c", - "src/core/surface/channel_connectivity.c", - "src/core/surface/channel_create.c", - "src/core/surface/channel_init.c", - "src/core/surface/channel_ping.c", - "src/core/surface/channel_stack_type.c", - "src/core/surface/completion_queue.c", - "src/core/surface/event_string.c", - "src/core/surface/init.c", - "src/core/surface/lame_client.c", - "src/core/surface/metadata_array.c", - "src/core/surface/server.c", - "src/core/surface/server_chttp2.c", - "src/core/surface/validate_metadata.c", - "src/core/surface/version.c", - "src/core/transport/byte_stream.c", - "src/core/transport/chttp2/alpn.c", - "src/core/transport/chttp2/bin_encoder.c", - "src/core/transport/chttp2/frame_data.c", - "src/core/transport/chttp2/frame_goaway.c", - "src/core/transport/chttp2/frame_ping.c", - "src/core/transport/chttp2/frame_rst_stream.c", - "src/core/transport/chttp2/frame_settings.c", - "src/core/transport/chttp2/frame_window_update.c", - "src/core/transport/chttp2/hpack_encoder.c", - "src/core/transport/chttp2/hpack_parser.c", - "src/core/transport/chttp2/hpack_table.c", - "src/core/transport/chttp2/huffsyms.c", - "src/core/transport/chttp2/incoming_metadata.c", - "src/core/transport/chttp2/parsing.c", - "src/core/transport/chttp2/status_conversion.c", - "src/core/transport/chttp2/stream_lists.c", - "src/core/transport/chttp2/stream_map.c", - "src/core/transport/chttp2/timeout_encoding.c", - "src/core/transport/chttp2/varint.c", - "src/core/transport/chttp2/writing.c", - "src/core/transport/chttp2_transport.c", - "src/core/transport/connectivity_state.c", - "src/core/transport/metadata.c", - "src/core/transport/metadata_batch.c", - "src/core/transport/static_metadata.c", - "src/core/transport/transport.c", - "src/core/transport/transport_op_string.c", - "src/core/http/httpcli_security_connector.c", - "src/core/security/b64.c", - "src/core/security/client_auth_filter.c", - "src/core/security/credentials.c", - "src/core/security/credentials_metadata.c", - "src/core/security/credentials_posix.c", - "src/core/security/credentials_win32.c", - "src/core/security/google_default_credentials.c", - "src/core/security/handshake.c", - "src/core/security/json_token.c", - "src/core/security/jwt_verifier.c", - "src/core/security/secure_endpoint.c", - "src/core/security/security_connector.c", - "src/core/security/security_context.c", - "src/core/security/server_auth_filter.c", - "src/core/security/server_secure_chttp2.c", - "src/core/surface/init_secure.c", - "src/core/surface/secure_channel_create.c", - "src/core/tsi/fake_transport_security.c", - "src/core/tsi/ssl_transport_security.c", - "src/core/tsi/transport_security.c", - "src/core/census/context.c", - "src/core/census/initialize.c", - "src/core/census/mlog.c", - "src/core/census/operation.c", - "src/core/census/placeholders.c", - "src/core/census/tracing.c", + "src/core/lib/census/grpc_context.c", + "src/core/lib/census/grpc_filter.c", + "src/core/lib/census/grpc_plugin.c", + "src/core/lib/channel/channel_args.c", + "src/core/lib/channel/channel_stack.c", + "src/core/lib/channel/channel_stack_builder.c", + "src/core/lib/channel/client_channel.c", + "src/core/lib/channel/compress_filter.c", + "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/http_client_filter.c", + "src/core/lib/channel/http_server_filter.c", + "src/core/lib/channel/subchannel_call_holder.c", + "src/core/lib/client_config/client_config.c", + "src/core/lib/client_config/connector.c", + "src/core/lib/client_config/default_initial_connect_string.c", + "src/core/lib/client_config/initial_connect_string.c", + "src/core/lib/client_config/lb_policies/load_balancer_api.c", + "src/core/lib/client_config/lb_policies/pick_first.c", + "src/core/lib/client_config/lb_policies/round_robin.c", + "src/core/lib/client_config/lb_policy.c", + "src/core/lib/client_config/lb_policy_factory.c", + "src/core/lib/client_config/lb_policy_registry.c", + "src/core/lib/client_config/resolver.c", + "src/core/lib/client_config/resolver_factory.c", + "src/core/lib/client_config/resolver_registry.c", + "src/core/lib/client_config/resolvers/dns_resolver.c", + "src/core/lib/client_config/resolvers/sockaddr_resolver.c", + "src/core/lib/client_config/subchannel.c", + "src/core/lib/client_config/subchannel_factory.c", + "src/core/lib/client_config/subchannel_index.c", + "src/core/lib/client_config/uri_parser.c", + "src/core/lib/compression/compression_algorithm.c", + "src/core/lib/compression/message_compress.c", + "src/core/lib/debug/trace.c", + "src/core/lib/http/format_request.c", + "src/core/lib/http/httpcli.c", + "src/core/lib/http/parser.c", + "src/core/lib/iomgr/closure.c", + "src/core/lib/iomgr/endpoint.c", + "src/core/lib/iomgr/endpoint_pair_posix.c", + "src/core/lib/iomgr/endpoint_pair_windows.c", + "src/core/lib/iomgr/exec_ctx.c", + "src/core/lib/iomgr/executor.c", + "src/core/lib/iomgr/fd_posix.c", + "src/core/lib/iomgr/iocp_windows.c", + "src/core/lib/iomgr/iomgr.c", + "src/core/lib/iomgr/iomgr_posix.c", + "src/core/lib/iomgr/iomgr_windows.c", + "src/core/lib/iomgr/pollset_multipoller_with_epoll.c", + "src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c", + "src/core/lib/iomgr/pollset_posix.c", + "src/core/lib/iomgr/pollset_set_posix.c", + "src/core/lib/iomgr/pollset_set_windows.c", + "src/core/lib/iomgr/pollset_windows.c", + "src/core/lib/iomgr/resolve_address_posix.c", + "src/core/lib/iomgr/resolve_address_windows.c", + "src/core/lib/iomgr/sockaddr_utils.c", + "src/core/lib/iomgr/socket_utils_common_posix.c", + "src/core/lib/iomgr/socket_utils_linux.c", + "src/core/lib/iomgr/socket_utils_posix.c", + "src/core/lib/iomgr/socket_windows.c", + "src/core/lib/iomgr/tcp_client_posix.c", + "src/core/lib/iomgr/tcp_client_windows.c", + "src/core/lib/iomgr/tcp_posix.c", + "src/core/lib/iomgr/tcp_server_posix.c", + "src/core/lib/iomgr/tcp_server_windows.c", + "src/core/lib/iomgr/tcp_windows.c", + "src/core/lib/iomgr/time_averaged_stats.c", + "src/core/lib/iomgr/timer.c", + "src/core/lib/iomgr/timer_heap.c", + "src/core/lib/iomgr/udp_server.c", + "src/core/lib/iomgr/unix_sockets_posix.c", + "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_eventfd.c", + "src/core/lib/iomgr/wakeup_fd_nospecial.c", + "src/core/lib/iomgr/wakeup_fd_pipe.c", + "src/core/lib/iomgr/wakeup_fd_posix.c", + "src/core/lib/iomgr/workqueue_posix.c", + "src/core/lib/iomgr/workqueue_windows.c", + "src/core/lib/json/json.c", + "src/core/lib/json/json_reader.c", + "src/core/lib/json/json_string.c", + "src/core/lib/json/json_writer.c", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c", + "src/core/lib/surface/alarm.c", + "src/core/lib/surface/api_trace.c", + "src/core/lib/surface/byte_buffer.c", + "src/core/lib/surface/byte_buffer_reader.c", + "src/core/lib/surface/call.c", + "src/core/lib/surface/call_details.c", + "src/core/lib/surface/call_log_batch.c", + "src/core/lib/surface/channel.c", + "src/core/lib/surface/channel_connectivity.c", + "src/core/lib/surface/channel_create.c", + "src/core/lib/surface/channel_init.c", + "src/core/lib/surface/channel_ping.c", + "src/core/lib/surface/channel_stack_type.c", + "src/core/lib/surface/completion_queue.c", + "src/core/lib/surface/event_string.c", + "src/core/lib/surface/init.c", + "src/core/lib/surface/lame_client.c", + "src/core/lib/surface/metadata_array.c", + "src/core/lib/surface/server.c", + "src/core/lib/surface/server_chttp2.c", + "src/core/lib/surface/validate_metadata.c", + "src/core/lib/surface/version.c", + "src/core/lib/transport/byte_stream.c", + "src/core/lib/transport/chttp2/alpn.c", + "src/core/lib/transport/chttp2/bin_encoder.c", + "src/core/lib/transport/chttp2/frame_data.c", + "src/core/lib/transport/chttp2/frame_goaway.c", + "src/core/lib/transport/chttp2/frame_ping.c", + "src/core/lib/transport/chttp2/frame_rst_stream.c", + "src/core/lib/transport/chttp2/frame_settings.c", + "src/core/lib/transport/chttp2/frame_window_update.c", + "src/core/lib/transport/chttp2/hpack_encoder.c", + "src/core/lib/transport/chttp2/hpack_parser.c", + "src/core/lib/transport/chttp2/hpack_table.c", + "src/core/lib/transport/chttp2/huffsyms.c", + "src/core/lib/transport/chttp2/incoming_metadata.c", + "src/core/lib/transport/chttp2/parsing.c", + "src/core/lib/transport/chttp2/status_conversion.c", + "src/core/lib/transport/chttp2/stream_lists.c", + "src/core/lib/transport/chttp2/stream_map.c", + "src/core/lib/transport/chttp2/timeout_encoding.c", + "src/core/lib/transport/chttp2/varint.c", + "src/core/lib/transport/chttp2/writing.c", + "src/core/lib/transport/chttp2_transport.c", + "src/core/lib/transport/connectivity_state.c", + "src/core/lib/transport/metadata.c", + "src/core/lib/transport/metadata_batch.c", + "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/transport.c", + "src/core/lib/transport/transport_op_string.c", + "src/core/lib/http/httpcli_security_connector.c", + "src/core/lib/security/b64.c", + "src/core/lib/security/client_auth_filter.c", + "src/core/lib/security/credentials.c", + "src/core/lib/security/credentials_metadata.c", + "src/core/lib/security/credentials_posix.c", + "src/core/lib/security/credentials_win32.c", + "src/core/lib/security/google_default_credentials.c", + "src/core/lib/security/handshake.c", + "src/core/lib/security/json_token.c", + "src/core/lib/security/jwt_verifier.c", + "src/core/lib/security/secure_endpoint.c", + "src/core/lib/security/security_connector.c", + "src/core/lib/security/security_context.c", + "src/core/lib/security/server_auth_filter.c", + "src/core/lib/security/server_secure_chttp2.c", + "src/core/lib/surface/init_secure.c", + "src/core/lib/surface/secure_channel_create.c", + "src/core/lib/tsi/fake_transport_security.c", + "src/core/lib/tsi/ssl_transport_security.c", + "src/core/lib/tsi/transport_security.c", + "src/core/lib/census/context.c", + "src/core/lib/census/initialize.c", + "src/core/lib/census/mlog.c", + "src/core/lib/census/operation.c", + "src/core/lib/census/placeholders.c", + "src/core/lib/census/tracing.c", "third_party/nanopb/pb_common.c", "third_party/nanopb/pb_decode.c", "third_party/nanopb/pb_encode.c", @@ -1540,143 +1540,143 @@ objc_library( "include/grpc/impl/codegen/propagation_bits.h", "include/grpc/impl/codegen/status.h", "include/grpc/census.h", - "src/core/census/grpc_filter.h", - "src/core/census/grpc_plugin.h", - "src/core/channel/channel_args.h", - "src/core/channel/channel_stack.h", - "src/core/channel/channel_stack_builder.h", - "src/core/channel/client_channel.h", - "src/core/channel/compress_filter.h", - "src/core/channel/connected_channel.h", - "src/core/channel/context.h", - "src/core/channel/http_client_filter.h", - "src/core/channel/http_server_filter.h", - "src/core/channel/subchannel_call_holder.h", - "src/core/client_config/client_config.h", - "src/core/client_config/connector.h", - "src/core/client_config/initial_connect_string.h", - "src/core/client_config/lb_policies/load_balancer_api.h", - "src/core/client_config/lb_policies/pick_first.h", - "src/core/client_config/lb_policies/round_robin.h", - "src/core/client_config/lb_policy.h", - "src/core/client_config/lb_policy_factory.h", - "src/core/client_config/lb_policy_registry.h", - "src/core/client_config/resolver.h", - "src/core/client_config/resolver_factory.h", - "src/core/client_config/resolver_registry.h", - "src/core/client_config/resolvers/dns_resolver.h", - "src/core/client_config/resolvers/sockaddr_resolver.h", - "src/core/client_config/subchannel.h", - "src/core/client_config/subchannel_factory.h", - "src/core/client_config/subchannel_index.h", - "src/core/client_config/uri_parser.h", - "src/core/compression/algorithm_metadata.h", - "src/core/compression/message_compress.h", - "src/core/debug/trace.h", - "src/core/http/format_request.h", - "src/core/http/httpcli.h", - "src/core/http/parser.h", - "src/core/iomgr/closure.h", - "src/core/iomgr/endpoint.h", - "src/core/iomgr/endpoint_pair.h", - "src/core/iomgr/exec_ctx.h", - "src/core/iomgr/executor.h", - "src/core/iomgr/fd_posix.h", - "src/core/iomgr/iocp_windows.h", - "src/core/iomgr/iomgr.h", - "src/core/iomgr/iomgr_internal.h", - "src/core/iomgr/iomgr_posix.h", - "src/core/iomgr/pollset.h", - "src/core/iomgr/pollset_posix.h", - "src/core/iomgr/pollset_set.h", - "src/core/iomgr/pollset_set_posix.h", - "src/core/iomgr/pollset_set_windows.h", - "src/core/iomgr/pollset_windows.h", - "src/core/iomgr/resolve_address.h", - "src/core/iomgr/sockaddr.h", - "src/core/iomgr/sockaddr_posix.h", - "src/core/iomgr/sockaddr_utils.h", - "src/core/iomgr/sockaddr_win32.h", - "src/core/iomgr/socket_utils_posix.h", - "src/core/iomgr/socket_windows.h", - "src/core/iomgr/tcp_client.h", - "src/core/iomgr/tcp_posix.h", - "src/core/iomgr/tcp_server.h", - "src/core/iomgr/tcp_windows.h", - "src/core/iomgr/time_averaged_stats.h", - "src/core/iomgr/timer.h", - "src/core/iomgr/timer_heap.h", - "src/core/iomgr/udp_server.h", - "src/core/iomgr/unix_sockets_posix.h", - "src/core/iomgr/wakeup_fd_pipe.h", - "src/core/iomgr/wakeup_fd_posix.h", - "src/core/iomgr/workqueue.h", - "src/core/iomgr/workqueue_posix.h", - "src/core/iomgr/workqueue_windows.h", - "src/core/json/json.h", - "src/core/json/json_common.h", - "src/core/json/json_reader.h", - "src/core/json/json_writer.h", - "src/core/proto/grpc/lb/v0/load_balancer.pb.h", - "src/core/statistics/census_interface.h", - "src/core/statistics/census_rpc_stats.h", - "src/core/surface/api_trace.h", - "src/core/surface/call.h", - "src/core/surface/call_test_only.h", - "src/core/surface/channel.h", - "src/core/surface/channel_init.h", - "src/core/surface/channel_stack_type.h", - "src/core/surface/completion_queue.h", - "src/core/surface/event_string.h", - "src/core/surface/init.h", - "src/core/surface/lame_client.h", - "src/core/surface/server.h", - "src/core/surface/surface_trace.h", - "src/core/transport/byte_stream.h", - "src/core/transport/chttp2/alpn.h", - "src/core/transport/chttp2/bin_encoder.h", - "src/core/transport/chttp2/frame.h", - "src/core/transport/chttp2/frame_data.h", - "src/core/transport/chttp2/frame_goaway.h", - "src/core/transport/chttp2/frame_ping.h", - "src/core/transport/chttp2/frame_rst_stream.h", - "src/core/transport/chttp2/frame_settings.h", - "src/core/transport/chttp2/frame_window_update.h", - "src/core/transport/chttp2/hpack_encoder.h", - "src/core/transport/chttp2/hpack_parser.h", - "src/core/transport/chttp2/hpack_table.h", - "src/core/transport/chttp2/http2_errors.h", - "src/core/transport/chttp2/huffsyms.h", - "src/core/transport/chttp2/incoming_metadata.h", - "src/core/transport/chttp2/internal.h", - "src/core/transport/chttp2/status_conversion.h", - "src/core/transport/chttp2/stream_map.h", - "src/core/transport/chttp2/timeout_encoding.h", - "src/core/transport/chttp2/varint.h", - "src/core/transport/chttp2_transport.h", - "src/core/transport/connectivity_state.h", - "src/core/transport/metadata.h", - "src/core/transport/metadata_batch.h", - "src/core/transport/static_metadata.h", - "src/core/transport/transport.h", - "src/core/transport/transport_impl.h", - "src/core/security/auth_filters.h", - "src/core/security/b64.h", - "src/core/security/credentials.h", - "src/core/security/handshake.h", - "src/core/security/json_token.h", - "src/core/security/jwt_verifier.h", - "src/core/security/secure_endpoint.h", - "src/core/security/security_connector.h", - "src/core/security/security_context.h", - "src/core/tsi/fake_transport_security.h", - "src/core/tsi/ssl_transport_security.h", - "src/core/tsi/ssl_types.h", - "src/core/tsi/transport_security.h", - "src/core/tsi/transport_security_interface.h", - "src/core/census/aggregation.h", - "src/core/census/mlog.h", - "src/core/census/rpc_metric_id.h", + "src/core/lib/census/grpc_filter.h", + "src/core/lib/census/grpc_plugin.h", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/client_channel.h", + "src/core/lib/channel/compress_filter.h", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/http_client_filter.h", + "src/core/lib/channel/http_server_filter.h", + "src/core/lib/channel/subchannel_call_holder.h", + "src/core/lib/client_config/client_config.h", + "src/core/lib/client_config/connector.h", + "src/core/lib/client_config/initial_connect_string.h", + "src/core/lib/client_config/lb_policies/load_balancer_api.h", + "src/core/lib/client_config/lb_policies/pick_first.h", + "src/core/lib/client_config/lb_policies/round_robin.h", + "src/core/lib/client_config/lb_policy.h", + "src/core/lib/client_config/lb_policy_factory.h", + "src/core/lib/client_config/lb_policy_registry.h", + "src/core/lib/client_config/resolver.h", + "src/core/lib/client_config/resolver_factory.h", + "src/core/lib/client_config/resolver_registry.h", + "src/core/lib/client_config/resolvers/dns_resolver.h", + "src/core/lib/client_config/resolvers/sockaddr_resolver.h", + "src/core/lib/client_config/subchannel.h", + "src/core/lib/client_config/subchannel_factory.h", + "src/core/lib/client_config/subchannel_index.h", + "src/core/lib/client_config/uri_parser.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/message_compress.h", + "src/core/lib/debug/trace.h", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/fd_posix.h", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_posix.h", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_posix.h", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_win32.h", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/iomgr/workqueue.h", + "src/core/lib/iomgr/workqueue_posix.h", + "src/core/lib/iomgr/workqueue_windows.h", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_writer.h", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h", + "src/core/lib/statistics/census_interface.h", + "src/core/lib/statistics/census_rpc_stats.h", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.h", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/server.h", + "src/core/lib/surface/surface_trace.h", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/chttp2/alpn.h", + "src/core/lib/transport/chttp2/bin_encoder.h", + "src/core/lib/transport/chttp2/frame.h", + "src/core/lib/transport/chttp2/frame_data.h", + "src/core/lib/transport/chttp2/frame_goaway.h", + "src/core/lib/transport/chttp2/frame_ping.h", + "src/core/lib/transport/chttp2/frame_rst_stream.h", + "src/core/lib/transport/chttp2/frame_settings.h", + "src/core/lib/transport/chttp2/frame_window_update.h", + "src/core/lib/transport/chttp2/hpack_encoder.h", + "src/core/lib/transport/chttp2/hpack_parser.h", + "src/core/lib/transport/chttp2/hpack_table.h", + "src/core/lib/transport/chttp2/http2_errors.h", + "src/core/lib/transport/chttp2/huffsyms.h", + "src/core/lib/transport/chttp2/incoming_metadata.h", + "src/core/lib/transport/chttp2/internal.h", + "src/core/lib/transport/chttp2/status_conversion.h", + "src/core/lib/transport/chttp2/stream_map.h", + "src/core/lib/transport/chttp2/timeout_encoding.h", + "src/core/lib/transport/chttp2/varint.h", + "src/core/lib/transport/chttp2_transport.h", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", + "src/core/lib/security/auth_filters.h", + "src/core/lib/security/b64.h", + "src/core/lib/security/credentials.h", + "src/core/lib/security/handshake.h", + "src/core/lib/security/json_token.h", + "src/core/lib/security/jwt_verifier.h", + "src/core/lib/security/secure_endpoint.h", + "src/core/lib/security/security_connector.h", + "src/core/lib/security/security_context.h", + "src/core/lib/tsi/fake_transport_security.h", + "src/core/lib/tsi/ssl_transport_security.h", + "src/core/lib/tsi/ssl_types.h", + "src/core/lib/tsi/transport_security.h", + "src/core/lib/tsi/transport_security_interface.h", + "src/core/lib/census/aggregation.h", + "src/core/lib/census/mlog.h", + "src/core/lib/census/rpc_metric_id.h", "third_party/nanopb/pb.h", "third_party/nanopb/pb_common.h", "third_party/nanopb/pb_decode.h", diff --git a/Makefile b/Makefile index 6c100f6cbd..112b7f8777 100644 --- a/Makefile +++ b/Makefile @@ -2268,50 +2268,50 @@ clean: LIBGPR_SRC = \ - src/core/profiling/basic_timers.c \ - src/core/profiling/stap_timers.c \ - src/core/support/alloc.c \ - src/core/support/avl.c \ - src/core/support/backoff.c \ - src/core/support/cmdline.c \ - src/core/support/cpu_iphone.c \ - src/core/support/cpu_linux.c \ - src/core/support/cpu_posix.c \ - src/core/support/cpu_windows.c \ - src/core/support/env_linux.c \ - src/core/support/env_posix.c \ - src/core/support/env_win32.c \ - src/core/support/histogram.c \ - src/core/support/host_port.c \ - src/core/support/load_file.c \ - src/core/support/log.c \ - src/core/support/log_android.c \ - src/core/support/log_linux.c \ - src/core/support/log_posix.c \ - src/core/support/log_win32.c \ - src/core/support/murmur_hash.c \ - src/core/support/slice.c \ - src/core/support/slice_buffer.c \ - src/core/support/stack_lockfree.c \ - src/core/support/string.c \ - src/core/support/string_posix.c \ - src/core/support/string_win32.c \ - src/core/support/subprocess_posix.c \ - src/core/support/subprocess_windows.c \ - src/core/support/sync.c \ - src/core/support/sync_posix.c \ - src/core/support/sync_win32.c \ - src/core/support/thd.c \ - src/core/support/thd_posix.c \ - src/core/support/thd_win32.c \ - src/core/support/time.c \ - src/core/support/time_posix.c \ - src/core/support/time_precise.c \ - src/core/support/time_win32.c \ - src/core/support/tls_pthread.c \ - src/core/support/tmpfile_posix.c \ - src/core/support/tmpfile_win32.c \ - src/core/support/wrap_memcpy.c \ + src/core/lib/profiling/basic_timers.c \ + src/core/lib/profiling/stap_timers.c \ + src/core/lib/support/alloc.c \ + src/core/lib/support/avl.c \ + src/core/lib/support/backoff.c \ + src/core/lib/support/cmdline.c \ + src/core/lib/support/cpu_iphone.c \ + src/core/lib/support/cpu_linux.c \ + src/core/lib/support/cpu_posix.c \ + src/core/lib/support/cpu_windows.c \ + src/core/lib/support/env_linux.c \ + src/core/lib/support/env_posix.c \ + src/core/lib/support/env_win32.c \ + src/core/lib/support/histogram.c \ + src/core/lib/support/host_port.c \ + src/core/lib/support/load_file.c \ + src/core/lib/support/log.c \ + src/core/lib/support/log_android.c \ + src/core/lib/support/log_linux.c \ + src/core/lib/support/log_posix.c \ + src/core/lib/support/log_win32.c \ + src/core/lib/support/murmur_hash.c \ + src/core/lib/support/slice.c \ + src/core/lib/support/slice_buffer.c \ + src/core/lib/support/stack_lockfree.c \ + src/core/lib/support/string.c \ + src/core/lib/support/string_posix.c \ + src/core/lib/support/string_win32.c \ + src/core/lib/support/subprocess_posix.c \ + src/core/lib/support/subprocess_windows.c \ + src/core/lib/support/sync.c \ + src/core/lib/support/sync_posix.c \ + src/core/lib/support/sync_win32.c \ + src/core/lib/support/thd.c \ + src/core/lib/support/thd_posix.c \ + src/core/lib/support/thd_win32.c \ + src/core/lib/support/time.c \ + src/core/lib/support/time_posix.c \ + src/core/lib/support/time_precise.c \ + src/core/lib/support/time_win32.c \ + src/core/lib/support/tls_pthread.c \ + src/core/lib/support/tmpfile_posix.c \ + src/core/lib/support/tmpfile_win32.c \ + src/core/lib/support/wrap_memcpy.c \ PUBLIC_HEADERS_C += \ include/grpc/support/alloc.h \ @@ -2419,167 +2419,167 @@ endif LIBGRPC_SRC = \ - src/core/census/grpc_context.c \ - src/core/census/grpc_filter.c \ - src/core/census/grpc_plugin.c \ - src/core/channel/channel_args.c \ - src/core/channel/channel_stack.c \ - src/core/channel/channel_stack_builder.c \ - src/core/channel/client_channel.c \ - src/core/channel/compress_filter.c \ - src/core/channel/connected_channel.c \ - src/core/channel/http_client_filter.c \ - src/core/channel/http_server_filter.c \ - src/core/channel/subchannel_call_holder.c \ - src/core/client_config/client_config.c \ - src/core/client_config/connector.c \ - src/core/client_config/default_initial_connect_string.c \ - src/core/client_config/initial_connect_string.c \ - src/core/client_config/lb_policies/load_balancer_api.c \ - src/core/client_config/lb_policies/pick_first.c \ - src/core/client_config/lb_policies/round_robin.c \ - src/core/client_config/lb_policy.c \ - src/core/client_config/lb_policy_factory.c \ - src/core/client_config/lb_policy_registry.c \ - src/core/client_config/resolver.c \ - src/core/client_config/resolver_factory.c \ - src/core/client_config/resolver_registry.c \ - src/core/client_config/resolvers/dns_resolver.c \ - src/core/client_config/resolvers/sockaddr_resolver.c \ - src/core/client_config/subchannel.c \ - src/core/client_config/subchannel_factory.c \ - src/core/client_config/subchannel_index.c \ - src/core/client_config/uri_parser.c \ - src/core/compression/compression_algorithm.c \ - src/core/compression/message_compress.c \ - src/core/debug/trace.c \ - src/core/http/format_request.c \ - src/core/http/httpcli.c \ - src/core/http/parser.c \ - src/core/iomgr/closure.c \ - src/core/iomgr/endpoint.c \ - src/core/iomgr/endpoint_pair_posix.c \ - src/core/iomgr/endpoint_pair_windows.c \ - src/core/iomgr/exec_ctx.c \ - src/core/iomgr/executor.c \ - src/core/iomgr/fd_posix.c \ - src/core/iomgr/iocp_windows.c \ - src/core/iomgr/iomgr.c \ - src/core/iomgr/iomgr_posix.c \ - src/core/iomgr/iomgr_windows.c \ - src/core/iomgr/pollset_multipoller_with_epoll.c \ - src/core/iomgr/pollset_multipoller_with_poll_posix.c \ - src/core/iomgr/pollset_posix.c \ - src/core/iomgr/pollset_set_posix.c \ - src/core/iomgr/pollset_set_windows.c \ - src/core/iomgr/pollset_windows.c \ - src/core/iomgr/resolve_address_posix.c \ - src/core/iomgr/resolve_address_windows.c \ - src/core/iomgr/sockaddr_utils.c \ - src/core/iomgr/socket_utils_common_posix.c \ - src/core/iomgr/socket_utils_linux.c \ - src/core/iomgr/socket_utils_posix.c \ - src/core/iomgr/socket_windows.c \ - src/core/iomgr/tcp_client_posix.c \ - src/core/iomgr/tcp_client_windows.c \ - src/core/iomgr/tcp_posix.c \ - src/core/iomgr/tcp_server_posix.c \ - src/core/iomgr/tcp_server_windows.c \ - src/core/iomgr/tcp_windows.c \ - src/core/iomgr/time_averaged_stats.c \ - src/core/iomgr/timer.c \ - src/core/iomgr/timer_heap.c \ - src/core/iomgr/udp_server.c \ - src/core/iomgr/unix_sockets_posix.c \ - src/core/iomgr/unix_sockets_posix_noop.c \ - src/core/iomgr/wakeup_fd_eventfd.c \ - src/core/iomgr/wakeup_fd_nospecial.c \ - src/core/iomgr/wakeup_fd_pipe.c \ - src/core/iomgr/wakeup_fd_posix.c \ - src/core/iomgr/workqueue_posix.c \ - src/core/iomgr/workqueue_windows.c \ - src/core/json/json.c \ - src/core/json/json_reader.c \ - src/core/json/json_string.c \ - src/core/json/json_writer.c \ - src/core/proto/grpc/lb/v0/load_balancer.pb.c \ - src/core/surface/alarm.c \ - src/core/surface/api_trace.c \ - src/core/surface/byte_buffer.c \ - src/core/surface/byte_buffer_reader.c \ - src/core/surface/call.c \ - src/core/surface/call_details.c \ - src/core/surface/call_log_batch.c \ - src/core/surface/channel.c \ - src/core/surface/channel_connectivity.c \ - src/core/surface/channel_create.c \ - src/core/surface/channel_init.c \ - src/core/surface/channel_ping.c \ - src/core/surface/channel_stack_type.c \ - src/core/surface/completion_queue.c \ - src/core/surface/event_string.c \ - src/core/surface/init.c \ - src/core/surface/lame_client.c \ - src/core/surface/metadata_array.c \ - src/core/surface/server.c \ - src/core/surface/server_chttp2.c \ - src/core/surface/validate_metadata.c \ - src/core/surface/version.c \ - src/core/transport/byte_stream.c \ - src/core/transport/chttp2/alpn.c \ - src/core/transport/chttp2/bin_encoder.c \ - src/core/transport/chttp2/frame_data.c \ - src/core/transport/chttp2/frame_goaway.c \ - src/core/transport/chttp2/frame_ping.c \ - src/core/transport/chttp2/frame_rst_stream.c \ - src/core/transport/chttp2/frame_settings.c \ - src/core/transport/chttp2/frame_window_update.c \ - src/core/transport/chttp2/hpack_encoder.c \ - src/core/transport/chttp2/hpack_parser.c \ - src/core/transport/chttp2/hpack_table.c \ - src/core/transport/chttp2/huffsyms.c \ - src/core/transport/chttp2/incoming_metadata.c \ - src/core/transport/chttp2/parsing.c \ - src/core/transport/chttp2/status_conversion.c \ - src/core/transport/chttp2/stream_lists.c \ - src/core/transport/chttp2/stream_map.c \ - src/core/transport/chttp2/timeout_encoding.c \ - src/core/transport/chttp2/varint.c \ - src/core/transport/chttp2/writing.c \ - src/core/transport/chttp2_transport.c \ - src/core/transport/connectivity_state.c \ - src/core/transport/metadata.c \ - src/core/transport/metadata_batch.c \ - src/core/transport/static_metadata.c \ - src/core/transport/transport.c \ - src/core/transport/transport_op_string.c \ - src/core/http/httpcli_security_connector.c \ - src/core/security/b64.c \ - src/core/security/client_auth_filter.c \ - src/core/security/credentials.c \ - src/core/security/credentials_metadata.c \ - src/core/security/credentials_posix.c \ - src/core/security/credentials_win32.c \ - src/core/security/google_default_credentials.c \ - src/core/security/handshake.c \ - src/core/security/json_token.c \ - src/core/security/jwt_verifier.c \ - src/core/security/secure_endpoint.c \ - src/core/security/security_connector.c \ - src/core/security/security_context.c \ - src/core/security/server_auth_filter.c \ - src/core/security/server_secure_chttp2.c \ - src/core/surface/init_secure.c \ - src/core/surface/secure_channel_create.c \ - src/core/tsi/fake_transport_security.c \ - src/core/tsi/ssl_transport_security.c \ - src/core/tsi/transport_security.c \ - src/core/census/context.c \ - src/core/census/initialize.c \ - src/core/census/mlog.c \ - src/core/census/operation.c \ - src/core/census/placeholders.c \ - src/core/census/tracing.c \ + src/core/lib/census/grpc_context.c \ + src/core/lib/census/grpc_filter.c \ + src/core/lib/census/grpc_plugin.c \ + src/core/lib/channel/channel_args.c \ + src/core/lib/channel/channel_stack.c \ + src/core/lib/channel/channel_stack_builder.c \ + src/core/lib/channel/client_channel.c \ + src/core/lib/channel/compress_filter.c \ + src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/http_client_filter.c \ + src/core/lib/channel/http_server_filter.c \ + src/core/lib/channel/subchannel_call_holder.c \ + src/core/lib/client_config/client_config.c \ + src/core/lib/client_config/connector.c \ + src/core/lib/client_config/default_initial_connect_string.c \ + src/core/lib/client_config/initial_connect_string.c \ + src/core/lib/client_config/lb_policies/load_balancer_api.c \ + src/core/lib/client_config/lb_policies/pick_first.c \ + src/core/lib/client_config/lb_policies/round_robin.c \ + src/core/lib/client_config/lb_policy.c \ + src/core/lib/client_config/lb_policy_factory.c \ + src/core/lib/client_config/lb_policy_registry.c \ + src/core/lib/client_config/resolver.c \ + src/core/lib/client_config/resolver_factory.c \ + src/core/lib/client_config/resolver_registry.c \ + src/core/lib/client_config/resolvers/dns_resolver.c \ + src/core/lib/client_config/resolvers/sockaddr_resolver.c \ + src/core/lib/client_config/subchannel.c \ + src/core/lib/client_config/subchannel_factory.c \ + src/core/lib/client_config/subchannel_index.c \ + src/core/lib/client_config/uri_parser.c \ + src/core/lib/compression/compression_algorithm.c \ + src/core/lib/compression/message_compress.c \ + src/core/lib/debug/trace.c \ + src/core/lib/http/format_request.c \ + src/core/lib/http/httpcli.c \ + src/core/lib/http/parser.c \ + src/core/lib/iomgr/closure.c \ + src/core/lib/iomgr/endpoint.c \ + src/core/lib/iomgr/endpoint_pair_posix.c \ + src/core/lib/iomgr/endpoint_pair_windows.c \ + src/core/lib/iomgr/exec_ctx.c \ + src/core/lib/iomgr/executor.c \ + src/core/lib/iomgr/fd_posix.c \ + src/core/lib/iomgr/iocp_windows.c \ + src/core/lib/iomgr/iomgr.c \ + src/core/lib/iomgr/iomgr_posix.c \ + src/core/lib/iomgr/iomgr_windows.c \ + src/core/lib/iomgr/pollset_multipoller_with_epoll.c \ + src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c \ + src/core/lib/iomgr/pollset_posix.c \ + src/core/lib/iomgr/pollset_set_posix.c \ + src/core/lib/iomgr/pollset_set_windows.c \ + src/core/lib/iomgr/pollset_windows.c \ + src/core/lib/iomgr/resolve_address_posix.c \ + src/core/lib/iomgr/resolve_address_windows.c \ + src/core/lib/iomgr/sockaddr_utils.c \ + src/core/lib/iomgr/socket_utils_common_posix.c \ + src/core/lib/iomgr/socket_utils_linux.c \ + src/core/lib/iomgr/socket_utils_posix.c \ + src/core/lib/iomgr/socket_windows.c \ + src/core/lib/iomgr/tcp_client_posix.c \ + src/core/lib/iomgr/tcp_client_windows.c \ + src/core/lib/iomgr/tcp_posix.c \ + src/core/lib/iomgr/tcp_server_posix.c \ + src/core/lib/iomgr/tcp_server_windows.c \ + src/core/lib/iomgr/tcp_windows.c \ + src/core/lib/iomgr/time_averaged_stats.c \ + src/core/lib/iomgr/timer.c \ + src/core/lib/iomgr/timer_heap.c \ + src/core/lib/iomgr/udp_server.c \ + src/core/lib/iomgr/unix_sockets_posix.c \ + src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_eventfd.c \ + src/core/lib/iomgr/wakeup_fd_nospecial.c \ + src/core/lib/iomgr/wakeup_fd_pipe.c \ + src/core/lib/iomgr/wakeup_fd_posix.c \ + src/core/lib/iomgr/workqueue_posix.c \ + src/core/lib/iomgr/workqueue_windows.c \ + src/core/lib/json/json.c \ + src/core/lib/json/json_reader.c \ + src/core/lib/json/json_string.c \ + src/core/lib/json/json_writer.c \ + src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c \ + src/core/lib/surface/alarm.c \ + src/core/lib/surface/api_trace.c \ + src/core/lib/surface/byte_buffer.c \ + src/core/lib/surface/byte_buffer_reader.c \ + src/core/lib/surface/call.c \ + src/core/lib/surface/call_details.c \ + src/core/lib/surface/call_log_batch.c \ + src/core/lib/surface/channel.c \ + src/core/lib/surface/channel_connectivity.c \ + src/core/lib/surface/channel_create.c \ + src/core/lib/surface/channel_init.c \ + src/core/lib/surface/channel_ping.c \ + src/core/lib/surface/channel_stack_type.c \ + src/core/lib/surface/completion_queue.c \ + src/core/lib/surface/event_string.c \ + src/core/lib/surface/init.c \ + src/core/lib/surface/lame_client.c \ + src/core/lib/surface/metadata_array.c \ + src/core/lib/surface/server.c \ + src/core/lib/surface/server_chttp2.c \ + src/core/lib/surface/validate_metadata.c \ + src/core/lib/surface/version.c \ + src/core/lib/transport/byte_stream.c \ + src/core/lib/transport/chttp2/alpn.c \ + src/core/lib/transport/chttp2/bin_encoder.c \ + src/core/lib/transport/chttp2/frame_data.c \ + src/core/lib/transport/chttp2/frame_goaway.c \ + src/core/lib/transport/chttp2/frame_ping.c \ + src/core/lib/transport/chttp2/frame_rst_stream.c \ + src/core/lib/transport/chttp2/frame_settings.c \ + src/core/lib/transport/chttp2/frame_window_update.c \ + src/core/lib/transport/chttp2/hpack_encoder.c \ + src/core/lib/transport/chttp2/hpack_parser.c \ + src/core/lib/transport/chttp2/hpack_table.c \ + src/core/lib/transport/chttp2/huffsyms.c \ + src/core/lib/transport/chttp2/incoming_metadata.c \ + src/core/lib/transport/chttp2/parsing.c \ + src/core/lib/transport/chttp2/status_conversion.c \ + src/core/lib/transport/chttp2/stream_lists.c \ + src/core/lib/transport/chttp2/stream_map.c \ + src/core/lib/transport/chttp2/timeout_encoding.c \ + src/core/lib/transport/chttp2/varint.c \ + src/core/lib/transport/chttp2/writing.c \ + src/core/lib/transport/chttp2_transport.c \ + src/core/lib/transport/connectivity_state.c \ + src/core/lib/transport/metadata.c \ + src/core/lib/transport/metadata_batch.c \ + src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/transport.c \ + src/core/lib/transport/transport_op_string.c \ + src/core/lib/http/httpcli_security_connector.c \ + src/core/lib/security/b64.c \ + src/core/lib/security/client_auth_filter.c \ + src/core/lib/security/credentials.c \ + src/core/lib/security/credentials_metadata.c \ + src/core/lib/security/credentials_posix.c \ + src/core/lib/security/credentials_win32.c \ + src/core/lib/security/google_default_credentials.c \ + src/core/lib/security/handshake.c \ + src/core/lib/security/json_token.c \ + src/core/lib/security/jwt_verifier.c \ + src/core/lib/security/secure_endpoint.c \ + src/core/lib/security/security_connector.c \ + src/core/lib/security/security_context.c \ + src/core/lib/security/server_auth_filter.c \ + src/core/lib/security/server_secure_chttp2.c \ + src/core/lib/surface/init_secure.c \ + src/core/lib/surface/secure_channel_create.c \ + src/core/lib/tsi/fake_transport_security.c \ + src/core/lib/tsi/ssl_transport_security.c \ + src/core/lib/tsi/transport_security.c \ + src/core/lib/census/context.c \ + src/core/lib/census/initialize.c \ + src/core/lib/census/mlog.c \ + src/core/lib/census/operation.c \ + src/core/lib/census/placeholders.c \ + src/core/lib/census/tracing.c \ third_party/nanopb/pb_common.c \ third_party/nanopb/pb_decode.c \ third_party/nanopb/pb_encode.c \ @@ -2780,147 +2780,147 @@ endif LIBGRPC_UNSECURE_SRC = \ - src/core/surface/init_unsecure.c \ - src/core/census/grpc_context.c \ - src/core/census/grpc_filter.c \ - src/core/census/grpc_plugin.c \ - src/core/channel/channel_args.c \ - src/core/channel/channel_stack.c \ - src/core/channel/channel_stack_builder.c \ - src/core/channel/client_channel.c \ - src/core/channel/compress_filter.c \ - src/core/channel/connected_channel.c \ - src/core/channel/http_client_filter.c \ - src/core/channel/http_server_filter.c \ - src/core/channel/subchannel_call_holder.c \ - src/core/client_config/client_config.c \ - src/core/client_config/connector.c \ - src/core/client_config/default_initial_connect_string.c \ - src/core/client_config/initial_connect_string.c \ - src/core/client_config/lb_policies/load_balancer_api.c \ - src/core/client_config/lb_policies/pick_first.c \ - src/core/client_config/lb_policies/round_robin.c \ - src/core/client_config/lb_policy.c \ - src/core/client_config/lb_policy_factory.c \ - src/core/client_config/lb_policy_registry.c \ - src/core/client_config/resolver.c \ - src/core/client_config/resolver_factory.c \ - src/core/client_config/resolver_registry.c \ - src/core/client_config/resolvers/dns_resolver.c \ - src/core/client_config/resolvers/sockaddr_resolver.c \ - src/core/client_config/subchannel.c \ - src/core/client_config/subchannel_factory.c \ - src/core/client_config/subchannel_index.c \ - src/core/client_config/uri_parser.c \ - src/core/compression/compression_algorithm.c \ - src/core/compression/message_compress.c \ - src/core/debug/trace.c \ - src/core/http/format_request.c \ - src/core/http/httpcli.c \ - src/core/http/parser.c \ - src/core/iomgr/closure.c \ - src/core/iomgr/endpoint.c \ - src/core/iomgr/endpoint_pair_posix.c \ - src/core/iomgr/endpoint_pair_windows.c \ - src/core/iomgr/exec_ctx.c \ - src/core/iomgr/executor.c \ - src/core/iomgr/fd_posix.c \ - src/core/iomgr/iocp_windows.c \ - src/core/iomgr/iomgr.c \ - src/core/iomgr/iomgr_posix.c \ - src/core/iomgr/iomgr_windows.c \ - src/core/iomgr/pollset_multipoller_with_epoll.c \ - src/core/iomgr/pollset_multipoller_with_poll_posix.c \ - src/core/iomgr/pollset_posix.c \ - src/core/iomgr/pollset_set_posix.c \ - src/core/iomgr/pollset_set_windows.c \ - src/core/iomgr/pollset_windows.c \ - src/core/iomgr/resolve_address_posix.c \ - src/core/iomgr/resolve_address_windows.c \ - src/core/iomgr/sockaddr_utils.c \ - src/core/iomgr/socket_utils_common_posix.c \ - src/core/iomgr/socket_utils_linux.c \ - src/core/iomgr/socket_utils_posix.c \ - src/core/iomgr/socket_windows.c \ - src/core/iomgr/tcp_client_posix.c \ - src/core/iomgr/tcp_client_windows.c \ - src/core/iomgr/tcp_posix.c \ - src/core/iomgr/tcp_server_posix.c \ - src/core/iomgr/tcp_server_windows.c \ - src/core/iomgr/tcp_windows.c \ - src/core/iomgr/time_averaged_stats.c \ - src/core/iomgr/timer.c \ - src/core/iomgr/timer_heap.c \ - src/core/iomgr/udp_server.c \ - src/core/iomgr/unix_sockets_posix.c \ - src/core/iomgr/unix_sockets_posix_noop.c \ - src/core/iomgr/wakeup_fd_eventfd.c \ - src/core/iomgr/wakeup_fd_nospecial.c \ - src/core/iomgr/wakeup_fd_pipe.c \ - src/core/iomgr/wakeup_fd_posix.c \ - src/core/iomgr/workqueue_posix.c \ - src/core/iomgr/workqueue_windows.c \ - src/core/json/json.c \ - src/core/json/json_reader.c \ - src/core/json/json_string.c \ - src/core/json/json_writer.c \ - src/core/proto/grpc/lb/v0/load_balancer.pb.c \ - src/core/surface/alarm.c \ - src/core/surface/api_trace.c \ - src/core/surface/byte_buffer.c \ - src/core/surface/byte_buffer_reader.c \ - src/core/surface/call.c \ - src/core/surface/call_details.c \ - src/core/surface/call_log_batch.c \ - src/core/surface/channel.c \ - src/core/surface/channel_connectivity.c \ - src/core/surface/channel_create.c \ - src/core/surface/channel_init.c \ - src/core/surface/channel_ping.c \ - src/core/surface/channel_stack_type.c \ - src/core/surface/completion_queue.c \ - src/core/surface/event_string.c \ - src/core/surface/init.c \ - src/core/surface/lame_client.c \ - src/core/surface/metadata_array.c \ - src/core/surface/server.c \ - src/core/surface/server_chttp2.c \ - src/core/surface/validate_metadata.c \ - src/core/surface/version.c \ - src/core/transport/byte_stream.c \ - src/core/transport/chttp2/alpn.c \ - src/core/transport/chttp2/bin_encoder.c \ - src/core/transport/chttp2/frame_data.c \ - src/core/transport/chttp2/frame_goaway.c \ - src/core/transport/chttp2/frame_ping.c \ - src/core/transport/chttp2/frame_rst_stream.c \ - src/core/transport/chttp2/frame_settings.c \ - src/core/transport/chttp2/frame_window_update.c \ - src/core/transport/chttp2/hpack_encoder.c \ - src/core/transport/chttp2/hpack_parser.c \ - src/core/transport/chttp2/hpack_table.c \ - src/core/transport/chttp2/huffsyms.c \ - src/core/transport/chttp2/incoming_metadata.c \ - src/core/transport/chttp2/parsing.c \ - src/core/transport/chttp2/status_conversion.c \ - src/core/transport/chttp2/stream_lists.c \ - src/core/transport/chttp2/stream_map.c \ - src/core/transport/chttp2/timeout_encoding.c \ - src/core/transport/chttp2/varint.c \ - src/core/transport/chttp2/writing.c \ - src/core/transport/chttp2_transport.c \ - src/core/transport/connectivity_state.c \ - src/core/transport/metadata.c \ - src/core/transport/metadata_batch.c \ - src/core/transport/static_metadata.c \ - src/core/transport/transport.c \ - src/core/transport/transport_op_string.c \ - src/core/census/context.c \ - src/core/census/initialize.c \ - src/core/census/mlog.c \ - src/core/census/operation.c \ - src/core/census/placeholders.c \ - src/core/census/tracing.c \ + src/core/lib/surface/init_unsecure.c \ + src/core/lib/census/grpc_context.c \ + src/core/lib/census/grpc_filter.c \ + src/core/lib/census/grpc_plugin.c \ + src/core/lib/channel/channel_args.c \ + src/core/lib/channel/channel_stack.c \ + src/core/lib/channel/channel_stack_builder.c \ + src/core/lib/channel/client_channel.c \ + src/core/lib/channel/compress_filter.c \ + src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/http_client_filter.c \ + src/core/lib/channel/http_server_filter.c \ + src/core/lib/channel/subchannel_call_holder.c \ + src/core/lib/client_config/client_config.c \ + src/core/lib/client_config/connector.c \ + src/core/lib/client_config/default_initial_connect_string.c \ + src/core/lib/client_config/initial_connect_string.c \ + src/core/lib/client_config/lb_policies/load_balancer_api.c \ + src/core/lib/client_config/lb_policies/pick_first.c \ + src/core/lib/client_config/lb_policies/round_robin.c \ + src/core/lib/client_config/lb_policy.c \ + src/core/lib/client_config/lb_policy_factory.c \ + src/core/lib/client_config/lb_policy_registry.c \ + src/core/lib/client_config/resolver.c \ + src/core/lib/client_config/resolver_factory.c \ + src/core/lib/client_config/resolver_registry.c \ + src/core/lib/client_config/resolvers/dns_resolver.c \ + src/core/lib/client_config/resolvers/sockaddr_resolver.c \ + src/core/lib/client_config/subchannel.c \ + src/core/lib/client_config/subchannel_factory.c \ + src/core/lib/client_config/subchannel_index.c \ + src/core/lib/client_config/uri_parser.c \ + src/core/lib/compression/compression_algorithm.c \ + src/core/lib/compression/message_compress.c \ + src/core/lib/debug/trace.c \ + src/core/lib/http/format_request.c \ + src/core/lib/http/httpcli.c \ + src/core/lib/http/parser.c \ + src/core/lib/iomgr/closure.c \ + src/core/lib/iomgr/endpoint.c \ + src/core/lib/iomgr/endpoint_pair_posix.c \ + src/core/lib/iomgr/endpoint_pair_windows.c \ + src/core/lib/iomgr/exec_ctx.c \ + src/core/lib/iomgr/executor.c \ + src/core/lib/iomgr/fd_posix.c \ + src/core/lib/iomgr/iocp_windows.c \ + src/core/lib/iomgr/iomgr.c \ + src/core/lib/iomgr/iomgr_posix.c \ + src/core/lib/iomgr/iomgr_windows.c \ + src/core/lib/iomgr/pollset_multipoller_with_epoll.c \ + src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c \ + src/core/lib/iomgr/pollset_posix.c \ + src/core/lib/iomgr/pollset_set_posix.c \ + src/core/lib/iomgr/pollset_set_windows.c \ + src/core/lib/iomgr/pollset_windows.c \ + src/core/lib/iomgr/resolve_address_posix.c \ + src/core/lib/iomgr/resolve_address_windows.c \ + src/core/lib/iomgr/sockaddr_utils.c \ + src/core/lib/iomgr/socket_utils_common_posix.c \ + src/core/lib/iomgr/socket_utils_linux.c \ + src/core/lib/iomgr/socket_utils_posix.c \ + src/core/lib/iomgr/socket_windows.c \ + src/core/lib/iomgr/tcp_client_posix.c \ + src/core/lib/iomgr/tcp_client_windows.c \ + src/core/lib/iomgr/tcp_posix.c \ + src/core/lib/iomgr/tcp_server_posix.c \ + src/core/lib/iomgr/tcp_server_windows.c \ + src/core/lib/iomgr/tcp_windows.c \ + src/core/lib/iomgr/time_averaged_stats.c \ + src/core/lib/iomgr/timer.c \ + src/core/lib/iomgr/timer_heap.c \ + src/core/lib/iomgr/udp_server.c \ + src/core/lib/iomgr/unix_sockets_posix.c \ + src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_eventfd.c \ + src/core/lib/iomgr/wakeup_fd_nospecial.c \ + src/core/lib/iomgr/wakeup_fd_pipe.c \ + src/core/lib/iomgr/wakeup_fd_posix.c \ + src/core/lib/iomgr/workqueue_posix.c \ + src/core/lib/iomgr/workqueue_windows.c \ + src/core/lib/json/json.c \ + src/core/lib/json/json_reader.c \ + src/core/lib/json/json_string.c \ + src/core/lib/json/json_writer.c \ + src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c \ + src/core/lib/surface/alarm.c \ + src/core/lib/surface/api_trace.c \ + src/core/lib/surface/byte_buffer.c \ + src/core/lib/surface/byte_buffer_reader.c \ + src/core/lib/surface/call.c \ + src/core/lib/surface/call_details.c \ + src/core/lib/surface/call_log_batch.c \ + src/core/lib/surface/channel.c \ + src/core/lib/surface/channel_connectivity.c \ + src/core/lib/surface/channel_create.c \ + src/core/lib/surface/channel_init.c \ + src/core/lib/surface/channel_ping.c \ + src/core/lib/surface/channel_stack_type.c \ + src/core/lib/surface/completion_queue.c \ + src/core/lib/surface/event_string.c \ + src/core/lib/surface/init.c \ + src/core/lib/surface/lame_client.c \ + src/core/lib/surface/metadata_array.c \ + src/core/lib/surface/server.c \ + src/core/lib/surface/server_chttp2.c \ + src/core/lib/surface/validate_metadata.c \ + src/core/lib/surface/version.c \ + src/core/lib/transport/byte_stream.c \ + src/core/lib/transport/chttp2/alpn.c \ + src/core/lib/transport/chttp2/bin_encoder.c \ + src/core/lib/transport/chttp2/frame_data.c \ + src/core/lib/transport/chttp2/frame_goaway.c \ + src/core/lib/transport/chttp2/frame_ping.c \ + src/core/lib/transport/chttp2/frame_rst_stream.c \ + src/core/lib/transport/chttp2/frame_settings.c \ + src/core/lib/transport/chttp2/frame_window_update.c \ + src/core/lib/transport/chttp2/hpack_encoder.c \ + src/core/lib/transport/chttp2/hpack_parser.c \ + src/core/lib/transport/chttp2/hpack_table.c \ + src/core/lib/transport/chttp2/huffsyms.c \ + src/core/lib/transport/chttp2/incoming_metadata.c \ + src/core/lib/transport/chttp2/parsing.c \ + src/core/lib/transport/chttp2/status_conversion.c \ + src/core/lib/transport/chttp2/stream_lists.c \ + src/core/lib/transport/chttp2/stream_map.c \ + src/core/lib/transport/chttp2/timeout_encoding.c \ + src/core/lib/transport/chttp2/varint.c \ + src/core/lib/transport/chttp2/writing.c \ + src/core/lib/transport/chttp2_transport.c \ + src/core/lib/transport/connectivity_state.c \ + src/core/lib/transport/metadata.c \ + src/core/lib/transport/metadata_batch.c \ + src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/transport.c \ + src/core/lib/transport/transport_op_string.c \ + src/core/lib/census/context.c \ + src/core/lib/census/initialize.c \ + src/core/lib/census/mlog.c \ + src/core/lib/census/operation.c \ + src/core/lib/census/placeholders.c \ + src/core/lib/census/tracing.c \ third_party/nanopb/pb_common.c \ third_party/nanopb/pb_decode.c \ third_party/nanopb/pb_encode.c \ @@ -2977,7 +2977,7 @@ endif LIBGRPC_ZOOKEEPER_SRC = \ - src/core/client_config/resolvers/zookeeper_resolver.c \ + src/core/lib/client_config/resolvers/zookeeper_resolver.c \ PUBLIC_HEADERS_C += \ include/grpc/grpc_zookeeper.h \ @@ -13416,27 +13416,27 @@ ifneq ($(OPENSSL_DEP),) # This is to ensure the embedded OpenSSL is built beforehand, properly # installing headers to their final destination on the drive. We need this # otherwise parallel compilation will fail if a source is compiled first. -src/core/http/httpcli_security_connector.c: $(OPENSSL_DEP) -src/core/security/b64.c: $(OPENSSL_DEP) -src/core/security/client_auth_filter.c: $(OPENSSL_DEP) -src/core/security/credentials.c: $(OPENSSL_DEP) -src/core/security/credentials_metadata.c: $(OPENSSL_DEP) -src/core/security/credentials_posix.c: $(OPENSSL_DEP) -src/core/security/credentials_win32.c: $(OPENSSL_DEP) -src/core/security/google_default_credentials.c: $(OPENSSL_DEP) -src/core/security/handshake.c: $(OPENSSL_DEP) -src/core/security/json_token.c: $(OPENSSL_DEP) -src/core/security/jwt_verifier.c: $(OPENSSL_DEP) -src/core/security/secure_endpoint.c: $(OPENSSL_DEP) -src/core/security/security_connector.c: $(OPENSSL_DEP) -src/core/security/security_context.c: $(OPENSSL_DEP) -src/core/security/server_auth_filter.c: $(OPENSSL_DEP) -src/core/security/server_secure_chttp2.c: $(OPENSSL_DEP) -src/core/surface/init_secure.c: $(OPENSSL_DEP) -src/core/surface/secure_channel_create.c: $(OPENSSL_DEP) -src/core/tsi/fake_transport_security.c: $(OPENSSL_DEP) -src/core/tsi/ssl_transport_security.c: $(OPENSSL_DEP) -src/core/tsi/transport_security.c: $(OPENSSL_DEP) +src/core/lib/http/httpcli_security_connector.c: $(OPENSSL_DEP) +src/core/lib/security/b64.c: $(OPENSSL_DEP) +src/core/lib/security/client_auth_filter.c: $(OPENSSL_DEP) +src/core/lib/security/credentials.c: $(OPENSSL_DEP) +src/core/lib/security/credentials_metadata.c: $(OPENSSL_DEP) +src/core/lib/security/credentials_posix.c: $(OPENSSL_DEP) +src/core/lib/security/credentials_win32.c: $(OPENSSL_DEP) +src/core/lib/security/google_default_credentials.c: $(OPENSSL_DEP) +src/core/lib/security/handshake.c: $(OPENSSL_DEP) +src/core/lib/security/json_token.c: $(OPENSSL_DEP) +src/core/lib/security/jwt_verifier.c: $(OPENSSL_DEP) +src/core/lib/security/secure_endpoint.c: $(OPENSSL_DEP) +src/core/lib/security/security_connector.c: $(OPENSSL_DEP) +src/core/lib/security/security_context.c: $(OPENSSL_DEP) +src/core/lib/security/server_auth_filter.c: $(OPENSSL_DEP) +src/core/lib/security/server_secure_chttp2.c: $(OPENSSL_DEP) +src/core/lib/surface/init_secure.c: $(OPENSSL_DEP) +src/core/lib/surface/secure_channel_create.c: $(OPENSSL_DEP) +src/core/lib/tsi/fake_transport_security.c: $(OPENSSL_DEP) +src/core/lib/tsi/ssl_transport_security.c: $(OPENSSL_DEP) +src/core/lib/tsi/transport_security.c: $(OPENSSL_DEP) src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP) src/cpp/common/auth_property_iterator.cc: $(OPENSSL_DEP) src/cpp/common/secure_auth_context.cc: $(OPENSSL_DEP) diff --git a/binding.gyp b/binding.gyp index 2ee383a95c..416ce20864 100644 --- a/binding.gyp +++ b/binding.gyp @@ -492,50 +492,50 @@ 'dependencies': [ ], 'sources': [ - 'src/core/profiling/basic_timers.c', - 'src/core/profiling/stap_timers.c', - 'src/core/support/alloc.c', - 'src/core/support/avl.c', - 'src/core/support/backoff.c', - 'src/core/support/cmdline.c', - 'src/core/support/cpu_iphone.c', - 'src/core/support/cpu_linux.c', - 'src/core/support/cpu_posix.c', - 'src/core/support/cpu_windows.c', - 'src/core/support/env_linux.c', - 'src/core/support/env_posix.c', - 'src/core/support/env_win32.c', - 'src/core/support/histogram.c', - 'src/core/support/host_port.c', - 'src/core/support/load_file.c', - 'src/core/support/log.c', - 'src/core/support/log_android.c', - 'src/core/support/log_linux.c', - 'src/core/support/log_posix.c', - 'src/core/support/log_win32.c', - 'src/core/support/murmur_hash.c', - 'src/core/support/slice.c', - 'src/core/support/slice_buffer.c', - 'src/core/support/stack_lockfree.c', - 'src/core/support/string.c', - 'src/core/support/string_posix.c', - 'src/core/support/string_win32.c', - 'src/core/support/subprocess_posix.c', - 'src/core/support/subprocess_windows.c', - 'src/core/support/sync.c', - 'src/core/support/sync_posix.c', - 'src/core/support/sync_win32.c', - 'src/core/support/thd.c', - 'src/core/support/thd_posix.c', - 'src/core/support/thd_win32.c', - 'src/core/support/time.c', - 'src/core/support/time_posix.c', - 'src/core/support/time_precise.c', - 'src/core/support/time_win32.c', - 'src/core/support/tls_pthread.c', - 'src/core/support/tmpfile_posix.c', - 'src/core/support/tmpfile_win32.c', - 'src/core/support/wrap_memcpy.c', + 'src/core/lib/profiling/basic_timers.c', + 'src/core/lib/profiling/stap_timers.c', + 'src/core/lib/support/alloc.c', + 'src/core/lib/support/avl.c', + 'src/core/lib/support/backoff.c', + 'src/core/lib/support/cmdline.c', + 'src/core/lib/support/cpu_iphone.c', + 'src/core/lib/support/cpu_linux.c', + 'src/core/lib/support/cpu_posix.c', + 'src/core/lib/support/cpu_windows.c', + 'src/core/lib/support/env_linux.c', + 'src/core/lib/support/env_posix.c', + 'src/core/lib/support/env_win32.c', + 'src/core/lib/support/histogram.c', + 'src/core/lib/support/host_port.c', + 'src/core/lib/support/load_file.c', + 'src/core/lib/support/log.c', + 'src/core/lib/support/log_android.c', + 'src/core/lib/support/log_linux.c', + 'src/core/lib/support/log_posix.c', + 'src/core/lib/support/log_win32.c', + 'src/core/lib/support/murmur_hash.c', + 'src/core/lib/support/slice.c', + 'src/core/lib/support/slice_buffer.c', + 'src/core/lib/support/stack_lockfree.c', + 'src/core/lib/support/string.c', + 'src/core/lib/support/string_posix.c', + 'src/core/lib/support/string_win32.c', + 'src/core/lib/support/subprocess_posix.c', + 'src/core/lib/support/subprocess_windows.c', + 'src/core/lib/support/sync.c', + 'src/core/lib/support/sync_posix.c', + 'src/core/lib/support/sync_win32.c', + 'src/core/lib/support/thd.c', + 'src/core/lib/support/thd_posix.c', + 'src/core/lib/support/thd_win32.c', + 'src/core/lib/support/time.c', + 'src/core/lib/support/time_posix.c', + 'src/core/lib/support/time_precise.c', + 'src/core/lib/support/time_win32.c', + 'src/core/lib/support/tls_pthread.c', + 'src/core/lib/support/tmpfile_posix.c', + 'src/core/lib/support/tmpfile_win32.c', + 'src/core/lib/support/wrap_memcpy.c', ], "conditions": [ ['OS == "mac"', { @@ -558,167 +558,167 @@ 'gpr', ], 'sources': [ - 'src/core/census/grpc_context.c', - 'src/core/census/grpc_filter.c', - 'src/core/census/grpc_plugin.c', - 'src/core/channel/channel_args.c', - 'src/core/channel/channel_stack.c', - 'src/core/channel/channel_stack_builder.c', - 'src/core/channel/client_channel.c', - 'src/core/channel/compress_filter.c', - 'src/core/channel/connected_channel.c', - 'src/core/channel/http_client_filter.c', - 'src/core/channel/http_server_filter.c', - 'src/core/channel/subchannel_call_holder.c', - 'src/core/client_config/client_config.c', - 'src/core/client_config/connector.c', - 'src/core/client_config/default_initial_connect_string.c', - 'src/core/client_config/initial_connect_string.c', - 'src/core/client_config/lb_policies/load_balancer_api.c', - 'src/core/client_config/lb_policies/pick_first.c', - 'src/core/client_config/lb_policies/round_robin.c', - 'src/core/client_config/lb_policy.c', - 'src/core/client_config/lb_policy_factory.c', - 'src/core/client_config/lb_policy_registry.c', - 'src/core/client_config/resolver.c', - 'src/core/client_config/resolver_factory.c', - 'src/core/client_config/resolver_registry.c', - 'src/core/client_config/resolvers/dns_resolver.c', - 'src/core/client_config/resolvers/sockaddr_resolver.c', - 'src/core/client_config/subchannel.c', - 'src/core/client_config/subchannel_factory.c', - 'src/core/client_config/subchannel_index.c', - 'src/core/client_config/uri_parser.c', - 'src/core/compression/compression_algorithm.c', - 'src/core/compression/message_compress.c', - 'src/core/debug/trace.c', - 'src/core/http/format_request.c', - 'src/core/http/httpcli.c', - 'src/core/http/parser.c', - 'src/core/iomgr/closure.c', - 'src/core/iomgr/endpoint.c', - 'src/core/iomgr/endpoint_pair_posix.c', - 'src/core/iomgr/endpoint_pair_windows.c', - 'src/core/iomgr/exec_ctx.c', - 'src/core/iomgr/executor.c', - 'src/core/iomgr/fd_posix.c', - 'src/core/iomgr/iocp_windows.c', - 'src/core/iomgr/iomgr.c', - 'src/core/iomgr/iomgr_posix.c', - 'src/core/iomgr/iomgr_windows.c', - 'src/core/iomgr/pollset_multipoller_with_epoll.c', - 'src/core/iomgr/pollset_multipoller_with_poll_posix.c', - 'src/core/iomgr/pollset_posix.c', - 'src/core/iomgr/pollset_set_posix.c', - 'src/core/iomgr/pollset_set_windows.c', - 'src/core/iomgr/pollset_windows.c', - 'src/core/iomgr/resolve_address_posix.c', - 'src/core/iomgr/resolve_address_windows.c', - 'src/core/iomgr/sockaddr_utils.c', - 'src/core/iomgr/socket_utils_common_posix.c', - 'src/core/iomgr/socket_utils_linux.c', - 'src/core/iomgr/socket_utils_posix.c', - 'src/core/iomgr/socket_windows.c', - 'src/core/iomgr/tcp_client_posix.c', - 'src/core/iomgr/tcp_client_windows.c', - 'src/core/iomgr/tcp_posix.c', - 'src/core/iomgr/tcp_server_posix.c', - 'src/core/iomgr/tcp_server_windows.c', - 'src/core/iomgr/tcp_windows.c', - 'src/core/iomgr/time_averaged_stats.c', - 'src/core/iomgr/timer.c', - 'src/core/iomgr/timer_heap.c', - 'src/core/iomgr/udp_server.c', - 'src/core/iomgr/unix_sockets_posix.c', - 'src/core/iomgr/unix_sockets_posix_noop.c', - 'src/core/iomgr/wakeup_fd_eventfd.c', - 'src/core/iomgr/wakeup_fd_nospecial.c', - 'src/core/iomgr/wakeup_fd_pipe.c', - 'src/core/iomgr/wakeup_fd_posix.c', - 'src/core/iomgr/workqueue_posix.c', - 'src/core/iomgr/workqueue_windows.c', - 'src/core/json/json.c', - 'src/core/json/json_reader.c', - 'src/core/json/json_string.c', - 'src/core/json/json_writer.c', - 'src/core/proto/grpc/lb/v0/load_balancer.pb.c', - 'src/core/surface/alarm.c', - 'src/core/surface/api_trace.c', - 'src/core/surface/byte_buffer.c', - 'src/core/surface/byte_buffer_reader.c', - 'src/core/surface/call.c', - 'src/core/surface/call_details.c', - 'src/core/surface/call_log_batch.c', - 'src/core/surface/channel.c', - 'src/core/surface/channel_connectivity.c', - 'src/core/surface/channel_create.c', - 'src/core/surface/channel_init.c', - 'src/core/surface/channel_ping.c', - 'src/core/surface/channel_stack_type.c', - 'src/core/surface/completion_queue.c', - 'src/core/surface/event_string.c', - 'src/core/surface/init.c', - 'src/core/surface/lame_client.c', - 'src/core/surface/metadata_array.c', - 'src/core/surface/server.c', - 'src/core/surface/server_chttp2.c', - 'src/core/surface/validate_metadata.c', - 'src/core/surface/version.c', - 'src/core/transport/byte_stream.c', - 'src/core/transport/chttp2/alpn.c', - 'src/core/transport/chttp2/bin_encoder.c', - 'src/core/transport/chttp2/frame_data.c', - 'src/core/transport/chttp2/frame_goaway.c', - 'src/core/transport/chttp2/frame_ping.c', - 'src/core/transport/chttp2/frame_rst_stream.c', - 'src/core/transport/chttp2/frame_settings.c', - 'src/core/transport/chttp2/frame_window_update.c', - 'src/core/transport/chttp2/hpack_encoder.c', - 'src/core/transport/chttp2/hpack_parser.c', - 'src/core/transport/chttp2/hpack_table.c', - 'src/core/transport/chttp2/huffsyms.c', - 'src/core/transport/chttp2/incoming_metadata.c', - 'src/core/transport/chttp2/parsing.c', - 'src/core/transport/chttp2/status_conversion.c', - 'src/core/transport/chttp2/stream_lists.c', - 'src/core/transport/chttp2/stream_map.c', - 'src/core/transport/chttp2/timeout_encoding.c', - 'src/core/transport/chttp2/varint.c', - 'src/core/transport/chttp2/writing.c', - 'src/core/transport/chttp2_transport.c', - 'src/core/transport/connectivity_state.c', - 'src/core/transport/metadata.c', - 'src/core/transport/metadata_batch.c', - 'src/core/transport/static_metadata.c', - 'src/core/transport/transport.c', - 'src/core/transport/transport_op_string.c', - 'src/core/http/httpcli_security_connector.c', - 'src/core/security/b64.c', - 'src/core/security/client_auth_filter.c', - 'src/core/security/credentials.c', - 'src/core/security/credentials_metadata.c', - 'src/core/security/credentials_posix.c', - 'src/core/security/credentials_win32.c', - 'src/core/security/google_default_credentials.c', - 'src/core/security/handshake.c', - 'src/core/security/json_token.c', - 'src/core/security/jwt_verifier.c', - 'src/core/security/secure_endpoint.c', - 'src/core/security/security_connector.c', - 'src/core/security/security_context.c', - 'src/core/security/server_auth_filter.c', - 'src/core/security/server_secure_chttp2.c', - 'src/core/surface/init_secure.c', - 'src/core/surface/secure_channel_create.c', - 'src/core/tsi/fake_transport_security.c', - 'src/core/tsi/ssl_transport_security.c', - 'src/core/tsi/transport_security.c', - 'src/core/census/context.c', - 'src/core/census/initialize.c', - 'src/core/census/mlog.c', - 'src/core/census/operation.c', - 'src/core/census/placeholders.c', - 'src/core/census/tracing.c', + 'src/core/lib/census/grpc_context.c', + 'src/core/lib/census/grpc_filter.c', + 'src/core/lib/census/grpc_plugin.c', + 'src/core/lib/channel/channel_args.c', + 'src/core/lib/channel/channel_stack.c', + 'src/core/lib/channel/channel_stack_builder.c', + 'src/core/lib/channel/client_channel.c', + 'src/core/lib/channel/compress_filter.c', + 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/http_client_filter.c', + 'src/core/lib/channel/http_server_filter.c', + 'src/core/lib/channel/subchannel_call_holder.c', + 'src/core/lib/client_config/client_config.c', + 'src/core/lib/client_config/connector.c', + 'src/core/lib/client_config/default_initial_connect_string.c', + 'src/core/lib/client_config/initial_connect_string.c', + 'src/core/lib/client_config/lb_policies/load_balancer_api.c', + 'src/core/lib/client_config/lb_policies/pick_first.c', + 'src/core/lib/client_config/lb_policies/round_robin.c', + 'src/core/lib/client_config/lb_policy.c', + 'src/core/lib/client_config/lb_policy_factory.c', + 'src/core/lib/client_config/lb_policy_registry.c', + 'src/core/lib/client_config/resolver.c', + 'src/core/lib/client_config/resolver_factory.c', + 'src/core/lib/client_config/resolver_registry.c', + 'src/core/lib/client_config/resolvers/dns_resolver.c', + 'src/core/lib/client_config/resolvers/sockaddr_resolver.c', + 'src/core/lib/client_config/subchannel.c', + 'src/core/lib/client_config/subchannel_factory.c', + 'src/core/lib/client_config/subchannel_index.c', + 'src/core/lib/client_config/uri_parser.c', + 'src/core/lib/compression/compression_algorithm.c', + 'src/core/lib/compression/message_compress.c', + 'src/core/lib/debug/trace.c', + 'src/core/lib/http/format_request.c', + 'src/core/lib/http/httpcli.c', + 'src/core/lib/http/parser.c', + 'src/core/lib/iomgr/closure.c', + 'src/core/lib/iomgr/endpoint.c', + 'src/core/lib/iomgr/endpoint_pair_posix.c', + 'src/core/lib/iomgr/endpoint_pair_windows.c', + 'src/core/lib/iomgr/exec_ctx.c', + 'src/core/lib/iomgr/executor.c', + 'src/core/lib/iomgr/fd_posix.c', + 'src/core/lib/iomgr/iocp_windows.c', + 'src/core/lib/iomgr/iomgr.c', + 'src/core/lib/iomgr/iomgr_posix.c', + 'src/core/lib/iomgr/iomgr_windows.c', + 'src/core/lib/iomgr/pollset_multipoller_with_epoll.c', + 'src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c', + 'src/core/lib/iomgr/pollset_posix.c', + 'src/core/lib/iomgr/pollset_set_posix.c', + 'src/core/lib/iomgr/pollset_set_windows.c', + 'src/core/lib/iomgr/pollset_windows.c', + 'src/core/lib/iomgr/resolve_address_posix.c', + 'src/core/lib/iomgr/resolve_address_windows.c', + 'src/core/lib/iomgr/sockaddr_utils.c', + 'src/core/lib/iomgr/socket_utils_common_posix.c', + 'src/core/lib/iomgr/socket_utils_linux.c', + 'src/core/lib/iomgr/socket_utils_posix.c', + 'src/core/lib/iomgr/socket_windows.c', + 'src/core/lib/iomgr/tcp_client_posix.c', + 'src/core/lib/iomgr/tcp_client_windows.c', + 'src/core/lib/iomgr/tcp_posix.c', + 'src/core/lib/iomgr/tcp_server_posix.c', + 'src/core/lib/iomgr/tcp_server_windows.c', + 'src/core/lib/iomgr/tcp_windows.c', + 'src/core/lib/iomgr/time_averaged_stats.c', + 'src/core/lib/iomgr/timer.c', + 'src/core/lib/iomgr/timer_heap.c', + 'src/core/lib/iomgr/udp_server.c', + 'src/core/lib/iomgr/unix_sockets_posix.c', + 'src/core/lib/iomgr/unix_sockets_posix_noop.c', + 'src/core/lib/iomgr/wakeup_fd_eventfd.c', + 'src/core/lib/iomgr/wakeup_fd_nospecial.c', + 'src/core/lib/iomgr/wakeup_fd_pipe.c', + 'src/core/lib/iomgr/wakeup_fd_posix.c', + 'src/core/lib/iomgr/workqueue_posix.c', + 'src/core/lib/iomgr/workqueue_windows.c', + 'src/core/lib/json/json.c', + 'src/core/lib/json/json_reader.c', + 'src/core/lib/json/json_string.c', + 'src/core/lib/json/json_writer.c', + 'src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c', + 'src/core/lib/surface/alarm.c', + 'src/core/lib/surface/api_trace.c', + 'src/core/lib/surface/byte_buffer.c', + 'src/core/lib/surface/byte_buffer_reader.c', + 'src/core/lib/surface/call.c', + 'src/core/lib/surface/call_details.c', + 'src/core/lib/surface/call_log_batch.c', + 'src/core/lib/surface/channel.c', + 'src/core/lib/surface/channel_connectivity.c', + 'src/core/lib/surface/channel_create.c', + 'src/core/lib/surface/channel_init.c', + 'src/core/lib/surface/channel_ping.c', + 'src/core/lib/surface/channel_stack_type.c', + 'src/core/lib/surface/completion_queue.c', + 'src/core/lib/surface/event_string.c', + 'src/core/lib/surface/init.c', + 'src/core/lib/surface/lame_client.c', + 'src/core/lib/surface/metadata_array.c', + 'src/core/lib/surface/server.c', + 'src/core/lib/surface/server_chttp2.c', + 'src/core/lib/surface/validate_metadata.c', + 'src/core/lib/surface/version.c', + 'src/core/lib/transport/byte_stream.c', + 'src/core/lib/transport/chttp2/alpn.c', + 'src/core/lib/transport/chttp2/bin_encoder.c', + 'src/core/lib/transport/chttp2/frame_data.c', + 'src/core/lib/transport/chttp2/frame_goaway.c', + 'src/core/lib/transport/chttp2/frame_ping.c', + 'src/core/lib/transport/chttp2/frame_rst_stream.c', + 'src/core/lib/transport/chttp2/frame_settings.c', + 'src/core/lib/transport/chttp2/frame_window_update.c', + 'src/core/lib/transport/chttp2/hpack_encoder.c', + 'src/core/lib/transport/chttp2/hpack_parser.c', + 'src/core/lib/transport/chttp2/hpack_table.c', + 'src/core/lib/transport/chttp2/huffsyms.c', + 'src/core/lib/transport/chttp2/incoming_metadata.c', + 'src/core/lib/transport/chttp2/parsing.c', + 'src/core/lib/transport/chttp2/status_conversion.c', + 'src/core/lib/transport/chttp2/stream_lists.c', + 'src/core/lib/transport/chttp2/stream_map.c', + 'src/core/lib/transport/chttp2/timeout_encoding.c', + 'src/core/lib/transport/chttp2/varint.c', + 'src/core/lib/transport/chttp2/writing.c', + 'src/core/lib/transport/chttp2_transport.c', + 'src/core/lib/transport/connectivity_state.c', + 'src/core/lib/transport/metadata.c', + 'src/core/lib/transport/metadata_batch.c', + 'src/core/lib/transport/static_metadata.c', + 'src/core/lib/transport/transport.c', + 'src/core/lib/transport/transport_op_string.c', + 'src/core/lib/http/httpcli_security_connector.c', + 'src/core/lib/security/b64.c', + 'src/core/lib/security/client_auth_filter.c', + 'src/core/lib/security/credentials.c', + 'src/core/lib/security/credentials_metadata.c', + 'src/core/lib/security/credentials_posix.c', + 'src/core/lib/security/credentials_win32.c', + 'src/core/lib/security/google_default_credentials.c', + 'src/core/lib/security/handshake.c', + 'src/core/lib/security/json_token.c', + 'src/core/lib/security/jwt_verifier.c', + 'src/core/lib/security/secure_endpoint.c', + 'src/core/lib/security/security_connector.c', + 'src/core/lib/security/security_context.c', + 'src/core/lib/security/server_auth_filter.c', + 'src/core/lib/security/server_secure_chttp2.c', + 'src/core/lib/surface/init_secure.c', + 'src/core/lib/surface/secure_channel_create.c', + 'src/core/lib/tsi/fake_transport_security.c', + 'src/core/lib/tsi/ssl_transport_security.c', + 'src/core/lib/tsi/transport_security.c', + 'src/core/lib/census/context.c', + 'src/core/lib/census/initialize.c', + 'src/core/lib/census/mlog.c', + 'src/core/lib/census/operation.c', + 'src/core/lib/census/placeholders.c', + 'src/core/lib/census/tracing.c', 'third_party/nanopb/pb_common.c', 'third_party/nanopb/pb_decode.c', 'third_party/nanopb/pb_encode.c', diff --git a/build.yaml b/build.yaml index fc170cc1ab..0398bc23b8 100644 --- a/build.yaml +++ b/build.yaml @@ -13,16 +13,16 @@ filegroups: public_headers: - include/grpc/census.h headers: - - src/core/census/aggregation.h - - src/core/census/mlog.h - - src/core/census/rpc_metric_id.h - src: - - src/core/census/context.c - - src/core/census/initialize.c - - src/core/census/mlog.c - - src/core/census/operation.c - - src/core/census/placeholders.c - - src/core/census/tracing.c + - src/core/lib/census/aggregation.h + - src/core/lib/census/mlog.h + - src/core/lib/census/rpc_metric_id.h + src: + - src/core/lib/census/context.c + - src/core/lib/census/initialize.c + - src/core/lib/census/mlog.c + - src/core/lib/census/operation.c + - src/core/lib/census/placeholders.c + - src/core/lib/census/tracing.c - name: gpr public_headers: - include/grpc/support/alloc.h @@ -54,63 +54,63 @@ filegroups: - include/grpc/support/tls_pthread.h - include/grpc/support/useful.h headers: - - src/core/profiling/timers.h - - src/core/support/backoff.h - - src/core/support/block_annotate.h - - src/core/support/env.h - - src/core/support/load_file.h - - src/core/support/murmur_hash.h - - src/core/support/stack_lockfree.h - - src/core/support/string.h - - src/core/support/string_win32.h - - src/core/support/thd_internal.h - - src/core/support/time_precise.h - - src/core/support/tmpfile.h - src: - - src/core/profiling/basic_timers.c - - src/core/profiling/stap_timers.c - - src/core/support/alloc.c - - src/core/support/avl.c - - src/core/support/backoff.c - - src/core/support/cmdline.c - - src/core/support/cpu_iphone.c - - src/core/support/cpu_linux.c - - src/core/support/cpu_posix.c - - src/core/support/cpu_windows.c - - src/core/support/env_linux.c - - src/core/support/env_posix.c - - src/core/support/env_win32.c - - src/core/support/histogram.c - - src/core/support/host_port.c - - src/core/support/load_file.c - - src/core/support/log.c - - src/core/support/log_android.c - - src/core/support/log_linux.c - - src/core/support/log_posix.c - - src/core/support/log_win32.c - - src/core/support/murmur_hash.c - - src/core/support/slice.c - - src/core/support/slice_buffer.c - - src/core/support/stack_lockfree.c - - src/core/support/string.c - - src/core/support/string_posix.c - - src/core/support/string_win32.c - - src/core/support/subprocess_posix.c - - src/core/support/subprocess_windows.c - - src/core/support/sync.c - - src/core/support/sync_posix.c - - src/core/support/sync_win32.c - - src/core/support/thd.c - - src/core/support/thd_posix.c - - src/core/support/thd_win32.c - - src/core/support/time.c - - src/core/support/time_posix.c - - src/core/support/time_precise.c - - src/core/support/time_win32.c - - src/core/support/tls_pthread.c - - src/core/support/tmpfile_posix.c - - src/core/support/tmpfile_win32.c - - src/core/support/wrap_memcpy.c + - src/core/lib/profiling/timers.h + - src/core/lib/support/backoff.h + - src/core/lib/support/block_annotate.h + - src/core/lib/support/env.h + - src/core/lib/support/load_file.h + - src/core/lib/support/murmur_hash.h + - src/core/lib/support/stack_lockfree.h + - src/core/lib/support/string.h + - src/core/lib/support/string_win32.h + - src/core/lib/support/thd_internal.h + - src/core/lib/support/time_precise.h + - src/core/lib/support/tmpfile.h + src: + - src/core/lib/profiling/basic_timers.c + - src/core/lib/profiling/stap_timers.c + - src/core/lib/support/alloc.c + - src/core/lib/support/avl.c + - src/core/lib/support/backoff.c + - src/core/lib/support/cmdline.c + - src/core/lib/support/cpu_iphone.c + - src/core/lib/support/cpu_linux.c + - src/core/lib/support/cpu_posix.c + - src/core/lib/support/cpu_windows.c + - src/core/lib/support/env_linux.c + - src/core/lib/support/env_posix.c + - src/core/lib/support/env_win32.c + - src/core/lib/support/histogram.c + - src/core/lib/support/host_port.c + - src/core/lib/support/load_file.c + - src/core/lib/support/log.c + - src/core/lib/support/log_android.c + - src/core/lib/support/log_linux.c + - src/core/lib/support/log_posix.c + - src/core/lib/support/log_win32.c + - src/core/lib/support/murmur_hash.c + - src/core/lib/support/slice.c + - src/core/lib/support/slice_buffer.c + - src/core/lib/support/stack_lockfree.c + - src/core/lib/support/string.c + - src/core/lib/support/string_posix.c + - src/core/lib/support/string_win32.c + - src/core/lib/support/subprocess_posix.c + - src/core/lib/support/subprocess_windows.c + - src/core/lib/support/sync.c + - src/core/lib/support/sync_posix.c + - src/core/lib/support/sync_win32.c + - src/core/lib/support/thd.c + - src/core/lib/support/thd_posix.c + - src/core/lib/support/thd_win32.c + - src/core/lib/support/time.c + - src/core/lib/support/time_posix.c + - src/core/lib/support/time_precise.c + - src/core/lib/support/time_win32.c + - src/core/lib/support/tls_pthread.c + - src/core/lib/support/tmpfile_posix.c + - src/core/lib/support/tmpfile_win32.c + - src/core/lib/support/wrap_memcpy.c - name: gpr_codegen public_headers: - include/grpc/impl/codegen/alloc.h @@ -247,261 +247,261 @@ filegroups: - include/grpc/grpc.h - include/grpc/status.h headers: - - src/core/census/grpc_filter.h - - src/core/census/grpc_plugin.h - - src/core/channel/channel_args.h - - src/core/channel/channel_stack.h - - src/core/channel/channel_stack_builder.h - - src/core/channel/client_channel.h - - src/core/channel/compress_filter.h - - src/core/channel/connected_channel.h - - src/core/channel/context.h - - src/core/channel/http_client_filter.h - - src/core/channel/http_server_filter.h - - src/core/channel/subchannel_call_holder.h - - src/core/client_config/client_config.h - - src/core/client_config/connector.h - - src/core/client_config/initial_connect_string.h - - src/core/client_config/lb_policies/load_balancer_api.h - - src/core/client_config/lb_policies/pick_first.h - - src/core/client_config/lb_policies/round_robin.h - - src/core/client_config/lb_policy.h - - src/core/client_config/lb_policy_factory.h - - src/core/client_config/lb_policy_registry.h - - src/core/client_config/resolver.h - - src/core/client_config/resolver_factory.h - - src/core/client_config/resolver_registry.h - - src/core/client_config/resolvers/dns_resolver.h - - src/core/client_config/resolvers/sockaddr_resolver.h - - src/core/client_config/subchannel.h - - src/core/client_config/subchannel_factory.h - - src/core/client_config/subchannel_index.h - - src/core/client_config/uri_parser.h - - src/core/compression/algorithm_metadata.h - - src/core/compression/message_compress.h - - src/core/debug/trace.h - - src/core/http/format_request.h - - src/core/http/httpcli.h - - src/core/http/parser.h - - src/core/iomgr/closure.h - - src/core/iomgr/endpoint.h - - src/core/iomgr/endpoint_pair.h - - src/core/iomgr/exec_ctx.h - - src/core/iomgr/executor.h - - src/core/iomgr/fd_posix.h - - src/core/iomgr/iocp_windows.h - - src/core/iomgr/iomgr.h - - src/core/iomgr/iomgr_internal.h - - src/core/iomgr/iomgr_posix.h - - src/core/iomgr/pollset.h - - src/core/iomgr/pollset_posix.h - - src/core/iomgr/pollset_set.h - - src/core/iomgr/pollset_set_posix.h - - src/core/iomgr/pollset_set_windows.h - - src/core/iomgr/pollset_windows.h - - src/core/iomgr/resolve_address.h - - src/core/iomgr/sockaddr.h - - src/core/iomgr/sockaddr_posix.h - - src/core/iomgr/sockaddr_utils.h - - src/core/iomgr/sockaddr_win32.h - - src/core/iomgr/socket_utils_posix.h - - src/core/iomgr/socket_windows.h - - src/core/iomgr/tcp_client.h - - src/core/iomgr/tcp_posix.h - - src/core/iomgr/tcp_server.h - - src/core/iomgr/tcp_windows.h - - src/core/iomgr/time_averaged_stats.h - - src/core/iomgr/timer.h - - src/core/iomgr/timer_heap.h - - src/core/iomgr/udp_server.h - - src/core/iomgr/unix_sockets_posix.h - - src/core/iomgr/wakeup_fd_pipe.h - - src/core/iomgr/wakeup_fd_posix.h - - src/core/iomgr/workqueue.h - - src/core/iomgr/workqueue_posix.h - - src/core/iomgr/workqueue_windows.h - - src/core/json/json.h - - src/core/json/json_common.h - - src/core/json/json_reader.h - - src/core/json/json_writer.h - - src/core/proto/grpc/lb/v0/load_balancer.pb.h - - src/core/statistics/census_interface.h - - src/core/statistics/census_rpc_stats.h - - src/core/surface/api_trace.h - - src/core/surface/call.h - - src/core/surface/call_test_only.h - - src/core/surface/channel.h - - src/core/surface/channel_init.h - - src/core/surface/channel_stack_type.h - - src/core/surface/completion_queue.h - - src/core/surface/event_string.h - - src/core/surface/init.h - - src/core/surface/lame_client.h - - src/core/surface/server.h - - src/core/surface/surface_trace.h - - src/core/transport/byte_stream.h - - src/core/transport/chttp2/alpn.h - - src/core/transport/chttp2/bin_encoder.h - - src/core/transport/chttp2/frame.h - - src/core/transport/chttp2/frame_data.h - - src/core/transport/chttp2/frame_goaway.h - - src/core/transport/chttp2/frame_ping.h - - src/core/transport/chttp2/frame_rst_stream.h - - src/core/transport/chttp2/frame_settings.h - - src/core/transport/chttp2/frame_window_update.h - - src/core/transport/chttp2/hpack_encoder.h - - src/core/transport/chttp2/hpack_parser.h - - src/core/transport/chttp2/hpack_table.h - - src/core/transport/chttp2/http2_errors.h - - src/core/transport/chttp2/huffsyms.h - - src/core/transport/chttp2/incoming_metadata.h - - src/core/transport/chttp2/internal.h - - src/core/transport/chttp2/status_conversion.h - - src/core/transport/chttp2/stream_map.h - - src/core/transport/chttp2/timeout_encoding.h - - src/core/transport/chttp2/varint.h - - src/core/transport/chttp2_transport.h - - src/core/transport/connectivity_state.h - - src/core/transport/metadata.h - - src/core/transport/metadata_batch.h - - src/core/transport/static_metadata.h - - src/core/transport/transport.h - - src/core/transport/transport_impl.h - src: - - src/core/census/grpc_context.c - - src/core/census/grpc_filter.c - - src/core/census/grpc_plugin.c - - src/core/channel/channel_args.c - - src/core/channel/channel_stack.c - - src/core/channel/channel_stack_builder.c - - src/core/channel/client_channel.c - - src/core/channel/compress_filter.c - - src/core/channel/connected_channel.c - - src/core/channel/http_client_filter.c - - src/core/channel/http_server_filter.c - - src/core/channel/subchannel_call_holder.c - - src/core/client_config/client_config.c - - src/core/client_config/connector.c - - src/core/client_config/default_initial_connect_string.c - - src/core/client_config/initial_connect_string.c - - src/core/client_config/lb_policies/load_balancer_api.c - - src/core/client_config/lb_policies/pick_first.c - - src/core/client_config/lb_policies/round_robin.c - - src/core/client_config/lb_policy.c - - src/core/client_config/lb_policy_factory.c - - src/core/client_config/lb_policy_registry.c - - src/core/client_config/resolver.c - - src/core/client_config/resolver_factory.c - - src/core/client_config/resolver_registry.c - - src/core/client_config/resolvers/dns_resolver.c - - src/core/client_config/resolvers/sockaddr_resolver.c - - src/core/client_config/subchannel.c - - src/core/client_config/subchannel_factory.c - - src/core/client_config/subchannel_index.c - - src/core/client_config/uri_parser.c - - src/core/compression/compression_algorithm.c - - src/core/compression/message_compress.c - - src/core/debug/trace.c - - src/core/http/format_request.c - - src/core/http/httpcli.c - - src/core/http/parser.c - - src/core/iomgr/closure.c - - src/core/iomgr/endpoint.c - - src/core/iomgr/endpoint_pair_posix.c - - src/core/iomgr/endpoint_pair_windows.c - - src/core/iomgr/exec_ctx.c - - src/core/iomgr/executor.c - - src/core/iomgr/fd_posix.c - - src/core/iomgr/iocp_windows.c - - src/core/iomgr/iomgr.c - - src/core/iomgr/iomgr_posix.c - - src/core/iomgr/iomgr_windows.c - - src/core/iomgr/pollset_multipoller_with_epoll.c - - src/core/iomgr/pollset_multipoller_with_poll_posix.c - - src/core/iomgr/pollset_posix.c - - src/core/iomgr/pollset_set_posix.c - - src/core/iomgr/pollset_set_windows.c - - src/core/iomgr/pollset_windows.c - - src/core/iomgr/resolve_address_posix.c - - src/core/iomgr/resolve_address_windows.c - - src/core/iomgr/sockaddr_utils.c - - src/core/iomgr/socket_utils_common_posix.c - - src/core/iomgr/socket_utils_linux.c - - src/core/iomgr/socket_utils_posix.c - - src/core/iomgr/socket_windows.c - - src/core/iomgr/tcp_client_posix.c - - src/core/iomgr/tcp_client_windows.c - - src/core/iomgr/tcp_posix.c - - src/core/iomgr/tcp_server_posix.c - - src/core/iomgr/tcp_server_windows.c - - src/core/iomgr/tcp_windows.c - - src/core/iomgr/time_averaged_stats.c - - src/core/iomgr/timer.c - - src/core/iomgr/timer_heap.c - - src/core/iomgr/udp_server.c - - src/core/iomgr/unix_sockets_posix.c - - src/core/iomgr/unix_sockets_posix_noop.c - - src/core/iomgr/wakeup_fd_eventfd.c - - src/core/iomgr/wakeup_fd_nospecial.c - - src/core/iomgr/wakeup_fd_pipe.c - - src/core/iomgr/wakeup_fd_posix.c - - src/core/iomgr/workqueue_posix.c - - src/core/iomgr/workqueue_windows.c - - src/core/json/json.c - - src/core/json/json_reader.c - - src/core/json/json_string.c - - src/core/json/json_writer.c - - src/core/proto/grpc/lb/v0/load_balancer.pb.c - - src/core/surface/alarm.c - - src/core/surface/api_trace.c - - src/core/surface/byte_buffer.c - - src/core/surface/byte_buffer_reader.c - - src/core/surface/call.c - - src/core/surface/call_details.c - - src/core/surface/call_log_batch.c - - src/core/surface/channel.c - - src/core/surface/channel_connectivity.c - - src/core/surface/channel_create.c - - src/core/surface/channel_init.c - - src/core/surface/channel_ping.c - - src/core/surface/channel_stack_type.c - - src/core/surface/completion_queue.c - - src/core/surface/event_string.c - - src/core/surface/init.c - - src/core/surface/lame_client.c - - src/core/surface/metadata_array.c - - src/core/surface/server.c - - src/core/surface/server_chttp2.c - - src/core/surface/validate_metadata.c - - src/core/surface/version.c - - src/core/transport/byte_stream.c - - src/core/transport/chttp2/alpn.c - - src/core/transport/chttp2/bin_encoder.c - - src/core/transport/chttp2/frame_data.c - - src/core/transport/chttp2/frame_goaway.c - - src/core/transport/chttp2/frame_ping.c - - src/core/transport/chttp2/frame_rst_stream.c - - src/core/transport/chttp2/frame_settings.c - - src/core/transport/chttp2/frame_window_update.c - - src/core/transport/chttp2/hpack_encoder.c - - src/core/transport/chttp2/hpack_parser.c - - src/core/transport/chttp2/hpack_table.c - - src/core/transport/chttp2/huffsyms.c - - src/core/transport/chttp2/incoming_metadata.c - - src/core/transport/chttp2/parsing.c - - src/core/transport/chttp2/status_conversion.c - - src/core/transport/chttp2/stream_lists.c - - src/core/transport/chttp2/stream_map.c - - src/core/transport/chttp2/timeout_encoding.c - - src/core/transport/chttp2/varint.c - - src/core/transport/chttp2/writing.c - - src/core/transport/chttp2_transport.c - - src/core/transport/connectivity_state.c - - src/core/transport/metadata.c - - src/core/transport/metadata_batch.c - - src/core/transport/static_metadata.c - - src/core/transport/transport.c - - src/core/transport/transport_op_string.c + - src/core/lib/census/grpc_filter.h + - src/core/lib/census/grpc_plugin.h + - src/core/lib/channel/channel_args.h + - src/core/lib/channel/channel_stack.h + - src/core/lib/channel/channel_stack_builder.h + - src/core/lib/channel/client_channel.h + - src/core/lib/channel/compress_filter.h + - src/core/lib/channel/connected_channel.h + - src/core/lib/channel/context.h + - src/core/lib/channel/http_client_filter.h + - src/core/lib/channel/http_server_filter.h + - src/core/lib/channel/subchannel_call_holder.h + - src/core/lib/client_config/client_config.h + - src/core/lib/client_config/connector.h + - src/core/lib/client_config/initial_connect_string.h + - src/core/lib/client_config/lb_policies/load_balancer_api.h + - src/core/lib/client_config/lb_policies/pick_first.h + - src/core/lib/client_config/lb_policies/round_robin.h + - src/core/lib/client_config/lb_policy.h + - src/core/lib/client_config/lb_policy_factory.h + - src/core/lib/client_config/lb_policy_registry.h + - src/core/lib/client_config/resolver.h + - src/core/lib/client_config/resolver_factory.h + - src/core/lib/client_config/resolver_registry.h + - src/core/lib/client_config/resolvers/dns_resolver.h + - src/core/lib/client_config/resolvers/sockaddr_resolver.h + - src/core/lib/client_config/subchannel.h + - src/core/lib/client_config/subchannel_factory.h + - src/core/lib/client_config/subchannel_index.h + - src/core/lib/client_config/uri_parser.h + - src/core/lib/compression/algorithm_metadata.h + - src/core/lib/compression/message_compress.h + - src/core/lib/debug/trace.h + - src/core/lib/http/format_request.h + - src/core/lib/http/httpcli.h + - src/core/lib/http/parser.h + - src/core/lib/iomgr/closure.h + - src/core/lib/iomgr/endpoint.h + - src/core/lib/iomgr/endpoint_pair.h + - src/core/lib/iomgr/exec_ctx.h + - src/core/lib/iomgr/executor.h + - src/core/lib/iomgr/fd_posix.h + - src/core/lib/iomgr/iocp_windows.h + - src/core/lib/iomgr/iomgr.h + - src/core/lib/iomgr/iomgr_internal.h + - src/core/lib/iomgr/iomgr_posix.h + - src/core/lib/iomgr/pollset.h + - src/core/lib/iomgr/pollset_posix.h + - src/core/lib/iomgr/pollset_set.h + - src/core/lib/iomgr/pollset_set_posix.h + - src/core/lib/iomgr/pollset_set_windows.h + - src/core/lib/iomgr/pollset_windows.h + - src/core/lib/iomgr/resolve_address.h + - src/core/lib/iomgr/sockaddr.h + - src/core/lib/iomgr/sockaddr_posix.h + - src/core/lib/iomgr/sockaddr_utils.h + - src/core/lib/iomgr/sockaddr_win32.h + - src/core/lib/iomgr/socket_utils_posix.h + - src/core/lib/iomgr/socket_windows.h + - src/core/lib/iomgr/tcp_client.h + - src/core/lib/iomgr/tcp_posix.h + - src/core/lib/iomgr/tcp_server.h + - src/core/lib/iomgr/tcp_windows.h + - src/core/lib/iomgr/time_averaged_stats.h + - src/core/lib/iomgr/timer.h + - src/core/lib/iomgr/timer_heap.h + - src/core/lib/iomgr/udp_server.h + - src/core/lib/iomgr/unix_sockets_posix.h + - src/core/lib/iomgr/wakeup_fd_pipe.h + - src/core/lib/iomgr/wakeup_fd_posix.h + - src/core/lib/iomgr/workqueue.h + - src/core/lib/iomgr/workqueue_posix.h + - src/core/lib/iomgr/workqueue_windows.h + - src/core/lib/json/json.h + - src/core/lib/json/json_common.h + - src/core/lib/json/json_reader.h + - src/core/lib/json/json_writer.h + - src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h + - src/core/lib/statistics/census_interface.h + - src/core/lib/statistics/census_rpc_stats.h + - src/core/lib/surface/api_trace.h + - src/core/lib/surface/call.h + - src/core/lib/surface/call_test_only.h + - src/core/lib/surface/channel.h + - src/core/lib/surface/channel_init.h + - src/core/lib/surface/channel_stack_type.h + - src/core/lib/surface/completion_queue.h + - src/core/lib/surface/event_string.h + - src/core/lib/surface/init.h + - src/core/lib/surface/lame_client.h + - src/core/lib/surface/server.h + - src/core/lib/surface/surface_trace.h + - src/core/lib/transport/byte_stream.h + - src/core/lib/transport/chttp2/alpn.h + - src/core/lib/transport/chttp2/bin_encoder.h + - src/core/lib/transport/chttp2/frame.h + - src/core/lib/transport/chttp2/frame_data.h + - src/core/lib/transport/chttp2/frame_goaway.h + - src/core/lib/transport/chttp2/frame_ping.h + - src/core/lib/transport/chttp2/frame_rst_stream.h + - src/core/lib/transport/chttp2/frame_settings.h + - src/core/lib/transport/chttp2/frame_window_update.h + - src/core/lib/transport/chttp2/hpack_encoder.h + - src/core/lib/transport/chttp2/hpack_parser.h + - src/core/lib/transport/chttp2/hpack_table.h + - src/core/lib/transport/chttp2/http2_errors.h + - src/core/lib/transport/chttp2/huffsyms.h + - src/core/lib/transport/chttp2/incoming_metadata.h + - src/core/lib/transport/chttp2/internal.h + - src/core/lib/transport/chttp2/status_conversion.h + - src/core/lib/transport/chttp2/stream_map.h + - src/core/lib/transport/chttp2/timeout_encoding.h + - src/core/lib/transport/chttp2/varint.h + - src/core/lib/transport/chttp2_transport.h + - src/core/lib/transport/connectivity_state.h + - src/core/lib/transport/metadata.h + - src/core/lib/transport/metadata_batch.h + - src/core/lib/transport/static_metadata.h + - src/core/lib/transport/transport.h + - src/core/lib/transport/transport_impl.h + src: + - src/core/lib/census/grpc_context.c + - src/core/lib/census/grpc_filter.c + - src/core/lib/census/grpc_plugin.c + - src/core/lib/channel/channel_args.c + - src/core/lib/channel/channel_stack.c + - src/core/lib/channel/channel_stack_builder.c + - src/core/lib/channel/client_channel.c + - src/core/lib/channel/compress_filter.c + - src/core/lib/channel/connected_channel.c + - src/core/lib/channel/http_client_filter.c + - src/core/lib/channel/http_server_filter.c + - src/core/lib/channel/subchannel_call_holder.c + - src/core/lib/client_config/client_config.c + - src/core/lib/client_config/connector.c + - src/core/lib/client_config/default_initial_connect_string.c + - src/core/lib/client_config/initial_connect_string.c + - src/core/lib/client_config/lb_policies/load_balancer_api.c + - src/core/lib/client_config/lb_policies/pick_first.c + - src/core/lib/client_config/lb_policies/round_robin.c + - src/core/lib/client_config/lb_policy.c + - src/core/lib/client_config/lb_policy_factory.c + - src/core/lib/client_config/lb_policy_registry.c + - src/core/lib/client_config/resolver.c + - src/core/lib/client_config/resolver_factory.c + - src/core/lib/client_config/resolver_registry.c + - src/core/lib/client_config/resolvers/dns_resolver.c + - src/core/lib/client_config/resolvers/sockaddr_resolver.c + - src/core/lib/client_config/subchannel.c + - src/core/lib/client_config/subchannel_factory.c + - src/core/lib/client_config/subchannel_index.c + - src/core/lib/client_config/uri_parser.c + - src/core/lib/compression/compression_algorithm.c + - src/core/lib/compression/message_compress.c + - src/core/lib/debug/trace.c + - src/core/lib/http/format_request.c + - src/core/lib/http/httpcli.c + - src/core/lib/http/parser.c + - src/core/lib/iomgr/closure.c + - src/core/lib/iomgr/endpoint.c + - src/core/lib/iomgr/endpoint_pair_posix.c + - src/core/lib/iomgr/endpoint_pair_windows.c + - src/core/lib/iomgr/exec_ctx.c + - src/core/lib/iomgr/executor.c + - src/core/lib/iomgr/fd_posix.c + - src/core/lib/iomgr/iocp_windows.c + - src/core/lib/iomgr/iomgr.c + - src/core/lib/iomgr/iomgr_posix.c + - src/core/lib/iomgr/iomgr_windows.c + - src/core/lib/iomgr/pollset_multipoller_with_epoll.c + - src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c + - src/core/lib/iomgr/pollset_posix.c + - src/core/lib/iomgr/pollset_set_posix.c + - src/core/lib/iomgr/pollset_set_windows.c + - src/core/lib/iomgr/pollset_windows.c + - src/core/lib/iomgr/resolve_address_posix.c + - src/core/lib/iomgr/resolve_address_windows.c + - src/core/lib/iomgr/sockaddr_utils.c + - src/core/lib/iomgr/socket_utils_common_posix.c + - src/core/lib/iomgr/socket_utils_linux.c + - src/core/lib/iomgr/socket_utils_posix.c + - src/core/lib/iomgr/socket_windows.c + - src/core/lib/iomgr/tcp_client_posix.c + - src/core/lib/iomgr/tcp_client_windows.c + - src/core/lib/iomgr/tcp_posix.c + - src/core/lib/iomgr/tcp_server_posix.c + - src/core/lib/iomgr/tcp_server_windows.c + - src/core/lib/iomgr/tcp_windows.c + - src/core/lib/iomgr/time_averaged_stats.c + - src/core/lib/iomgr/timer.c + - src/core/lib/iomgr/timer_heap.c + - src/core/lib/iomgr/udp_server.c + - src/core/lib/iomgr/unix_sockets_posix.c + - src/core/lib/iomgr/unix_sockets_posix_noop.c + - src/core/lib/iomgr/wakeup_fd_eventfd.c + - src/core/lib/iomgr/wakeup_fd_nospecial.c + - src/core/lib/iomgr/wakeup_fd_pipe.c + - src/core/lib/iomgr/wakeup_fd_posix.c + - src/core/lib/iomgr/workqueue_posix.c + - src/core/lib/iomgr/workqueue_windows.c + - src/core/lib/json/json.c + - src/core/lib/json/json_reader.c + - src/core/lib/json/json_string.c + - src/core/lib/json/json_writer.c + - src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c + - src/core/lib/surface/alarm.c + - src/core/lib/surface/api_trace.c + - src/core/lib/surface/byte_buffer.c + - src/core/lib/surface/byte_buffer_reader.c + - src/core/lib/surface/call.c + - src/core/lib/surface/call_details.c + - src/core/lib/surface/call_log_batch.c + - src/core/lib/surface/channel.c + - src/core/lib/surface/channel_connectivity.c + - src/core/lib/surface/channel_create.c + - src/core/lib/surface/channel_init.c + - src/core/lib/surface/channel_ping.c + - src/core/lib/surface/channel_stack_type.c + - src/core/lib/surface/completion_queue.c + - src/core/lib/surface/event_string.c + - src/core/lib/surface/init.c + - src/core/lib/surface/lame_client.c + - src/core/lib/surface/metadata_array.c + - src/core/lib/surface/server.c + - src/core/lib/surface/server_chttp2.c + - src/core/lib/surface/validate_metadata.c + - src/core/lib/surface/version.c + - src/core/lib/transport/byte_stream.c + - src/core/lib/transport/chttp2/alpn.c + - src/core/lib/transport/chttp2/bin_encoder.c + - src/core/lib/transport/chttp2/frame_data.c + - src/core/lib/transport/chttp2/frame_goaway.c + - src/core/lib/transport/chttp2/frame_ping.c + - src/core/lib/transport/chttp2/frame_rst_stream.c + - src/core/lib/transport/chttp2/frame_settings.c + - src/core/lib/transport/chttp2/frame_window_update.c + - src/core/lib/transport/chttp2/hpack_encoder.c + - src/core/lib/transport/chttp2/hpack_parser.c + - src/core/lib/transport/chttp2/hpack_table.c + - src/core/lib/transport/chttp2/huffsyms.c + - src/core/lib/transport/chttp2/incoming_metadata.c + - src/core/lib/transport/chttp2/parsing.c + - src/core/lib/transport/chttp2/status_conversion.c + - src/core/lib/transport/chttp2/stream_lists.c + - src/core/lib/transport/chttp2/stream_map.c + - src/core/lib/transport/chttp2/timeout_encoding.c + - src/core/lib/transport/chttp2/varint.c + - src/core/lib/transport/chttp2/writing.c + - src/core/lib/transport/chttp2_transport.c + - src/core/lib/transport/connectivity_state.c + - src/core/lib/transport/metadata.c + - src/core/lib/transport/metadata_batch.c + - src/core/lib/transport/static_metadata.c + - src/core/lib/transport/transport.c + - src/core/lib/transport/transport_op_string.c - name: grpc_codegen public_headers: - include/grpc/impl/codegen/byte_buffer.h @@ -512,42 +512,42 @@ filegroups: - include/grpc/impl/codegen/status.h - name: grpc_secure headers: - - src/core/security/auth_filters.h - - src/core/security/b64.h - - src/core/security/credentials.h - - src/core/security/handshake.h - - src/core/security/json_token.h - - src/core/security/jwt_verifier.h - - src/core/security/secure_endpoint.h - - src/core/security/security_connector.h - - src/core/security/security_context.h - - src/core/tsi/fake_transport_security.h - - src/core/tsi/ssl_transport_security.h - - src/core/tsi/ssl_types.h - - src/core/tsi/transport_security.h - - src/core/tsi/transport_security_interface.h - src: - - src/core/http/httpcli_security_connector.c - - src/core/security/b64.c - - src/core/security/client_auth_filter.c - - src/core/security/credentials.c - - src/core/security/credentials_metadata.c - - src/core/security/credentials_posix.c - - src/core/security/credentials_win32.c - - src/core/security/google_default_credentials.c - - src/core/security/handshake.c - - src/core/security/json_token.c - - src/core/security/jwt_verifier.c - - src/core/security/secure_endpoint.c - - src/core/security/security_connector.c - - src/core/security/security_context.c - - src/core/security/server_auth_filter.c - - src/core/security/server_secure_chttp2.c - - src/core/surface/init_secure.c - - src/core/surface/secure_channel_create.c - - src/core/tsi/fake_transport_security.c - - src/core/tsi/ssl_transport_security.c - - src/core/tsi/transport_security.c + - src/core/lib/security/auth_filters.h + - src/core/lib/security/b64.h + - src/core/lib/security/credentials.h + - src/core/lib/security/handshake.h + - src/core/lib/security/json_token.h + - src/core/lib/security/jwt_verifier.h + - src/core/lib/security/secure_endpoint.h + - src/core/lib/security/security_connector.h + - src/core/lib/security/security_context.h + - src/core/lib/tsi/fake_transport_security.h + - src/core/lib/tsi/ssl_transport_security.h + - src/core/lib/tsi/ssl_types.h + - src/core/lib/tsi/transport_security.h + - src/core/lib/tsi/transport_security_interface.h + src: + - src/core/lib/http/httpcli_security_connector.c + - src/core/lib/security/b64.c + - src/core/lib/security/client_auth_filter.c + - src/core/lib/security/credentials.c + - src/core/lib/security/credentials_metadata.c + - src/core/lib/security/credentials_posix.c + - src/core/lib/security/credentials_win32.c + - src/core/lib/security/google_default_credentials.c + - src/core/lib/security/handshake.c + - src/core/lib/security/json_token.c + - src/core/lib/security/jwt_verifier.c + - src/core/lib/security/secure_endpoint.c + - src/core/lib/security/security_connector.c + - src/core/lib/security/security_context.c + - src/core/lib/security/server_auth_filter.c + - src/core/lib/security/server_secure_chttp2.c + - src/core/lib/surface/init_secure.c + - src/core/lib/surface/secure_channel_create.c + - src/core/lib/tsi/fake_transport_security.c + - src/core/lib/tsi/ssl_transport_security.c + - src/core/lib/tsi/transport_security.c - name: grpc_test_util_base headers: - test/core/end2end/cq_verifier.h @@ -683,7 +683,7 @@ libs: build: all language: c src: - - src/core/surface/init_unsecure.c + - src/core/lib/surface/init_unsecure.c deps: - gpr baselib: true @@ -702,9 +702,9 @@ libs: public_headers: - include/grpc/grpc_zookeeper.h headers: - - src/core/client_config/resolvers/zookeeper_resolver.h + - src/core/lib/client_config/resolvers/zookeeper_resolver.h src: - - src/core/client_config/resolvers/zookeeper_resolver.c + - src/core/lib/client_config/resolvers/zookeeper_resolver.c deps: - gpr - grpc diff --git a/config.m4 b/config.m4 index 8a5b2391b9..549e632cee 100644 --- a/config.m4 +++ b/config.m4 @@ -36,211 +36,211 @@ if test "$PHP_GRPC" != "no"; then src/php/ext/grpc/server.c \ src/php/ext/grpc/server_credentials.c \ src/php/ext/grpc/timeval.c \ - src/core/profiling/basic_timers.c \ - src/core/profiling/stap_timers.c \ - src/core/support/alloc.c \ - src/core/support/avl.c \ - src/core/support/backoff.c \ - src/core/support/cmdline.c \ - src/core/support/cpu_iphone.c \ - src/core/support/cpu_linux.c \ - src/core/support/cpu_posix.c \ - src/core/support/cpu_windows.c \ - src/core/support/env_linux.c \ - src/core/support/env_posix.c \ - src/core/support/env_win32.c \ - src/core/support/histogram.c \ - src/core/support/host_port.c \ - src/core/support/load_file.c \ - src/core/support/log.c \ - src/core/support/log_android.c \ - src/core/support/log_linux.c \ - src/core/support/log_posix.c \ - src/core/support/log_win32.c \ - src/core/support/murmur_hash.c \ - src/core/support/slice.c \ - src/core/support/slice_buffer.c \ - src/core/support/stack_lockfree.c \ - src/core/support/string.c \ - src/core/support/string_posix.c \ - src/core/support/string_win32.c \ - src/core/support/subprocess_posix.c \ - src/core/support/subprocess_windows.c \ - src/core/support/sync.c \ - src/core/support/sync_posix.c \ - src/core/support/sync_win32.c \ - src/core/support/thd.c \ - src/core/support/thd_posix.c \ - src/core/support/thd_win32.c \ - src/core/support/time.c \ - src/core/support/time_posix.c \ - src/core/support/time_precise.c \ - src/core/support/time_win32.c \ - src/core/support/tls_pthread.c \ - src/core/support/tmpfile_posix.c \ - src/core/support/tmpfile_win32.c \ - src/core/support/wrap_memcpy.c \ - src/core/census/grpc_context.c \ - src/core/census/grpc_filter.c \ - src/core/census/grpc_plugin.c \ - src/core/channel/channel_args.c \ - src/core/channel/channel_stack.c \ - src/core/channel/channel_stack_builder.c \ - src/core/channel/client_channel.c \ - src/core/channel/compress_filter.c \ - src/core/channel/connected_channel.c \ - src/core/channel/http_client_filter.c \ - src/core/channel/http_server_filter.c \ - src/core/channel/subchannel_call_holder.c \ - src/core/client_config/client_config.c \ - src/core/client_config/connector.c \ - src/core/client_config/default_initial_connect_string.c \ - src/core/client_config/initial_connect_string.c \ - src/core/client_config/lb_policies/load_balancer_api.c \ - src/core/client_config/lb_policies/pick_first.c \ - src/core/client_config/lb_policies/round_robin.c \ - src/core/client_config/lb_policy.c \ - src/core/client_config/lb_policy_factory.c \ - src/core/client_config/lb_policy_registry.c \ - src/core/client_config/resolver.c \ - src/core/client_config/resolver_factory.c \ - src/core/client_config/resolver_registry.c \ - src/core/client_config/resolvers/dns_resolver.c \ - src/core/client_config/resolvers/sockaddr_resolver.c \ - src/core/client_config/subchannel.c \ - src/core/client_config/subchannel_factory.c \ - src/core/client_config/subchannel_index.c \ - src/core/client_config/uri_parser.c \ - src/core/compression/compression_algorithm.c \ - src/core/compression/message_compress.c \ - src/core/debug/trace.c \ - src/core/http/format_request.c \ - src/core/http/httpcli.c \ - src/core/http/parser.c \ - src/core/iomgr/closure.c \ - src/core/iomgr/endpoint.c \ - src/core/iomgr/endpoint_pair_posix.c \ - src/core/iomgr/endpoint_pair_windows.c \ - src/core/iomgr/exec_ctx.c \ - src/core/iomgr/executor.c \ - src/core/iomgr/fd_posix.c \ - src/core/iomgr/iocp_windows.c \ - src/core/iomgr/iomgr.c \ - src/core/iomgr/iomgr_posix.c \ - src/core/iomgr/iomgr_windows.c \ - src/core/iomgr/pollset_multipoller_with_epoll.c \ - src/core/iomgr/pollset_multipoller_with_poll_posix.c \ - src/core/iomgr/pollset_posix.c \ - src/core/iomgr/pollset_set_posix.c \ - src/core/iomgr/pollset_set_windows.c \ - src/core/iomgr/pollset_windows.c \ - src/core/iomgr/resolve_address_posix.c \ - src/core/iomgr/resolve_address_windows.c \ - src/core/iomgr/sockaddr_utils.c \ - src/core/iomgr/socket_utils_common_posix.c \ - src/core/iomgr/socket_utils_linux.c \ - src/core/iomgr/socket_utils_posix.c \ - src/core/iomgr/socket_windows.c \ - src/core/iomgr/tcp_client_posix.c \ - src/core/iomgr/tcp_client_windows.c \ - src/core/iomgr/tcp_posix.c \ - src/core/iomgr/tcp_server_posix.c \ - src/core/iomgr/tcp_server_windows.c \ - src/core/iomgr/tcp_windows.c \ - src/core/iomgr/time_averaged_stats.c \ - src/core/iomgr/timer.c \ - src/core/iomgr/timer_heap.c \ - src/core/iomgr/udp_server.c \ - src/core/iomgr/unix_sockets_posix.c \ - src/core/iomgr/unix_sockets_posix_noop.c \ - src/core/iomgr/wakeup_fd_eventfd.c \ - src/core/iomgr/wakeup_fd_nospecial.c \ - src/core/iomgr/wakeup_fd_pipe.c \ - src/core/iomgr/wakeup_fd_posix.c \ - src/core/iomgr/workqueue_posix.c \ - src/core/iomgr/workqueue_windows.c \ - src/core/json/json.c \ - src/core/json/json_reader.c \ - src/core/json/json_string.c \ - src/core/json/json_writer.c \ - src/core/proto/grpc/lb/v0/load_balancer.pb.c \ - src/core/surface/alarm.c \ - src/core/surface/api_trace.c \ - src/core/surface/byte_buffer.c \ - src/core/surface/byte_buffer_reader.c \ - src/core/surface/call.c \ - src/core/surface/call_details.c \ - src/core/surface/call_log_batch.c \ - src/core/surface/channel.c \ - src/core/surface/channel_connectivity.c \ - src/core/surface/channel_create.c \ - src/core/surface/channel_init.c \ - src/core/surface/channel_ping.c \ - src/core/surface/channel_stack_type.c \ - src/core/surface/completion_queue.c \ - src/core/surface/event_string.c \ - src/core/surface/init.c \ - src/core/surface/lame_client.c \ - src/core/surface/metadata_array.c \ - src/core/surface/server.c \ - src/core/surface/server_chttp2.c \ - src/core/surface/validate_metadata.c \ - src/core/surface/version.c \ - src/core/transport/byte_stream.c \ - src/core/transport/chttp2/alpn.c \ - src/core/transport/chttp2/bin_encoder.c \ - src/core/transport/chttp2/frame_data.c \ - src/core/transport/chttp2/frame_goaway.c \ - src/core/transport/chttp2/frame_ping.c \ - src/core/transport/chttp2/frame_rst_stream.c \ - src/core/transport/chttp2/frame_settings.c \ - src/core/transport/chttp2/frame_window_update.c \ - src/core/transport/chttp2/hpack_encoder.c \ - src/core/transport/chttp2/hpack_parser.c \ - src/core/transport/chttp2/hpack_table.c \ - src/core/transport/chttp2/huffsyms.c \ - src/core/transport/chttp2/incoming_metadata.c \ - src/core/transport/chttp2/parsing.c \ - src/core/transport/chttp2/status_conversion.c \ - src/core/transport/chttp2/stream_lists.c \ - src/core/transport/chttp2/stream_map.c \ - src/core/transport/chttp2/timeout_encoding.c \ - src/core/transport/chttp2/varint.c \ - src/core/transport/chttp2/writing.c \ - src/core/transport/chttp2_transport.c \ - src/core/transport/connectivity_state.c \ - src/core/transport/metadata.c \ - src/core/transport/metadata_batch.c \ - src/core/transport/static_metadata.c \ - src/core/transport/transport.c \ - src/core/transport/transport_op_string.c \ - src/core/http/httpcli_security_connector.c \ - src/core/security/b64.c \ - src/core/security/client_auth_filter.c \ - src/core/security/credentials.c \ - src/core/security/credentials_metadata.c \ - src/core/security/credentials_posix.c \ - src/core/security/credentials_win32.c \ - src/core/security/google_default_credentials.c \ - src/core/security/handshake.c \ - src/core/security/json_token.c \ - src/core/security/jwt_verifier.c \ - src/core/security/secure_endpoint.c \ - src/core/security/security_connector.c \ - src/core/security/security_context.c \ - src/core/security/server_auth_filter.c \ - src/core/security/server_secure_chttp2.c \ - src/core/surface/init_secure.c \ - src/core/surface/secure_channel_create.c \ - src/core/tsi/fake_transport_security.c \ - src/core/tsi/ssl_transport_security.c \ - src/core/tsi/transport_security.c \ - src/core/census/context.c \ - src/core/census/initialize.c \ - src/core/census/mlog.c \ - src/core/census/operation.c \ - src/core/census/placeholders.c \ - src/core/census/tracing.c \ + src/core/lib/profiling/basic_timers.c \ + src/core/lib/profiling/stap_timers.c \ + src/core/lib/support/alloc.c \ + src/core/lib/support/avl.c \ + src/core/lib/support/backoff.c \ + src/core/lib/support/cmdline.c \ + src/core/lib/support/cpu_iphone.c \ + src/core/lib/support/cpu_linux.c \ + src/core/lib/support/cpu_posix.c \ + src/core/lib/support/cpu_windows.c \ + src/core/lib/support/env_linux.c \ + src/core/lib/support/env_posix.c \ + src/core/lib/support/env_win32.c \ + src/core/lib/support/histogram.c \ + src/core/lib/support/host_port.c \ + src/core/lib/support/load_file.c \ + src/core/lib/support/log.c \ + src/core/lib/support/log_android.c \ + src/core/lib/support/log_linux.c \ + src/core/lib/support/log_posix.c \ + src/core/lib/support/log_win32.c \ + src/core/lib/support/murmur_hash.c \ + src/core/lib/support/slice.c \ + src/core/lib/support/slice_buffer.c \ + src/core/lib/support/stack_lockfree.c \ + src/core/lib/support/string.c \ + src/core/lib/support/string_posix.c \ + src/core/lib/support/string_win32.c \ + src/core/lib/support/subprocess_posix.c \ + src/core/lib/support/subprocess_windows.c \ + src/core/lib/support/sync.c \ + src/core/lib/support/sync_posix.c \ + src/core/lib/support/sync_win32.c \ + src/core/lib/support/thd.c \ + src/core/lib/support/thd_posix.c \ + src/core/lib/support/thd_win32.c \ + src/core/lib/support/time.c \ + src/core/lib/support/time_posix.c \ + src/core/lib/support/time_precise.c \ + src/core/lib/support/time_win32.c \ + src/core/lib/support/tls_pthread.c \ + src/core/lib/support/tmpfile_posix.c \ + src/core/lib/support/tmpfile_win32.c \ + src/core/lib/support/wrap_memcpy.c \ + src/core/lib/census/grpc_context.c \ + src/core/lib/census/grpc_filter.c \ + src/core/lib/census/grpc_plugin.c \ + src/core/lib/channel/channel_args.c \ + src/core/lib/channel/channel_stack.c \ + src/core/lib/channel/channel_stack_builder.c \ + src/core/lib/channel/client_channel.c \ + src/core/lib/channel/compress_filter.c \ + src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/http_client_filter.c \ + src/core/lib/channel/http_server_filter.c \ + src/core/lib/channel/subchannel_call_holder.c \ + src/core/lib/client_config/client_config.c \ + src/core/lib/client_config/connector.c \ + src/core/lib/client_config/default_initial_connect_string.c \ + src/core/lib/client_config/initial_connect_string.c \ + src/core/lib/client_config/lb_policies/load_balancer_api.c \ + src/core/lib/client_config/lb_policies/pick_first.c \ + src/core/lib/client_config/lb_policies/round_robin.c \ + src/core/lib/client_config/lb_policy.c \ + src/core/lib/client_config/lb_policy_factory.c \ + src/core/lib/client_config/lb_policy_registry.c \ + src/core/lib/client_config/resolver.c \ + src/core/lib/client_config/resolver_factory.c \ + src/core/lib/client_config/resolver_registry.c \ + src/core/lib/client_config/resolvers/dns_resolver.c \ + src/core/lib/client_config/resolvers/sockaddr_resolver.c \ + src/core/lib/client_config/subchannel.c \ + src/core/lib/client_config/subchannel_factory.c \ + src/core/lib/client_config/subchannel_index.c \ + src/core/lib/client_config/uri_parser.c \ + src/core/lib/compression/compression_algorithm.c \ + src/core/lib/compression/message_compress.c \ + src/core/lib/debug/trace.c \ + src/core/lib/http/format_request.c \ + src/core/lib/http/httpcli.c \ + src/core/lib/http/parser.c \ + src/core/lib/iomgr/closure.c \ + src/core/lib/iomgr/endpoint.c \ + src/core/lib/iomgr/endpoint_pair_posix.c \ + src/core/lib/iomgr/endpoint_pair_windows.c \ + src/core/lib/iomgr/exec_ctx.c \ + src/core/lib/iomgr/executor.c \ + src/core/lib/iomgr/fd_posix.c \ + src/core/lib/iomgr/iocp_windows.c \ + src/core/lib/iomgr/iomgr.c \ + src/core/lib/iomgr/iomgr_posix.c \ + src/core/lib/iomgr/iomgr_windows.c \ + src/core/lib/iomgr/pollset_multipoller_with_epoll.c \ + src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c \ + src/core/lib/iomgr/pollset_posix.c \ + src/core/lib/iomgr/pollset_set_posix.c \ + src/core/lib/iomgr/pollset_set_windows.c \ + src/core/lib/iomgr/pollset_windows.c \ + src/core/lib/iomgr/resolve_address_posix.c \ + src/core/lib/iomgr/resolve_address_windows.c \ + src/core/lib/iomgr/sockaddr_utils.c \ + src/core/lib/iomgr/socket_utils_common_posix.c \ + src/core/lib/iomgr/socket_utils_linux.c \ + src/core/lib/iomgr/socket_utils_posix.c \ + src/core/lib/iomgr/socket_windows.c \ + src/core/lib/iomgr/tcp_client_posix.c \ + src/core/lib/iomgr/tcp_client_windows.c \ + src/core/lib/iomgr/tcp_posix.c \ + src/core/lib/iomgr/tcp_server_posix.c \ + src/core/lib/iomgr/tcp_server_windows.c \ + src/core/lib/iomgr/tcp_windows.c \ + src/core/lib/iomgr/time_averaged_stats.c \ + src/core/lib/iomgr/timer.c \ + src/core/lib/iomgr/timer_heap.c \ + src/core/lib/iomgr/udp_server.c \ + src/core/lib/iomgr/unix_sockets_posix.c \ + src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_eventfd.c \ + src/core/lib/iomgr/wakeup_fd_nospecial.c \ + src/core/lib/iomgr/wakeup_fd_pipe.c \ + src/core/lib/iomgr/wakeup_fd_posix.c \ + src/core/lib/iomgr/workqueue_posix.c \ + src/core/lib/iomgr/workqueue_windows.c \ + src/core/lib/json/json.c \ + src/core/lib/json/json_reader.c \ + src/core/lib/json/json_string.c \ + src/core/lib/json/json_writer.c \ + src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c \ + src/core/lib/surface/alarm.c \ + src/core/lib/surface/api_trace.c \ + src/core/lib/surface/byte_buffer.c \ + src/core/lib/surface/byte_buffer_reader.c \ + src/core/lib/surface/call.c \ + src/core/lib/surface/call_details.c \ + src/core/lib/surface/call_log_batch.c \ + src/core/lib/surface/channel.c \ + src/core/lib/surface/channel_connectivity.c \ + src/core/lib/surface/channel_create.c \ + src/core/lib/surface/channel_init.c \ + src/core/lib/surface/channel_ping.c \ + src/core/lib/surface/channel_stack_type.c \ + src/core/lib/surface/completion_queue.c \ + src/core/lib/surface/event_string.c \ + src/core/lib/surface/init.c \ + src/core/lib/surface/lame_client.c \ + src/core/lib/surface/metadata_array.c \ + src/core/lib/surface/server.c \ + src/core/lib/surface/server_chttp2.c \ + src/core/lib/surface/validate_metadata.c \ + src/core/lib/surface/version.c \ + src/core/lib/transport/byte_stream.c \ + src/core/lib/transport/chttp2/alpn.c \ + src/core/lib/transport/chttp2/bin_encoder.c \ + src/core/lib/transport/chttp2/frame_data.c \ + src/core/lib/transport/chttp2/frame_goaway.c \ + src/core/lib/transport/chttp2/frame_ping.c \ + src/core/lib/transport/chttp2/frame_rst_stream.c \ + src/core/lib/transport/chttp2/frame_settings.c \ + src/core/lib/transport/chttp2/frame_window_update.c \ + src/core/lib/transport/chttp2/hpack_encoder.c \ + src/core/lib/transport/chttp2/hpack_parser.c \ + src/core/lib/transport/chttp2/hpack_table.c \ + src/core/lib/transport/chttp2/huffsyms.c \ + src/core/lib/transport/chttp2/incoming_metadata.c \ + src/core/lib/transport/chttp2/parsing.c \ + src/core/lib/transport/chttp2/status_conversion.c \ + src/core/lib/transport/chttp2/stream_lists.c \ + src/core/lib/transport/chttp2/stream_map.c \ + src/core/lib/transport/chttp2/timeout_encoding.c \ + src/core/lib/transport/chttp2/varint.c \ + src/core/lib/transport/chttp2/writing.c \ + src/core/lib/transport/chttp2_transport.c \ + src/core/lib/transport/connectivity_state.c \ + src/core/lib/transport/metadata.c \ + src/core/lib/transport/metadata_batch.c \ + src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/transport.c \ + src/core/lib/transport/transport_op_string.c \ + src/core/lib/http/httpcli_security_connector.c \ + src/core/lib/security/b64.c \ + src/core/lib/security/client_auth_filter.c \ + src/core/lib/security/credentials.c \ + src/core/lib/security/credentials_metadata.c \ + src/core/lib/security/credentials_posix.c \ + src/core/lib/security/credentials_win32.c \ + src/core/lib/security/google_default_credentials.c \ + src/core/lib/security/handshake.c \ + src/core/lib/security/json_token.c \ + src/core/lib/security/jwt_verifier.c \ + src/core/lib/security/secure_endpoint.c \ + src/core/lib/security/security_connector.c \ + src/core/lib/security/security_context.c \ + src/core/lib/security/server_auth_filter.c \ + src/core/lib/security/server_secure_chttp2.c \ + src/core/lib/surface/init_secure.c \ + src/core/lib/surface/secure_channel_create.c \ + src/core/lib/tsi/fake_transport_security.c \ + src/core/lib/tsi/ssl_transport_security.c \ + src/core/lib/tsi/transport_security.c \ + src/core/lib/census/context.c \ + src/core/lib/census/initialize.c \ + src/core/lib/census/mlog.c \ + src/core/lib/census/operation.c \ + src/core/lib/census/placeholders.c \ + src/core/lib/census/tracing.c \ third_party/nanopb/pb_common.c \ third_party/nanopb/pb_decode.c \ third_party/nanopb/pb_encode.c \ @@ -546,24 +546,24 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc) PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/census) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/channel) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/client_config) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/client_config/lb_policies) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/client_config/resolvers) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/compression) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/debug) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/http) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/iomgr) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/json) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/profiling) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/proto/grpc/lb/v0) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/security) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/support) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/surface) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/transport) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/transport/chttp2) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/tsi) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/census) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/channel) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/client_config) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/client_config/lb_policies) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/client_config/resolvers) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/compression) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/debug) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/http) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/json) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/profiling) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/proto/grpc/lb/v0) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/support) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/surface) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/transport) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/transport/chttp2) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/tsi) PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto) PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/aes) PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/asn1) diff --git a/gRPC.podspec b/gRPC.podspec index 2a3ed15141..3d5e8af15f 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -63,18 +63,18 @@ Pod::Spec.new do |s| # Core cross-platform gRPC library, written in C. s.subspec 'C-Core' do |ss| - ss.source_files = 'src/core/profiling/timers.h', - 'src/core/support/backoff.h', - 'src/core/support/block_annotate.h', - 'src/core/support/env.h', - 'src/core/support/load_file.h', - 'src/core/support/murmur_hash.h', - 'src/core/support/stack_lockfree.h', - 'src/core/support/string.h', - 'src/core/support/string_win32.h', - 'src/core/support/thd_internal.h', - 'src/core/support/time_precise.h', - 'src/core/support/tmpfile.h', + ss.source_files = 'src/core/lib/profiling/timers.h', + 'src/core/lib/support/backoff.h', + 'src/core/lib/support/block_annotate.h', + 'src/core/lib/support/env.h', + 'src/core/lib/support/load_file.h', + 'src/core/lib/support/murmur_hash.h', + 'src/core/lib/support/stack_lockfree.h', + 'src/core/lib/support/string.h', + 'src/core/lib/support/string_win32.h', + 'src/core/lib/support/thd_internal.h', + 'src/core/lib/support/time_precise.h', + 'src/core/lib/support/tmpfile.h', 'include/grpc/support/alloc.h', 'include/grpc/support/atm.h', 'include/grpc/support/atm_gcc_atomic.h', @@ -117,187 +117,187 @@ Pod::Spec.new do |s| 'include/grpc/impl/codegen/sync_posix.h', 'include/grpc/impl/codegen/sync_win32.h', 'include/grpc/impl/codegen/time.h', - 'src/core/profiling/basic_timers.c', - 'src/core/profiling/stap_timers.c', - 'src/core/support/alloc.c', - 'src/core/support/avl.c', - 'src/core/support/backoff.c', - 'src/core/support/cmdline.c', - 'src/core/support/cpu_iphone.c', - 'src/core/support/cpu_linux.c', - 'src/core/support/cpu_posix.c', - 'src/core/support/cpu_windows.c', - 'src/core/support/env_linux.c', - 'src/core/support/env_posix.c', - 'src/core/support/env_win32.c', - 'src/core/support/histogram.c', - 'src/core/support/host_port.c', - 'src/core/support/load_file.c', - 'src/core/support/log.c', - 'src/core/support/log_android.c', - 'src/core/support/log_linux.c', - 'src/core/support/log_posix.c', - 'src/core/support/log_win32.c', - 'src/core/support/murmur_hash.c', - 'src/core/support/slice.c', - 'src/core/support/slice_buffer.c', - 'src/core/support/stack_lockfree.c', - 'src/core/support/string.c', - 'src/core/support/string_posix.c', - 'src/core/support/string_win32.c', - 'src/core/support/subprocess_posix.c', - 'src/core/support/subprocess_windows.c', - 'src/core/support/sync.c', - 'src/core/support/sync_posix.c', - 'src/core/support/sync_win32.c', - 'src/core/support/thd.c', - 'src/core/support/thd_posix.c', - 'src/core/support/thd_win32.c', - 'src/core/support/time.c', - 'src/core/support/time_posix.c', - 'src/core/support/time_precise.c', - 'src/core/support/time_win32.c', - 'src/core/support/tls_pthread.c', - 'src/core/support/tmpfile_posix.c', - 'src/core/support/tmpfile_win32.c', - 'src/core/support/wrap_memcpy.c', - 'src/core/census/grpc_filter.h', - 'src/core/census/grpc_plugin.h', - 'src/core/channel/channel_args.h', - 'src/core/channel/channel_stack.h', - 'src/core/channel/channel_stack_builder.h', - 'src/core/channel/client_channel.h', - 'src/core/channel/compress_filter.h', - 'src/core/channel/connected_channel.h', - 'src/core/channel/context.h', - 'src/core/channel/http_client_filter.h', - 'src/core/channel/http_server_filter.h', - 'src/core/channel/subchannel_call_holder.h', - 'src/core/client_config/client_config.h', - 'src/core/client_config/connector.h', - 'src/core/client_config/initial_connect_string.h', - 'src/core/client_config/lb_policies/load_balancer_api.h', - 'src/core/client_config/lb_policies/pick_first.h', - 'src/core/client_config/lb_policies/round_robin.h', - 'src/core/client_config/lb_policy.h', - 'src/core/client_config/lb_policy_factory.h', - 'src/core/client_config/lb_policy_registry.h', - 'src/core/client_config/resolver.h', - 'src/core/client_config/resolver_factory.h', - 'src/core/client_config/resolver_registry.h', - 'src/core/client_config/resolvers/dns_resolver.h', - 'src/core/client_config/resolvers/sockaddr_resolver.h', - 'src/core/client_config/subchannel.h', - 'src/core/client_config/subchannel_factory.h', - 'src/core/client_config/subchannel_index.h', - 'src/core/client_config/uri_parser.h', - 'src/core/compression/algorithm_metadata.h', - 'src/core/compression/message_compress.h', - 'src/core/debug/trace.h', - 'src/core/http/format_request.h', - 'src/core/http/httpcli.h', - 'src/core/http/parser.h', - 'src/core/iomgr/closure.h', - 'src/core/iomgr/endpoint.h', - 'src/core/iomgr/endpoint_pair.h', - 'src/core/iomgr/exec_ctx.h', - 'src/core/iomgr/executor.h', - 'src/core/iomgr/fd_posix.h', - 'src/core/iomgr/iocp_windows.h', - 'src/core/iomgr/iomgr.h', - 'src/core/iomgr/iomgr_internal.h', - 'src/core/iomgr/iomgr_posix.h', - 'src/core/iomgr/pollset.h', - 'src/core/iomgr/pollset_posix.h', - 'src/core/iomgr/pollset_set.h', - 'src/core/iomgr/pollset_set_posix.h', - 'src/core/iomgr/pollset_set_windows.h', - 'src/core/iomgr/pollset_windows.h', - 'src/core/iomgr/resolve_address.h', - 'src/core/iomgr/sockaddr.h', - 'src/core/iomgr/sockaddr_posix.h', - 'src/core/iomgr/sockaddr_utils.h', - 'src/core/iomgr/sockaddr_win32.h', - 'src/core/iomgr/socket_utils_posix.h', - 'src/core/iomgr/socket_windows.h', - 'src/core/iomgr/tcp_client.h', - 'src/core/iomgr/tcp_posix.h', - 'src/core/iomgr/tcp_server.h', - 'src/core/iomgr/tcp_windows.h', - 'src/core/iomgr/time_averaged_stats.h', - 'src/core/iomgr/timer.h', - 'src/core/iomgr/timer_heap.h', - 'src/core/iomgr/udp_server.h', - 'src/core/iomgr/unix_sockets_posix.h', - 'src/core/iomgr/wakeup_fd_pipe.h', - 'src/core/iomgr/wakeup_fd_posix.h', - 'src/core/iomgr/workqueue.h', - 'src/core/iomgr/workqueue_posix.h', - 'src/core/iomgr/workqueue_windows.h', - 'src/core/json/json.h', - 'src/core/json/json_common.h', - 'src/core/json/json_reader.h', - 'src/core/json/json_writer.h', - 'src/core/proto/grpc/lb/v0/load_balancer.pb.h', - 'src/core/statistics/census_interface.h', - 'src/core/statistics/census_rpc_stats.h', - 'src/core/surface/api_trace.h', - 'src/core/surface/call.h', - 'src/core/surface/call_test_only.h', - 'src/core/surface/channel.h', - 'src/core/surface/channel_init.h', - 'src/core/surface/channel_stack_type.h', - 'src/core/surface/completion_queue.h', - 'src/core/surface/event_string.h', - 'src/core/surface/init.h', - 'src/core/surface/lame_client.h', - 'src/core/surface/server.h', - 'src/core/surface/surface_trace.h', - 'src/core/transport/byte_stream.h', - 'src/core/transport/chttp2/alpn.h', - 'src/core/transport/chttp2/bin_encoder.h', - 'src/core/transport/chttp2/frame.h', - 'src/core/transport/chttp2/frame_data.h', - 'src/core/transport/chttp2/frame_goaway.h', - 'src/core/transport/chttp2/frame_ping.h', - 'src/core/transport/chttp2/frame_rst_stream.h', - 'src/core/transport/chttp2/frame_settings.h', - 'src/core/transport/chttp2/frame_window_update.h', - 'src/core/transport/chttp2/hpack_encoder.h', - 'src/core/transport/chttp2/hpack_parser.h', - 'src/core/transport/chttp2/hpack_table.h', - 'src/core/transport/chttp2/http2_errors.h', - 'src/core/transport/chttp2/huffsyms.h', - 'src/core/transport/chttp2/incoming_metadata.h', - 'src/core/transport/chttp2/internal.h', - 'src/core/transport/chttp2/status_conversion.h', - 'src/core/transport/chttp2/stream_map.h', - 'src/core/transport/chttp2/timeout_encoding.h', - 'src/core/transport/chttp2/varint.h', - 'src/core/transport/chttp2_transport.h', - 'src/core/transport/connectivity_state.h', - 'src/core/transport/metadata.h', - 'src/core/transport/metadata_batch.h', - 'src/core/transport/static_metadata.h', - 'src/core/transport/transport.h', - 'src/core/transport/transport_impl.h', - 'src/core/security/auth_filters.h', - 'src/core/security/b64.h', - 'src/core/security/credentials.h', - 'src/core/security/handshake.h', - 'src/core/security/json_token.h', - 'src/core/security/jwt_verifier.h', - 'src/core/security/secure_endpoint.h', - 'src/core/security/security_connector.h', - 'src/core/security/security_context.h', - 'src/core/tsi/fake_transport_security.h', - 'src/core/tsi/ssl_transport_security.h', - 'src/core/tsi/ssl_types.h', - 'src/core/tsi/transport_security.h', - 'src/core/tsi/transport_security_interface.h', - 'src/core/census/aggregation.h', - 'src/core/census/mlog.h', - 'src/core/census/rpc_metric_id.h', + 'src/core/lib/profiling/basic_timers.c', + 'src/core/lib/profiling/stap_timers.c', + 'src/core/lib/support/alloc.c', + 'src/core/lib/support/avl.c', + 'src/core/lib/support/backoff.c', + 'src/core/lib/support/cmdline.c', + 'src/core/lib/support/cpu_iphone.c', + 'src/core/lib/support/cpu_linux.c', + 'src/core/lib/support/cpu_posix.c', + 'src/core/lib/support/cpu_windows.c', + 'src/core/lib/support/env_linux.c', + 'src/core/lib/support/env_posix.c', + 'src/core/lib/support/env_win32.c', + 'src/core/lib/support/histogram.c', + 'src/core/lib/support/host_port.c', + 'src/core/lib/support/load_file.c', + 'src/core/lib/support/log.c', + 'src/core/lib/support/log_android.c', + 'src/core/lib/support/log_linux.c', + 'src/core/lib/support/log_posix.c', + 'src/core/lib/support/log_win32.c', + 'src/core/lib/support/murmur_hash.c', + 'src/core/lib/support/slice.c', + 'src/core/lib/support/slice_buffer.c', + 'src/core/lib/support/stack_lockfree.c', + 'src/core/lib/support/string.c', + 'src/core/lib/support/string_posix.c', + 'src/core/lib/support/string_win32.c', + 'src/core/lib/support/subprocess_posix.c', + 'src/core/lib/support/subprocess_windows.c', + 'src/core/lib/support/sync.c', + 'src/core/lib/support/sync_posix.c', + 'src/core/lib/support/sync_win32.c', + 'src/core/lib/support/thd.c', + 'src/core/lib/support/thd_posix.c', + 'src/core/lib/support/thd_win32.c', + 'src/core/lib/support/time.c', + 'src/core/lib/support/time_posix.c', + 'src/core/lib/support/time_precise.c', + 'src/core/lib/support/time_win32.c', + 'src/core/lib/support/tls_pthread.c', + 'src/core/lib/support/tmpfile_posix.c', + 'src/core/lib/support/tmpfile_win32.c', + 'src/core/lib/support/wrap_memcpy.c', + 'src/core/lib/census/grpc_filter.h', + 'src/core/lib/census/grpc_plugin.h', + 'src/core/lib/channel/channel_args.h', + 'src/core/lib/channel/channel_stack.h', + 'src/core/lib/channel/channel_stack_builder.h', + 'src/core/lib/channel/client_channel.h', + 'src/core/lib/channel/compress_filter.h', + 'src/core/lib/channel/connected_channel.h', + 'src/core/lib/channel/context.h', + 'src/core/lib/channel/http_client_filter.h', + 'src/core/lib/channel/http_server_filter.h', + 'src/core/lib/channel/subchannel_call_holder.h', + 'src/core/lib/client_config/client_config.h', + 'src/core/lib/client_config/connector.h', + 'src/core/lib/client_config/initial_connect_string.h', + 'src/core/lib/client_config/lb_policies/load_balancer_api.h', + 'src/core/lib/client_config/lb_policies/pick_first.h', + 'src/core/lib/client_config/lb_policies/round_robin.h', + 'src/core/lib/client_config/lb_policy.h', + 'src/core/lib/client_config/lb_policy_factory.h', + 'src/core/lib/client_config/lb_policy_registry.h', + 'src/core/lib/client_config/resolver.h', + 'src/core/lib/client_config/resolver_factory.h', + 'src/core/lib/client_config/resolver_registry.h', + 'src/core/lib/client_config/resolvers/dns_resolver.h', + 'src/core/lib/client_config/resolvers/sockaddr_resolver.h', + 'src/core/lib/client_config/subchannel.h', + 'src/core/lib/client_config/subchannel_factory.h', + 'src/core/lib/client_config/subchannel_index.h', + 'src/core/lib/client_config/uri_parser.h', + 'src/core/lib/compression/algorithm_metadata.h', + 'src/core/lib/compression/message_compress.h', + 'src/core/lib/debug/trace.h', + 'src/core/lib/http/format_request.h', + 'src/core/lib/http/httpcli.h', + 'src/core/lib/http/parser.h', + 'src/core/lib/iomgr/closure.h', + 'src/core/lib/iomgr/endpoint.h', + 'src/core/lib/iomgr/endpoint_pair.h', + 'src/core/lib/iomgr/exec_ctx.h', + 'src/core/lib/iomgr/executor.h', + 'src/core/lib/iomgr/fd_posix.h', + 'src/core/lib/iomgr/iocp_windows.h', + 'src/core/lib/iomgr/iomgr.h', + 'src/core/lib/iomgr/iomgr_internal.h', + 'src/core/lib/iomgr/iomgr_posix.h', + 'src/core/lib/iomgr/pollset.h', + 'src/core/lib/iomgr/pollset_posix.h', + 'src/core/lib/iomgr/pollset_set.h', + 'src/core/lib/iomgr/pollset_set_posix.h', + 'src/core/lib/iomgr/pollset_set_windows.h', + 'src/core/lib/iomgr/pollset_windows.h', + 'src/core/lib/iomgr/resolve_address.h', + 'src/core/lib/iomgr/sockaddr.h', + 'src/core/lib/iomgr/sockaddr_posix.h', + 'src/core/lib/iomgr/sockaddr_utils.h', + 'src/core/lib/iomgr/sockaddr_win32.h', + 'src/core/lib/iomgr/socket_utils_posix.h', + 'src/core/lib/iomgr/socket_windows.h', + 'src/core/lib/iomgr/tcp_client.h', + 'src/core/lib/iomgr/tcp_posix.h', + 'src/core/lib/iomgr/tcp_server.h', + 'src/core/lib/iomgr/tcp_windows.h', + 'src/core/lib/iomgr/time_averaged_stats.h', + 'src/core/lib/iomgr/timer.h', + 'src/core/lib/iomgr/timer_heap.h', + 'src/core/lib/iomgr/udp_server.h', + 'src/core/lib/iomgr/unix_sockets_posix.h', + 'src/core/lib/iomgr/wakeup_fd_pipe.h', + 'src/core/lib/iomgr/wakeup_fd_posix.h', + 'src/core/lib/iomgr/workqueue.h', + 'src/core/lib/iomgr/workqueue_posix.h', + 'src/core/lib/iomgr/workqueue_windows.h', + 'src/core/lib/json/json.h', + 'src/core/lib/json/json_common.h', + 'src/core/lib/json/json_reader.h', + 'src/core/lib/json/json_writer.h', + 'src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h', + 'src/core/lib/statistics/census_interface.h', + 'src/core/lib/statistics/census_rpc_stats.h', + 'src/core/lib/surface/api_trace.h', + 'src/core/lib/surface/call.h', + 'src/core/lib/surface/call_test_only.h', + 'src/core/lib/surface/channel.h', + 'src/core/lib/surface/channel_init.h', + 'src/core/lib/surface/channel_stack_type.h', + 'src/core/lib/surface/completion_queue.h', + 'src/core/lib/surface/event_string.h', + 'src/core/lib/surface/init.h', + 'src/core/lib/surface/lame_client.h', + 'src/core/lib/surface/server.h', + 'src/core/lib/surface/surface_trace.h', + 'src/core/lib/transport/byte_stream.h', + 'src/core/lib/transport/chttp2/alpn.h', + 'src/core/lib/transport/chttp2/bin_encoder.h', + 'src/core/lib/transport/chttp2/frame.h', + 'src/core/lib/transport/chttp2/frame_data.h', + 'src/core/lib/transport/chttp2/frame_goaway.h', + 'src/core/lib/transport/chttp2/frame_ping.h', + 'src/core/lib/transport/chttp2/frame_rst_stream.h', + 'src/core/lib/transport/chttp2/frame_settings.h', + 'src/core/lib/transport/chttp2/frame_window_update.h', + 'src/core/lib/transport/chttp2/hpack_encoder.h', + 'src/core/lib/transport/chttp2/hpack_parser.h', + 'src/core/lib/transport/chttp2/hpack_table.h', + 'src/core/lib/transport/chttp2/http2_errors.h', + 'src/core/lib/transport/chttp2/huffsyms.h', + 'src/core/lib/transport/chttp2/incoming_metadata.h', + 'src/core/lib/transport/chttp2/internal.h', + 'src/core/lib/transport/chttp2/status_conversion.h', + 'src/core/lib/transport/chttp2/stream_map.h', + 'src/core/lib/transport/chttp2/timeout_encoding.h', + 'src/core/lib/transport/chttp2/varint.h', + 'src/core/lib/transport/chttp2_transport.h', + 'src/core/lib/transport/connectivity_state.h', + 'src/core/lib/transport/metadata.h', + 'src/core/lib/transport/metadata_batch.h', + 'src/core/lib/transport/static_metadata.h', + 'src/core/lib/transport/transport.h', + 'src/core/lib/transport/transport_impl.h', + 'src/core/lib/security/auth_filters.h', + 'src/core/lib/security/b64.h', + 'src/core/lib/security/credentials.h', + 'src/core/lib/security/handshake.h', + 'src/core/lib/security/json_token.h', + 'src/core/lib/security/jwt_verifier.h', + 'src/core/lib/security/secure_endpoint.h', + 'src/core/lib/security/security_connector.h', + 'src/core/lib/security/security_context.h', + 'src/core/lib/tsi/fake_transport_security.h', + 'src/core/lib/tsi/ssl_transport_security.h', + 'src/core/lib/tsi/ssl_types.h', + 'src/core/lib/tsi/transport_security.h', + 'src/core/lib/tsi/transport_security_interface.h', + 'src/core/lib/census/aggregation.h', + 'src/core/lib/census/mlog.h', + 'src/core/lib/census/rpc_metric_id.h', 'third_party/nanopb/pb.h', 'third_party/nanopb/pb_common.h', 'third_party/nanopb/pb_decode.h', @@ -315,320 +315,320 @@ Pod::Spec.new do |s| 'include/grpc/impl/codegen/propagation_bits.h', 'include/grpc/impl/codegen/status.h', 'include/grpc/census.h', - 'src/core/census/grpc_context.c', - 'src/core/census/grpc_filter.c', - 'src/core/census/grpc_plugin.c', - 'src/core/channel/channel_args.c', - 'src/core/channel/channel_stack.c', - 'src/core/channel/channel_stack_builder.c', - 'src/core/channel/client_channel.c', - 'src/core/channel/compress_filter.c', - 'src/core/channel/connected_channel.c', - 'src/core/channel/http_client_filter.c', - 'src/core/channel/http_server_filter.c', - 'src/core/channel/subchannel_call_holder.c', - 'src/core/client_config/client_config.c', - 'src/core/client_config/connector.c', - 'src/core/client_config/default_initial_connect_string.c', - 'src/core/client_config/initial_connect_string.c', - 'src/core/client_config/lb_policies/load_balancer_api.c', - 'src/core/client_config/lb_policies/pick_first.c', - 'src/core/client_config/lb_policies/round_robin.c', - 'src/core/client_config/lb_policy.c', - 'src/core/client_config/lb_policy_factory.c', - 'src/core/client_config/lb_policy_registry.c', - 'src/core/client_config/resolver.c', - 'src/core/client_config/resolver_factory.c', - 'src/core/client_config/resolver_registry.c', - 'src/core/client_config/resolvers/dns_resolver.c', - 'src/core/client_config/resolvers/sockaddr_resolver.c', - 'src/core/client_config/subchannel.c', - 'src/core/client_config/subchannel_factory.c', - 'src/core/client_config/subchannel_index.c', - 'src/core/client_config/uri_parser.c', - 'src/core/compression/compression_algorithm.c', - 'src/core/compression/message_compress.c', - 'src/core/debug/trace.c', - 'src/core/http/format_request.c', - 'src/core/http/httpcli.c', - 'src/core/http/parser.c', - 'src/core/iomgr/closure.c', - 'src/core/iomgr/endpoint.c', - 'src/core/iomgr/endpoint_pair_posix.c', - 'src/core/iomgr/endpoint_pair_windows.c', - 'src/core/iomgr/exec_ctx.c', - 'src/core/iomgr/executor.c', - 'src/core/iomgr/fd_posix.c', - 'src/core/iomgr/iocp_windows.c', - 'src/core/iomgr/iomgr.c', - 'src/core/iomgr/iomgr_posix.c', - 'src/core/iomgr/iomgr_windows.c', - 'src/core/iomgr/pollset_multipoller_with_epoll.c', - 'src/core/iomgr/pollset_multipoller_with_poll_posix.c', - 'src/core/iomgr/pollset_posix.c', - 'src/core/iomgr/pollset_set_posix.c', - 'src/core/iomgr/pollset_set_windows.c', - 'src/core/iomgr/pollset_windows.c', - 'src/core/iomgr/resolve_address_posix.c', - 'src/core/iomgr/resolve_address_windows.c', - 'src/core/iomgr/sockaddr_utils.c', - 'src/core/iomgr/socket_utils_common_posix.c', - 'src/core/iomgr/socket_utils_linux.c', - 'src/core/iomgr/socket_utils_posix.c', - 'src/core/iomgr/socket_windows.c', - 'src/core/iomgr/tcp_client_posix.c', - 'src/core/iomgr/tcp_client_windows.c', - 'src/core/iomgr/tcp_posix.c', - 'src/core/iomgr/tcp_server_posix.c', - 'src/core/iomgr/tcp_server_windows.c', - 'src/core/iomgr/tcp_windows.c', - 'src/core/iomgr/time_averaged_stats.c', - 'src/core/iomgr/timer.c', - 'src/core/iomgr/timer_heap.c', - 'src/core/iomgr/udp_server.c', - 'src/core/iomgr/unix_sockets_posix.c', - 'src/core/iomgr/unix_sockets_posix_noop.c', - 'src/core/iomgr/wakeup_fd_eventfd.c', - 'src/core/iomgr/wakeup_fd_nospecial.c', - 'src/core/iomgr/wakeup_fd_pipe.c', - 'src/core/iomgr/wakeup_fd_posix.c', - 'src/core/iomgr/workqueue_posix.c', - 'src/core/iomgr/workqueue_windows.c', - 'src/core/json/json.c', - 'src/core/json/json_reader.c', - 'src/core/json/json_string.c', - 'src/core/json/json_writer.c', - 'src/core/proto/grpc/lb/v0/load_balancer.pb.c', - 'src/core/surface/alarm.c', - 'src/core/surface/api_trace.c', - 'src/core/surface/byte_buffer.c', - 'src/core/surface/byte_buffer_reader.c', - 'src/core/surface/call.c', - 'src/core/surface/call_details.c', - 'src/core/surface/call_log_batch.c', - 'src/core/surface/channel.c', - 'src/core/surface/channel_connectivity.c', - 'src/core/surface/channel_create.c', - 'src/core/surface/channel_init.c', - 'src/core/surface/channel_ping.c', - 'src/core/surface/channel_stack_type.c', - 'src/core/surface/completion_queue.c', - 'src/core/surface/event_string.c', - 'src/core/surface/init.c', - 'src/core/surface/lame_client.c', - 'src/core/surface/metadata_array.c', - 'src/core/surface/server.c', - 'src/core/surface/server_chttp2.c', - 'src/core/surface/validate_metadata.c', - 'src/core/surface/version.c', - 'src/core/transport/byte_stream.c', - 'src/core/transport/chttp2/alpn.c', - 'src/core/transport/chttp2/bin_encoder.c', - 'src/core/transport/chttp2/frame_data.c', - 'src/core/transport/chttp2/frame_goaway.c', - 'src/core/transport/chttp2/frame_ping.c', - 'src/core/transport/chttp2/frame_rst_stream.c', - 'src/core/transport/chttp2/frame_settings.c', - 'src/core/transport/chttp2/frame_window_update.c', - 'src/core/transport/chttp2/hpack_encoder.c', - 'src/core/transport/chttp2/hpack_parser.c', - 'src/core/transport/chttp2/hpack_table.c', - 'src/core/transport/chttp2/huffsyms.c', - 'src/core/transport/chttp2/incoming_metadata.c', - 'src/core/transport/chttp2/parsing.c', - 'src/core/transport/chttp2/status_conversion.c', - 'src/core/transport/chttp2/stream_lists.c', - 'src/core/transport/chttp2/stream_map.c', - 'src/core/transport/chttp2/timeout_encoding.c', - 'src/core/transport/chttp2/varint.c', - 'src/core/transport/chttp2/writing.c', - 'src/core/transport/chttp2_transport.c', - 'src/core/transport/connectivity_state.c', - 'src/core/transport/metadata.c', - 'src/core/transport/metadata_batch.c', - 'src/core/transport/static_metadata.c', - 'src/core/transport/transport.c', - 'src/core/transport/transport_op_string.c', - 'src/core/http/httpcli_security_connector.c', - 'src/core/security/b64.c', - 'src/core/security/client_auth_filter.c', - 'src/core/security/credentials.c', - 'src/core/security/credentials_metadata.c', - 'src/core/security/credentials_posix.c', - 'src/core/security/credentials_win32.c', - 'src/core/security/google_default_credentials.c', - 'src/core/security/handshake.c', - 'src/core/security/json_token.c', - 'src/core/security/jwt_verifier.c', - 'src/core/security/secure_endpoint.c', - 'src/core/security/security_connector.c', - 'src/core/security/security_context.c', - 'src/core/security/server_auth_filter.c', - 'src/core/security/server_secure_chttp2.c', - 'src/core/surface/init_secure.c', - 'src/core/surface/secure_channel_create.c', - 'src/core/tsi/fake_transport_security.c', - 'src/core/tsi/ssl_transport_security.c', - 'src/core/tsi/transport_security.c', - 'src/core/census/context.c', - 'src/core/census/initialize.c', - 'src/core/census/mlog.c', - 'src/core/census/operation.c', - 'src/core/census/placeholders.c', - 'src/core/census/tracing.c', + 'src/core/lib/census/grpc_context.c', + 'src/core/lib/census/grpc_filter.c', + 'src/core/lib/census/grpc_plugin.c', + 'src/core/lib/channel/channel_args.c', + 'src/core/lib/channel/channel_stack.c', + 'src/core/lib/channel/channel_stack_builder.c', + 'src/core/lib/channel/client_channel.c', + 'src/core/lib/channel/compress_filter.c', + 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/http_client_filter.c', + 'src/core/lib/channel/http_server_filter.c', + 'src/core/lib/channel/subchannel_call_holder.c', + 'src/core/lib/client_config/client_config.c', + 'src/core/lib/client_config/connector.c', + 'src/core/lib/client_config/default_initial_connect_string.c', + 'src/core/lib/client_config/initial_connect_string.c', + 'src/core/lib/client_config/lb_policies/load_balancer_api.c', + 'src/core/lib/client_config/lb_policies/pick_first.c', + 'src/core/lib/client_config/lb_policies/round_robin.c', + 'src/core/lib/client_config/lb_policy.c', + 'src/core/lib/client_config/lb_policy_factory.c', + 'src/core/lib/client_config/lb_policy_registry.c', + 'src/core/lib/client_config/resolver.c', + 'src/core/lib/client_config/resolver_factory.c', + 'src/core/lib/client_config/resolver_registry.c', + 'src/core/lib/client_config/resolvers/dns_resolver.c', + 'src/core/lib/client_config/resolvers/sockaddr_resolver.c', + 'src/core/lib/client_config/subchannel.c', + 'src/core/lib/client_config/subchannel_factory.c', + 'src/core/lib/client_config/subchannel_index.c', + 'src/core/lib/client_config/uri_parser.c', + 'src/core/lib/compression/compression_algorithm.c', + 'src/core/lib/compression/message_compress.c', + 'src/core/lib/debug/trace.c', + 'src/core/lib/http/format_request.c', + 'src/core/lib/http/httpcli.c', + 'src/core/lib/http/parser.c', + 'src/core/lib/iomgr/closure.c', + 'src/core/lib/iomgr/endpoint.c', + 'src/core/lib/iomgr/endpoint_pair_posix.c', + 'src/core/lib/iomgr/endpoint_pair_windows.c', + 'src/core/lib/iomgr/exec_ctx.c', + 'src/core/lib/iomgr/executor.c', + 'src/core/lib/iomgr/fd_posix.c', + 'src/core/lib/iomgr/iocp_windows.c', + 'src/core/lib/iomgr/iomgr.c', + 'src/core/lib/iomgr/iomgr_posix.c', + 'src/core/lib/iomgr/iomgr_windows.c', + 'src/core/lib/iomgr/pollset_multipoller_with_epoll.c', + 'src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c', + 'src/core/lib/iomgr/pollset_posix.c', + 'src/core/lib/iomgr/pollset_set_posix.c', + 'src/core/lib/iomgr/pollset_set_windows.c', + 'src/core/lib/iomgr/pollset_windows.c', + 'src/core/lib/iomgr/resolve_address_posix.c', + 'src/core/lib/iomgr/resolve_address_windows.c', + 'src/core/lib/iomgr/sockaddr_utils.c', + 'src/core/lib/iomgr/socket_utils_common_posix.c', + 'src/core/lib/iomgr/socket_utils_linux.c', + 'src/core/lib/iomgr/socket_utils_posix.c', + 'src/core/lib/iomgr/socket_windows.c', + 'src/core/lib/iomgr/tcp_client_posix.c', + 'src/core/lib/iomgr/tcp_client_windows.c', + 'src/core/lib/iomgr/tcp_posix.c', + 'src/core/lib/iomgr/tcp_server_posix.c', + 'src/core/lib/iomgr/tcp_server_windows.c', + 'src/core/lib/iomgr/tcp_windows.c', + 'src/core/lib/iomgr/time_averaged_stats.c', + 'src/core/lib/iomgr/timer.c', + 'src/core/lib/iomgr/timer_heap.c', + 'src/core/lib/iomgr/udp_server.c', + 'src/core/lib/iomgr/unix_sockets_posix.c', + 'src/core/lib/iomgr/unix_sockets_posix_noop.c', + 'src/core/lib/iomgr/wakeup_fd_eventfd.c', + 'src/core/lib/iomgr/wakeup_fd_nospecial.c', + 'src/core/lib/iomgr/wakeup_fd_pipe.c', + 'src/core/lib/iomgr/wakeup_fd_posix.c', + 'src/core/lib/iomgr/workqueue_posix.c', + 'src/core/lib/iomgr/workqueue_windows.c', + 'src/core/lib/json/json.c', + 'src/core/lib/json/json_reader.c', + 'src/core/lib/json/json_string.c', + 'src/core/lib/json/json_writer.c', + 'src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c', + 'src/core/lib/surface/alarm.c', + 'src/core/lib/surface/api_trace.c', + 'src/core/lib/surface/byte_buffer.c', + 'src/core/lib/surface/byte_buffer_reader.c', + 'src/core/lib/surface/call.c', + 'src/core/lib/surface/call_details.c', + 'src/core/lib/surface/call_log_batch.c', + 'src/core/lib/surface/channel.c', + 'src/core/lib/surface/channel_connectivity.c', + 'src/core/lib/surface/channel_create.c', + 'src/core/lib/surface/channel_init.c', + 'src/core/lib/surface/channel_ping.c', + 'src/core/lib/surface/channel_stack_type.c', + 'src/core/lib/surface/completion_queue.c', + 'src/core/lib/surface/event_string.c', + 'src/core/lib/surface/init.c', + 'src/core/lib/surface/lame_client.c', + 'src/core/lib/surface/metadata_array.c', + 'src/core/lib/surface/server.c', + 'src/core/lib/surface/server_chttp2.c', + 'src/core/lib/surface/validate_metadata.c', + 'src/core/lib/surface/version.c', + 'src/core/lib/transport/byte_stream.c', + 'src/core/lib/transport/chttp2/alpn.c', + 'src/core/lib/transport/chttp2/bin_encoder.c', + 'src/core/lib/transport/chttp2/frame_data.c', + 'src/core/lib/transport/chttp2/frame_goaway.c', + 'src/core/lib/transport/chttp2/frame_ping.c', + 'src/core/lib/transport/chttp2/frame_rst_stream.c', + 'src/core/lib/transport/chttp2/frame_settings.c', + 'src/core/lib/transport/chttp2/frame_window_update.c', + 'src/core/lib/transport/chttp2/hpack_encoder.c', + 'src/core/lib/transport/chttp2/hpack_parser.c', + 'src/core/lib/transport/chttp2/hpack_table.c', + 'src/core/lib/transport/chttp2/huffsyms.c', + 'src/core/lib/transport/chttp2/incoming_metadata.c', + 'src/core/lib/transport/chttp2/parsing.c', + 'src/core/lib/transport/chttp2/status_conversion.c', + 'src/core/lib/transport/chttp2/stream_lists.c', + 'src/core/lib/transport/chttp2/stream_map.c', + 'src/core/lib/transport/chttp2/timeout_encoding.c', + 'src/core/lib/transport/chttp2/varint.c', + 'src/core/lib/transport/chttp2/writing.c', + 'src/core/lib/transport/chttp2_transport.c', + 'src/core/lib/transport/connectivity_state.c', + 'src/core/lib/transport/metadata.c', + 'src/core/lib/transport/metadata_batch.c', + 'src/core/lib/transport/static_metadata.c', + 'src/core/lib/transport/transport.c', + 'src/core/lib/transport/transport_op_string.c', + 'src/core/lib/http/httpcli_security_connector.c', + 'src/core/lib/security/b64.c', + 'src/core/lib/security/client_auth_filter.c', + 'src/core/lib/security/credentials.c', + 'src/core/lib/security/credentials_metadata.c', + 'src/core/lib/security/credentials_posix.c', + 'src/core/lib/security/credentials_win32.c', + 'src/core/lib/security/google_default_credentials.c', + 'src/core/lib/security/handshake.c', + 'src/core/lib/security/json_token.c', + 'src/core/lib/security/jwt_verifier.c', + 'src/core/lib/security/secure_endpoint.c', + 'src/core/lib/security/security_connector.c', + 'src/core/lib/security/security_context.c', + 'src/core/lib/security/server_auth_filter.c', + 'src/core/lib/security/server_secure_chttp2.c', + 'src/core/lib/surface/init_secure.c', + 'src/core/lib/surface/secure_channel_create.c', + 'src/core/lib/tsi/fake_transport_security.c', + 'src/core/lib/tsi/ssl_transport_security.c', + 'src/core/lib/tsi/transport_security.c', + 'src/core/lib/census/context.c', + 'src/core/lib/census/initialize.c', + 'src/core/lib/census/mlog.c', + 'src/core/lib/census/operation.c', + 'src/core/lib/census/placeholders.c', + 'src/core/lib/census/tracing.c', 'third_party/nanopb/pb_common.c', 'third_party/nanopb/pb_decode.c', 'third_party/nanopb/pb_encode.c' - ss.private_header_files = 'src/core/profiling/timers.h', - 'src/core/support/backoff.h', - 'src/core/support/block_annotate.h', - 'src/core/support/env.h', - 'src/core/support/load_file.h', - 'src/core/support/murmur_hash.h', - 'src/core/support/stack_lockfree.h', - 'src/core/support/string.h', - 'src/core/support/string_win32.h', - 'src/core/support/thd_internal.h', - 'src/core/support/time_precise.h', - 'src/core/support/tmpfile.h', - 'src/core/census/grpc_filter.h', - 'src/core/census/grpc_plugin.h', - 'src/core/channel/channel_args.h', - 'src/core/channel/channel_stack.h', - 'src/core/channel/channel_stack_builder.h', - 'src/core/channel/client_channel.h', - 'src/core/channel/compress_filter.h', - 'src/core/channel/connected_channel.h', - 'src/core/channel/context.h', - 'src/core/channel/http_client_filter.h', - 'src/core/channel/http_server_filter.h', - 'src/core/channel/subchannel_call_holder.h', - 'src/core/client_config/client_config.h', - 'src/core/client_config/connector.h', - 'src/core/client_config/initial_connect_string.h', - 'src/core/client_config/lb_policies/load_balancer_api.h', - 'src/core/client_config/lb_policies/pick_first.h', - 'src/core/client_config/lb_policies/round_robin.h', - 'src/core/client_config/lb_policy.h', - 'src/core/client_config/lb_policy_factory.h', - 'src/core/client_config/lb_policy_registry.h', - 'src/core/client_config/resolver.h', - 'src/core/client_config/resolver_factory.h', - 'src/core/client_config/resolver_registry.h', - 'src/core/client_config/resolvers/dns_resolver.h', - 'src/core/client_config/resolvers/sockaddr_resolver.h', - 'src/core/client_config/subchannel.h', - 'src/core/client_config/subchannel_factory.h', - 'src/core/client_config/subchannel_index.h', - 'src/core/client_config/uri_parser.h', - 'src/core/compression/algorithm_metadata.h', - 'src/core/compression/message_compress.h', - 'src/core/debug/trace.h', - 'src/core/http/format_request.h', - 'src/core/http/httpcli.h', - 'src/core/http/parser.h', - 'src/core/iomgr/closure.h', - 'src/core/iomgr/endpoint.h', - 'src/core/iomgr/endpoint_pair.h', - 'src/core/iomgr/exec_ctx.h', - 'src/core/iomgr/executor.h', - 'src/core/iomgr/fd_posix.h', - 'src/core/iomgr/iocp_windows.h', - 'src/core/iomgr/iomgr.h', - 'src/core/iomgr/iomgr_internal.h', - 'src/core/iomgr/iomgr_posix.h', - 'src/core/iomgr/pollset.h', - 'src/core/iomgr/pollset_posix.h', - 'src/core/iomgr/pollset_set.h', - 'src/core/iomgr/pollset_set_posix.h', - 'src/core/iomgr/pollset_set_windows.h', - 'src/core/iomgr/pollset_windows.h', - 'src/core/iomgr/resolve_address.h', - 'src/core/iomgr/sockaddr.h', - 'src/core/iomgr/sockaddr_posix.h', - 'src/core/iomgr/sockaddr_utils.h', - 'src/core/iomgr/sockaddr_win32.h', - 'src/core/iomgr/socket_utils_posix.h', - 'src/core/iomgr/socket_windows.h', - 'src/core/iomgr/tcp_client.h', - 'src/core/iomgr/tcp_posix.h', - 'src/core/iomgr/tcp_server.h', - 'src/core/iomgr/tcp_windows.h', - 'src/core/iomgr/time_averaged_stats.h', - 'src/core/iomgr/timer.h', - 'src/core/iomgr/timer_heap.h', - 'src/core/iomgr/udp_server.h', - 'src/core/iomgr/unix_sockets_posix.h', - 'src/core/iomgr/wakeup_fd_pipe.h', - 'src/core/iomgr/wakeup_fd_posix.h', - 'src/core/iomgr/workqueue.h', - 'src/core/iomgr/workqueue_posix.h', - 'src/core/iomgr/workqueue_windows.h', - 'src/core/json/json.h', - 'src/core/json/json_common.h', - 'src/core/json/json_reader.h', - 'src/core/json/json_writer.h', - 'src/core/proto/grpc/lb/v0/load_balancer.pb.h', - 'src/core/statistics/census_interface.h', - 'src/core/statistics/census_rpc_stats.h', - 'src/core/surface/api_trace.h', - 'src/core/surface/call.h', - 'src/core/surface/call_test_only.h', - 'src/core/surface/channel.h', - 'src/core/surface/channel_init.h', - 'src/core/surface/channel_stack_type.h', - 'src/core/surface/completion_queue.h', - 'src/core/surface/event_string.h', - 'src/core/surface/init.h', - 'src/core/surface/lame_client.h', - 'src/core/surface/server.h', - 'src/core/surface/surface_trace.h', - 'src/core/transport/byte_stream.h', - 'src/core/transport/chttp2/alpn.h', - 'src/core/transport/chttp2/bin_encoder.h', - 'src/core/transport/chttp2/frame.h', - 'src/core/transport/chttp2/frame_data.h', - 'src/core/transport/chttp2/frame_goaway.h', - 'src/core/transport/chttp2/frame_ping.h', - 'src/core/transport/chttp2/frame_rst_stream.h', - 'src/core/transport/chttp2/frame_settings.h', - 'src/core/transport/chttp2/frame_window_update.h', - 'src/core/transport/chttp2/hpack_encoder.h', - 'src/core/transport/chttp2/hpack_parser.h', - 'src/core/transport/chttp2/hpack_table.h', - 'src/core/transport/chttp2/http2_errors.h', - 'src/core/transport/chttp2/huffsyms.h', - 'src/core/transport/chttp2/incoming_metadata.h', - 'src/core/transport/chttp2/internal.h', - 'src/core/transport/chttp2/status_conversion.h', - 'src/core/transport/chttp2/stream_map.h', - 'src/core/transport/chttp2/timeout_encoding.h', - 'src/core/transport/chttp2/varint.h', - 'src/core/transport/chttp2_transport.h', - 'src/core/transport/connectivity_state.h', - 'src/core/transport/metadata.h', - 'src/core/transport/metadata_batch.h', - 'src/core/transport/static_metadata.h', - 'src/core/transport/transport.h', - 'src/core/transport/transport_impl.h', - 'src/core/security/auth_filters.h', - 'src/core/security/b64.h', - 'src/core/security/credentials.h', - 'src/core/security/handshake.h', - 'src/core/security/json_token.h', - 'src/core/security/jwt_verifier.h', - 'src/core/security/secure_endpoint.h', - 'src/core/security/security_connector.h', - 'src/core/security/security_context.h', - 'src/core/tsi/fake_transport_security.h', - 'src/core/tsi/ssl_transport_security.h', - 'src/core/tsi/ssl_types.h', - 'src/core/tsi/transport_security.h', - 'src/core/tsi/transport_security_interface.h', - 'src/core/census/aggregation.h', - 'src/core/census/mlog.h', - 'src/core/census/rpc_metric_id.h', + ss.private_header_files = 'src/core/lib/profiling/timers.h', + 'src/core/lib/support/backoff.h', + 'src/core/lib/support/block_annotate.h', + 'src/core/lib/support/env.h', + 'src/core/lib/support/load_file.h', + 'src/core/lib/support/murmur_hash.h', + 'src/core/lib/support/stack_lockfree.h', + 'src/core/lib/support/string.h', + 'src/core/lib/support/string_win32.h', + 'src/core/lib/support/thd_internal.h', + 'src/core/lib/support/time_precise.h', + 'src/core/lib/support/tmpfile.h', + 'src/core/lib/census/grpc_filter.h', + 'src/core/lib/census/grpc_plugin.h', + 'src/core/lib/channel/channel_args.h', + 'src/core/lib/channel/channel_stack.h', + 'src/core/lib/channel/channel_stack_builder.h', + 'src/core/lib/channel/client_channel.h', + 'src/core/lib/channel/compress_filter.h', + 'src/core/lib/channel/connected_channel.h', + 'src/core/lib/channel/context.h', + 'src/core/lib/channel/http_client_filter.h', + 'src/core/lib/channel/http_server_filter.h', + 'src/core/lib/channel/subchannel_call_holder.h', + 'src/core/lib/client_config/client_config.h', + 'src/core/lib/client_config/connector.h', + 'src/core/lib/client_config/initial_connect_string.h', + 'src/core/lib/client_config/lb_policies/load_balancer_api.h', + 'src/core/lib/client_config/lb_policies/pick_first.h', + 'src/core/lib/client_config/lb_policies/round_robin.h', + 'src/core/lib/client_config/lb_policy.h', + 'src/core/lib/client_config/lb_policy_factory.h', + 'src/core/lib/client_config/lb_policy_registry.h', + 'src/core/lib/client_config/resolver.h', + 'src/core/lib/client_config/resolver_factory.h', + 'src/core/lib/client_config/resolver_registry.h', + 'src/core/lib/client_config/resolvers/dns_resolver.h', + 'src/core/lib/client_config/resolvers/sockaddr_resolver.h', + 'src/core/lib/client_config/subchannel.h', + 'src/core/lib/client_config/subchannel_factory.h', + 'src/core/lib/client_config/subchannel_index.h', + 'src/core/lib/client_config/uri_parser.h', + 'src/core/lib/compression/algorithm_metadata.h', + 'src/core/lib/compression/message_compress.h', + 'src/core/lib/debug/trace.h', + 'src/core/lib/http/format_request.h', + 'src/core/lib/http/httpcli.h', + 'src/core/lib/http/parser.h', + 'src/core/lib/iomgr/closure.h', + 'src/core/lib/iomgr/endpoint.h', + 'src/core/lib/iomgr/endpoint_pair.h', + 'src/core/lib/iomgr/exec_ctx.h', + 'src/core/lib/iomgr/executor.h', + 'src/core/lib/iomgr/fd_posix.h', + 'src/core/lib/iomgr/iocp_windows.h', + 'src/core/lib/iomgr/iomgr.h', + 'src/core/lib/iomgr/iomgr_internal.h', + 'src/core/lib/iomgr/iomgr_posix.h', + 'src/core/lib/iomgr/pollset.h', + 'src/core/lib/iomgr/pollset_posix.h', + 'src/core/lib/iomgr/pollset_set.h', + 'src/core/lib/iomgr/pollset_set_posix.h', + 'src/core/lib/iomgr/pollset_set_windows.h', + 'src/core/lib/iomgr/pollset_windows.h', + 'src/core/lib/iomgr/resolve_address.h', + 'src/core/lib/iomgr/sockaddr.h', + 'src/core/lib/iomgr/sockaddr_posix.h', + 'src/core/lib/iomgr/sockaddr_utils.h', + 'src/core/lib/iomgr/sockaddr_win32.h', + 'src/core/lib/iomgr/socket_utils_posix.h', + 'src/core/lib/iomgr/socket_windows.h', + 'src/core/lib/iomgr/tcp_client.h', + 'src/core/lib/iomgr/tcp_posix.h', + 'src/core/lib/iomgr/tcp_server.h', + 'src/core/lib/iomgr/tcp_windows.h', + 'src/core/lib/iomgr/time_averaged_stats.h', + 'src/core/lib/iomgr/timer.h', + 'src/core/lib/iomgr/timer_heap.h', + 'src/core/lib/iomgr/udp_server.h', + 'src/core/lib/iomgr/unix_sockets_posix.h', + 'src/core/lib/iomgr/wakeup_fd_pipe.h', + 'src/core/lib/iomgr/wakeup_fd_posix.h', + 'src/core/lib/iomgr/workqueue.h', + 'src/core/lib/iomgr/workqueue_posix.h', + 'src/core/lib/iomgr/workqueue_windows.h', + 'src/core/lib/json/json.h', + 'src/core/lib/json/json_common.h', + 'src/core/lib/json/json_reader.h', + 'src/core/lib/json/json_writer.h', + 'src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h', + 'src/core/lib/statistics/census_interface.h', + 'src/core/lib/statistics/census_rpc_stats.h', + 'src/core/lib/surface/api_trace.h', + 'src/core/lib/surface/call.h', + 'src/core/lib/surface/call_test_only.h', + 'src/core/lib/surface/channel.h', + 'src/core/lib/surface/channel_init.h', + 'src/core/lib/surface/channel_stack_type.h', + 'src/core/lib/surface/completion_queue.h', + 'src/core/lib/surface/event_string.h', + 'src/core/lib/surface/init.h', + 'src/core/lib/surface/lame_client.h', + 'src/core/lib/surface/server.h', + 'src/core/lib/surface/surface_trace.h', + 'src/core/lib/transport/byte_stream.h', + 'src/core/lib/transport/chttp2/alpn.h', + 'src/core/lib/transport/chttp2/bin_encoder.h', + 'src/core/lib/transport/chttp2/frame.h', + 'src/core/lib/transport/chttp2/frame_data.h', + 'src/core/lib/transport/chttp2/frame_goaway.h', + 'src/core/lib/transport/chttp2/frame_ping.h', + 'src/core/lib/transport/chttp2/frame_rst_stream.h', + 'src/core/lib/transport/chttp2/frame_settings.h', + 'src/core/lib/transport/chttp2/frame_window_update.h', + 'src/core/lib/transport/chttp2/hpack_encoder.h', + 'src/core/lib/transport/chttp2/hpack_parser.h', + 'src/core/lib/transport/chttp2/hpack_table.h', + 'src/core/lib/transport/chttp2/http2_errors.h', + 'src/core/lib/transport/chttp2/huffsyms.h', + 'src/core/lib/transport/chttp2/incoming_metadata.h', + 'src/core/lib/transport/chttp2/internal.h', + 'src/core/lib/transport/chttp2/status_conversion.h', + 'src/core/lib/transport/chttp2/stream_map.h', + 'src/core/lib/transport/chttp2/timeout_encoding.h', + 'src/core/lib/transport/chttp2/varint.h', + 'src/core/lib/transport/chttp2_transport.h', + 'src/core/lib/transport/connectivity_state.h', + 'src/core/lib/transport/metadata.h', + 'src/core/lib/transport/metadata_batch.h', + 'src/core/lib/transport/static_metadata.h', + 'src/core/lib/transport/transport.h', + 'src/core/lib/transport/transport_impl.h', + 'src/core/lib/security/auth_filters.h', + 'src/core/lib/security/b64.h', + 'src/core/lib/security/credentials.h', + 'src/core/lib/security/handshake.h', + 'src/core/lib/security/json_token.h', + 'src/core/lib/security/jwt_verifier.h', + 'src/core/lib/security/secure_endpoint.h', + 'src/core/lib/security/security_connector.h', + 'src/core/lib/security/security_context.h', + 'src/core/lib/tsi/fake_transport_security.h', + 'src/core/lib/tsi/ssl_transport_security.h', + 'src/core/lib/tsi/ssl_types.h', + 'src/core/lib/tsi/transport_security.h', + 'src/core/lib/tsi/transport_security_interface.h', + 'src/core/lib/census/aggregation.h', + 'src/core/lib/census/mlog.h', + 'src/core/lib/census/rpc_metric_id.h', 'third_party/nanopb/pb.h', 'third_party/nanopb/pb_common.h', 'third_party/nanopb/pb_decode.h', diff --git a/grpc.gemspec b/grpc.gemspec index eeda035ee8..aa52890aeb 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -88,62 +88,62 @@ Gem::Specification.new do |s| s.files += %w( include/grpc/impl/codegen/sync_posix.h ) s.files += %w( include/grpc/impl/codegen/sync_win32.h ) s.files += %w( include/grpc/impl/codegen/time.h ) - s.files += %w( src/core/profiling/timers.h ) - s.files += %w( src/core/support/backoff.h ) - s.files += %w( src/core/support/block_annotate.h ) - s.files += %w( src/core/support/env.h ) - s.files += %w( src/core/support/load_file.h ) - s.files += %w( src/core/support/murmur_hash.h ) - s.files += %w( src/core/support/stack_lockfree.h ) - s.files += %w( src/core/support/string.h ) - s.files += %w( src/core/support/string_win32.h ) - s.files += %w( src/core/support/thd_internal.h ) - s.files += %w( src/core/support/time_precise.h ) - s.files += %w( src/core/support/tmpfile.h ) - s.files += %w( src/core/profiling/basic_timers.c ) - s.files += %w( src/core/profiling/stap_timers.c ) - s.files += %w( src/core/support/alloc.c ) - s.files += %w( src/core/support/avl.c ) - s.files += %w( src/core/support/backoff.c ) - s.files += %w( src/core/support/cmdline.c ) - s.files += %w( src/core/support/cpu_iphone.c ) - s.files += %w( src/core/support/cpu_linux.c ) - s.files += %w( src/core/support/cpu_posix.c ) - s.files += %w( src/core/support/cpu_windows.c ) - s.files += %w( src/core/support/env_linux.c ) - s.files += %w( src/core/support/env_posix.c ) - s.files += %w( src/core/support/env_win32.c ) - s.files += %w( src/core/support/histogram.c ) - s.files += %w( src/core/support/host_port.c ) - s.files += %w( src/core/support/load_file.c ) - s.files += %w( src/core/support/log.c ) - s.files += %w( src/core/support/log_android.c ) - s.files += %w( src/core/support/log_linux.c ) - s.files += %w( src/core/support/log_posix.c ) - s.files += %w( src/core/support/log_win32.c ) - s.files += %w( src/core/support/murmur_hash.c ) - s.files += %w( src/core/support/slice.c ) - s.files += %w( src/core/support/slice_buffer.c ) - s.files += %w( src/core/support/stack_lockfree.c ) - s.files += %w( src/core/support/string.c ) - s.files += %w( src/core/support/string_posix.c ) - s.files += %w( src/core/support/string_win32.c ) - s.files += %w( src/core/support/subprocess_posix.c ) - s.files += %w( src/core/support/subprocess_windows.c ) - s.files += %w( src/core/support/sync.c ) - s.files += %w( src/core/support/sync_posix.c ) - s.files += %w( src/core/support/sync_win32.c ) - s.files += %w( src/core/support/thd.c ) - s.files += %w( src/core/support/thd_posix.c ) - s.files += %w( src/core/support/thd_win32.c ) - s.files += %w( src/core/support/time.c ) - s.files += %w( src/core/support/time_posix.c ) - s.files += %w( src/core/support/time_precise.c ) - s.files += %w( src/core/support/time_win32.c ) - s.files += %w( src/core/support/tls_pthread.c ) - s.files += %w( src/core/support/tmpfile_posix.c ) - s.files += %w( src/core/support/tmpfile_win32.c ) - s.files += %w( src/core/support/wrap_memcpy.c ) + s.files += %w( src/core/lib/profiling/timers.h ) + s.files += %w( src/core/lib/support/backoff.h ) + s.files += %w( src/core/lib/support/block_annotate.h ) + s.files += %w( src/core/lib/support/env.h ) + s.files += %w( src/core/lib/support/load_file.h ) + s.files += %w( src/core/lib/support/murmur_hash.h ) + s.files += %w( src/core/lib/support/stack_lockfree.h ) + s.files += %w( src/core/lib/support/string.h ) + s.files += %w( src/core/lib/support/string_win32.h ) + s.files += %w( src/core/lib/support/thd_internal.h ) + s.files += %w( src/core/lib/support/time_precise.h ) + s.files += %w( src/core/lib/support/tmpfile.h ) + s.files += %w( src/core/lib/profiling/basic_timers.c ) + s.files += %w( src/core/lib/profiling/stap_timers.c ) + s.files += %w( src/core/lib/support/alloc.c ) + s.files += %w( src/core/lib/support/avl.c ) + s.files += %w( src/core/lib/support/backoff.c ) + s.files += %w( src/core/lib/support/cmdline.c ) + s.files += %w( src/core/lib/support/cpu_iphone.c ) + s.files += %w( src/core/lib/support/cpu_linux.c ) + s.files += %w( src/core/lib/support/cpu_posix.c ) + s.files += %w( src/core/lib/support/cpu_windows.c ) + s.files += %w( src/core/lib/support/env_linux.c ) + s.files += %w( src/core/lib/support/env_posix.c ) + s.files += %w( src/core/lib/support/env_win32.c ) + s.files += %w( src/core/lib/support/histogram.c ) + s.files += %w( src/core/lib/support/host_port.c ) + s.files += %w( src/core/lib/support/load_file.c ) + s.files += %w( src/core/lib/support/log.c ) + s.files += %w( src/core/lib/support/log_android.c ) + s.files += %w( src/core/lib/support/log_linux.c ) + s.files += %w( src/core/lib/support/log_posix.c ) + s.files += %w( src/core/lib/support/log_win32.c ) + s.files += %w( src/core/lib/support/murmur_hash.c ) + s.files += %w( src/core/lib/support/slice.c ) + s.files += %w( src/core/lib/support/slice_buffer.c ) + s.files += %w( src/core/lib/support/stack_lockfree.c ) + s.files += %w( src/core/lib/support/string.c ) + s.files += %w( src/core/lib/support/string_posix.c ) + s.files += %w( src/core/lib/support/string_win32.c ) + s.files += %w( src/core/lib/support/subprocess_posix.c ) + s.files += %w( src/core/lib/support/subprocess_windows.c ) + s.files += %w( src/core/lib/support/sync.c ) + s.files += %w( src/core/lib/support/sync_posix.c ) + s.files += %w( src/core/lib/support/sync_win32.c ) + s.files += %w( src/core/lib/support/thd.c ) + s.files += %w( src/core/lib/support/thd_posix.c ) + s.files += %w( src/core/lib/support/thd_win32.c ) + s.files += %w( src/core/lib/support/time.c ) + s.files += %w( src/core/lib/support/time_posix.c ) + s.files += %w( src/core/lib/support/time_precise.c ) + s.files += %w( src/core/lib/support/time_win32.c ) + s.files += %w( src/core/lib/support/tls_pthread.c ) + s.files += %w( src/core/lib/support/tmpfile_posix.c ) + s.files += %w( src/core/lib/support/tmpfile_win32.c ) + s.files += %w( src/core/lib/support/wrap_memcpy.c ) s.files += %w( include/grpc/grpc_security.h ) s.files += %w( include/grpc/byte_buffer.h ) s.files += %w( include/grpc/byte_buffer_reader.h ) @@ -157,308 +157,308 @@ Gem::Specification.new do |s| s.files += %w( include/grpc/impl/codegen/propagation_bits.h ) s.files += %w( include/grpc/impl/codegen/status.h ) s.files += %w( include/grpc/census.h ) - s.files += %w( src/core/census/grpc_filter.h ) - s.files += %w( src/core/census/grpc_plugin.h ) - s.files += %w( src/core/channel/channel_args.h ) - s.files += %w( src/core/channel/channel_stack.h ) - s.files += %w( src/core/channel/channel_stack_builder.h ) - s.files += %w( src/core/channel/client_channel.h ) - s.files += %w( src/core/channel/compress_filter.h ) - s.files += %w( src/core/channel/connected_channel.h ) - s.files += %w( src/core/channel/context.h ) - s.files += %w( src/core/channel/http_client_filter.h ) - s.files += %w( src/core/channel/http_server_filter.h ) - s.files += %w( src/core/channel/subchannel_call_holder.h ) - s.files += %w( src/core/client_config/client_config.h ) - s.files += %w( src/core/client_config/connector.h ) - s.files += %w( src/core/client_config/initial_connect_string.h ) - s.files += %w( src/core/client_config/lb_policies/load_balancer_api.h ) - s.files += %w( src/core/client_config/lb_policies/pick_first.h ) - s.files += %w( src/core/client_config/lb_policies/round_robin.h ) - s.files += %w( src/core/client_config/lb_policy.h ) - s.files += %w( src/core/client_config/lb_policy_factory.h ) - s.files += %w( src/core/client_config/lb_policy_registry.h ) - s.files += %w( src/core/client_config/resolver.h ) - s.files += %w( src/core/client_config/resolver_factory.h ) - s.files += %w( src/core/client_config/resolver_registry.h ) - s.files += %w( src/core/client_config/resolvers/dns_resolver.h ) - s.files += %w( src/core/client_config/resolvers/sockaddr_resolver.h ) - s.files += %w( src/core/client_config/subchannel.h ) - s.files += %w( src/core/client_config/subchannel_factory.h ) - s.files += %w( src/core/client_config/subchannel_index.h ) - s.files += %w( src/core/client_config/uri_parser.h ) - s.files += %w( src/core/compression/algorithm_metadata.h ) - s.files += %w( src/core/compression/message_compress.h ) - s.files += %w( src/core/debug/trace.h ) - s.files += %w( src/core/http/format_request.h ) - s.files += %w( src/core/http/httpcli.h ) - s.files += %w( src/core/http/parser.h ) - s.files += %w( src/core/iomgr/closure.h ) - s.files += %w( src/core/iomgr/endpoint.h ) - s.files += %w( src/core/iomgr/endpoint_pair.h ) - s.files += %w( src/core/iomgr/exec_ctx.h ) - s.files += %w( src/core/iomgr/executor.h ) - s.files += %w( src/core/iomgr/fd_posix.h ) - s.files += %w( src/core/iomgr/iocp_windows.h ) - s.files += %w( src/core/iomgr/iomgr.h ) - s.files += %w( src/core/iomgr/iomgr_internal.h ) - s.files += %w( src/core/iomgr/iomgr_posix.h ) - s.files += %w( src/core/iomgr/pollset.h ) - s.files += %w( src/core/iomgr/pollset_posix.h ) - s.files += %w( src/core/iomgr/pollset_set.h ) - s.files += %w( src/core/iomgr/pollset_set_posix.h ) - s.files += %w( src/core/iomgr/pollset_set_windows.h ) - s.files += %w( src/core/iomgr/pollset_windows.h ) - s.files += %w( src/core/iomgr/resolve_address.h ) - s.files += %w( src/core/iomgr/sockaddr.h ) - s.files += %w( src/core/iomgr/sockaddr_posix.h ) - s.files += %w( src/core/iomgr/sockaddr_utils.h ) - s.files += %w( src/core/iomgr/sockaddr_win32.h ) - s.files += %w( src/core/iomgr/socket_utils_posix.h ) - s.files += %w( src/core/iomgr/socket_windows.h ) - s.files += %w( src/core/iomgr/tcp_client.h ) - s.files += %w( src/core/iomgr/tcp_posix.h ) - s.files += %w( src/core/iomgr/tcp_server.h ) - s.files += %w( src/core/iomgr/tcp_windows.h ) - s.files += %w( src/core/iomgr/time_averaged_stats.h ) - s.files += %w( src/core/iomgr/timer.h ) - s.files += %w( src/core/iomgr/timer_heap.h ) - s.files += %w( src/core/iomgr/udp_server.h ) - s.files += %w( src/core/iomgr/unix_sockets_posix.h ) - s.files += %w( src/core/iomgr/wakeup_fd_pipe.h ) - s.files += %w( src/core/iomgr/wakeup_fd_posix.h ) - s.files += %w( src/core/iomgr/workqueue.h ) - s.files += %w( src/core/iomgr/workqueue_posix.h ) - s.files += %w( src/core/iomgr/workqueue_windows.h ) - s.files += %w( src/core/json/json.h ) - s.files += %w( src/core/json/json_common.h ) - s.files += %w( src/core/json/json_reader.h ) - s.files += %w( src/core/json/json_writer.h ) - s.files += %w( src/core/proto/grpc/lb/v0/load_balancer.pb.h ) - s.files += %w( src/core/statistics/census_interface.h ) - s.files += %w( src/core/statistics/census_rpc_stats.h ) - s.files += %w( src/core/surface/api_trace.h ) - s.files += %w( src/core/surface/call.h ) - s.files += %w( src/core/surface/call_test_only.h ) - s.files += %w( src/core/surface/channel.h ) - s.files += %w( src/core/surface/channel_init.h ) - s.files += %w( src/core/surface/channel_stack_type.h ) - s.files += %w( src/core/surface/completion_queue.h ) - s.files += %w( src/core/surface/event_string.h ) - s.files += %w( src/core/surface/init.h ) - s.files += %w( src/core/surface/lame_client.h ) - s.files += %w( src/core/surface/server.h ) - s.files += %w( src/core/surface/surface_trace.h ) - s.files += %w( src/core/transport/byte_stream.h ) - s.files += %w( src/core/transport/chttp2/alpn.h ) - s.files += %w( src/core/transport/chttp2/bin_encoder.h ) - s.files += %w( src/core/transport/chttp2/frame.h ) - s.files += %w( src/core/transport/chttp2/frame_data.h ) - s.files += %w( src/core/transport/chttp2/frame_goaway.h ) - s.files += %w( src/core/transport/chttp2/frame_ping.h ) - s.files += %w( src/core/transport/chttp2/frame_rst_stream.h ) - s.files += %w( src/core/transport/chttp2/frame_settings.h ) - s.files += %w( src/core/transport/chttp2/frame_window_update.h ) - s.files += %w( src/core/transport/chttp2/hpack_encoder.h ) - s.files += %w( src/core/transport/chttp2/hpack_parser.h ) - s.files += %w( src/core/transport/chttp2/hpack_table.h ) - s.files += %w( src/core/transport/chttp2/http2_errors.h ) - s.files += %w( src/core/transport/chttp2/huffsyms.h ) - s.files += %w( src/core/transport/chttp2/incoming_metadata.h ) - s.files += %w( src/core/transport/chttp2/internal.h ) - s.files += %w( src/core/transport/chttp2/status_conversion.h ) - s.files += %w( src/core/transport/chttp2/stream_map.h ) - s.files += %w( src/core/transport/chttp2/timeout_encoding.h ) - s.files += %w( src/core/transport/chttp2/varint.h ) - s.files += %w( src/core/transport/chttp2_transport.h ) - s.files += %w( src/core/transport/connectivity_state.h ) - s.files += %w( src/core/transport/metadata.h ) - s.files += %w( src/core/transport/metadata_batch.h ) - s.files += %w( src/core/transport/static_metadata.h ) - s.files += %w( src/core/transport/transport.h ) - s.files += %w( src/core/transport/transport_impl.h ) - s.files += %w( src/core/security/auth_filters.h ) - s.files += %w( src/core/security/b64.h ) - s.files += %w( src/core/security/credentials.h ) - s.files += %w( src/core/security/handshake.h ) - s.files += %w( src/core/security/json_token.h ) - s.files += %w( src/core/security/jwt_verifier.h ) - s.files += %w( src/core/security/secure_endpoint.h ) - s.files += %w( src/core/security/security_connector.h ) - s.files += %w( src/core/security/security_context.h ) - s.files += %w( src/core/tsi/fake_transport_security.h ) - s.files += %w( src/core/tsi/ssl_transport_security.h ) - s.files += %w( src/core/tsi/ssl_types.h ) - s.files += %w( src/core/tsi/transport_security.h ) - s.files += %w( src/core/tsi/transport_security_interface.h ) - s.files += %w( src/core/census/aggregation.h ) - s.files += %w( src/core/census/mlog.h ) - s.files += %w( src/core/census/rpc_metric_id.h ) + s.files += %w( src/core/lib/census/grpc_filter.h ) + s.files += %w( src/core/lib/census/grpc_plugin.h ) + s.files += %w( src/core/lib/channel/channel_args.h ) + s.files += %w( src/core/lib/channel/channel_stack.h ) + s.files += %w( src/core/lib/channel/channel_stack_builder.h ) + s.files += %w( src/core/lib/channel/client_channel.h ) + s.files += %w( src/core/lib/channel/compress_filter.h ) + s.files += %w( src/core/lib/channel/connected_channel.h ) + s.files += %w( src/core/lib/channel/context.h ) + s.files += %w( src/core/lib/channel/http_client_filter.h ) + s.files += %w( src/core/lib/channel/http_server_filter.h ) + s.files += %w( src/core/lib/channel/subchannel_call_holder.h ) + s.files += %w( src/core/lib/client_config/client_config.h ) + s.files += %w( src/core/lib/client_config/connector.h ) + s.files += %w( src/core/lib/client_config/initial_connect_string.h ) + s.files += %w( src/core/lib/client_config/lb_policies/load_balancer_api.h ) + s.files += %w( src/core/lib/client_config/lb_policies/pick_first.h ) + s.files += %w( src/core/lib/client_config/lb_policies/round_robin.h ) + s.files += %w( src/core/lib/client_config/lb_policy.h ) + s.files += %w( src/core/lib/client_config/lb_policy_factory.h ) + s.files += %w( src/core/lib/client_config/lb_policy_registry.h ) + s.files += %w( src/core/lib/client_config/resolver.h ) + s.files += %w( src/core/lib/client_config/resolver_factory.h ) + s.files += %w( src/core/lib/client_config/resolver_registry.h ) + s.files += %w( src/core/lib/client_config/resolvers/dns_resolver.h ) + s.files += %w( src/core/lib/client_config/resolvers/sockaddr_resolver.h ) + s.files += %w( src/core/lib/client_config/subchannel.h ) + s.files += %w( src/core/lib/client_config/subchannel_factory.h ) + s.files += %w( src/core/lib/client_config/subchannel_index.h ) + s.files += %w( src/core/lib/client_config/uri_parser.h ) + s.files += %w( src/core/lib/compression/algorithm_metadata.h ) + s.files += %w( src/core/lib/compression/message_compress.h ) + s.files += %w( src/core/lib/debug/trace.h ) + s.files += %w( src/core/lib/http/format_request.h ) + s.files += %w( src/core/lib/http/httpcli.h ) + s.files += %w( src/core/lib/http/parser.h ) + s.files += %w( src/core/lib/iomgr/closure.h ) + s.files += %w( src/core/lib/iomgr/endpoint.h ) + s.files += %w( src/core/lib/iomgr/endpoint_pair.h ) + s.files += %w( src/core/lib/iomgr/exec_ctx.h ) + s.files += %w( src/core/lib/iomgr/executor.h ) + s.files += %w( src/core/lib/iomgr/fd_posix.h ) + s.files += %w( src/core/lib/iomgr/iocp_windows.h ) + s.files += %w( src/core/lib/iomgr/iomgr.h ) + s.files += %w( src/core/lib/iomgr/iomgr_internal.h ) + s.files += %w( src/core/lib/iomgr/iomgr_posix.h ) + s.files += %w( src/core/lib/iomgr/pollset.h ) + s.files += %w( src/core/lib/iomgr/pollset_posix.h ) + s.files += %w( src/core/lib/iomgr/pollset_set.h ) + s.files += %w( src/core/lib/iomgr/pollset_set_posix.h ) + s.files += %w( src/core/lib/iomgr/pollset_set_windows.h ) + s.files += %w( src/core/lib/iomgr/pollset_windows.h ) + s.files += %w( src/core/lib/iomgr/resolve_address.h ) + s.files += %w( src/core/lib/iomgr/sockaddr.h ) + s.files += %w( src/core/lib/iomgr/sockaddr_posix.h ) + s.files += %w( src/core/lib/iomgr/sockaddr_utils.h ) + s.files += %w( src/core/lib/iomgr/sockaddr_win32.h ) + s.files += %w( src/core/lib/iomgr/socket_utils_posix.h ) + s.files += %w( src/core/lib/iomgr/socket_windows.h ) + s.files += %w( src/core/lib/iomgr/tcp_client.h ) + s.files += %w( src/core/lib/iomgr/tcp_posix.h ) + s.files += %w( src/core/lib/iomgr/tcp_server.h ) + s.files += %w( src/core/lib/iomgr/tcp_windows.h ) + s.files += %w( src/core/lib/iomgr/time_averaged_stats.h ) + s.files += %w( src/core/lib/iomgr/timer.h ) + s.files += %w( src/core/lib/iomgr/timer_heap.h ) + s.files += %w( src/core/lib/iomgr/udp_server.h ) + s.files += %w( src/core/lib/iomgr/unix_sockets_posix.h ) + s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.h ) + s.files += %w( src/core/lib/iomgr/wakeup_fd_posix.h ) + s.files += %w( src/core/lib/iomgr/workqueue.h ) + s.files += %w( src/core/lib/iomgr/workqueue_posix.h ) + s.files += %w( src/core/lib/iomgr/workqueue_windows.h ) + s.files += %w( src/core/lib/json/json.h ) + s.files += %w( src/core/lib/json/json_common.h ) + s.files += %w( src/core/lib/json/json_reader.h ) + s.files += %w( src/core/lib/json/json_writer.h ) + s.files += %w( src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h ) + s.files += %w( src/core/lib/statistics/census_interface.h ) + s.files += %w( src/core/lib/statistics/census_rpc_stats.h ) + s.files += %w( src/core/lib/surface/api_trace.h ) + s.files += %w( src/core/lib/surface/call.h ) + s.files += %w( src/core/lib/surface/call_test_only.h ) + s.files += %w( src/core/lib/surface/channel.h ) + s.files += %w( src/core/lib/surface/channel_init.h ) + s.files += %w( src/core/lib/surface/channel_stack_type.h ) + s.files += %w( src/core/lib/surface/completion_queue.h ) + s.files += %w( src/core/lib/surface/event_string.h ) + s.files += %w( src/core/lib/surface/init.h ) + s.files += %w( src/core/lib/surface/lame_client.h ) + s.files += %w( src/core/lib/surface/server.h ) + s.files += %w( src/core/lib/surface/surface_trace.h ) + s.files += %w( src/core/lib/transport/byte_stream.h ) + s.files += %w( src/core/lib/transport/chttp2/alpn.h ) + s.files += %w( src/core/lib/transport/chttp2/bin_encoder.h ) + s.files += %w( src/core/lib/transport/chttp2/frame.h ) + s.files += %w( src/core/lib/transport/chttp2/frame_data.h ) + s.files += %w( src/core/lib/transport/chttp2/frame_goaway.h ) + s.files += %w( src/core/lib/transport/chttp2/frame_ping.h ) + s.files += %w( src/core/lib/transport/chttp2/frame_rst_stream.h ) + s.files += %w( src/core/lib/transport/chttp2/frame_settings.h ) + s.files += %w( src/core/lib/transport/chttp2/frame_window_update.h ) + s.files += %w( src/core/lib/transport/chttp2/hpack_encoder.h ) + s.files += %w( src/core/lib/transport/chttp2/hpack_parser.h ) + s.files += %w( src/core/lib/transport/chttp2/hpack_table.h ) + s.files += %w( src/core/lib/transport/chttp2/http2_errors.h ) + s.files += %w( src/core/lib/transport/chttp2/huffsyms.h ) + s.files += %w( src/core/lib/transport/chttp2/incoming_metadata.h ) + s.files += %w( src/core/lib/transport/chttp2/internal.h ) + s.files += %w( src/core/lib/transport/chttp2/status_conversion.h ) + s.files += %w( src/core/lib/transport/chttp2/stream_map.h ) + s.files += %w( src/core/lib/transport/chttp2/timeout_encoding.h ) + s.files += %w( src/core/lib/transport/chttp2/varint.h ) + s.files += %w( src/core/lib/transport/chttp2_transport.h ) + s.files += %w( src/core/lib/transport/connectivity_state.h ) + s.files += %w( src/core/lib/transport/metadata.h ) + s.files += %w( src/core/lib/transport/metadata_batch.h ) + s.files += %w( src/core/lib/transport/static_metadata.h ) + s.files += %w( src/core/lib/transport/transport.h ) + s.files += %w( src/core/lib/transport/transport_impl.h ) + s.files += %w( src/core/lib/security/auth_filters.h ) + s.files += %w( src/core/lib/security/b64.h ) + s.files += %w( src/core/lib/security/credentials.h ) + s.files += %w( src/core/lib/security/handshake.h ) + s.files += %w( src/core/lib/security/json_token.h ) + s.files += %w( src/core/lib/security/jwt_verifier.h ) + s.files += %w( src/core/lib/security/secure_endpoint.h ) + s.files += %w( src/core/lib/security/security_connector.h ) + s.files += %w( src/core/lib/security/security_context.h ) + s.files += %w( src/core/lib/tsi/fake_transport_security.h ) + s.files += %w( src/core/lib/tsi/ssl_transport_security.h ) + s.files += %w( src/core/lib/tsi/ssl_types.h ) + s.files += %w( src/core/lib/tsi/transport_security.h ) + s.files += %w( src/core/lib/tsi/transport_security_interface.h ) + s.files += %w( src/core/lib/census/aggregation.h ) + s.files += %w( src/core/lib/census/mlog.h ) + s.files += %w( src/core/lib/census/rpc_metric_id.h ) s.files += %w( third_party/nanopb/pb.h ) s.files += %w( third_party/nanopb/pb_common.h ) s.files += %w( third_party/nanopb/pb_decode.h ) s.files += %w( third_party/nanopb/pb_encode.h ) - s.files += %w( src/core/census/grpc_context.c ) - s.files += %w( src/core/census/grpc_filter.c ) - s.files += %w( src/core/census/grpc_plugin.c ) - s.files += %w( src/core/channel/channel_args.c ) - s.files += %w( src/core/channel/channel_stack.c ) - s.files += %w( src/core/channel/channel_stack_builder.c ) - s.files += %w( src/core/channel/client_channel.c ) - s.files += %w( src/core/channel/compress_filter.c ) - s.files += %w( src/core/channel/connected_channel.c ) - s.files += %w( src/core/channel/http_client_filter.c ) - s.files += %w( src/core/channel/http_server_filter.c ) - s.files += %w( src/core/channel/subchannel_call_holder.c ) - s.files += %w( src/core/client_config/client_config.c ) - s.files += %w( src/core/client_config/connector.c ) - s.files += %w( src/core/client_config/default_initial_connect_string.c ) - s.files += %w( src/core/client_config/initial_connect_string.c ) - s.files += %w( src/core/client_config/lb_policies/load_balancer_api.c ) - s.files += %w( src/core/client_config/lb_policies/pick_first.c ) - s.files += %w( src/core/client_config/lb_policies/round_robin.c ) - s.files += %w( src/core/client_config/lb_policy.c ) - s.files += %w( src/core/client_config/lb_policy_factory.c ) - s.files += %w( src/core/client_config/lb_policy_registry.c ) - s.files += %w( src/core/client_config/resolver.c ) - s.files += %w( src/core/client_config/resolver_factory.c ) - s.files += %w( src/core/client_config/resolver_registry.c ) - s.files += %w( src/core/client_config/resolvers/dns_resolver.c ) - s.files += %w( src/core/client_config/resolvers/sockaddr_resolver.c ) - s.files += %w( src/core/client_config/subchannel.c ) - s.files += %w( src/core/client_config/subchannel_factory.c ) - s.files += %w( src/core/client_config/subchannel_index.c ) - s.files += %w( src/core/client_config/uri_parser.c ) - s.files += %w( src/core/compression/compression_algorithm.c ) - s.files += %w( src/core/compression/message_compress.c ) - s.files += %w( src/core/debug/trace.c ) - s.files += %w( src/core/http/format_request.c ) - s.files += %w( src/core/http/httpcli.c ) - s.files += %w( src/core/http/parser.c ) - s.files += %w( src/core/iomgr/closure.c ) - s.files += %w( src/core/iomgr/endpoint.c ) - s.files += %w( src/core/iomgr/endpoint_pair_posix.c ) - s.files += %w( src/core/iomgr/endpoint_pair_windows.c ) - s.files += %w( src/core/iomgr/exec_ctx.c ) - s.files += %w( src/core/iomgr/executor.c ) - s.files += %w( src/core/iomgr/fd_posix.c ) - s.files += %w( src/core/iomgr/iocp_windows.c ) - s.files += %w( src/core/iomgr/iomgr.c ) - s.files += %w( src/core/iomgr/iomgr_posix.c ) - s.files += %w( src/core/iomgr/iomgr_windows.c ) - s.files += %w( src/core/iomgr/pollset_multipoller_with_epoll.c ) - s.files += %w( src/core/iomgr/pollset_multipoller_with_poll_posix.c ) - s.files += %w( src/core/iomgr/pollset_posix.c ) - s.files += %w( src/core/iomgr/pollset_set_posix.c ) - s.files += %w( src/core/iomgr/pollset_set_windows.c ) - s.files += %w( src/core/iomgr/pollset_windows.c ) - s.files += %w( src/core/iomgr/resolve_address_posix.c ) - s.files += %w( src/core/iomgr/resolve_address_windows.c ) - s.files += %w( src/core/iomgr/sockaddr_utils.c ) - s.files += %w( src/core/iomgr/socket_utils_common_posix.c ) - s.files += %w( src/core/iomgr/socket_utils_linux.c ) - s.files += %w( src/core/iomgr/socket_utils_posix.c ) - s.files += %w( src/core/iomgr/socket_windows.c ) - s.files += %w( src/core/iomgr/tcp_client_posix.c ) - s.files += %w( src/core/iomgr/tcp_client_windows.c ) - s.files += %w( src/core/iomgr/tcp_posix.c ) - s.files += %w( src/core/iomgr/tcp_server_posix.c ) - s.files += %w( src/core/iomgr/tcp_server_windows.c ) - s.files += %w( src/core/iomgr/tcp_windows.c ) - s.files += %w( src/core/iomgr/time_averaged_stats.c ) - s.files += %w( src/core/iomgr/timer.c ) - s.files += %w( src/core/iomgr/timer_heap.c ) - s.files += %w( src/core/iomgr/udp_server.c ) - s.files += %w( src/core/iomgr/unix_sockets_posix.c ) - s.files += %w( src/core/iomgr/unix_sockets_posix_noop.c ) - s.files += %w( src/core/iomgr/wakeup_fd_eventfd.c ) - s.files += %w( src/core/iomgr/wakeup_fd_nospecial.c ) - s.files += %w( src/core/iomgr/wakeup_fd_pipe.c ) - s.files += %w( src/core/iomgr/wakeup_fd_posix.c ) - s.files += %w( src/core/iomgr/workqueue_posix.c ) - s.files += %w( src/core/iomgr/workqueue_windows.c ) - s.files += %w( src/core/json/json.c ) - s.files += %w( src/core/json/json_reader.c ) - s.files += %w( src/core/json/json_string.c ) - s.files += %w( src/core/json/json_writer.c ) - s.files += %w( src/core/proto/grpc/lb/v0/load_balancer.pb.c ) - s.files += %w( src/core/surface/alarm.c ) - s.files += %w( src/core/surface/api_trace.c ) - s.files += %w( src/core/surface/byte_buffer.c ) - s.files += %w( src/core/surface/byte_buffer_reader.c ) - s.files += %w( src/core/surface/call.c ) - s.files += %w( src/core/surface/call_details.c ) - s.files += %w( src/core/surface/call_log_batch.c ) - s.files += %w( src/core/surface/channel.c ) - s.files += %w( src/core/surface/channel_connectivity.c ) - s.files += %w( src/core/surface/channel_create.c ) - s.files += %w( src/core/surface/channel_init.c ) - s.files += %w( src/core/surface/channel_ping.c ) - s.files += %w( src/core/surface/channel_stack_type.c ) - s.files += %w( src/core/surface/completion_queue.c ) - s.files += %w( src/core/surface/event_string.c ) - s.files += %w( src/core/surface/init.c ) - s.files += %w( src/core/surface/lame_client.c ) - s.files += %w( src/core/surface/metadata_array.c ) - s.files += %w( src/core/surface/server.c ) - s.files += %w( src/core/surface/server_chttp2.c ) - s.files += %w( src/core/surface/validate_metadata.c ) - s.files += %w( src/core/surface/version.c ) - s.files += %w( src/core/transport/byte_stream.c ) - s.files += %w( src/core/transport/chttp2/alpn.c ) - s.files += %w( src/core/transport/chttp2/bin_encoder.c ) - s.files += %w( src/core/transport/chttp2/frame_data.c ) - s.files += %w( src/core/transport/chttp2/frame_goaway.c ) - s.files += %w( src/core/transport/chttp2/frame_ping.c ) - s.files += %w( src/core/transport/chttp2/frame_rst_stream.c ) - s.files += %w( src/core/transport/chttp2/frame_settings.c ) - s.files += %w( src/core/transport/chttp2/frame_window_update.c ) - s.files += %w( src/core/transport/chttp2/hpack_encoder.c ) - s.files += %w( src/core/transport/chttp2/hpack_parser.c ) - s.files += %w( src/core/transport/chttp2/hpack_table.c ) - s.files += %w( src/core/transport/chttp2/huffsyms.c ) - s.files += %w( src/core/transport/chttp2/incoming_metadata.c ) - s.files += %w( src/core/transport/chttp2/parsing.c ) - s.files += %w( src/core/transport/chttp2/status_conversion.c ) - s.files += %w( src/core/transport/chttp2/stream_lists.c ) - s.files += %w( src/core/transport/chttp2/stream_map.c ) - s.files += %w( src/core/transport/chttp2/timeout_encoding.c ) - s.files += %w( src/core/transport/chttp2/varint.c ) - s.files += %w( src/core/transport/chttp2/writing.c ) - s.files += %w( src/core/transport/chttp2_transport.c ) - s.files += %w( src/core/transport/connectivity_state.c ) - s.files += %w( src/core/transport/metadata.c ) - s.files += %w( src/core/transport/metadata_batch.c ) - s.files += %w( src/core/transport/static_metadata.c ) - s.files += %w( src/core/transport/transport.c ) - s.files += %w( src/core/transport/transport_op_string.c ) - s.files += %w( src/core/http/httpcli_security_connector.c ) - s.files += %w( src/core/security/b64.c ) - s.files += %w( src/core/security/client_auth_filter.c ) - s.files += %w( src/core/security/credentials.c ) - s.files += %w( src/core/security/credentials_metadata.c ) - s.files += %w( src/core/security/credentials_posix.c ) - s.files += %w( src/core/security/credentials_win32.c ) - s.files += %w( src/core/security/google_default_credentials.c ) - s.files += %w( src/core/security/handshake.c ) - s.files += %w( src/core/security/json_token.c ) - s.files += %w( src/core/security/jwt_verifier.c ) - s.files += %w( src/core/security/secure_endpoint.c ) - s.files += %w( src/core/security/security_connector.c ) - s.files += %w( src/core/security/security_context.c ) - s.files += %w( src/core/security/server_auth_filter.c ) - s.files += %w( src/core/security/server_secure_chttp2.c ) - s.files += %w( src/core/surface/init_secure.c ) - s.files += %w( src/core/surface/secure_channel_create.c ) - s.files += %w( src/core/tsi/fake_transport_security.c ) - s.files += %w( src/core/tsi/ssl_transport_security.c ) - s.files += %w( src/core/tsi/transport_security.c ) - s.files += %w( src/core/census/context.c ) - s.files += %w( src/core/census/initialize.c ) - s.files += %w( src/core/census/mlog.c ) - s.files += %w( src/core/census/operation.c ) - s.files += %w( src/core/census/placeholders.c ) - s.files += %w( src/core/census/tracing.c ) + s.files += %w( src/core/lib/census/grpc_context.c ) + s.files += %w( src/core/lib/census/grpc_filter.c ) + s.files += %w( src/core/lib/census/grpc_plugin.c ) + s.files += %w( src/core/lib/channel/channel_args.c ) + s.files += %w( src/core/lib/channel/channel_stack.c ) + s.files += %w( src/core/lib/channel/channel_stack_builder.c ) + s.files += %w( src/core/lib/channel/client_channel.c ) + s.files += %w( src/core/lib/channel/compress_filter.c ) + s.files += %w( src/core/lib/channel/connected_channel.c ) + s.files += %w( src/core/lib/channel/http_client_filter.c ) + s.files += %w( src/core/lib/channel/http_server_filter.c ) + s.files += %w( src/core/lib/channel/subchannel_call_holder.c ) + s.files += %w( src/core/lib/client_config/client_config.c ) + s.files += %w( src/core/lib/client_config/connector.c ) + s.files += %w( src/core/lib/client_config/default_initial_connect_string.c ) + s.files += %w( src/core/lib/client_config/initial_connect_string.c ) + s.files += %w( src/core/lib/client_config/lb_policies/load_balancer_api.c ) + s.files += %w( src/core/lib/client_config/lb_policies/pick_first.c ) + s.files += %w( src/core/lib/client_config/lb_policies/round_robin.c ) + s.files += %w( src/core/lib/client_config/lb_policy.c ) + s.files += %w( src/core/lib/client_config/lb_policy_factory.c ) + s.files += %w( src/core/lib/client_config/lb_policy_registry.c ) + s.files += %w( src/core/lib/client_config/resolver.c ) + s.files += %w( src/core/lib/client_config/resolver_factory.c ) + s.files += %w( src/core/lib/client_config/resolver_registry.c ) + s.files += %w( src/core/lib/client_config/resolvers/dns_resolver.c ) + s.files += %w( src/core/lib/client_config/resolvers/sockaddr_resolver.c ) + s.files += %w( src/core/lib/client_config/subchannel.c ) + s.files += %w( src/core/lib/client_config/subchannel_factory.c ) + s.files += %w( src/core/lib/client_config/subchannel_index.c ) + s.files += %w( src/core/lib/client_config/uri_parser.c ) + s.files += %w( src/core/lib/compression/compression_algorithm.c ) + s.files += %w( src/core/lib/compression/message_compress.c ) + s.files += %w( src/core/lib/debug/trace.c ) + s.files += %w( src/core/lib/http/format_request.c ) + s.files += %w( src/core/lib/http/httpcli.c ) + s.files += %w( src/core/lib/http/parser.c ) + s.files += %w( src/core/lib/iomgr/closure.c ) + s.files += %w( src/core/lib/iomgr/endpoint.c ) + s.files += %w( src/core/lib/iomgr/endpoint_pair_posix.c ) + s.files += %w( src/core/lib/iomgr/endpoint_pair_windows.c ) + s.files += %w( src/core/lib/iomgr/exec_ctx.c ) + s.files += %w( src/core/lib/iomgr/executor.c ) + s.files += %w( src/core/lib/iomgr/fd_posix.c ) + s.files += %w( src/core/lib/iomgr/iocp_windows.c ) + s.files += %w( src/core/lib/iomgr/iomgr.c ) + s.files += %w( src/core/lib/iomgr/iomgr_posix.c ) + s.files += %w( src/core/lib/iomgr/iomgr_windows.c ) + s.files += %w( src/core/lib/iomgr/pollset_multipoller_with_epoll.c ) + s.files += %w( src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c ) + s.files += %w( src/core/lib/iomgr/pollset_posix.c ) + s.files += %w( src/core/lib/iomgr/pollset_set_posix.c ) + s.files += %w( src/core/lib/iomgr/pollset_set_windows.c ) + s.files += %w( src/core/lib/iomgr/pollset_windows.c ) + s.files += %w( src/core/lib/iomgr/resolve_address_posix.c ) + s.files += %w( src/core/lib/iomgr/resolve_address_windows.c ) + s.files += %w( src/core/lib/iomgr/sockaddr_utils.c ) + s.files += %w( src/core/lib/iomgr/socket_utils_common_posix.c ) + s.files += %w( src/core/lib/iomgr/socket_utils_linux.c ) + s.files += %w( src/core/lib/iomgr/socket_utils_posix.c ) + s.files += %w( src/core/lib/iomgr/socket_windows.c ) + s.files += %w( src/core/lib/iomgr/tcp_client_posix.c ) + s.files += %w( src/core/lib/iomgr/tcp_client_windows.c ) + s.files += %w( src/core/lib/iomgr/tcp_posix.c ) + s.files += %w( src/core/lib/iomgr/tcp_server_posix.c ) + s.files += %w( src/core/lib/iomgr/tcp_server_windows.c ) + s.files += %w( src/core/lib/iomgr/tcp_windows.c ) + s.files += %w( src/core/lib/iomgr/time_averaged_stats.c ) + s.files += %w( src/core/lib/iomgr/timer.c ) + s.files += %w( src/core/lib/iomgr/timer_heap.c ) + s.files += %w( src/core/lib/iomgr/udp_server.c ) + s.files += %w( src/core/lib/iomgr/unix_sockets_posix.c ) + s.files += %w( src/core/lib/iomgr/unix_sockets_posix_noop.c ) + s.files += %w( src/core/lib/iomgr/wakeup_fd_eventfd.c ) + s.files += %w( src/core/lib/iomgr/wakeup_fd_nospecial.c ) + s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.c ) + s.files += %w( src/core/lib/iomgr/wakeup_fd_posix.c ) + s.files += %w( src/core/lib/iomgr/workqueue_posix.c ) + s.files += %w( src/core/lib/iomgr/workqueue_windows.c ) + s.files += %w( src/core/lib/json/json.c ) + s.files += %w( src/core/lib/json/json_reader.c ) + s.files += %w( src/core/lib/json/json_string.c ) + s.files += %w( src/core/lib/json/json_writer.c ) + s.files += %w( src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c ) + s.files += %w( src/core/lib/surface/alarm.c ) + s.files += %w( src/core/lib/surface/api_trace.c ) + s.files += %w( src/core/lib/surface/byte_buffer.c ) + s.files += %w( src/core/lib/surface/byte_buffer_reader.c ) + s.files += %w( src/core/lib/surface/call.c ) + s.files += %w( src/core/lib/surface/call_details.c ) + s.files += %w( src/core/lib/surface/call_log_batch.c ) + s.files += %w( src/core/lib/surface/channel.c ) + s.files += %w( src/core/lib/surface/channel_connectivity.c ) + s.files += %w( src/core/lib/surface/channel_create.c ) + s.files += %w( src/core/lib/surface/channel_init.c ) + s.files += %w( src/core/lib/surface/channel_ping.c ) + s.files += %w( src/core/lib/surface/channel_stack_type.c ) + s.files += %w( src/core/lib/surface/completion_queue.c ) + s.files += %w( src/core/lib/surface/event_string.c ) + s.files += %w( src/core/lib/surface/init.c ) + s.files += %w( src/core/lib/surface/lame_client.c ) + s.files += %w( src/core/lib/surface/metadata_array.c ) + s.files += %w( src/core/lib/surface/server.c ) + s.files += %w( src/core/lib/surface/server_chttp2.c ) + s.files += %w( src/core/lib/surface/validate_metadata.c ) + s.files += %w( src/core/lib/surface/version.c ) + s.files += %w( src/core/lib/transport/byte_stream.c ) + s.files += %w( src/core/lib/transport/chttp2/alpn.c ) + s.files += %w( src/core/lib/transport/chttp2/bin_encoder.c ) + s.files += %w( src/core/lib/transport/chttp2/frame_data.c ) + s.files += %w( src/core/lib/transport/chttp2/frame_goaway.c ) + s.files += %w( src/core/lib/transport/chttp2/frame_ping.c ) + s.files += %w( src/core/lib/transport/chttp2/frame_rst_stream.c ) + s.files += %w( src/core/lib/transport/chttp2/frame_settings.c ) + s.files += %w( src/core/lib/transport/chttp2/frame_window_update.c ) + s.files += %w( src/core/lib/transport/chttp2/hpack_encoder.c ) + s.files += %w( src/core/lib/transport/chttp2/hpack_parser.c ) + s.files += %w( src/core/lib/transport/chttp2/hpack_table.c ) + s.files += %w( src/core/lib/transport/chttp2/huffsyms.c ) + s.files += %w( src/core/lib/transport/chttp2/incoming_metadata.c ) + s.files += %w( src/core/lib/transport/chttp2/parsing.c ) + s.files += %w( src/core/lib/transport/chttp2/status_conversion.c ) + s.files += %w( src/core/lib/transport/chttp2/stream_lists.c ) + s.files += %w( src/core/lib/transport/chttp2/stream_map.c ) + s.files += %w( src/core/lib/transport/chttp2/timeout_encoding.c ) + s.files += %w( src/core/lib/transport/chttp2/varint.c ) + s.files += %w( src/core/lib/transport/chttp2/writing.c ) + s.files += %w( src/core/lib/transport/chttp2_transport.c ) + s.files += %w( src/core/lib/transport/connectivity_state.c ) + s.files += %w( src/core/lib/transport/metadata.c ) + s.files += %w( src/core/lib/transport/metadata_batch.c ) + s.files += %w( src/core/lib/transport/static_metadata.c ) + s.files += %w( src/core/lib/transport/transport.c ) + s.files += %w( src/core/lib/transport/transport_op_string.c ) + s.files += %w( src/core/lib/http/httpcli_security_connector.c ) + s.files += %w( src/core/lib/security/b64.c ) + s.files += %w( src/core/lib/security/client_auth_filter.c ) + s.files += %w( src/core/lib/security/credentials.c ) + s.files += %w( src/core/lib/security/credentials_metadata.c ) + s.files += %w( src/core/lib/security/credentials_posix.c ) + s.files += %w( src/core/lib/security/credentials_win32.c ) + s.files += %w( src/core/lib/security/google_default_credentials.c ) + s.files += %w( src/core/lib/security/handshake.c ) + s.files += %w( src/core/lib/security/json_token.c ) + s.files += %w( src/core/lib/security/jwt_verifier.c ) + s.files += %w( src/core/lib/security/secure_endpoint.c ) + s.files += %w( src/core/lib/security/security_connector.c ) + s.files += %w( src/core/lib/security/security_context.c ) + s.files += %w( src/core/lib/security/server_auth_filter.c ) + s.files += %w( src/core/lib/security/server_secure_chttp2.c ) + s.files += %w( src/core/lib/surface/init_secure.c ) + s.files += %w( src/core/lib/surface/secure_channel_create.c ) + s.files += %w( src/core/lib/tsi/fake_transport_security.c ) + s.files += %w( src/core/lib/tsi/ssl_transport_security.c ) + s.files += %w( src/core/lib/tsi/transport_security.c ) + s.files += %w( src/core/lib/census/context.c ) + s.files += %w( src/core/lib/census/initialize.c ) + s.files += %w( src/core/lib/census/mlog.c ) + s.files += %w( src/core/lib/census/operation.c ) + s.files += %w( src/core/lib/census/placeholders.c ) + s.files += %w( src/core/lib/census/tracing.c ) s.files += %w( third_party/nanopb/pb_common.c ) s.files += %w( third_party/nanopb/pb_decode.c ) s.files += %w( third_party/nanopb/pb_encode.c ) diff --git a/package.json b/package.json index fe085775f8..37856d7cc7 100644 --- a/package.json +++ b/package.json @@ -99,308 +99,308 @@ "include/grpc/impl/codegen/propagation_bits.h", "include/grpc/impl/codegen/status.h", "include/grpc/census.h", - "src/core/census/grpc_filter.h", - "src/core/census/grpc_plugin.h", - "src/core/channel/channel_args.h", - "src/core/channel/channel_stack.h", - "src/core/channel/channel_stack_builder.h", - "src/core/channel/client_channel.h", - "src/core/channel/compress_filter.h", - "src/core/channel/connected_channel.h", - "src/core/channel/context.h", - "src/core/channel/http_client_filter.h", - "src/core/channel/http_server_filter.h", - "src/core/channel/subchannel_call_holder.h", - "src/core/client_config/client_config.h", - "src/core/client_config/connector.h", - "src/core/client_config/initial_connect_string.h", - "src/core/client_config/lb_policies/load_balancer_api.h", - "src/core/client_config/lb_policies/pick_first.h", - "src/core/client_config/lb_policies/round_robin.h", - "src/core/client_config/lb_policy.h", - "src/core/client_config/lb_policy_factory.h", - "src/core/client_config/lb_policy_registry.h", - "src/core/client_config/resolver.h", - "src/core/client_config/resolver_factory.h", - "src/core/client_config/resolver_registry.h", - "src/core/client_config/resolvers/dns_resolver.h", - "src/core/client_config/resolvers/sockaddr_resolver.h", - "src/core/client_config/subchannel.h", - "src/core/client_config/subchannel_factory.h", - "src/core/client_config/subchannel_index.h", - "src/core/client_config/uri_parser.h", - "src/core/compression/algorithm_metadata.h", - "src/core/compression/message_compress.h", - "src/core/debug/trace.h", - "src/core/http/format_request.h", - "src/core/http/httpcli.h", - "src/core/http/parser.h", - "src/core/iomgr/closure.h", - "src/core/iomgr/endpoint.h", - "src/core/iomgr/endpoint_pair.h", - "src/core/iomgr/exec_ctx.h", - "src/core/iomgr/executor.h", - "src/core/iomgr/fd_posix.h", - "src/core/iomgr/iocp_windows.h", - "src/core/iomgr/iomgr.h", - "src/core/iomgr/iomgr_internal.h", - "src/core/iomgr/iomgr_posix.h", - "src/core/iomgr/pollset.h", - "src/core/iomgr/pollset_posix.h", - "src/core/iomgr/pollset_set.h", - "src/core/iomgr/pollset_set_posix.h", - "src/core/iomgr/pollset_set_windows.h", - "src/core/iomgr/pollset_windows.h", - "src/core/iomgr/resolve_address.h", - "src/core/iomgr/sockaddr.h", - "src/core/iomgr/sockaddr_posix.h", - "src/core/iomgr/sockaddr_utils.h", - "src/core/iomgr/sockaddr_win32.h", - "src/core/iomgr/socket_utils_posix.h", - "src/core/iomgr/socket_windows.h", - "src/core/iomgr/tcp_client.h", - "src/core/iomgr/tcp_posix.h", - "src/core/iomgr/tcp_server.h", - "src/core/iomgr/tcp_windows.h", - "src/core/iomgr/time_averaged_stats.h", - "src/core/iomgr/timer.h", - "src/core/iomgr/timer_heap.h", - "src/core/iomgr/udp_server.h", - "src/core/iomgr/unix_sockets_posix.h", - "src/core/iomgr/wakeup_fd_pipe.h", - "src/core/iomgr/wakeup_fd_posix.h", - "src/core/iomgr/workqueue.h", - "src/core/iomgr/workqueue_posix.h", - "src/core/iomgr/workqueue_windows.h", - "src/core/json/json.h", - "src/core/json/json_common.h", - "src/core/json/json_reader.h", - "src/core/json/json_writer.h", - "src/core/proto/grpc/lb/v0/load_balancer.pb.h", - "src/core/statistics/census_interface.h", - "src/core/statistics/census_rpc_stats.h", - "src/core/surface/api_trace.h", - "src/core/surface/call.h", - "src/core/surface/call_test_only.h", - "src/core/surface/channel.h", - "src/core/surface/channel_init.h", - "src/core/surface/channel_stack_type.h", - "src/core/surface/completion_queue.h", - "src/core/surface/event_string.h", - "src/core/surface/init.h", - "src/core/surface/lame_client.h", - "src/core/surface/server.h", - "src/core/surface/surface_trace.h", - "src/core/transport/byte_stream.h", - "src/core/transport/chttp2/alpn.h", - "src/core/transport/chttp2/bin_encoder.h", - "src/core/transport/chttp2/frame.h", - "src/core/transport/chttp2/frame_data.h", - "src/core/transport/chttp2/frame_goaway.h", - "src/core/transport/chttp2/frame_ping.h", - "src/core/transport/chttp2/frame_rst_stream.h", - "src/core/transport/chttp2/frame_settings.h", - "src/core/transport/chttp2/frame_window_update.h", - "src/core/transport/chttp2/hpack_encoder.h", - "src/core/transport/chttp2/hpack_parser.h", - "src/core/transport/chttp2/hpack_table.h", - "src/core/transport/chttp2/http2_errors.h", - "src/core/transport/chttp2/huffsyms.h", - "src/core/transport/chttp2/incoming_metadata.h", - "src/core/transport/chttp2/internal.h", - "src/core/transport/chttp2/status_conversion.h", - "src/core/transport/chttp2/stream_map.h", - "src/core/transport/chttp2/timeout_encoding.h", - "src/core/transport/chttp2/varint.h", - "src/core/transport/chttp2_transport.h", - "src/core/transport/connectivity_state.h", - "src/core/transport/metadata.h", - "src/core/transport/metadata_batch.h", - "src/core/transport/static_metadata.h", - "src/core/transport/transport.h", - "src/core/transport/transport_impl.h", - "src/core/security/auth_filters.h", - "src/core/security/b64.h", - "src/core/security/credentials.h", - "src/core/security/handshake.h", - "src/core/security/json_token.h", - "src/core/security/jwt_verifier.h", - "src/core/security/secure_endpoint.h", - "src/core/security/security_connector.h", - "src/core/security/security_context.h", - "src/core/tsi/fake_transport_security.h", - "src/core/tsi/ssl_transport_security.h", - "src/core/tsi/ssl_types.h", - "src/core/tsi/transport_security.h", - "src/core/tsi/transport_security_interface.h", - "src/core/census/aggregation.h", - "src/core/census/mlog.h", - "src/core/census/rpc_metric_id.h", + "src/core/lib/census/grpc_filter.h", + "src/core/lib/census/grpc_plugin.h", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/client_channel.h", + "src/core/lib/channel/compress_filter.h", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/http_client_filter.h", + "src/core/lib/channel/http_server_filter.h", + "src/core/lib/channel/subchannel_call_holder.h", + "src/core/lib/client_config/client_config.h", + "src/core/lib/client_config/connector.h", + "src/core/lib/client_config/initial_connect_string.h", + "src/core/lib/client_config/lb_policies/load_balancer_api.h", + "src/core/lib/client_config/lb_policies/pick_first.h", + "src/core/lib/client_config/lb_policies/round_robin.h", + "src/core/lib/client_config/lb_policy.h", + "src/core/lib/client_config/lb_policy_factory.h", + "src/core/lib/client_config/lb_policy_registry.h", + "src/core/lib/client_config/resolver.h", + "src/core/lib/client_config/resolver_factory.h", + "src/core/lib/client_config/resolver_registry.h", + "src/core/lib/client_config/resolvers/dns_resolver.h", + "src/core/lib/client_config/resolvers/sockaddr_resolver.h", + "src/core/lib/client_config/subchannel.h", + "src/core/lib/client_config/subchannel_factory.h", + "src/core/lib/client_config/subchannel_index.h", + "src/core/lib/client_config/uri_parser.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/message_compress.h", + "src/core/lib/debug/trace.h", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/fd_posix.h", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_posix.h", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_posix.h", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_win32.h", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/iomgr/workqueue.h", + "src/core/lib/iomgr/workqueue_posix.h", + "src/core/lib/iomgr/workqueue_windows.h", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_writer.h", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h", + "src/core/lib/statistics/census_interface.h", + "src/core/lib/statistics/census_rpc_stats.h", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.h", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/server.h", + "src/core/lib/surface/surface_trace.h", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/chttp2/alpn.h", + "src/core/lib/transport/chttp2/bin_encoder.h", + "src/core/lib/transport/chttp2/frame.h", + "src/core/lib/transport/chttp2/frame_data.h", + "src/core/lib/transport/chttp2/frame_goaway.h", + "src/core/lib/transport/chttp2/frame_ping.h", + "src/core/lib/transport/chttp2/frame_rst_stream.h", + "src/core/lib/transport/chttp2/frame_settings.h", + "src/core/lib/transport/chttp2/frame_window_update.h", + "src/core/lib/transport/chttp2/hpack_encoder.h", + "src/core/lib/transport/chttp2/hpack_parser.h", + "src/core/lib/transport/chttp2/hpack_table.h", + "src/core/lib/transport/chttp2/http2_errors.h", + "src/core/lib/transport/chttp2/huffsyms.h", + "src/core/lib/transport/chttp2/incoming_metadata.h", + "src/core/lib/transport/chttp2/internal.h", + "src/core/lib/transport/chttp2/status_conversion.h", + "src/core/lib/transport/chttp2/stream_map.h", + "src/core/lib/transport/chttp2/timeout_encoding.h", + "src/core/lib/transport/chttp2/varint.h", + "src/core/lib/transport/chttp2_transport.h", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", + "src/core/lib/security/auth_filters.h", + "src/core/lib/security/b64.h", + "src/core/lib/security/credentials.h", + "src/core/lib/security/handshake.h", + "src/core/lib/security/json_token.h", + "src/core/lib/security/jwt_verifier.h", + "src/core/lib/security/secure_endpoint.h", + "src/core/lib/security/security_connector.h", + "src/core/lib/security/security_context.h", + "src/core/lib/tsi/fake_transport_security.h", + "src/core/lib/tsi/ssl_transport_security.h", + "src/core/lib/tsi/ssl_types.h", + "src/core/lib/tsi/transport_security.h", + "src/core/lib/tsi/transport_security_interface.h", + "src/core/lib/census/aggregation.h", + "src/core/lib/census/mlog.h", + "src/core/lib/census/rpc_metric_id.h", "third_party/nanopb/pb.h", "third_party/nanopb/pb_common.h", "third_party/nanopb/pb_decode.h", "third_party/nanopb/pb_encode.h", - "src/core/census/grpc_context.c", - "src/core/census/grpc_filter.c", - "src/core/census/grpc_plugin.c", - "src/core/channel/channel_args.c", - "src/core/channel/channel_stack.c", - "src/core/channel/channel_stack_builder.c", - "src/core/channel/client_channel.c", - "src/core/channel/compress_filter.c", - "src/core/channel/connected_channel.c", - "src/core/channel/http_client_filter.c", - "src/core/channel/http_server_filter.c", - "src/core/channel/subchannel_call_holder.c", - "src/core/client_config/client_config.c", - "src/core/client_config/connector.c", - "src/core/client_config/default_initial_connect_string.c", - "src/core/client_config/initial_connect_string.c", - "src/core/client_config/lb_policies/load_balancer_api.c", - "src/core/client_config/lb_policies/pick_first.c", - "src/core/client_config/lb_policies/round_robin.c", - "src/core/client_config/lb_policy.c", - "src/core/client_config/lb_policy_factory.c", - "src/core/client_config/lb_policy_registry.c", - "src/core/client_config/resolver.c", - "src/core/client_config/resolver_factory.c", - "src/core/client_config/resolver_registry.c", - "src/core/client_config/resolvers/dns_resolver.c", - "src/core/client_config/resolvers/sockaddr_resolver.c", - "src/core/client_config/subchannel.c", - "src/core/client_config/subchannel_factory.c", - "src/core/client_config/subchannel_index.c", - "src/core/client_config/uri_parser.c", - "src/core/compression/compression_algorithm.c", - "src/core/compression/message_compress.c", - "src/core/debug/trace.c", - "src/core/http/format_request.c", - "src/core/http/httpcli.c", - "src/core/http/parser.c", - "src/core/iomgr/closure.c", - "src/core/iomgr/endpoint.c", - "src/core/iomgr/endpoint_pair_posix.c", - "src/core/iomgr/endpoint_pair_windows.c", - "src/core/iomgr/exec_ctx.c", - "src/core/iomgr/executor.c", - "src/core/iomgr/fd_posix.c", - "src/core/iomgr/iocp_windows.c", - "src/core/iomgr/iomgr.c", - "src/core/iomgr/iomgr_posix.c", - "src/core/iomgr/iomgr_windows.c", - "src/core/iomgr/pollset_multipoller_with_epoll.c", - "src/core/iomgr/pollset_multipoller_with_poll_posix.c", - "src/core/iomgr/pollset_posix.c", - "src/core/iomgr/pollset_set_posix.c", - "src/core/iomgr/pollset_set_windows.c", - "src/core/iomgr/pollset_windows.c", - "src/core/iomgr/resolve_address_posix.c", - "src/core/iomgr/resolve_address_windows.c", - "src/core/iomgr/sockaddr_utils.c", - "src/core/iomgr/socket_utils_common_posix.c", - "src/core/iomgr/socket_utils_linux.c", - "src/core/iomgr/socket_utils_posix.c", - "src/core/iomgr/socket_windows.c", - "src/core/iomgr/tcp_client_posix.c", - "src/core/iomgr/tcp_client_windows.c", - "src/core/iomgr/tcp_posix.c", - "src/core/iomgr/tcp_server_posix.c", - "src/core/iomgr/tcp_server_windows.c", - "src/core/iomgr/tcp_windows.c", - "src/core/iomgr/time_averaged_stats.c", - "src/core/iomgr/timer.c", - "src/core/iomgr/timer_heap.c", - "src/core/iomgr/udp_server.c", - "src/core/iomgr/unix_sockets_posix.c", - "src/core/iomgr/unix_sockets_posix_noop.c", - "src/core/iomgr/wakeup_fd_eventfd.c", - "src/core/iomgr/wakeup_fd_nospecial.c", - "src/core/iomgr/wakeup_fd_pipe.c", - "src/core/iomgr/wakeup_fd_posix.c", - "src/core/iomgr/workqueue_posix.c", - "src/core/iomgr/workqueue_windows.c", - "src/core/json/json.c", - "src/core/json/json_reader.c", - "src/core/json/json_string.c", - "src/core/json/json_writer.c", - "src/core/proto/grpc/lb/v0/load_balancer.pb.c", - "src/core/surface/alarm.c", - "src/core/surface/api_trace.c", - "src/core/surface/byte_buffer.c", - "src/core/surface/byte_buffer_reader.c", - "src/core/surface/call.c", - "src/core/surface/call_details.c", - "src/core/surface/call_log_batch.c", - "src/core/surface/channel.c", - "src/core/surface/channel_connectivity.c", - "src/core/surface/channel_create.c", - "src/core/surface/channel_init.c", - "src/core/surface/channel_ping.c", - "src/core/surface/channel_stack_type.c", - "src/core/surface/completion_queue.c", - "src/core/surface/event_string.c", - "src/core/surface/init.c", - "src/core/surface/lame_client.c", - "src/core/surface/metadata_array.c", - "src/core/surface/server.c", - "src/core/surface/server_chttp2.c", - "src/core/surface/validate_metadata.c", - "src/core/surface/version.c", - "src/core/transport/byte_stream.c", - "src/core/transport/chttp2/alpn.c", - "src/core/transport/chttp2/bin_encoder.c", - "src/core/transport/chttp2/frame_data.c", - "src/core/transport/chttp2/frame_goaway.c", - "src/core/transport/chttp2/frame_ping.c", - "src/core/transport/chttp2/frame_rst_stream.c", - "src/core/transport/chttp2/frame_settings.c", - "src/core/transport/chttp2/frame_window_update.c", - "src/core/transport/chttp2/hpack_encoder.c", - "src/core/transport/chttp2/hpack_parser.c", - "src/core/transport/chttp2/hpack_table.c", - "src/core/transport/chttp2/huffsyms.c", - "src/core/transport/chttp2/incoming_metadata.c", - "src/core/transport/chttp2/parsing.c", - "src/core/transport/chttp2/status_conversion.c", - "src/core/transport/chttp2/stream_lists.c", - "src/core/transport/chttp2/stream_map.c", - "src/core/transport/chttp2/timeout_encoding.c", - "src/core/transport/chttp2/varint.c", - "src/core/transport/chttp2/writing.c", - "src/core/transport/chttp2_transport.c", - "src/core/transport/connectivity_state.c", - "src/core/transport/metadata.c", - "src/core/transport/metadata_batch.c", - "src/core/transport/static_metadata.c", - "src/core/transport/transport.c", - "src/core/transport/transport_op_string.c", - "src/core/http/httpcli_security_connector.c", - "src/core/security/b64.c", - "src/core/security/client_auth_filter.c", - "src/core/security/credentials.c", - "src/core/security/credentials_metadata.c", - "src/core/security/credentials_posix.c", - "src/core/security/credentials_win32.c", - "src/core/security/google_default_credentials.c", - "src/core/security/handshake.c", - "src/core/security/json_token.c", - "src/core/security/jwt_verifier.c", - "src/core/security/secure_endpoint.c", - "src/core/security/security_connector.c", - "src/core/security/security_context.c", - "src/core/security/server_auth_filter.c", - "src/core/security/server_secure_chttp2.c", - "src/core/surface/init_secure.c", - "src/core/surface/secure_channel_create.c", - "src/core/tsi/fake_transport_security.c", - "src/core/tsi/ssl_transport_security.c", - "src/core/tsi/transport_security.c", - "src/core/census/context.c", - "src/core/census/initialize.c", - "src/core/census/mlog.c", - "src/core/census/operation.c", - "src/core/census/placeholders.c", - "src/core/census/tracing.c", + "src/core/lib/census/grpc_context.c", + "src/core/lib/census/grpc_filter.c", + "src/core/lib/census/grpc_plugin.c", + "src/core/lib/channel/channel_args.c", + "src/core/lib/channel/channel_stack.c", + "src/core/lib/channel/channel_stack_builder.c", + "src/core/lib/channel/client_channel.c", + "src/core/lib/channel/compress_filter.c", + "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/http_client_filter.c", + "src/core/lib/channel/http_server_filter.c", + "src/core/lib/channel/subchannel_call_holder.c", + "src/core/lib/client_config/client_config.c", + "src/core/lib/client_config/connector.c", + "src/core/lib/client_config/default_initial_connect_string.c", + "src/core/lib/client_config/initial_connect_string.c", + "src/core/lib/client_config/lb_policies/load_balancer_api.c", + "src/core/lib/client_config/lb_policies/pick_first.c", + "src/core/lib/client_config/lb_policies/round_robin.c", + "src/core/lib/client_config/lb_policy.c", + "src/core/lib/client_config/lb_policy_factory.c", + "src/core/lib/client_config/lb_policy_registry.c", + "src/core/lib/client_config/resolver.c", + "src/core/lib/client_config/resolver_factory.c", + "src/core/lib/client_config/resolver_registry.c", + "src/core/lib/client_config/resolvers/dns_resolver.c", + "src/core/lib/client_config/resolvers/sockaddr_resolver.c", + "src/core/lib/client_config/subchannel.c", + "src/core/lib/client_config/subchannel_factory.c", + "src/core/lib/client_config/subchannel_index.c", + "src/core/lib/client_config/uri_parser.c", + "src/core/lib/compression/compression_algorithm.c", + "src/core/lib/compression/message_compress.c", + "src/core/lib/debug/trace.c", + "src/core/lib/http/format_request.c", + "src/core/lib/http/httpcli.c", + "src/core/lib/http/parser.c", + "src/core/lib/iomgr/closure.c", + "src/core/lib/iomgr/endpoint.c", + "src/core/lib/iomgr/endpoint_pair_posix.c", + "src/core/lib/iomgr/endpoint_pair_windows.c", + "src/core/lib/iomgr/exec_ctx.c", + "src/core/lib/iomgr/executor.c", + "src/core/lib/iomgr/fd_posix.c", + "src/core/lib/iomgr/iocp_windows.c", + "src/core/lib/iomgr/iomgr.c", + "src/core/lib/iomgr/iomgr_posix.c", + "src/core/lib/iomgr/iomgr_windows.c", + "src/core/lib/iomgr/pollset_multipoller_with_epoll.c", + "src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c", + "src/core/lib/iomgr/pollset_posix.c", + "src/core/lib/iomgr/pollset_set_posix.c", + "src/core/lib/iomgr/pollset_set_windows.c", + "src/core/lib/iomgr/pollset_windows.c", + "src/core/lib/iomgr/resolve_address_posix.c", + "src/core/lib/iomgr/resolve_address_windows.c", + "src/core/lib/iomgr/sockaddr_utils.c", + "src/core/lib/iomgr/socket_utils_common_posix.c", + "src/core/lib/iomgr/socket_utils_linux.c", + "src/core/lib/iomgr/socket_utils_posix.c", + "src/core/lib/iomgr/socket_windows.c", + "src/core/lib/iomgr/tcp_client_posix.c", + "src/core/lib/iomgr/tcp_client_windows.c", + "src/core/lib/iomgr/tcp_posix.c", + "src/core/lib/iomgr/tcp_server_posix.c", + "src/core/lib/iomgr/tcp_server_windows.c", + "src/core/lib/iomgr/tcp_windows.c", + "src/core/lib/iomgr/time_averaged_stats.c", + "src/core/lib/iomgr/timer.c", + "src/core/lib/iomgr/timer_heap.c", + "src/core/lib/iomgr/udp_server.c", + "src/core/lib/iomgr/unix_sockets_posix.c", + "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_eventfd.c", + "src/core/lib/iomgr/wakeup_fd_nospecial.c", + "src/core/lib/iomgr/wakeup_fd_pipe.c", + "src/core/lib/iomgr/wakeup_fd_posix.c", + "src/core/lib/iomgr/workqueue_posix.c", + "src/core/lib/iomgr/workqueue_windows.c", + "src/core/lib/json/json.c", + "src/core/lib/json/json_reader.c", + "src/core/lib/json/json_string.c", + "src/core/lib/json/json_writer.c", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c", + "src/core/lib/surface/alarm.c", + "src/core/lib/surface/api_trace.c", + "src/core/lib/surface/byte_buffer.c", + "src/core/lib/surface/byte_buffer_reader.c", + "src/core/lib/surface/call.c", + "src/core/lib/surface/call_details.c", + "src/core/lib/surface/call_log_batch.c", + "src/core/lib/surface/channel.c", + "src/core/lib/surface/channel_connectivity.c", + "src/core/lib/surface/channel_create.c", + "src/core/lib/surface/channel_init.c", + "src/core/lib/surface/channel_ping.c", + "src/core/lib/surface/channel_stack_type.c", + "src/core/lib/surface/completion_queue.c", + "src/core/lib/surface/event_string.c", + "src/core/lib/surface/init.c", + "src/core/lib/surface/lame_client.c", + "src/core/lib/surface/metadata_array.c", + "src/core/lib/surface/server.c", + "src/core/lib/surface/server_chttp2.c", + "src/core/lib/surface/validate_metadata.c", + "src/core/lib/surface/version.c", + "src/core/lib/transport/byte_stream.c", + "src/core/lib/transport/chttp2/alpn.c", + "src/core/lib/transport/chttp2/bin_encoder.c", + "src/core/lib/transport/chttp2/frame_data.c", + "src/core/lib/transport/chttp2/frame_goaway.c", + "src/core/lib/transport/chttp2/frame_ping.c", + "src/core/lib/transport/chttp2/frame_rst_stream.c", + "src/core/lib/transport/chttp2/frame_settings.c", + "src/core/lib/transport/chttp2/frame_window_update.c", + "src/core/lib/transport/chttp2/hpack_encoder.c", + "src/core/lib/transport/chttp2/hpack_parser.c", + "src/core/lib/transport/chttp2/hpack_table.c", + "src/core/lib/transport/chttp2/huffsyms.c", + "src/core/lib/transport/chttp2/incoming_metadata.c", + "src/core/lib/transport/chttp2/parsing.c", + "src/core/lib/transport/chttp2/status_conversion.c", + "src/core/lib/transport/chttp2/stream_lists.c", + "src/core/lib/transport/chttp2/stream_map.c", + "src/core/lib/transport/chttp2/timeout_encoding.c", + "src/core/lib/transport/chttp2/varint.c", + "src/core/lib/transport/chttp2/writing.c", + "src/core/lib/transport/chttp2_transport.c", + "src/core/lib/transport/connectivity_state.c", + "src/core/lib/transport/metadata.c", + "src/core/lib/transport/metadata_batch.c", + "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/transport.c", + "src/core/lib/transport/transport_op_string.c", + "src/core/lib/http/httpcli_security_connector.c", + "src/core/lib/security/b64.c", + "src/core/lib/security/client_auth_filter.c", + "src/core/lib/security/credentials.c", + "src/core/lib/security/credentials_metadata.c", + "src/core/lib/security/credentials_posix.c", + "src/core/lib/security/credentials_win32.c", + "src/core/lib/security/google_default_credentials.c", + "src/core/lib/security/handshake.c", + "src/core/lib/security/json_token.c", + "src/core/lib/security/jwt_verifier.c", + "src/core/lib/security/secure_endpoint.c", + "src/core/lib/security/security_connector.c", + "src/core/lib/security/security_context.c", + "src/core/lib/security/server_auth_filter.c", + "src/core/lib/security/server_secure_chttp2.c", + "src/core/lib/surface/init_secure.c", + "src/core/lib/surface/secure_channel_create.c", + "src/core/lib/tsi/fake_transport_security.c", + "src/core/lib/tsi/ssl_transport_security.c", + "src/core/lib/tsi/transport_security.c", + "src/core/lib/census/context.c", + "src/core/lib/census/initialize.c", + "src/core/lib/census/mlog.c", + "src/core/lib/census/operation.c", + "src/core/lib/census/placeholders.c", + "src/core/lib/census/tracing.c", "third_party/nanopb/pb_common.c", "third_party/nanopb/pb_decode.c", "third_party/nanopb/pb_encode.c", @@ -873,62 +873,62 @@ "include/grpc/impl/codegen/sync_posix.h", "include/grpc/impl/codegen/sync_win32.h", "include/grpc/impl/codegen/time.h", - "src/core/profiling/timers.h", - "src/core/support/backoff.h", - "src/core/support/block_annotate.h", - "src/core/support/env.h", - "src/core/support/load_file.h", - "src/core/support/murmur_hash.h", - "src/core/support/stack_lockfree.h", - "src/core/support/string.h", - "src/core/support/string_win32.h", - "src/core/support/thd_internal.h", - "src/core/support/time_precise.h", - "src/core/support/tmpfile.h", - "src/core/profiling/basic_timers.c", - "src/core/profiling/stap_timers.c", - "src/core/support/alloc.c", - "src/core/support/avl.c", - "src/core/support/backoff.c", - "src/core/support/cmdline.c", - "src/core/support/cpu_iphone.c", - "src/core/support/cpu_linux.c", - "src/core/support/cpu_posix.c", - "src/core/support/cpu_windows.c", - "src/core/support/env_linux.c", - "src/core/support/env_posix.c", - "src/core/support/env_win32.c", - "src/core/support/histogram.c", - "src/core/support/host_port.c", - "src/core/support/load_file.c", - "src/core/support/log.c", - "src/core/support/log_android.c", - "src/core/support/log_linux.c", - "src/core/support/log_posix.c", - "src/core/support/log_win32.c", - "src/core/support/murmur_hash.c", - "src/core/support/slice.c", - "src/core/support/slice_buffer.c", - "src/core/support/stack_lockfree.c", - "src/core/support/string.c", - "src/core/support/string_posix.c", - "src/core/support/string_win32.c", - "src/core/support/subprocess_posix.c", - "src/core/support/subprocess_windows.c", - "src/core/support/sync.c", - "src/core/support/sync_posix.c", - "src/core/support/sync_win32.c", - "src/core/support/thd.c", - "src/core/support/thd_posix.c", - "src/core/support/thd_win32.c", - "src/core/support/time.c", - "src/core/support/time_posix.c", - "src/core/support/time_precise.c", - "src/core/support/time_win32.c", - "src/core/support/tls_pthread.c", - "src/core/support/tmpfile_posix.c", - "src/core/support/tmpfile_win32.c", - "src/core/support/wrap_memcpy.c", + "src/core/lib/profiling/timers.h", + "src/core/lib/support/backoff.h", + "src/core/lib/support/block_annotate.h", + "src/core/lib/support/env.h", + "src/core/lib/support/load_file.h", + "src/core/lib/support/murmur_hash.h", + "src/core/lib/support/stack_lockfree.h", + "src/core/lib/support/string.h", + "src/core/lib/support/string_win32.h", + "src/core/lib/support/thd_internal.h", + "src/core/lib/support/time_precise.h", + "src/core/lib/support/tmpfile.h", + "src/core/lib/profiling/basic_timers.c", + "src/core/lib/profiling/stap_timers.c", + "src/core/lib/support/alloc.c", + "src/core/lib/support/avl.c", + "src/core/lib/support/backoff.c", + "src/core/lib/support/cmdline.c", + "src/core/lib/support/cpu_iphone.c", + "src/core/lib/support/cpu_linux.c", + "src/core/lib/support/cpu_posix.c", + "src/core/lib/support/cpu_windows.c", + "src/core/lib/support/env_linux.c", + "src/core/lib/support/env_posix.c", + "src/core/lib/support/env_win32.c", + "src/core/lib/support/histogram.c", + "src/core/lib/support/host_port.c", + "src/core/lib/support/load_file.c", + "src/core/lib/support/log.c", + "src/core/lib/support/log_android.c", + "src/core/lib/support/log_linux.c", + "src/core/lib/support/log_posix.c", + "src/core/lib/support/log_win32.c", + "src/core/lib/support/murmur_hash.c", + "src/core/lib/support/slice.c", + "src/core/lib/support/slice_buffer.c", + "src/core/lib/support/stack_lockfree.c", + "src/core/lib/support/string.c", + "src/core/lib/support/string_posix.c", + "src/core/lib/support/string_win32.c", + "src/core/lib/support/subprocess_posix.c", + "src/core/lib/support/subprocess_windows.c", + "src/core/lib/support/sync.c", + "src/core/lib/support/sync_posix.c", + "src/core/lib/support/sync_win32.c", + "src/core/lib/support/thd.c", + "src/core/lib/support/thd_posix.c", + "src/core/lib/support/thd_win32.c", + "src/core/lib/support/time.c", + "src/core/lib/support/time_posix.c", + "src/core/lib/support/time_precise.c", + "src/core/lib/support/time_win32.c", + "src/core/lib/support/tls_pthread.c", + "src/core/lib/support/tmpfile_posix.c", + "src/core/lib/support/tmpfile_win32.c", + "src/core/lib/support/wrap_memcpy.c", "binding.gyp" ], "main": "src/node/index.js", diff --git a/package.xml b/package.xml index 4a99922fb3..bb969d115c 100644 --- a/package.xml +++ b/package.xml @@ -92,62 +92,62 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -161,308 +161,308 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/core/census/README.md b/src/core/census/README.md deleted file mode 100644 index fb615a2194..0000000000 --- a/src/core/census/README.md +++ /dev/null @@ -1,76 +0,0 @@ - - -# Census - a resource measurement and tracing system - -This directory contains code for Census, which will ultimately provide the -following features for any gRPC-using system: -* A [dapper](http://research.google.com/pubs/pub36356.html)-like tracing - system, enabling tracing across a distributed infrastructure. -* RPC statistics and measurements for key metrics, such as latency, bytes - transferred, number of errors etc. -* Resource measurement framework which can be used for measuring custom - metrics. Through the use of [tags](#Tags), these can be broken down across - the entire distributed stack. -* Easy integration of the above with - [Google Cloud Trace](https://cloud.google.com/tools/cloud-trace) and - [Google Cloud Monitoring](https://cloud.google.com/monitoring/). - -## Concepts - -### Context - -### Operations - -### Tags - -### Metrics - -## API - -### Internal/RPC API - -### External/Client API - -### RPC API - -## Files in this directory - -Note that files and functions in this directory can be split into two -categories: -* Files that define core census library functions. Functions etc. in these - files are named census\_\*, and constitute the core census library - functionality. At some time in the future, these will become a standalone - library. -* Files that define functions etc. that provide a convenient interface between - grpc and the core census functionality. These files are all named - grpc\_\*.{c,h}, and define function names beginning with grpc\_census\_\*. - diff --git a/src/core/census/aggregation.h b/src/core/census/aggregation.h deleted file mode 100644 index e0ef9630c9..0000000000 --- a/src/core/census/aggregation.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifndef GRPC_CORE_CENSUS_AGGREGATION_H -#define GRPC_CORE_CENSUS_AGGREGATION_H - -/** Structure used to describe an aggregation type. */ -struct census_aggregation_ops { - /* Create a new aggregation. The pointer returned can be used in future calls - to clone(), free(), record(), data() and reset(). */ - void *(*create)(const void *create_arg); - /* Make a copy of an aggregation created by create() */ - void *(*clone)(const void *aggregation); - /* Destroy an aggregation created by create() */ - void (*free)(void *aggregation); - /* Record a new value against aggregation. */ - void (*record)(void *aggregation, double value); - /* Return current aggregation data. The caller must cast this object into - the correct type for the aggregation result. The object returned can be - freed by using free_data(). */ - void *(*data)(const void *aggregation); - /* free data returned by data() */ - void (*free_data)(void *data); - /* Reset an aggregation to default (zero) values. */ - void (*reset)(void *aggregation); - /* Merge 'from' aggregation into 'to'. Both aggregations must be compatible */ - void (*merge)(void *to, const void *from); - /* Fill buffer with printable string version of aggregation contents. For - debugging only. Returns the number of bytes added to buffer (a value == n - implies the buffer was of insufficient size). */ - size_t (*print)(const void *aggregation, char *buffer, size_t n); -}; - -#endif /* GRPC_CORE_CENSUS_AGGREGATION_H */ diff --git a/src/core/census/context.c b/src/core/census/context.c deleted file mode 100644 index 89b8ee0b39..0000000000 --- a/src/core/census/context.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * - * Copyright 2015-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 -#include -#include -#include -#include -#include -#include -#include "src/core/support/string.h" - -// Functions in this file support the public context API, including -// encoding/decoding as part of context propagation across RPC's. The overall -// requirements (in approximate priority order) for the -// context representation: -// 1. Efficient conversion to/from wire format -// 2. Minimal bytes used on-wire -// 3. Efficient context creation -// 4. Efficient lookup of tag value for a key -// 5. Efficient iteration over tags -// 6. Minimal memory footprint -// -// Notes on tradeoffs/decisions: -// * tag includes 1 byte length of key, as well as nil-terminating byte. These -// are to aid in efficient parsing and the ability to directly return key -// strings. This is more important than saving a single byte/tag on the wire. -// * The wire encoding uses only single byte values. This eliminates the need -// to handle endian-ness conversions. It also means there is a hard upper -// limit of 255 for both CENSUS_MAX_TAG_KV_LEN and CENSUS_MAX_PROPAGATED_TAGS. -// * Keep all tag information (keys/values/flags) in a single memory buffer, -// that can be directly copied to the wire. - -// min and max valid chars in tag keys and values. All printable ASCII is OK. -#define MIN_VALID_TAG_CHAR 32 // ' ' -#define MAX_VALID_TAG_CHAR 126 // '~' - -// Structure representing a set of tags. Essentially a count of number of tags -// present, and pointer to a chunk of memory that contains the per-tag details. -struct tag_set { - int ntags; // number of tags. - int ntags_alloc; // ntags + number of deleted tags (total number of tags - // in all of kvm). This will always be == ntags, except during the process - // of building a new tag set. - size_t kvm_size; // number of bytes allocated for key/value storage. - size_t kvm_used; // number of bytes of used key/value memory - char *kvm; // key/value memory. Consists of repeated entries of: - // Offset Size Description - // 0 1 Key length, including trailing 0. (K) - // 1 1 Value length, including trailing 0 (V) - // 2 1 Flags - // 3 K Key bytes - // 3 + K V Value bytes - // - // We refer to the first 3 entries as the 'tag header'. If extra values are - // introduced in the header, you will need to modify the TAG_HEADER_SIZE - // constant, the raw_tag structure (and everything that uses it) and the - // encode/decode functions appropriately. -}; - -// Number of bytes in tag header. -#define TAG_HEADER_SIZE 3 // key length (1) + value length (1) + flags (1) -// Offsets to tag header entries. -#define KEY_LEN_OFFSET 0 -#define VALUE_LEN_OFFSET 1 -#define FLAG_OFFSET 2 - -// raw_tag represents the raw-storage form of a tag in the kvm of a tag_set. -struct raw_tag { - uint8_t key_len; - uint8_t value_len; - uint8_t flags; - char *key; - char *value; -}; - -// Use a reserved flag bit for indication of deleted tag. -#define CENSUS_TAG_DELETED CENSUS_TAG_RESERVED -#define CENSUS_TAG_IS_DELETED(flags) (flags & CENSUS_TAG_DELETED) - -// Primary representation of a context. Composed of 2 underlying tag_set -// structs, one each for propagated and local (non-propagated) tags. This is -// to efficiently support tag encoding/decoding. -// TODO(aveitch): need to add tracing id's/structure. -struct census_context { - struct tag_set tags[2]; - census_context_status status; -}; - -// Indices into the tags member of census_context -#define PROPAGATED_TAGS 0 -#define LOCAL_TAGS 1 - -// Validate (check all characters are in range and size is less than limit) a -// key or value string. Returns 0 if the string is invalid, or the length -// (including terminator) if valid. -static size_t validate_tag(const char *kv) { - size_t len = 1; - char ch; - while ((ch = *kv++) != 0) { - if (ch < MIN_VALID_TAG_CHAR || ch > MAX_VALID_TAG_CHAR) { - return 0; - } - len++; - } - if (len > CENSUS_MAX_TAG_KV_LEN) { - return 0; - } - return len; -} - -// Extract a raw tag given a pointer (raw) to the tag header. Allow for some -// extra bytes in the tag header (see encode/decode functions for usage: this -// allows for future expansion of the tag header). -static char *decode_tag(struct raw_tag *tag, char *header, int offset) { - tag->key_len = (uint8_t)(*header++); - tag->value_len = (uint8_t)(*header++); - tag->flags = (uint8_t)(*header++); - header += offset; - tag->key = header; - header += tag->key_len; - tag->value = header; - return header + tag->value_len; -} - -// Make a copy (in 'to') of an existing tag_set. -static void tag_set_copy(struct tag_set *to, const struct tag_set *from) { - memcpy(to, from, sizeof(struct tag_set)); - to->kvm = gpr_malloc(to->kvm_size); - memcpy(to->kvm, from->kvm, from->kvm_used); -} - -// Delete a tag from a tag_set, if it exists (returns true if it did). -static bool tag_set_delete_tag(struct tag_set *tags, const char *key, - size_t key_len) { - char *kvp = tags->kvm; - for (int i = 0; i < tags->ntags_alloc; i++) { - uint8_t *flags = (uint8_t *)(kvp + FLAG_OFFSET); - struct raw_tag tag; - kvp = decode_tag(&tag, kvp, 0); - if (CENSUS_TAG_IS_DELETED(tag.flags)) continue; - if ((key_len == tag.key_len) && (memcmp(key, tag.key, key_len) == 0)) { - *flags |= CENSUS_TAG_DELETED; - tags->ntags--; - return true; - } - } - return false; -} - -// Delete a tag from a context, return true if it existed. -static bool context_delete_tag(census_context *context, const census_tag *tag, - size_t key_len) { - return ( - tag_set_delete_tag(&context->tags[LOCAL_TAGS], tag->key, key_len) || - tag_set_delete_tag(&context->tags[PROPAGATED_TAGS], tag->key, key_len)); -} - -// Add a tag to a tag_set. Return true on success, false if the tag could -// not be added because of constraints on tag set size. This function should -// not be called if the tag may already exist (in a non-deleted state) in -// the tag_set, as that would result in two tags with the same key. -static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag, - size_t key_len, size_t value_len) { - if (tags->ntags == CENSUS_MAX_PROPAGATED_TAGS) { - return false; - } - const size_t tag_size = key_len + value_len + TAG_HEADER_SIZE; - if (tags->kvm_used + tag_size > tags->kvm_size) { - // allocate new memory if needed - tags->kvm_size += 2 * CENSUS_MAX_TAG_KV_LEN + TAG_HEADER_SIZE; - char *new_kvm = gpr_malloc(tags->kvm_size); - memcpy(new_kvm, tags->kvm, tags->kvm_used); - gpr_free(tags->kvm); - tags->kvm = new_kvm; - } - char *kvp = tags->kvm + tags->kvm_used; - *kvp++ = (char)key_len; - *kvp++ = (char)value_len; - // ensure reserved flags are not used. - *kvp++ = (char)(tag->flags & (CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS)); - memcpy(kvp, tag->key, key_len); - kvp += key_len; - memcpy(kvp, tag->value, value_len); - tags->kvm_used += tag_size; - tags->ntags++; - tags->ntags_alloc++; - return true; -} - -// Add/modify/delete a tag to/in a context. Caller must validate that tag key -// etc. are valid. -static void context_modify_tag(census_context *context, const census_tag *tag, - size_t key_len, size_t value_len) { - // First delete the tag if it is already present. - bool deleted = context_delete_tag(context, tag, key_len); - bool added = false; - if (CENSUS_TAG_IS_PROPAGATED(tag->flags)) { - added = tag_set_add_tag(&context->tags[PROPAGATED_TAGS], tag, key_len, - value_len); - } else { - added = - tag_set_add_tag(&context->tags[LOCAL_TAGS], tag, key_len, value_len); - } - - if (deleted) { - context->status.n_modified_tags++; - } else { - if (added) { - context->status.n_added_tags++; - } else { - context->status.n_ignored_tags++; - } - } -} - -// Remove memory used for deleted tags from a tag set. Basic algorithm: -// 1) Walk through tag set to find first deleted tag. Record where it is. -// 2) Find the next not-deleted tag. Copy all of kvm from there to the end -// "over" the deleted tags -// 3) repeat #1 and #2 until we have seen all tags -// 4) if we are still looking for a not-deleted tag, then all the end portion -// of the kvm is deleted. Just reduce the used amount of memory by the -// appropriate amount. -static void tag_set_flatten(struct tag_set *tags) { - if (tags->ntags == tags->ntags_alloc) return; - bool found_deleted = false; // found a deleted tag. - char *kvp = tags->kvm; - char *dbase = NULL; // record location of deleted tag - for (int i = 0; i < tags->ntags_alloc; i++) { - struct raw_tag tag; - char *next_kvp = decode_tag(&tag, kvp, 0); - if (found_deleted) { - if (!CENSUS_TAG_IS_DELETED(tag.flags)) { - ptrdiff_t reduce = kvp - dbase; // #bytes in deleted tags - GPR_ASSERT(reduce > 0); - ptrdiff_t copy_size = tags->kvm + tags->kvm_used - kvp; - GPR_ASSERT(copy_size > 0); - memmove(dbase, kvp, (size_t)copy_size); - tags->kvm_used -= (size_t)reduce; - next_kvp -= reduce; - found_deleted = false; - } - } else { - if (CENSUS_TAG_IS_DELETED(tag.flags)) { - dbase = kvp; - found_deleted = true; - } - } - kvp = next_kvp; - } - if (found_deleted) { - GPR_ASSERT(dbase > tags->kvm); - tags->kvm_used = (size_t)(dbase - tags->kvm); - } - tags->ntags_alloc = tags->ntags; -} - -census_context *census_context_create(const census_context *base, - const census_tag *tags, int ntags, - census_context_status const **status) { - census_context *context = gpr_malloc(sizeof(census_context)); - // If we are given a base, copy it into our new tag set. Otherwise set it - // to zero/NULL everything. - if (base == NULL) { - memset(context, 0, sizeof(census_context)); - } else { - tag_set_copy(&context->tags[PROPAGATED_TAGS], &base->tags[PROPAGATED_TAGS]); - tag_set_copy(&context->tags[LOCAL_TAGS], &base->tags[LOCAL_TAGS]); - memset(&context->status, 0, sizeof(context->status)); - } - // Walk over the additional tags and, for those that aren't invalid, modify - // the context to add/replace/delete as required. - for (int i = 0; i < ntags; i++) { - const census_tag *tag = &tags[i]; - size_t key_len = validate_tag(tag->key); - // ignore the tag if it is invalid or too short. - if (key_len <= 1) { - context->status.n_invalid_tags++; - } else { - if (tag->value != NULL) { - size_t value_len = validate_tag(tag->value); - if (value_len != 0) { - context_modify_tag(context, tag, key_len, value_len); - } else { - context->status.n_invalid_tags++; - } - } else { - if (context_delete_tag(context, tag, key_len)) { - context->status.n_deleted_tags++; - } - } - } - } - // Remove any deleted tags, update status if needed, and return. - tag_set_flatten(&context->tags[PROPAGATED_TAGS]); - tag_set_flatten(&context->tags[LOCAL_TAGS]); - context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags; - context->status.n_local_tags = context->tags[LOCAL_TAGS].ntags; - if (status) { - *status = &context->status; - } - return context; -} - -const census_context_status *census_context_get_status( - const census_context *context) { - return &context->status; -} - -void census_context_destroy(census_context *context) { - gpr_free(context->tags[PROPAGATED_TAGS].kvm); - gpr_free(context->tags[LOCAL_TAGS].kvm); - gpr_free(context); -} - -void census_context_initialize_iterator(const census_context *context, - census_context_iterator *iterator) { - iterator->context = context; - iterator->index = 0; - if (context->tags[PROPAGATED_TAGS].ntags != 0) { - iterator->base = PROPAGATED_TAGS; - iterator->kvm = context->tags[PROPAGATED_TAGS].kvm; - } else if (context->tags[LOCAL_TAGS].ntags != 0) { - iterator->base = LOCAL_TAGS; - iterator->kvm = context->tags[LOCAL_TAGS].kvm; - } else { - iterator->base = -1; - } -} - -int census_context_next_tag(census_context_iterator *iterator, - census_tag *tag) { - if (iterator->base < 0) { - return 0; - } - struct raw_tag raw; - iterator->kvm = decode_tag(&raw, iterator->kvm, 0); - tag->key = raw.key; - tag->value = raw.value; - tag->flags = raw.flags; - if (++iterator->index == iterator->context->tags[iterator->base].ntags) { - do { - if (iterator->base == LOCAL_TAGS) { - iterator->base = -1; - return 1; - } - } while (iterator->context->tags[++iterator->base].ntags == 0); - iterator->index = 0; - iterator->kvm = iterator->context->tags[iterator->base].kvm; - } - return 1; -} - -// Find a tag in a tag_set by key. Return true if found, false otherwise. -static bool tag_set_get_tag(const struct tag_set *tags, const char *key, - size_t key_len, census_tag *tag) { - char *kvp = tags->kvm; - for (int i = 0; i < tags->ntags; i++) { - struct raw_tag raw; - kvp = decode_tag(&raw, kvp, 0); - if (key_len == raw.key_len && memcmp(raw.key, key, key_len) == 0) { - tag->key = raw.key; - tag->value = raw.value; - tag->flags = raw.flags; - return true; - } - } - return false; -} - -int census_context_get_tag(const census_context *context, const char *key, - census_tag *tag) { - size_t key_len = strlen(key) + 1; - if (key_len == 1) { - return 0; - } - if (tag_set_get_tag(&context->tags[PROPAGATED_TAGS], key, key_len, tag) || - tag_set_get_tag(&context->tags[LOCAL_TAGS], key, key_len, tag)) { - return 1; - } - return 0; -} - -// Context encoding and decoding functions. -// -// Wire format for tag_set's on the wire: -// -// First, a tag set header: -// -// offset bytes description -// 0 1 version number -// 1 1 number of bytes in this header. This allows for future -// expansion. -// 2 1 number of bytes in each tag header. -// 3 1 ntags value from tag set. -// -// This is followed by the key/value memory from struct tag_set. - -#define ENCODED_VERSION 0 // Version number -#define ENCODED_HEADER_SIZE 4 // size of tag set header - -// Encode a tag set. Returns 0 if buffer is too small. -static size_t tag_set_encode(const struct tag_set *tags, char *buffer, - size_t buf_size) { - if (buf_size < ENCODED_HEADER_SIZE + tags->kvm_used) { - return 0; - } - buf_size -= ENCODED_HEADER_SIZE; - *buffer++ = (char)ENCODED_VERSION; - *buffer++ = (char)ENCODED_HEADER_SIZE; - *buffer++ = (char)TAG_HEADER_SIZE; - *buffer++ = (char)tags->ntags; - if (tags->ntags == 0) { - return ENCODED_HEADER_SIZE; - } - memcpy(buffer, tags->kvm, tags->kvm_used); - return ENCODED_HEADER_SIZE + tags->kvm_used; -} - -size_t census_context_encode(const census_context *context, char *buffer, - size_t buf_size) { - return tag_set_encode(&context->tags[PROPAGATED_TAGS], buffer, buf_size); -} - -// Decode a tag set. -static void tag_set_decode(struct tag_set *tags, const char *buffer, - size_t size) { - uint8_t version = (uint8_t)(*buffer++); - uint8_t header_size = (uint8_t)(*buffer++); - uint8_t tag_header_size = (uint8_t)(*buffer++); - tags->ntags = tags->ntags_alloc = (int)(*buffer++); - if (tags->ntags == 0) { - tags->ntags_alloc = 0; - tags->kvm_size = 0; - tags->kvm_used = 0; - tags->kvm = NULL; - return; - } - if (header_size != ENCODED_HEADER_SIZE) { - GPR_ASSERT(version != ENCODED_VERSION); - GPR_ASSERT(ENCODED_HEADER_SIZE < header_size); - buffer += (header_size - ENCODED_HEADER_SIZE); - } - tags->kvm_used = size - header_size; - tags->kvm_size = tags->kvm_used + CENSUS_MAX_TAG_KV_LEN; - tags->kvm = gpr_malloc(tags->kvm_size); - if (tag_header_size != TAG_HEADER_SIZE) { - // something new in the tag information. I don't understand it, so - // don't copy it over. - GPR_ASSERT(version != ENCODED_VERSION); - GPR_ASSERT(tag_header_size > TAG_HEADER_SIZE); - char *kvp = tags->kvm; - for (int i = 0; i < tags->ntags; i++) { - memcpy(kvp, buffer, TAG_HEADER_SIZE); - kvp += header_size; - struct raw_tag raw; - buffer = - decode_tag(&raw, (char *)buffer, tag_header_size - TAG_HEADER_SIZE); - memcpy(kvp, raw.key, (size_t)raw.key_len + raw.value_len); - kvp += raw.key_len + raw.value_len; - } - } else { - memcpy(tags->kvm, buffer, tags->kvm_used); - } -} - -census_context *census_context_decode(const char *buffer, size_t size) { - census_context *context = gpr_malloc(sizeof(census_context)); - memset(&context->tags[LOCAL_TAGS], 0, sizeof(struct tag_set)); - if (buffer == NULL) { - memset(&context->tags[PROPAGATED_TAGS], 0, sizeof(struct tag_set)); - } else { - tag_set_decode(&context->tags[PROPAGATED_TAGS], buffer, size); - } - memset(&context->status, 0, sizeof(context->status)); - context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags; - return context; -} diff --git a/src/core/census/grpc_context.c b/src/core/census/grpc_context.c deleted file mode 100644 index 4b61382a2c..0000000000 --- a/src/core/census/grpc_context.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Copyright 2015, 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 -#include -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" - -void grpc_census_call_set_context(grpc_call *call, census_context *context) { - GRPC_API_TRACE("grpc_census_call_set_context(call=%p, census_context=%p)", 2, - (call, context)); - if (census_enabled() == CENSUS_FEATURE_NONE) { - return; - } - if (context != NULL) { - grpc_call_context_set(call, GRPC_CONTEXT_TRACING, context, NULL); - } -} - -census_context *grpc_census_call_get_context(grpc_call *call) { - GRPC_API_TRACE("grpc_census_call_get_context(call=%p)", 1, (call)); - return (census_context *)grpc_call_context_get(call, GRPC_CONTEXT_TRACING); -} diff --git a/src/core/census/grpc_filter.c b/src/core/census/grpc_filter.c deleted file mode 100644 index 11120a28d1..0000000000 --- a/src/core/census/grpc_filter.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * - * Copyright 2015-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/census/grpc_filter.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include "src/core/channel/channel_stack.h" -#include "src/core/statistics/census_interface.h" -#include "src/core/statistics/census_rpc_stats.h" -#include "src/core/transport/static_metadata.h" - -typedef struct call_data { - census_op_id op_id; - census_context *ctxt; - gpr_timespec start_ts; - int error; - - /* recv callback */ - grpc_metadata_batch *recv_initial_metadata; - grpc_closure *on_done_recv; - grpc_closure finish_recv; -} call_data; - -typedef struct channel_data { uint8_t unused; } channel_data; - -static void extract_and_annotate_method_tag(grpc_metadata_batch *md, - call_data *calld, - channel_data *chand) { - grpc_linked_mdelem *m; - for (m = md->list.head; m != NULL; m = m->next) { - if (m->md->key == GRPC_MDSTR_PATH) { - gpr_log(GPR_DEBUG, "%s", - (const char *)GPR_SLICE_START_PTR(m->md->value->slice)); - /* Add method tag here */ - } - } -} - -static void client_mutate_op(grpc_call_element *elem, - grpc_transport_stream_op *op) { - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - if (op->send_initial_metadata) { - extract_and_annotate_method_tag(op->send_initial_metadata, calld, chand); - } -} - -static void client_start_transport_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - client_mutate_op(elem, op); - grpc_call_next_op(exec_ctx, elem, op); -} - -static void server_on_done_recv(grpc_exec_ctx *exec_ctx, void *ptr, - bool success) { - grpc_call_element *elem = ptr; - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - if (success) { - extract_and_annotate_method_tag(calld->recv_initial_metadata, calld, chand); - } - calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, success); -} - -static void server_mutate_op(grpc_call_element *elem, - grpc_transport_stream_op *op) { - call_data *calld = elem->call_data; - if (op->recv_initial_metadata) { - /* substitute our callback for the op callback */ - calld->recv_initial_metadata = op->recv_initial_metadata; - calld->on_done_recv = op->recv_initial_metadata_ready; - op->recv_initial_metadata_ready = &calld->finish_recv; - } -} - -static void server_start_transport_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - /* TODO(ctiller): this code fails. I don't know why. I expect it's - incomplete, and someone should look at it soon. - - call_data *calld = elem->call_data; - GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0)); */ - server_mutate_op(elem, op); - grpc_call_next_op(exec_ctx, elem, op); -} - -static void client_init_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_call_element_args *args) { - call_data *d = elem->call_data; - GPR_ASSERT(d != NULL); - memset(d, 0, sizeof(*d)); - d->start_ts = gpr_now(GPR_CLOCK_REALTIME); -} - -static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - call_data *d = elem->call_data; - GPR_ASSERT(d != NULL); - /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */ -} - -static void server_init_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_call_element_args *args) { - call_data *d = elem->call_data; - GPR_ASSERT(d != NULL); - memset(d, 0, sizeof(*d)); - d->start_ts = gpr_now(GPR_CLOCK_REALTIME); - /* TODO(hongyu): call census_tracing_start_op here. */ - grpc_closure_init(&d->finish_recv, server_on_done_recv, elem); -} - -static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - call_data *d = elem->call_data; - GPR_ASSERT(d != NULL); - /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */ -} - -static void init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - channel_data *chand = elem->channel_data; - GPR_ASSERT(chand != NULL); -} - -static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) { - channel_data *chand = elem->channel_data; - GPR_ASSERT(chand != NULL); -} - -const grpc_channel_filter grpc_client_census_filter = { - client_start_transport_op, - grpc_channel_next_op, - sizeof(call_data), - client_init_call_elem, - grpc_call_stack_ignore_set_pollset, - client_destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - grpc_call_next_get_peer, - "census-client"}; - -const grpc_channel_filter grpc_server_census_filter = { - server_start_transport_op, - grpc_channel_next_op, - sizeof(call_data), - server_init_call_elem, - grpc_call_stack_ignore_set_pollset, - server_destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - grpc_call_next_get_peer, - "census-server"}; diff --git a/src/core/census/grpc_filter.h b/src/core/census/grpc_filter.h deleted file mode 100644 index 4699e4d692..0000000000 --- a/src/core/census/grpc_filter.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * Copyright 2015-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_CENSUS_GRPC_FILTER_H -#define GRPC_CORE_CENSUS_GRPC_FILTER_H - -#include "src/core/channel/channel_stack.h" - -/* Census filters: provides tracing and stats collection functionalities. It - needs to reside right below the surface filter in the channel stack. */ -extern const grpc_channel_filter grpc_client_census_filter; -extern const grpc_channel_filter grpc_server_census_filter; - -#endif /* GRPC_CORE_CENSUS_GRPC_FILTER_H */ diff --git a/src/core/census/grpc_plugin.c b/src/core/census/grpc_plugin.c deleted file mode 100644 index 3ca9400f7e..0000000000 --- a/src/core/census/grpc_plugin.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * Copyright 2015-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/census/grpc_plugin.h" - -#include - -#include - -#include "src/core/census/grpc_filter.h" -#include "src/core/channel/channel_stack_builder.h" -#include "src/core/surface/channel_init.h" - -static bool maybe_add_census_filter(grpc_channel_stack_builder *builder, - void *arg_must_be_null) { - const grpc_channel_args *args = - grpc_channel_stack_builder_get_channel_arguments(builder); - if (grpc_channel_args_is_census_enabled(args)) { - return grpc_channel_stack_builder_prepend_filter( - builder, &grpc_client_census_filter, NULL, NULL); - } - return true; -} - -void census_grpc_plugin_init(void) { - /* Only initialize census if no one else has and some features are - * available. */ - if (census_enabled() == CENSUS_FEATURE_NONE && - census_supported() != CENSUS_FEATURE_NONE) { - if (census_initialize(census_supported())) { /* enable all features. */ - gpr_log(GPR_ERROR, "Could not initialize census."); - } - } - grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, - maybe_add_census_filter, NULL); - grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, - maybe_add_census_filter, NULL); -} - -void census_grpc_plugin_destroy(void) { census_shutdown(); } diff --git a/src/core/census/grpc_plugin.h b/src/core/census/grpc_plugin.h deleted file mode 100644 index 9321c2c30f..0000000000 --- a/src/core/census/grpc_plugin.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * Copyright 2015-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_CENSUS_GRPC_PLUGIN_H -#define GRPC_CORE_CENSUS_GRPC_PLUGIN_H - -void census_grpc_plugin_init(void); -void census_grpc_plugin_destroy(void); - -#endif /* GRPC_CORE_CENSUS_GRPC_PLUGIN_H */ diff --git a/src/core/census/initialize.c b/src/core/census/initialize.c deleted file mode 100644 index ce7ec09b89..0000000000 --- a/src/core/census/initialize.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Copyright 2015-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 - -static int features_enabled = CENSUS_FEATURE_NONE; - -int census_initialize(int features) { - if (features_enabled != CENSUS_FEATURE_NONE) { - // Must have been a previous call to census_initialize; return error - return 1; - } - features_enabled = features; - return 0; -} - -void census_shutdown(void) { features_enabled = CENSUS_FEATURE_NONE; } - -int census_supported(void) { - /* TODO(aveitch): improve this as we implement features... */ - return CENSUS_FEATURE_NONE; -} - -int census_enabled(void) { return features_enabled; } diff --git a/src/core/census/mlog.c b/src/core/census/mlog.c deleted file mode 100644 index a2cc46d3f2..0000000000 --- a/src/core/census/mlog.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -// Implements an efficient in-memory log, optimized for multiple writers and -// a single reader. Available log space is divided up in blocks of -// CENSUS_LOG_2_MAX_RECORD_SIZE bytes. A block can be in one of the following -// three data structures: -// - Free blocks (free_block_list) -// - Blocks with unread data (dirty_block_list) -// - Blocks currently attached to cores (core_local_blocks[]) -// -// census_log_start_write() moves a block from core_local_blocks[] to the end of -// dirty_block_list when block: -// - is out-of-space OR -// - has an incomplete record (an incomplete record occurs when a thread calls -// census_log_start_write() and is context-switched before calling -// census_log_end_write() -// So, blocks in dirty_block_list are ordered, from oldest to newest, by the -// time when block is detached from the core. -// -// census_log_read_next() first iterates over dirty_block_list and then -// core_local_blocks[]. It moves completely read blocks from dirty_block_list -// to free_block_list. Blocks in core_local_blocks[] are not freed, even when -// completely read. -// -// If the log is configured to discard old records and free_block_list is empty, -// census_log_start_write() iterates over dirty_block_list to allocate a -// new block. It moves the oldest available block (no pending read/write) to -// core_local_blocks[]. -// -// core_local_block_struct is used to implement a map from core id to the block -// associated with that core. This mapping is advisory. It is possible that the -// block returned by this mapping is no longer associated with that core. This -// mapping is updated, lazily, by census_log_start_write(). -// -// Locking in block struct: -// -// Exclusive g_log.lock must be held before calling any functions operating on -// block structs except census_log_start_write() and census_log_end_write(). -// -// Writes to a block are serialized via writer_lock. census_log_start_write() -// acquires this lock and census_log_end_write() releases it. On failure to -// acquire the lock, writer allocates a new block for the current core and -// updates core_local_block accordingly. -// -// Simultaneous read and write access is allowed. Readers can safely read up to -// committed bytes (bytes_committed). -// -// reader_lock protects the block, currently being read, from getting recycled. -// start_read() acquires reader_lock and end_read() releases the lock. -// -// Read/write access to a block is disabled via try_disable_access(). It returns -// with both writer_lock and reader_lock held. These locks are subsequently -// released by enable_access() to enable access to the block. -// -// A note on naming: Most function/struct names are prepended by cl_ -// (shorthand for census_log). Further, functions that manipulate structures -// include the name of the structure, which will be passed as the first -// argument. E.g. cl_block_initialize() will initialize a cl_block. - -#include "src/core/census/mlog.h" -#include -#include -#include -#include -#include -#include -#include -#include - -// End of platform specific code - -typedef struct census_log_block_list_struct { - struct census_log_block_list_struct* next; - struct census_log_block_list_struct* prev; - struct census_log_block* block; -} cl_block_list_struct; - -typedef struct census_log_block { - // Pointer to underlying buffer. - char* buffer; - gpr_atm writer_lock; - gpr_atm reader_lock; - // Keeps completely written bytes. Declared atomic because accessed - // simultaneously by reader and writer. - gpr_atm bytes_committed; - // Bytes already read. - size_t bytes_read; - // Links for list. - cl_block_list_struct link; -// We want this structure to be cacheline aligned. We assume the following -// sizes for the various parts on 32/64bit systems: -// type 32b size 64b size -// char* 4 8 -// 3x gpr_atm 12 24 -// size_t 4 8 -// cl_block_list_struct 12 24 -// TOTAL 32 64 -// -// Depending on the size of our cacheline and the architecture, we -// selectively add char buffering to this structure. The size is checked -// via assert in census_log_initialize(). -#if defined(GPR_ARCH_64) -#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 64) -#else -#if defined(GPR_ARCH_32) -#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 32) -#else -#error "Unknown architecture" -#endif -#endif -#if CL_BLOCK_PAD_SIZE > 0 - char padding[CL_BLOCK_PAD_SIZE]; -#endif -} cl_block; - -// A list of cl_blocks, doubly-linked through cl_block::link. -typedef struct census_log_block_list { - int32_t count; // Number of items in list. - cl_block_list_struct ht; // head/tail of linked list. -} cl_block_list; - -// Cacheline aligned block pointers to avoid false sharing. Block pointer must -// be initialized via set_block(), before calling other functions -typedef struct census_log_core_local_block { - gpr_atm block; -// Ensure cachline alignment: we assume sizeof(gpr_atm) == 4 or 8 -#if defined(GPR_ARCH_64) -#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 8) -#else -#if defined(GPR_ARCH_32) -#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 4) -#else -#error "Unknown architecture" -#endif -#endif -#if CL_CORE_LOCAL_BLOCK_PAD_SIZE > 0 - char padding[CL_CORE_LOCAL_BLOCK_PAD_SIZE]; -#endif -} cl_core_local_block; - -struct census_log { - int discard_old_records; - // Number of cores (aka hardware-contexts) - unsigned num_cores; - // number of CENSUS_LOG_2_MAX_RECORD_SIZE blocks in log - uint32_t num_blocks; - cl_block* blocks; // Block metadata. - cl_core_local_block* core_local_blocks; // Keeps core to block mappings. - gpr_mu lock; - int initialized; // has log been initialized? - // Keeps the state of the reader iterator. A value of 0 indicates that - // iterator has reached the end. census_log_init_reader() resets the value - // to num_core to restart iteration. - uint32_t read_iterator_state; - // Points to the block being read. If non-NULL, the block is locked for - // reading(block_being_read_->reader_lock is held). - cl_block* block_being_read; - char* buffer; - cl_block_list free_block_list; - cl_block_list dirty_block_list; - gpr_atm out_of_space_count; -}; - -// Single internal log. -static struct census_log g_log; - -// Functions that operate on an atomic memory location used as a lock. - -// Returns non-zero if lock is acquired. -static int cl_try_lock(gpr_atm* lock) { return gpr_atm_acq_cas(lock, 0, 1); } - -static void cl_unlock(gpr_atm* lock) { gpr_atm_rel_store(lock, 0); } - -// Functions that operate on cl_core_local_block's. - -static void cl_core_local_block_set_block(cl_core_local_block* clb, - cl_block* block) { - gpr_atm_rel_store(&clb->block, (gpr_atm)block); -} - -static cl_block* cl_core_local_block_get_block(cl_core_local_block* clb) { - return (cl_block*)gpr_atm_acq_load(&clb->block); -} - -// Functions that operate on cl_block_list_struct's. - -static void cl_block_list_struct_initialize(cl_block_list_struct* bls, - cl_block* block) { - bls->next = bls->prev = bls; - bls->block = block; -} - -// Functions that operate on cl_block_list's. - -static void cl_block_list_initialize(cl_block_list* list) { - list->count = 0; - cl_block_list_struct_initialize(&list->ht, NULL); -} - -// Returns head of *this, or NULL if empty. -static cl_block* cl_block_list_head(cl_block_list* list) { - return list->ht.next->block; -} - -// Insert element *e after *pos. -static void cl_block_list_insert(cl_block_list* list, cl_block_list_struct* pos, - cl_block_list_struct* e) { - list->count++; - e->next = pos->next; - e->prev = pos; - e->next->prev = e; - e->prev->next = e; -} - -// Insert block at the head of the list -static void cl_block_list_insert_at_head(cl_block_list* list, cl_block* block) { - cl_block_list_insert(list, &list->ht, &block->link); -} - -// Insert block at the tail of the list. -static void cl_block_list_insert_at_tail(cl_block_list* list, cl_block* block) { - cl_block_list_insert(list, list->ht.prev, &block->link); -} - -// Removes block *b. Requires *b be in the list. -static void cl_block_list_remove(cl_block_list* list, cl_block* b) { - list->count--; - b->link.next->prev = b->link.prev; - b->link.prev->next = b->link.next; -} - -// Functions that operate on cl_block's - -static void cl_block_initialize(cl_block* block, char* buffer) { - block->buffer = buffer; - gpr_atm_rel_store(&block->writer_lock, 0); - gpr_atm_rel_store(&block->reader_lock, 0); - gpr_atm_rel_store(&block->bytes_committed, 0); - block->bytes_read = 0; - cl_block_list_struct_initialize(&block->link, block); -} - -// Guards against exposing partially written buffer to the reader. -static void cl_block_set_bytes_committed(cl_block* block, - size_t bytes_committed) { - gpr_atm_rel_store(&block->bytes_committed, (gpr_atm)bytes_committed); -} - -static size_t cl_block_get_bytes_committed(cl_block* block) { - return (size_t)gpr_atm_acq_load(&block->bytes_committed); -} - -// Tries to disable future read/write access to this block. Succeeds if: -// - no in-progress write AND -// - no in-progress read AND -// - 'discard_data' set to true OR no unread data -// On success, clears the block state and returns with writer_lock_ and -// reader_lock_ held. These locks are released by a subsequent -// cl_block_access_enable() call. -static bool cl_block_try_disable_access(cl_block* block, int discard_data) { - if (!cl_try_lock(&block->writer_lock)) { - return false; - } - if (!cl_try_lock(&block->reader_lock)) { - cl_unlock(&block->writer_lock); - return false; - } - if (!discard_data && - (block->bytes_read != cl_block_get_bytes_committed(block))) { - cl_unlock(&block->reader_lock); - cl_unlock(&block->writer_lock); - return false; - } - cl_block_set_bytes_committed(block, 0); - block->bytes_read = 0; - return true; -} - -static void cl_block_enable_access(cl_block* block) { - cl_unlock(&block->reader_lock); - cl_unlock(&block->writer_lock); -} - -// Returns with writer_lock held. -static void* cl_block_start_write(cl_block* block, size_t size) { - if (!cl_try_lock(&block->writer_lock)) { - return NULL; - } - size_t bytes_committed = cl_block_get_bytes_committed(block); - if (bytes_committed + size > CENSUS_LOG_MAX_RECORD_SIZE) { - cl_unlock(&block->writer_lock); - return NULL; - } - return block->buffer + bytes_committed; -} - -// Releases writer_lock and increments committed bytes by 'bytes_written'. -// 'bytes_written' must be <= 'size' specified in the corresponding -// StartWrite() call. This function is thread-safe. -static void cl_block_end_write(cl_block* block, size_t bytes_written) { - cl_block_set_bytes_committed( - block, cl_block_get_bytes_committed(block) + bytes_written); - cl_unlock(&block->writer_lock); -} - -// Returns a pointer to the first unread byte in buffer. The number of bytes -// available are returned in 'bytes_available'. Acquires reader lock that is -// released by a subsequent cl_block_end_read() call. Returns NULL if: -// - read in progress -// - no data available -static void* cl_block_start_read(cl_block* block, size_t* bytes_available) { - if (!cl_try_lock(&block->reader_lock)) { - return NULL; - } - // bytes_committed may change from under us. Use bytes_available to update - // bytes_read below. - size_t bytes_committed = cl_block_get_bytes_committed(block); - GPR_ASSERT(bytes_committed >= block->bytes_read); - *bytes_available = bytes_committed - block->bytes_read; - if (*bytes_available == 0) { - cl_unlock(&block->reader_lock); - return NULL; - } - void* record = block->buffer + block->bytes_read; - block->bytes_read += *bytes_available; - return record; -} - -static void cl_block_end_read(cl_block* block) { - cl_unlock(&block->reader_lock); -} - -// Internal functions operating on g_log - -// Allocates a new free block (or recycles an available dirty block if log is -// configured to discard old records). Returns NULL if out-of-space. -static cl_block* cl_allocate_block(void) { - cl_block* block = cl_block_list_head(&g_log.free_block_list); - if (block != NULL) { - cl_block_list_remove(&g_log.free_block_list, block); - return block; - } - if (!g_log.discard_old_records) { - // No free block and log is configured to keep old records. - return NULL; - } - // Recycle dirty block. Start from the oldest. - for (block = cl_block_list_head(&g_log.dirty_block_list); block != NULL; - block = block->link.next->block) { - if (cl_block_try_disable_access(block, 1 /* discard data */)) { - cl_block_list_remove(&g_log.dirty_block_list, block); - return block; - } - } - return NULL; -} - -// Allocates a new block and updates core id => block mapping. 'old_block' -// points to the block that the caller thinks is attached to -// 'core_id'. 'old_block' may be NULL. Returns true if: -// - allocated a new block OR -// - 'core_id' => 'old_block' mapping changed (another thread allocated a -// block before lock was acquired). -static bool cl_allocate_core_local_block(uint32_t core_id, - cl_block* old_block) { - // Now that we have the lock, check if core-local mapping has changed. - cl_core_local_block* core_local_block = &g_log.core_local_blocks[core_id]; - cl_block* block = cl_core_local_block_get_block(core_local_block); - if ((block != NULL) && (block != old_block)) { - return true; - } - if (block != NULL) { - cl_core_local_block_set_block(core_local_block, NULL); - cl_block_list_insert_at_tail(&g_log.dirty_block_list, block); - } - block = cl_allocate_block(); - if (block == NULL) { - return false; - } - cl_core_local_block_set_block(core_local_block, block); - cl_block_enable_access(block); - return true; -} - -static cl_block* cl_get_block(void* record) { - uintptr_t p = (uintptr_t)((char*)record - g_log.buffer); - uintptr_t index = p >> CENSUS_LOG_2_MAX_RECORD_SIZE; - return &g_log.blocks[index]; -} - -// Gets the next block to read and tries to free 'prev' block (if not NULL). -// Returns NULL if reached the end. -static cl_block* cl_next_block_to_read(cl_block* prev) { - cl_block* block = NULL; - if (g_log.read_iterator_state == g_log.num_cores) { - // We are traversing dirty list; find the next dirty block. - if (prev != NULL) { - // Try to free the previous block if there is no unread data. This - // block - // may have unread data if previously incomplete record completed - // between - // read_next() calls. - block = prev->link.next->block; - if (cl_block_try_disable_access(prev, 0 /* do not discard data */)) { - cl_block_list_remove(&g_log.dirty_block_list, prev); - cl_block_list_insert_at_head(&g_log.free_block_list, prev); - } - } else { - block = cl_block_list_head(&g_log.dirty_block_list); - } - if (block != NULL) { - return block; - } - // We are done with the dirty list; moving on to core-local blocks. - } - while (g_log.read_iterator_state > 0) { - g_log.read_iterator_state--; - block = cl_core_local_block_get_block( - &g_log.core_local_blocks[g_log.read_iterator_state]); - if (block != NULL) { - return block; - } - } - return NULL; -} - -#define CL_LOG_2_MB 20 // 2^20 = 1MB - -// External functions: primary stats_log interface -void census_log_initialize(size_t size_in_mb, int discard_old_records) { - // Check cacheline alignment. - GPR_ASSERT(sizeof(cl_block) % GPR_CACHELINE_SIZE == 0); - GPR_ASSERT(sizeof(cl_core_local_block) % GPR_CACHELINE_SIZE == 0); - GPR_ASSERT(!g_log.initialized); - g_log.discard_old_records = discard_old_records; - g_log.num_cores = gpr_cpu_num_cores(); - // Ensure that we will not get any overflow in calaculating num_blocks - GPR_ASSERT(CL_LOG_2_MB >= CENSUS_LOG_2_MAX_RECORD_SIZE); - GPR_ASSERT(size_in_mb < 1000); - // Ensure at least 2x as many blocks as there are cores. - g_log.num_blocks = - (uint32_t)GPR_MAX(2 * g_log.num_cores, (size_in_mb << CL_LOG_2_MB) >> - CENSUS_LOG_2_MAX_RECORD_SIZE); - gpr_mu_init(&g_log.lock); - g_log.read_iterator_state = 0; - g_log.block_being_read = NULL; - g_log.core_local_blocks = (cl_core_local_block*)gpr_malloc_aligned( - g_log.num_cores * sizeof(cl_core_local_block), GPR_CACHELINE_SIZE_LOG); - memset(g_log.core_local_blocks, 0, - g_log.num_cores * sizeof(cl_core_local_block)); - g_log.blocks = (cl_block*)gpr_malloc_aligned( - g_log.num_blocks * sizeof(cl_block), GPR_CACHELINE_SIZE_LOG); - memset(g_log.blocks, 0, g_log.num_blocks * sizeof(cl_block)); - g_log.buffer = gpr_malloc(g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE); - memset(g_log.buffer, 0, g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE); - cl_block_list_initialize(&g_log.free_block_list); - cl_block_list_initialize(&g_log.dirty_block_list); - for (uint32_t i = 0; i < g_log.num_blocks; ++i) { - cl_block* block = g_log.blocks + i; - cl_block_initialize(block, g_log.buffer + (CENSUS_LOG_MAX_RECORD_SIZE * i)); - cl_block_try_disable_access(block, 1 /* discard data */); - cl_block_list_insert_at_tail(&g_log.free_block_list, block); - } - gpr_atm_rel_store(&g_log.out_of_space_count, 0); - g_log.initialized = 1; -} - -void census_log_shutdown(void) { - GPR_ASSERT(g_log.initialized); - gpr_mu_destroy(&g_log.lock); - gpr_free_aligned(g_log.core_local_blocks); - g_log.core_local_blocks = NULL; - gpr_free_aligned(g_log.blocks); - g_log.blocks = NULL; - gpr_free(g_log.buffer); - g_log.buffer = NULL; - g_log.initialized = 0; -} - -void* census_log_start_write(size_t size) { - // Used to bound number of times block allocation is attempted. - GPR_ASSERT(size > 0); - GPR_ASSERT(g_log.initialized); - if (size > CENSUS_LOG_MAX_RECORD_SIZE) { - return NULL; - } - uint32_t attempts_remaining = g_log.num_blocks; - uint32_t core_id = gpr_cpu_current_cpu(); - do { - void* record = NULL; - cl_block* block = - cl_core_local_block_get_block(&g_log.core_local_blocks[core_id]); - if (block && (record = cl_block_start_write(block, size))) { - return record; - } - // Need to allocate a new block. We are here if: - // - No block associated with the core OR - // - Write in-progress on the block OR - // - block is out of space - gpr_mu_lock(&g_log.lock); - bool allocated = cl_allocate_core_local_block(core_id, block); - gpr_mu_unlock(&g_log.lock); - if (!allocated) { - gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1); - return NULL; - } - } while (attempts_remaining--); - // Give up. - gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1); - return NULL; -} - -void census_log_end_write(void* record, size_t bytes_written) { - GPR_ASSERT(g_log.initialized); - cl_block_end_write(cl_get_block(record), bytes_written); -} - -void census_log_init_reader(void) { - GPR_ASSERT(g_log.initialized); - gpr_mu_lock(&g_log.lock); - // If a block is locked for reading unlock it. - if (g_log.block_being_read != NULL) { - cl_block_end_read(g_log.block_being_read); - g_log.block_being_read = NULL; - } - g_log.read_iterator_state = g_log.num_cores; - gpr_mu_unlock(&g_log.lock); -} - -const void* census_log_read_next(size_t* bytes_available) { - GPR_ASSERT(g_log.initialized); - gpr_mu_lock(&g_log.lock); - if (g_log.block_being_read != NULL) { - cl_block_end_read(g_log.block_being_read); - } - do { - g_log.block_being_read = cl_next_block_to_read(g_log.block_being_read); - if (g_log.block_being_read != NULL) { - void* record = - cl_block_start_read(g_log.block_being_read, bytes_available); - if (record != NULL) { - gpr_mu_unlock(&g_log.lock); - return record; - } - } - } while (g_log.block_being_read != NULL); - gpr_mu_unlock(&g_log.lock); - return NULL; -} - -size_t census_log_remaining_space(void) { - GPR_ASSERT(g_log.initialized); - size_t space = 0; - gpr_mu_lock(&g_log.lock); - if (g_log.discard_old_records) { - // Remaining space is not meaningful; just return the entire log space. - space = g_log.num_blocks << CENSUS_LOG_2_MAX_RECORD_SIZE; - } else { - GPR_ASSERT(g_log.free_block_list.count >= 0); - space = (size_t)g_log.free_block_list.count * CENSUS_LOG_MAX_RECORD_SIZE; - } - gpr_mu_unlock(&g_log.lock); - return space; -} - -int64_t census_log_out_of_space_count(void) { - GPR_ASSERT(g_log.initialized); - return gpr_atm_acq_load(&g_log.out_of_space_count); -} diff --git a/src/core/census/mlog.h b/src/core/census/mlog.h deleted file mode 100644 index bc6eaeaf28..0000000000 --- a/src/core/census/mlog.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* A very fast in-memory log, optimized for multiple writers. */ - -#ifndef GRPC_CORE_CENSUS_MLOG_H -#define GRPC_CORE_CENSUS_MLOG_H - -#include -#include - -/* Maximum record size, in bytes. */ -#define CENSUS_LOG_2_MAX_RECORD_SIZE 14 /* 2^14 = 16KB */ -#define CENSUS_LOG_MAX_RECORD_SIZE (1 << CENSUS_LOG_2_MAX_RECORD_SIZE) - -/* Initialize the statistics logging subsystem with the given log size. A log - size of 0 will result in the smallest possible log for the platform - (approximately CENSUS_LOG_MAX_RECORD_SIZE * gpr_cpu_num_cores()). If - discard_old_records is non-zero, then new records will displace older ones - when the log is full. This function must be called before any other - census_log functions. -*/ -void census_log_initialize(size_t size_in_mb, int discard_old_records); - -/* Shutdown the logging subsystem. Caller must ensure that: - - no in progress or future call to any census_log functions - - no incomplete records -*/ -void census_log_shutdown(void); - -/* Allocates and returns a 'size' bytes record and marks it in use. A - subsequent census_log_end_write() marks the record complete. The - 'bytes_written' census_log_end_write() argument must be <= - 'size'. Returns NULL if out-of-space AND: - - log is configured to keep old records OR - - all blocks are pinned by incomplete records. -*/ -void* census_log_start_write(size_t size); - -void census_log_end_write(void* record, size_t bytes_written); - -void census_log_init_reader(void); - -/* census_log_read_next() iterates over blocks with data and for each block - returns a pointer to the first unread byte. The number of bytes that can be - read are returned in 'bytes_available'. Reader is expected to read all - available data. Reading the data consumes it i.e. it cannot be read again. - census_log_read_next() returns NULL if the end is reached i.e last block - is read. census_log_init_reader() starts the iteration or aborts the - current iteration. -*/ -const void* census_log_read_next(size_t* bytes_available); - -/* Returns estimated remaining space across all blocks, in bytes. If log is - configured to discard old records, returns total log space. Otherwise, - returns space available in empty blocks (partially filled blocks are - treated as full). -*/ -size_t census_log_remaining_space(void); - -/* Returns the number of times gprc_stats_log_start_write() failed due to - out-of-space. */ -int64_t census_log_out_of_space_count(void); - -#endif /* GRPC_CORE_CENSUS_MLOG_H */ diff --git a/src/core/census/operation.c b/src/core/census/operation.c deleted file mode 100644 index 5c58704372..0000000000 --- a/src/core/census/operation.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2015, 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 - -/* TODO(aveitch): These are all placeholder implementations. */ - -census_timestamp census_start_rpc_op_timestamp(void) { - census_timestamp ct; - /* TODO(aveitch): assumes gpr_timespec implementation of census_timestamp. */ - ct.ts = gpr_now(GPR_CLOCK_MONOTONIC); - return ct; -} - -census_context *census_start_client_rpc_op( - const census_context *context, int64_t rpc_name_id, - const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, - const census_timestamp *start_time) { - return NULL; -} - -census_context *census_start_server_rpc_op( - const char *buffer, int64_t rpc_name_id, - const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, - census_timestamp *start_time) { - return NULL; -} - -census_context *census_start_op(census_context *context, const char *family, - const char *name, int trace_mask) { - return NULL; -} - -void census_end_op(census_context *context, int status) {} diff --git a/src/core/census/placeholders.c b/src/core/census/placeholders.c deleted file mode 100644 index fe23d13971..0000000000 --- a/src/core/census/placeholders.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * - * 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 - -#include - -/* Placeholders for the pending APIs */ - -int census_get_trace_record(census_trace_record *trace_record) { - (void)trace_record; - abort(); -} - -void census_record_values(census_context *context, census_value *values, - size_t nvalues) { - (void)context; - (void)values; - (void)nvalues; - abort(); -} - -void census_set_rpc_client_peer(census_context *context, const char *peer) { - (void)context; - (void)peer; - abort(); -} - -void census_trace_scan_end() { abort(); } - -int census_trace_scan_start(int consume) { - (void)consume; - abort(); -} - -const census_aggregation *census_view_aggregrations(const census_view *view) { - (void)view; - abort(); -} - -census_view *census_view_create(uint32_t metric_id, const census_context *tags, - const census_aggregation *aggregations, - size_t naggregations) { - (void)metric_id; - (void)tags; - (void)aggregations; - (void)naggregations; - abort(); -} - -const census_context *census_view_tags(const census_view *view) { - (void)view; - abort(); -} - -void census_view_delete(census_view *view) { - (void)view; - abort(); -} - -const census_view_data *census_view_get_data(const census_view *view) { - (void)view; - abort(); -} - -size_t census_view_metric(const census_view *view) { - (void)view; - abort(); -} - -size_t census_view_naggregations(const census_view *view) { - (void)view; - abort(); -} - -void census_view_reset(census_view *view) { - (void)view; - abort(); -} diff --git a/src/core/census/rpc_metric_id.h b/src/core/census/rpc_metric_id.h deleted file mode 100644 index f8d8dad0bf..0000000000 --- a/src/core/census/rpc_metric_id.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright 2015-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_CENSUS_RPC_METRIC_ID_H -#define GRPC_CORE_CENSUS_RPC_METRIC_ID_H - -/* Metric ID's used for RPC measurements. */ -/* Count of client requests sent. */ -#define CENSUS_METRIC_RPC_CLIENT_REQUESTS ((uint32_t)0) -/* Count of server requests sent. */ -#define CENSUS_METRIC_RPC_SERVER_REQUESTS ((uint32_t)1) -/* Client error counts. */ -#define CENSUS_METRIC_RPC_CLIENT_ERRORS ((uint32_t)2) -/* Server error counts. */ -#define CENSUS_METRIC_RPC_SERVER_ERRORS ((uint32_t)3) -/* Client side request latency. */ -#define CENSUS_METRIC_RPC_CLIENT_LATENCY ((uint32_t)4) -/* Server side request latency. */ -#define CENSUS_METRIC_RPC_SERVER_LATENCY ((uint32_t)5) - -#endif /* GRPC_CORE_CENSUS_RPC_METRIC_ID_H */ diff --git a/src/core/census/tracing.c b/src/core/census/tracing.c deleted file mode 100644 index 3b5d6dab2b..0000000000 --- a/src/core/census/tracing.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Copyright 2015, 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 - -/* 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) {} - -void census_trace_print(census_context *context, uint32_t type, - const char *buffer, size_t n) {} diff --git a/src/core/channel/channel_args.c b/src/core/channel/channel_args.c deleted file mode 100644 index e0382fa0d9..0000000000 --- a/src/core/channel/channel_args.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * - * Copyright 2015-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/channel/channel_args.h" -#include -#include "src/core/support/string.h" - -#include -#include -#include -#include -#include - -#include - -static grpc_arg copy_arg(const grpc_arg *src) { - grpc_arg dst; - dst.type = src->type; - dst.key = gpr_strdup(src->key); - switch (dst.type) { - case GRPC_ARG_STRING: - dst.value.string = gpr_strdup(src->value.string); - break; - case GRPC_ARG_INTEGER: - dst.value.integer = src->value.integer; - break; - case GRPC_ARG_POINTER: - dst.value.pointer = src->value.pointer; - dst.value.pointer.p = - src->value.pointer.vtable->copy(src->value.pointer.p); - break; - } - return dst; -} - -grpc_channel_args *grpc_channel_args_copy_and_add(const grpc_channel_args *src, - const grpc_arg *to_add, - size_t num_to_add) { - grpc_channel_args *dst = gpr_malloc(sizeof(grpc_channel_args)); - size_t i; - size_t src_num_args = (src == NULL) ? 0 : src->num_args; - if (!src && !to_add) { - dst->num_args = 0; - dst->args = NULL; - return dst; - } - dst->num_args = src_num_args + num_to_add; - dst->args = gpr_malloc(sizeof(grpc_arg) * dst->num_args); - for (i = 0; i < src_num_args; i++) { - dst->args[i] = copy_arg(&src->args[i]); - } - for (i = 0; i < num_to_add; i++) { - dst->args[i + src_num_args] = copy_arg(&to_add[i]); - } - return dst; -} - -grpc_channel_args *grpc_channel_args_copy(const grpc_channel_args *src) { - return grpc_channel_args_copy_and_add(src, NULL, 0); -} - -grpc_channel_args *grpc_channel_args_merge(const grpc_channel_args *a, - const grpc_channel_args *b) { - return grpc_channel_args_copy_and_add(a, b->args, b->num_args); -} - -static int cmp_arg(const grpc_arg *a, const grpc_arg *b) { - int c = GPR_ICMP(a->type, b->type); - if (c != 0) return c; - c = strcmp(a->key, b->key); - if (c != 0) return c; - switch (a->type) { - case GRPC_ARG_STRING: - return strcmp(a->value.string, b->value.string); - case GRPC_ARG_INTEGER: - return GPR_ICMP(a->value.integer, b->value.integer); - case GRPC_ARG_POINTER: - c = GPR_ICMP(a->value.pointer.p, b->value.pointer.p); - if (c != 0) { - c = GPR_ICMP(a->value.pointer.vtable, b->value.pointer.vtable); - if (c == 0) { - c = a->value.pointer.vtable->cmp(a->value.pointer.p, - b->value.pointer.p); - } - } - return c; - } - GPR_UNREACHABLE_CODE(return 0); -} - -/* stabilizing comparison function: since channel_args ordering matters for - * keys with the same name, we need to preserve that ordering */ -static int cmp_key_stable(const void *ap, const void *bp) { - const grpc_arg *const *a = ap; - const grpc_arg *const *b = bp; - int c = strcmp((*a)->key, (*b)->key); - if (c == 0) c = GPR_ICMP(*a, *b); - return c; -} - -grpc_channel_args *grpc_channel_args_normalize(const grpc_channel_args *a) { - grpc_arg **args = gpr_malloc(sizeof(grpc_arg *) * a->num_args); - for (size_t i = 0; i < a->num_args; i++) { - args[i] = &a->args[i]; - } - qsort(args, a->num_args, sizeof(grpc_arg *), cmp_key_stable); - - grpc_channel_args *b = gpr_malloc(sizeof(grpc_channel_args)); - b->num_args = a->num_args; - b->args = gpr_malloc(sizeof(grpc_arg) * b->num_args); - for (size_t i = 0; i < a->num_args; i++) { - b->args[i] = copy_arg(args[i]); - } - - gpr_free(args); - return b; -} - -void grpc_channel_args_destroy(grpc_channel_args *a) { - size_t i; - for (i = 0; i < a->num_args; i++) { - switch (a->args[i].type) { - case GRPC_ARG_STRING: - gpr_free(a->args[i].value.string); - break; - case GRPC_ARG_INTEGER: - break; - case GRPC_ARG_POINTER: - a->args[i].value.pointer.vtable->destroy(a->args[i].value.pointer.p); - break; - } - gpr_free(a->args[i].key); - } - gpr_free(a->args); - gpr_free(a); -} - -int grpc_channel_args_is_census_enabled(const grpc_channel_args *a) { - size_t i; - if (a == NULL) return 0; - for (i = 0; i < a->num_args; i++) { - if (0 == strcmp(a->args[i].key, GRPC_ARG_ENABLE_CENSUS)) { - return a->args[i].value.integer != 0 && census_enabled(); - } - } - return census_enabled(); -} - -grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( - const grpc_channel_args *a) { - size_t i; - if (a == NULL) return 0; - for (i = 0; i < a->num_args; ++i) { - if (a->args[i].type == GRPC_ARG_INTEGER && - !strcmp(GRPC_COMPRESSION_ALGORITHM_ARG, a->args[i].key)) { - return (grpc_compression_algorithm)a->args[i].value.integer; - break; - } - } - return GRPC_COMPRESS_NONE; -} - -grpc_channel_args *grpc_channel_args_set_compression_algorithm( - grpc_channel_args *a, grpc_compression_algorithm algorithm) { - grpc_arg tmp; - tmp.type = GRPC_ARG_INTEGER; - tmp.key = GRPC_COMPRESSION_ALGORITHM_ARG; - tmp.value.integer = algorithm; - return grpc_channel_args_copy_and_add(a, &tmp, 1); -} - -/** Returns 1 if the argument for compression algorithm's enabled states bitset - * was found in \a a, returning the arg's value in \a states. Otherwise, returns - * 0. */ -static int find_compression_algorithm_states_bitset(const grpc_channel_args *a, - int **states_arg) { - if (a != NULL) { - size_t i; - for (i = 0; i < a->num_args; ++i) { - if (a->args[i].type == GRPC_ARG_INTEGER && - !strcmp(GRPC_COMPRESSION_ALGORITHM_STATE_ARG, a->args[i].key)) { - *states_arg = &a->args[i].value.integer; - return 1; /* GPR_TRUE */ - } - } - } - return 0; /* GPR_FALSE */ -} - -grpc_channel_args *grpc_channel_args_compression_algorithm_set_state( - grpc_channel_args **a, grpc_compression_algorithm algorithm, int state) { - int *states_arg; - grpc_channel_args *result = *a; - const int states_arg_found = - find_compression_algorithm_states_bitset(*a, &states_arg); - - if (states_arg_found) { - if (state != 0) { - GPR_BITSET((unsigned *)states_arg, algorithm); - } else { - GPR_BITCLEAR((unsigned *)states_arg, algorithm); - } - } else { - /* create a new arg */ - grpc_arg tmp; - tmp.type = GRPC_ARG_INTEGER; - tmp.key = GRPC_COMPRESSION_ALGORITHM_STATE_ARG; - /* all enabled by default */ - tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; - if (state != 0) { - GPR_BITSET((unsigned *)&tmp.value.integer, algorithm); - } else { - GPR_BITCLEAR((unsigned *)&tmp.value.integer, algorithm); - } - result = grpc_channel_args_copy_and_add(*a, &tmp, 1); - grpc_channel_args_destroy(*a); - *a = result; - } - return result; -} - -int grpc_channel_args_compression_algorithm_get_states( - const grpc_channel_args *a) { - int *states_arg; - if (find_compression_algorithm_states_bitset(a, &states_arg)) { - return *states_arg; - } else { - return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */ - } -} - -int grpc_channel_args_compare(const grpc_channel_args *a, - const grpc_channel_args *b) { - int c = GPR_ICMP(a->num_args, b->num_args); - if (c != 0) return c; - for (size_t i = 0; i < a->num_args; i++) { - c = cmp_arg(&a->args[i], &b->args[i]); - if (c != 0) return c; - } - return 0; -} diff --git a/src/core/channel/channel_args.h b/src/core/channel/channel_args.h deleted file mode 100644 index e19440f76f..0000000000 --- a/src/core/channel/channel_args.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * Copyright 2015-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_CHANNEL_CHANNEL_ARGS_H -#define GRPC_CORE_CHANNEL_CHANNEL_ARGS_H - -#include -#include - -/* Copy some arguments */ -grpc_channel_args *grpc_channel_args_copy(const grpc_channel_args *src); - -/* Copy some arguments, stably sorting keys */ -grpc_channel_args *grpc_channel_args_normalize(const grpc_channel_args *a); - -/** Copy some arguments and add the to_add parameter in the end. - If to_add is NULL, it is equivalent to call grpc_channel_args_copy. */ -grpc_channel_args *grpc_channel_args_copy_and_add(const grpc_channel_args *src, - const grpc_arg *to_add, - size_t num_to_add); - -/** Copy args from a then args from b into a new channel args */ -grpc_channel_args *grpc_channel_args_merge(const grpc_channel_args *a, - const grpc_channel_args *b); - -/** Destroy arguments created by grpc_channel_args_copy */ -void grpc_channel_args_destroy(grpc_channel_args *a); - -/** Reads census_enabled settings from channel args. Returns 1 if census_enabled - * is specified in channel args, otherwise returns 0. */ -int grpc_channel_args_is_census_enabled(const grpc_channel_args *a); - -/** Returns the compression algorithm set in \a a. */ -grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( - const grpc_channel_args *a); - -/** Returns a channel arg instance with compression enabled. If \a a is - * non-NULL, its args are copied. N.B. GRPC_COMPRESS_NONE disables compression - * for the channel. */ -grpc_channel_args *grpc_channel_args_set_compression_algorithm( - grpc_channel_args *a, grpc_compression_algorithm algorithm); - -/** Sets the support for the given compression algorithm. By default, all - * compression algorithms are enabled. It's an error to disable an algorithm set - * by grpc_channel_args_set_compression_algorithm. - * - * Returns an instance with the updated algorithm states. The \a a pointer is - * modified to point to the returned instance (which may be different from the - * input value of \a a). */ -grpc_channel_args *grpc_channel_args_compression_algorithm_set_state( - grpc_channel_args **a, grpc_compression_algorithm algorithm, int enabled); - -/** Returns the bitset representing the support state (true for enabled, false - * for disabled) for compression algorithms. - * - * The i-th bit of the returned bitset corresponds to the i-th entry in the - * grpc_compression_algorithm enum. */ -int grpc_channel_args_compression_algorithm_get_states( - const grpc_channel_args *a); - -int grpc_channel_args_compare(const grpc_channel_args *a, - const grpc_channel_args *b); - -#endif /* GRPC_CORE_CHANNEL_CHANNEL_ARGS_H */ diff --git a/src/core/channel/channel_stack.c b/src/core/channel/channel_stack.c deleted file mode 100644 index 3e61688364..0000000000 --- a/src/core/channel/channel_stack.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * - * Copyright 2015, 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/channel/channel_stack.h" -#include - -#include -#include - -int grpc_trace_channel = 0; - -/* Memory layouts. - - Channel stack is laid out as: { - grpc_channel_stack stk; - padding to GPR_MAX_ALIGNMENT - grpc_channel_element[stk.count]; - per-filter memory, aligned to GPR_MAX_ALIGNMENT - } - - Call stack is laid out as: { - grpc_call_stack stk; - padding to GPR_MAX_ALIGNMENT - grpc_call_element[stk.count]; - per-filter memory, aligned to GPR_MAX_ALIGNMENT - } */ - -/* Given a size, round up to the next multiple of sizeof(void*) */ -#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \ - (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u)) - -size_t grpc_channel_stack_size(const grpc_channel_filter **filters, - size_t filter_count) { - /* always need the header, and size for the channel elements */ - size_t size = - ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)) + - ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element)); - size_t i; - - GPR_ASSERT((GPR_MAX_ALIGNMENT & (GPR_MAX_ALIGNMENT - 1)) == 0 && - "GPR_MAX_ALIGNMENT must be a power of two"); - - /* add the size for each filter */ - for (i = 0; i < filter_count; i++) { - size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); - } - - return size; -} - -#define CHANNEL_ELEMS_FROM_STACK(stk) \ - ((grpc_channel_element *)((char *)(stk) + ROUND_UP_TO_ALIGNMENT_SIZE( \ - sizeof(grpc_channel_stack)))) - -#define CALL_ELEMS_FROM_STACK(stk) \ - ((grpc_call_element *)((char *)(stk) + \ - ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)))) - -grpc_channel_element *grpc_channel_stack_element( - grpc_channel_stack *channel_stack, size_t index) { - return CHANNEL_ELEMS_FROM_STACK(channel_stack) + index; -} - -grpc_channel_element *grpc_channel_stack_last_element( - grpc_channel_stack *channel_stack) { - return grpc_channel_stack_element(channel_stack, channel_stack->count - 1); -} - -grpc_call_element *grpc_call_stack_element(grpc_call_stack *call_stack, - size_t index) { - return CALL_ELEMS_FROM_STACK(call_stack) + index; -} - -void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs, - grpc_iomgr_cb_func destroy, void *destroy_arg, - const grpc_channel_filter **filters, - size_t filter_count, - const grpc_channel_args *channel_args, - const char *name, grpc_channel_stack *stack) { - size_t call_size = - ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) + - ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element)); - grpc_channel_element *elems; - grpc_channel_element_args args; - char *user_data; - size_t i; - - stack->count = filter_count; - GRPC_STREAM_REF_INIT(&stack->refcount, initial_refs, destroy, destroy_arg, - name); - elems = CHANNEL_ELEMS_FROM_STACK(stack); - user_data = - ((char *)elems) + - ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element)); - - /* init per-filter data */ - for (i = 0; i < filter_count; i++) { - args.channel_stack = stack; - args.channel_args = channel_args; - args.is_first = i == 0; - args.is_last = i == (filter_count - 1); - elems[i].filter = filters[i]; - elems[i].channel_data = user_data; - elems[i].filter->init_channel_elem(exec_ctx, &elems[i], &args); - user_data += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); - call_size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data); - } - - GPR_ASSERT(user_data > (char *)stack); - GPR_ASSERT((uintptr_t)(user_data - (char *)stack) == - grpc_channel_stack_size(filters, filter_count)); - - stack->call_stack_size = call_size; -} - -void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx, - grpc_channel_stack *stack) { - grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(stack); - size_t count = stack->count; - size_t i; - - /* destroy per-filter data */ - for (i = 0; i < count; i++) { - channel_elems[i].filter->destroy_channel_elem(exec_ctx, &channel_elems[i]); - } -} - -void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, - grpc_channel_stack *channel_stack, int initial_refs, - grpc_iomgr_cb_func destroy, void *destroy_arg, - grpc_call_context_element *context, - const void *transport_server_data, - grpc_call_stack *call_stack) { - grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(channel_stack); - grpc_call_element_args args; - size_t count = channel_stack->count; - grpc_call_element *call_elems; - char *user_data; - size_t i; - - call_stack->count = count; - GRPC_STREAM_REF_INIT(&call_stack->refcount, initial_refs, destroy, - destroy_arg, "CALL_STACK"); - call_elems = CALL_ELEMS_FROM_STACK(call_stack); - user_data = ((char *)call_elems) + - ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element)); - - /* init per-filter data */ - for (i = 0; i < count; i++) { - args.call_stack = call_stack; - args.server_transport_data = transport_server_data; - args.context = context; - call_elems[i].filter = channel_elems[i].filter; - call_elems[i].channel_data = channel_elems[i].channel_data; - call_elems[i].call_data = user_data; - call_elems[i].filter->init_call_elem(exec_ctx, &call_elems[i], &args); - user_data += - ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data); - } -} - -void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx, - grpc_call_stack *call_stack, - grpc_pollset *pollset) { - size_t count = call_stack->count; - grpc_call_element *call_elems; - char *user_data; - size_t i; - - call_elems = CALL_ELEMS_FROM_STACK(call_stack); - user_data = ((char *)call_elems) + - ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element)); - - /* init per-filter data */ - for (i = 0; i < count; i++) { - call_elems[i].filter->set_pollset(exec_ctx, &call_elems[i], pollset); - user_data += - ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data); - } -} - -void grpc_call_stack_ignore_set_pollset(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_pollset *pollset) {} - -void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack) { - grpc_call_element *elems = CALL_ELEMS_FROM_STACK(stack); - size_t count = stack->count; - size_t i; - - /* destroy per-filter data */ - for (i = 0; i < count; i++) { - elems[i].filter->destroy_call_elem(exec_ctx, &elems[i]); - } -} - -void grpc_call_next_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_transport_stream_op *op) { - grpc_call_element *next_elem = elem + 1; - next_elem->filter->start_transport_stream_op(exec_ctx, next_elem, op); -} - -char *grpc_call_next_get_peer(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - grpc_call_element *next_elem = elem + 1; - return next_elem->filter->get_peer(exec_ctx, next_elem); -} - -void grpc_channel_next_op(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, - grpc_transport_op *op) { - grpc_channel_element *next_elem = elem + 1; - next_elem->filter->start_transport_op(exec_ctx, next_elem, op); -} - -grpc_channel_stack *grpc_channel_stack_from_top_element( - grpc_channel_element *elem) { - return (grpc_channel_stack *)((char *)(elem)-ROUND_UP_TO_ALIGNMENT_SIZE( - sizeof(grpc_channel_stack))); -} - -grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem) { - return (grpc_call_stack *)((char *)(elem)-ROUND_UP_TO_ALIGNMENT_SIZE( - sizeof(grpc_call_stack))); -} - -void grpc_call_element_send_cancel(grpc_exec_ctx *exec_ctx, - grpc_call_element *cur_elem) { - grpc_transport_stream_op op; - memset(&op, 0, sizeof(op)); - op.cancel_with_status = GRPC_STATUS_CANCELLED; - grpc_call_next_op(exec_ctx, cur_elem, &op); -} diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h deleted file mode 100644 index 52362f0b20..0000000000 --- a/src/core/channel/channel_stack.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * - * Copyright 2015-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_CHANNEL_CHANNEL_STACK_H -#define GRPC_CORE_CHANNEL_CHANNEL_STACK_H - -/* A channel filter defines how operations on a channel are implemented. - Channel filters are chained together to create full channels, and if those - chains are linear, then channel stacks provide a mechanism to minimize - allocations for that chain. - Call stacks are created by channel stacks and represent the per-call data - for that stack. */ - -#include - -#include -#include -#include "src/core/debug/trace.h" -#include "src/core/transport/transport.h" - -typedef struct grpc_channel_element grpc_channel_element; -typedef struct grpc_call_element grpc_call_element; - -typedef struct grpc_channel_stack grpc_channel_stack; -typedef struct grpc_call_stack grpc_call_stack; - -typedef struct { - grpc_channel_stack *channel_stack; - const grpc_channel_args *channel_args; - int is_first; - int is_last; -} grpc_channel_element_args; - -typedef struct { - grpc_call_stack *call_stack; - const void *server_transport_data; - grpc_call_context_element *context; -} grpc_call_element_args; - -/* Channel filters specify: - 1. the amount of memory needed in the channel & call (via the sizeof_XXX - members) - 2. functions to initialize and destroy channel & call data - (init_XXX, destroy_XXX) - 3. functions to implement call operations and channel operations (call_op, - channel_op) - 4. a name, which is useful when debugging - - Members are laid out in approximate frequency of use order. */ -typedef struct { - /* Called to eg. send/receive data on a call. - See grpc_call_next_op on how to call the next element in the stack */ - void (*start_transport_stream_op)(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op); - /* Called to handle channel level operations - e.g. new calls, or transport - closure. - See grpc_channel_next_op on how to call the next element in the stack */ - void (*start_transport_op)(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, grpc_transport_op *op); - - /* sizeof(per call data) */ - size_t sizeof_call_data; - /* Initialize per call data. - elem is initialized at the start of the call, and elem->call_data is what - needs initializing. - The filter does not need to do any chaining. - server_transport_data is an opaque pointer. If it is NULL, this call is - on a client; if it is non-NULL, then it points to memory owned by the - transport and is on the server. Most filters want to ignore this - argument. */ - void (*init_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args); - void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_pollset *pollset); - /* Destroy per call data. - The filter does not need to do any chaining */ - void (*destroy_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); - - /* sizeof(per channel data) */ - size_t sizeof_channel_data; - /* Initialize per-channel data. - elem is initialized at the start of the call, and elem->channel_data is - what needs initializing. - is_first, is_last designate this elements position in the stack, and are - useful for asserting correct configuration by upper layer code. - The filter does not need to do any chaining */ - void (*init_channel_elem)(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, - grpc_channel_element_args *args); - /* Destroy per channel data. - The filter does not need to do any chaining */ - void (*destroy_channel_elem)(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem); - - /* Implement grpc_call_get_peer() */ - char *(*get_peer)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); - - /* The name of this filter */ - const char *name; -} grpc_channel_filter; - -/* A channel_element tracks its filter and the filter requested memory within - a channel allocation */ -struct grpc_channel_element { - const grpc_channel_filter *filter; - void *channel_data; -}; - -/* A call_element tracks its filter, the filter requested memory within - a channel allocation, and the filter requested memory within a call - allocation */ -struct grpc_call_element { - const grpc_channel_filter *filter; - void *channel_data; - void *call_data; -}; - -/* A channel stack tracks a set of related filters for one channel, and - guarantees they live within a single malloc() allocation */ -struct grpc_channel_stack { - grpc_stream_refcount refcount; - size_t count; - /* Memory required for a call stack (computed at channel stack - initialization) */ - size_t call_stack_size; -}; - -/* A call stack tracks a set of related filters for one call, and guarantees - they live within a single malloc() allocation */ -struct grpc_call_stack { - /* shared refcount for this channel stack. - MUST be the first element: the underlying code calls destroy - with the address of the refcount, but higher layers prefer to think - about the address of the call stack itself. */ - grpc_stream_refcount refcount; - size_t count; -}; - -/* Get a channel element given a channel stack and its index */ -grpc_channel_element *grpc_channel_stack_element(grpc_channel_stack *stack, - size_t i); -/* Get the last channel element in a channel stack */ -grpc_channel_element *grpc_channel_stack_last_element( - grpc_channel_stack *stack); -/* Get a call stack element given a call stack and an index */ -grpc_call_element *grpc_call_stack_element(grpc_call_stack *stack, size_t i); - -/* Determine memory required for a channel stack containing a set of filters */ -size_t grpc_channel_stack_size(const grpc_channel_filter **filters, - size_t filter_count); -/* Initialize a channel stack given some filters */ -void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs, - grpc_iomgr_cb_func destroy, void *destroy_arg, - const grpc_channel_filter **filters, - size_t filter_count, const grpc_channel_args *args, - const char *name, grpc_channel_stack *stack); -/* Destroy a channel stack */ -void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx, - grpc_channel_stack *stack); - -/* Initialize a call stack given a channel stack. transport_server_data is - expected to be NULL on a client, or an opaque transport owned pointer on the - server. */ -void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, - grpc_channel_stack *channel_stack, int initial_refs, - grpc_iomgr_cb_func destroy, void *destroy_arg, - grpc_call_context_element *context, - const void *transport_server_data, - grpc_call_stack *call_stack); -/* Set a pollset for a call stack: must occur before the first op is started */ -void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx, - grpc_call_stack *call_stack, - grpc_pollset *pollset); - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -#define GRPC_CALL_STACK_REF(call_stack, reason) \ - grpc_stream_ref(&(call_stack)->refcount, reason) -#define GRPC_CALL_STACK_UNREF(exec_ctx, call_stack, reason) \ - grpc_stream_unref(exec_ctx, &(call_stack)->refcount, reason) -#define GRPC_CHANNEL_STACK_REF(channel_stack, reason) \ - grpc_stream_ref(&(channel_stack)->refcount, reason) -#define GRPC_CHANNEL_STACK_UNREF(exec_ctx, channel_stack, reason) \ - grpc_stream_unref(exec_ctx, &(channel_stack)->refcount, reason) -#else -#define GRPC_CALL_STACK_REF(call_stack, reason) \ - grpc_stream_ref(&(call_stack)->refcount) -#define GRPC_CALL_STACK_UNREF(exec_ctx, call_stack, reason) \ - grpc_stream_unref(exec_ctx, &(call_stack)->refcount) -#define GRPC_CHANNEL_STACK_REF(channel_stack, reason) \ - grpc_stream_ref(&(channel_stack)->refcount) -#define GRPC_CHANNEL_STACK_UNREF(exec_ctx, channel_stack, reason) \ - grpc_stream_unref(exec_ctx, &(channel_stack)->refcount) -#endif - -/* Destroy a call stack */ -void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack); - -/* Ignore set pollset - used by filters to implement the set_pollset method - if they don't care about pollsets at all. Does nothing. */ -void grpc_call_stack_ignore_set_pollset(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_pollset *pollset); -/* Call the next operation in a call stack */ -void grpc_call_next_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_transport_stream_op *op); -/* Call the next operation (depending on call directionality) in a channel - stack */ -void grpc_channel_next_op(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, - grpc_transport_op *op); -/* Pass through a request to get_peer to the next child element */ -char *grpc_call_next_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); - -/* Given the top element of a channel stack, get the channel stack itself */ -grpc_channel_stack *grpc_channel_stack_from_top_element( - grpc_channel_element *elem); -/* Given the top element of a call stack, get the call stack itself */ -grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem); - -void grpc_call_log_op(char *file, int line, gpr_log_severity severity, - grpc_call_element *elem, grpc_transport_stream_op *op); - -void grpc_call_element_send_cancel(grpc_exec_ctx *exec_ctx, - grpc_call_element *cur_elem); - -extern int grpc_trace_channel; - -#define GRPC_CALL_LOG_OP(sev, elem, op) \ - if (grpc_trace_channel) grpc_call_log_op(sev, elem, op) - -#endif /* GRPC_CORE_CHANNEL_CHANNEL_STACK_H */ diff --git a/src/core/channel/channel_stack_builder.c b/src/core/channel/channel_stack_builder.c deleted file mode 100644 index 1b1004e5f9..0000000000 --- a/src/core/channel/channel_stack_builder.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * - * 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/channel/channel_stack_builder.h" - -#include - -#include - -int grpc_trace_channel_stack_builder = 0; - -typedef struct filter_node { - struct filter_node *next; - struct filter_node *prev; - const grpc_channel_filter *filter; - grpc_post_filter_create_init_func init; - void *init_arg; -} filter_node; - -struct grpc_channel_stack_builder { - // sentinel nodes for filters that have been added - filter_node begin; - filter_node end; - // various set/get-able parameters - const grpc_channel_args *args; - grpc_transport *transport; - const char *name; -}; - -struct grpc_channel_stack_builder_iterator { - grpc_channel_stack_builder *builder; - filter_node *node; -}; - -grpc_channel_stack_builder *grpc_channel_stack_builder_create(void) { - grpc_channel_stack_builder *b = gpr_malloc(sizeof(*b)); - memset(b, 0, sizeof(*b)); - - b->begin.filter = NULL; - b->end.filter = NULL; - b->begin.next = &b->end; - b->begin.prev = &b->end; - b->end.next = &b->begin; - b->end.prev = &b->begin; - - return b; -} - -static grpc_channel_stack_builder_iterator *create_iterator_at_filter_node( - grpc_channel_stack_builder *builder, filter_node *node) { - grpc_channel_stack_builder_iterator *it = gpr_malloc(sizeof(*it)); - it->builder = builder; - it->node = node; - return it; -} - -void grpc_channel_stack_builder_iterator_destroy( - grpc_channel_stack_builder_iterator *it) { - gpr_free(it); -} - -grpc_channel_stack_builder_iterator * -grpc_channel_stack_builder_create_iterator_at_first( - grpc_channel_stack_builder *builder) { - return create_iterator_at_filter_node(builder, &builder->begin); -} - -grpc_channel_stack_builder_iterator * -grpc_channel_stack_builder_create_iterator_at_last( - grpc_channel_stack_builder *builder) { - return create_iterator_at_filter_node(builder, &builder->end); -} - -bool grpc_channel_stack_builder_move_next( - grpc_channel_stack_builder_iterator *iterator) { - if (iterator->node == &iterator->builder->end) return false; - iterator->node = iterator->node->next; - return true; -} - -bool grpc_channel_stack_builder_move_prev( - grpc_channel_stack_builder_iterator *iterator) { - if (iterator->node == &iterator->builder->begin) return false; - iterator->node = iterator->node->prev; - return true; -} - -bool grpc_channel_stack_builder_move_prev( - grpc_channel_stack_builder_iterator *iterator); - -void grpc_channel_stack_builder_set_name(grpc_channel_stack_builder *builder, - const char *name) { - GPR_ASSERT(builder->name == NULL); - builder->name = name; -} - -void grpc_channel_stack_builder_set_channel_arguments( - grpc_channel_stack_builder *builder, const grpc_channel_args *args) { - GPR_ASSERT(builder->args == NULL); - builder->args = args; -} - -void grpc_channel_stack_builder_set_transport( - grpc_channel_stack_builder *builder, grpc_transport *transport) { - GPR_ASSERT(builder->transport == NULL); - builder->transport = transport; -} - -grpc_transport *grpc_channel_stack_builder_get_transport( - grpc_channel_stack_builder *builder) { - return builder->transport; -} - -const grpc_channel_args *grpc_channel_stack_builder_get_channel_arguments( - grpc_channel_stack_builder *builder) { - return builder->args; -} - -bool grpc_channel_stack_builder_append_filter( - grpc_channel_stack_builder *builder, const grpc_channel_filter *filter, - grpc_post_filter_create_init_func post_init_func, void *user_data) { - grpc_channel_stack_builder_iterator *it = - grpc_channel_stack_builder_create_iterator_at_last(builder); - bool ok = grpc_channel_stack_builder_add_filter_before( - it, filter, post_init_func, user_data); - grpc_channel_stack_builder_iterator_destroy(it); - return ok; -} - -bool grpc_channel_stack_builder_prepend_filter( - grpc_channel_stack_builder *builder, const grpc_channel_filter *filter, - grpc_post_filter_create_init_func post_init_func, void *user_data) { - grpc_channel_stack_builder_iterator *it = - grpc_channel_stack_builder_create_iterator_at_first(builder); - bool ok = grpc_channel_stack_builder_add_filter_after( - it, filter, post_init_func, user_data); - grpc_channel_stack_builder_iterator_destroy(it); - return ok; -} - -static void add_after(filter_node *before, const grpc_channel_filter *filter, - grpc_post_filter_create_init_func post_init_func, - void *user_data) { - filter_node *new = gpr_malloc(sizeof(*new)); - new->next = before->next; - new->prev = before; - new->next->prev = new->prev->next = new; - new->filter = filter; - new->init = post_init_func; - new->init_arg = user_data; -} - -bool grpc_channel_stack_builder_add_filter_before( - grpc_channel_stack_builder_iterator *iterator, - const grpc_channel_filter *filter, - grpc_post_filter_create_init_func post_init_func, void *user_data) { - if (iterator->node == &iterator->builder->begin) return false; - add_after(iterator->node->prev, filter, post_init_func, user_data); - return true; -} - -bool grpc_channel_stack_builder_add_filter_after( - grpc_channel_stack_builder_iterator *iterator, - const grpc_channel_filter *filter, - grpc_post_filter_create_init_func post_init_func, void *user_data) { - if (iterator->node == &iterator->builder->end) return false; - add_after(iterator->node, filter, post_init_func, user_data); - return true; -} - -void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder) { - filter_node *p = builder->begin.next; - while (p != &builder->end) { - filter_node *next = p->next; - gpr_free(p); - p = next; - } - gpr_free(builder); -} - -void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx, - grpc_channel_stack_builder *builder, - size_t prefix_bytes, int initial_refs, - grpc_iomgr_cb_func destroy, - void *destroy_arg) { - // count the number of filters - size_t num_filters = 0; - for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) { - num_filters++; - } - - // create an array of filters - const grpc_channel_filter **filters = - gpr_malloc(sizeof(*filters) * num_filters); - size_t i = 0; - for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) { - filters[i++] = p->filter; - } - - // calculate the size of the channel stack - size_t channel_stack_size = grpc_channel_stack_size(filters, num_filters); - - // allocate memory, with prefix_bytes followed by channel_stack_size - char *result = gpr_malloc(prefix_bytes + channel_stack_size); - // fetch a pointer to the channel stack - grpc_channel_stack *channel_stack = - (grpc_channel_stack *)(result + prefix_bytes); - // and initialize it - grpc_channel_stack_init(exec_ctx, initial_refs, destroy, - destroy_arg == NULL ? result : destroy_arg, filters, - num_filters, builder->args, builder->name, - channel_stack); - - // run post-initialization functions - i = 0; - for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) { - if (p->init != NULL) { - p->init(channel_stack, grpc_channel_stack_element(channel_stack, i), - p->init_arg); - } - i++; - } - - grpc_channel_stack_builder_destroy(builder); - gpr_free((grpc_channel_filter **)filters); - - return result; -} diff --git a/src/core/channel/channel_stack_builder.h b/src/core/channel/channel_stack_builder.h deleted file mode 100644 index 15f395e8b8..0000000000 --- a/src/core/channel/channel_stack_builder.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * - * 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_CHANNEL_CHANNEL_STACK_BUILDER_H -#define GRPC_CORE_CHANNEL_CHANNEL_STACK_BUILDER_H - -#include - -#include "src/core/channel/channel_args.h" -#include "src/core/channel/channel_stack.h" - -/// grpc_channel_stack_builder offers a programmatic interface to selected -/// and order channel filters -typedef struct grpc_channel_stack_builder grpc_channel_stack_builder; -typedef struct grpc_channel_stack_builder_iterator - grpc_channel_stack_builder_iterator; - -/// Create a new channel stack builder -grpc_channel_stack_builder *grpc_channel_stack_builder_create(void); - -/// Assign a name to the channel stack: \a name must be statically allocated -void grpc_channel_stack_builder_set_name(grpc_channel_stack_builder *builder, - const char *name); - -/// Attach \a transport to the builder (does not take ownership) -void grpc_channel_stack_builder_set_transport( - grpc_channel_stack_builder *builder, grpc_transport *transport); - -/// Fetch attached transport -grpc_transport *grpc_channel_stack_builder_get_transport( - grpc_channel_stack_builder *builder); - -/// Set channel arguments: \a args must continue to exist until after -/// grpc_channel_stack_builder_finish returns -void grpc_channel_stack_builder_set_channel_arguments( - grpc_channel_stack_builder *builder, const grpc_channel_args *args); - -/// Return a borrowed pointer to the channel arguments -const grpc_channel_args *grpc_channel_stack_builder_get_channel_arguments( - grpc_channel_stack_builder *builder); - -/// Begin iterating over already defined filters in the builder at the beginning -grpc_channel_stack_builder_iterator * -grpc_channel_stack_builder_create_iterator_at_first( - grpc_channel_stack_builder *builder); - -/// Begin iterating over already defined filters in the builder at the end -grpc_channel_stack_builder_iterator * -grpc_channel_stack_builder_create_iterator_at_last( - grpc_channel_stack_builder *builder); - -/// Is an iterator at the first element? -bool grpc_channel_stack_builder_iterator_is_first( - grpc_channel_stack_builder_iterator *iterator); - -/// Is an iterator at the end? -bool grpc_channel_stack_builder_iterator_is_end( - grpc_channel_stack_builder_iterator *iterator); - -/// Move an iterator to the next item -bool grpc_channel_stack_builder_move_next( - grpc_channel_stack_builder_iterator *iterator); - -/// Move an iterator to the previous item -bool grpc_channel_stack_builder_move_prev( - grpc_channel_stack_builder_iterator *iterator); - -typedef void (*grpc_post_filter_create_init_func)( - grpc_channel_stack *channel_stack, grpc_channel_element *elem, void *arg); - -/// Add \a filter to the stack, after \a iterator. -/// Call \a post_init_func(..., \a user_data) once the channel stack is -/// created. -bool grpc_channel_stack_builder_add_filter_after( - grpc_channel_stack_builder_iterator *iterator, - const grpc_channel_filter *filter, - grpc_post_filter_create_init_func post_init_func, - void *user_data) GRPC_MUST_USE_RESULT; - -/// Add \a filter to the stack, before \a iterator. -/// Call \a post_init_func(..., \a user_data) once the channel stack is -/// created. -bool grpc_channel_stack_builder_add_filter_before( - grpc_channel_stack_builder_iterator *iterator, - const grpc_channel_filter *filter, - grpc_post_filter_create_init_func post_init_func, - void *user_data) GRPC_MUST_USE_RESULT; - -/// Add \a filter to the beginning of the filter list. -/// Call \a post_init_func(..., \a user_data) once the channel stack is -/// created. -bool grpc_channel_stack_builder_prepend_filter( - grpc_channel_stack_builder *builder, const grpc_channel_filter *filter, - grpc_post_filter_create_init_func post_init_func, - void *user_data) GRPC_MUST_USE_RESULT; - -/// Add \a filter to the end of the filter list. -/// Call \a post_init_func(..., \a user_data) once the channel stack is -/// created. -bool grpc_channel_stack_builder_append_filter( - grpc_channel_stack_builder *builder, const grpc_channel_filter *filter, - grpc_post_filter_create_init_func post_init_func, - void *user_data) GRPC_MUST_USE_RESULT; - -/// Terminate iteration and destroy \a iterator -void grpc_channel_stack_builder_iterator_destroy( - grpc_channel_stack_builder_iterator *iterator); - -/// Destroy the builder, return the freshly minted channel stack -/// Allocates \a prefix_bytes bytes before the channel stack -/// Returns the base pointer of the allocated block -/// \a initial_refs, \a destroy, \a destroy_arg are as per -/// grpc_channel_stack_init -void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx, - grpc_channel_stack_builder *builder, - size_t prefix_bytes, int initial_refs, - grpc_iomgr_cb_func destroy, - void *destroy_arg); - -/// Destroy the builder without creating a channel stack -void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder); - -extern int grpc_trace_channel_stack_builder; - -#endif /* GRPC_CORE_CHANNEL_CHANNEL_STACK_BUILDER_H */ diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c deleted file mode 100644 index ad1ded9ab7..0000000000 --- a/src/core/channel/client_channel.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * - * Copyright 2015-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/channel/client_channel.h" - -#include -#include - -#include -#include -#include -#include - -#include "src/core/channel/channel_args.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/subchannel_call_holder.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/surface/channel.h" -#include "src/core/transport/connectivity_state.h" - -/* Client channel implementation */ - -typedef grpc_subchannel_call_holder call_data; - -typedef struct client_channel_channel_data { - /** resolver for this channel */ - grpc_resolver *resolver; - /** have we started resolving this channel */ - int started_resolving; - - /** mutex protecting client configuration, including all - variables below in this data structure */ - gpr_mu mu_config; - /** currently active load balancer - guarded by mu_config */ - grpc_lb_policy *lb_policy; - /** incoming configuration - set by resolver.next - guarded by mu_config */ - grpc_client_config *incoming_configuration; - /** a list of closures that are all waiting for config to come in */ - grpc_closure_list waiting_for_config_closures; - /** resolver callback */ - grpc_closure on_config_changed; - /** connectivity state being tracked */ - grpc_connectivity_state_tracker state_tracker; - /** when an lb_policy arrives, should we try to exit idle */ - int exit_idle_when_lb_policy_arrives; - /** owning stack */ - grpc_channel_stack *owning_stack; - /** interested parties (owned) */ - grpc_pollset_set *interested_parties; -} channel_data; - -/** We create one watcher for each new lb_policy that is returned from a - resolver, - to watch for state changes from the lb_policy. When a state change is seen, - we - update the channel, and create a new watcher */ -typedef struct { - channel_data *chand; - grpc_closure on_changed; - grpc_connectivity_state state; - grpc_lb_policy *lb_policy; -} lb_policy_connectivity_watcher; - -typedef struct { - grpc_closure closure; - grpc_call_element *elem; -} waiting_call; - -static char *cc_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { - return grpc_subchannel_call_holder_get_peer(exec_ctx, elem->call_data); -} - -static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - GRPC_CALL_LOG_OP(GPR_INFO, elem, op); - grpc_subchannel_call_holder_perform_op(exec_ctx, elem->call_data, op); -} - -static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand, - grpc_lb_policy *lb_policy, - grpc_connectivity_state current_state); - -static void on_lb_policy_state_changed_locked( - grpc_exec_ctx *exec_ctx, lb_policy_connectivity_watcher *w) { - grpc_connectivity_state publish_state = w->state; - /* check if the notification is for a stale policy */ - if (w->lb_policy != w->chand->lb_policy) return; - - if (publish_state == GRPC_CHANNEL_FATAL_FAILURE && - w->chand->resolver != NULL) { - publish_state = GRPC_CHANNEL_TRANSIENT_FAILURE; - grpc_resolver_channel_saw_error(exec_ctx, w->chand->resolver); - GRPC_LB_POLICY_UNREF(exec_ctx, w->chand->lb_policy, "channel"); - w->chand->lb_policy = NULL; - } - grpc_connectivity_state_set(exec_ctx, &w->chand->state_tracker, publish_state, - "lb_changed"); - if (w->state != GRPC_CHANNEL_FATAL_FAILURE) { - watch_lb_policy(exec_ctx, w->chand, w->lb_policy, w->state); - } -} - -static void on_lb_policy_state_changed(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_success) { - lb_policy_connectivity_watcher *w = arg; - - gpr_mu_lock(&w->chand->mu_config); - on_lb_policy_state_changed_locked(exec_ctx, w); - gpr_mu_unlock(&w->chand->mu_config); - - GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack, "watch_lb_policy"); - gpr_free(w); -} - -static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand, - grpc_lb_policy *lb_policy, - grpc_connectivity_state current_state) { - lb_policy_connectivity_watcher *w = gpr_malloc(sizeof(*w)); - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "watch_lb_policy"); - - w->chand = chand; - grpc_closure_init(&w->on_changed, on_lb_policy_state_changed, w); - w->state = current_state; - w->lb_policy = lb_policy; - grpc_lb_policy_notify_on_state_change(exec_ctx, lb_policy, &w->state, - &w->on_changed); -} - -static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_success) { - channel_data *chand = arg; - grpc_lb_policy *lb_policy = NULL; - grpc_lb_policy *old_lb_policy; - grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE; - int exit_idle = 0; - - if (chand->incoming_configuration != NULL) { - lb_policy = grpc_client_config_get_lb_policy(chand->incoming_configuration); - if (lb_policy != NULL) { - GRPC_LB_POLICY_REF(lb_policy, "channel"); - GRPC_LB_POLICY_REF(lb_policy, "config_change"); - state = grpc_lb_policy_check_connectivity(exec_ctx, lb_policy); - } - - grpc_client_config_unref(exec_ctx, chand->incoming_configuration); - } - - chand->incoming_configuration = NULL; - - if (lb_policy != NULL) { - grpc_pollset_set_add_pollset_set(exec_ctx, lb_policy->interested_parties, - chand->interested_parties); - } - - gpr_mu_lock(&chand->mu_config); - old_lb_policy = chand->lb_policy; - chand->lb_policy = lb_policy; - if (lb_policy != NULL || chand->resolver == NULL /* disconnected */) { - grpc_exec_ctx_enqueue_list(exec_ctx, &chand->waiting_for_config_closures, - NULL); - } - if (lb_policy != NULL && chand->exit_idle_when_lb_policy_arrives) { - GRPC_LB_POLICY_REF(lb_policy, "exit_idle"); - exit_idle = 1; - chand->exit_idle_when_lb_policy_arrives = 0; - } - - if (iomgr_success && chand->resolver) { - grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, state, - "new_lb+resolver"); - if (lb_policy != NULL) { - watch_lb_policy(exec_ctx, chand, lb_policy, state); - } - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); - grpc_resolver_next(exec_ctx, chand->resolver, - &chand->incoming_configuration, - &chand->on_config_changed); - gpr_mu_unlock(&chand->mu_config); - } else { - if (chand->resolver != NULL) { - grpc_resolver_shutdown(exec_ctx, chand->resolver); - GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel"); - chand->resolver = NULL; - } - grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, - GRPC_CHANNEL_FATAL_FAILURE, "resolver_gone"); - gpr_mu_unlock(&chand->mu_config); - } - - if (exit_idle) { - grpc_lb_policy_exit_idle(exec_ctx, lb_policy); - GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "exit_idle"); - } - - if (old_lb_policy != NULL) { - grpc_pollset_set_del_pollset_set( - exec_ctx, old_lb_policy->interested_parties, chand->interested_parties); - GRPC_LB_POLICY_UNREF(exec_ctx, old_lb_policy, "channel"); - } - - if (lb_policy != NULL) { - GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "config_change"); - } - - GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->owning_stack, "resolver"); -} - -static void cc_start_transport_op(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_transport_op *op) { - channel_data *chand = elem->channel_data; - - grpc_exec_ctx_enqueue(exec_ctx, op->on_consumed, true, NULL); - - GPR_ASSERT(op->set_accept_stream == false); - if (op->bind_pollset != NULL) { - grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, - op->bind_pollset); - } - - gpr_mu_lock(&chand->mu_config); - if (op->on_connectivity_state_change != NULL) { - grpc_connectivity_state_notify_on_state_change( - exec_ctx, &chand->state_tracker, op->connectivity_state, - op->on_connectivity_state_change); - op->on_connectivity_state_change = NULL; - op->connectivity_state = NULL; - } - - if (op->send_ping != NULL) { - if (chand->lb_policy == NULL) { - grpc_exec_ctx_enqueue(exec_ctx, op->send_ping, false, NULL); - } else { - grpc_lb_policy_ping_one(exec_ctx, chand->lb_policy, op->send_ping); - op->bind_pollset = NULL; - } - op->send_ping = NULL; - } - - if (op->disconnect && chand->resolver != NULL) { - grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, - GRPC_CHANNEL_FATAL_FAILURE, "disconnect"); - grpc_resolver_shutdown(exec_ctx, chand->resolver); - GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel"); - chand->resolver = NULL; - if (chand->lb_policy != NULL) { - grpc_pollset_set_del_pollset_set(exec_ctx, - chand->lb_policy->interested_parties, - chand->interested_parties); - GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel"); - chand->lb_policy = NULL; - } - } - gpr_mu_unlock(&chand->mu_config); -} - -typedef struct { - grpc_metadata_batch *initial_metadata; - grpc_connected_subchannel **connected_subchannel; - grpc_closure *on_ready; - grpc_call_element *elem; - grpc_closure closure; -} continue_picking_args; - -static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *arg, - grpc_metadata_batch *initial_metadata, - grpc_connected_subchannel **connected_subchannel, - grpc_closure *on_ready); - -static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - continue_picking_args *cpa = arg; - if (!success) { - grpc_exec_ctx_enqueue(exec_ctx, cpa->on_ready, false, NULL); - } else if (cpa->connected_subchannel == NULL) { - /* cancelled, do nothing */ - } else if (cc_pick_subchannel(exec_ctx, cpa->elem, cpa->initial_metadata, - cpa->connected_subchannel, cpa->on_ready)) { - grpc_exec_ctx_enqueue(exec_ctx, cpa->on_ready, true, NULL); - } - gpr_free(cpa); -} - -static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp, - grpc_metadata_batch *initial_metadata, - grpc_connected_subchannel **connected_subchannel, - grpc_closure *on_ready) { - grpc_call_element *elem = elemp; - channel_data *chand = elem->channel_data; - call_data *calld = elem->call_data; - continue_picking_args *cpa; - grpc_closure *closure; - - GPR_ASSERT(connected_subchannel); - - gpr_mu_lock(&chand->mu_config); - if (initial_metadata == NULL) { - if (chand->lb_policy != NULL) { - grpc_lb_policy_cancel_pick(exec_ctx, chand->lb_policy, - connected_subchannel); - } - for (closure = chand->waiting_for_config_closures.head; closure != NULL; - closure = grpc_closure_next(closure)) { - cpa = closure->cb_arg; - if (cpa->connected_subchannel == connected_subchannel) { - cpa->connected_subchannel = NULL; - grpc_exec_ctx_enqueue(exec_ctx, cpa->on_ready, false, NULL); - } - } - gpr_mu_unlock(&chand->mu_config); - return 1; - } - if (chand->lb_policy != NULL) { - grpc_lb_policy *lb_policy = chand->lb_policy; - int r; - GRPC_LB_POLICY_REF(lb_policy, "cc_pick_subchannel"); - gpr_mu_unlock(&chand->mu_config); - r = grpc_lb_policy_pick(exec_ctx, lb_policy, calld->pollset, - initial_metadata, connected_subchannel, on_ready); - GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "cc_pick_subchannel"); - return r; - } - if (chand->resolver != NULL && !chand->started_resolving) { - chand->started_resolving = 1; - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); - grpc_resolver_next(exec_ctx, chand->resolver, - &chand->incoming_configuration, - &chand->on_config_changed); - } - cpa = gpr_malloc(sizeof(*cpa)); - cpa->initial_metadata = initial_metadata; - cpa->connected_subchannel = connected_subchannel; - cpa->on_ready = on_ready; - cpa->elem = elem; - grpc_closure_init(&cpa->closure, continue_picking, cpa); - grpc_closure_list_add(&chand->waiting_for_config_closures, &cpa->closure, 1); - gpr_mu_unlock(&chand->mu_config); - return 0; -} - -/* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { - grpc_subchannel_call_holder_init(elem->call_data, cc_pick_subchannel, elem, - args->call_stack); -} - -/* Destructor for call_data */ -static void destroy_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - grpc_subchannel_call_holder_destroy(exec_ctx, elem->call_data); -} - -/* Constructor for channel_data */ -static void init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - channel_data *chand = elem->channel_data; - - memset(chand, 0, sizeof(*chand)); - - GPR_ASSERT(args->is_last); - GPR_ASSERT(elem->filter == &grpc_client_channel_filter); - - gpr_mu_init(&chand->mu_config); - grpc_closure_init(&chand->on_config_changed, cc_on_config_changed, chand); - chand->owning_stack = args->channel_stack; - - grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, - "client_channel"); - chand->interested_parties = grpc_pollset_set_create(); -} - -/* Destructor for channel_data */ -static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) { - channel_data *chand = elem->channel_data; - - if (chand->resolver != NULL) { - grpc_resolver_shutdown(exec_ctx, chand->resolver); - GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel"); - } - if (chand->lb_policy != NULL) { - grpc_pollset_set_del_pollset_set(exec_ctx, - chand->lb_policy->interested_parties, - chand->interested_parties); - GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel"); - } - grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker); - grpc_pollset_set_destroy(chand->interested_parties); - gpr_mu_destroy(&chand->mu_config); -} - -static void cc_set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_pollset *pollset) { - call_data *calld = elem->call_data; - calld->pollset = pollset; -} - -const grpc_channel_filter grpc_client_channel_filter = { - cc_start_transport_stream_op, - cc_start_transport_op, - sizeof(call_data), - init_call_elem, - cc_set_pollset, - destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - cc_get_peer, - "client-channel", -}; - -void grpc_client_channel_set_resolver(grpc_exec_ctx *exec_ctx, - grpc_channel_stack *channel_stack, - grpc_resolver *resolver) { - /* post construction initialization: set the transport setup pointer */ - grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack); - channel_data *chand = elem->channel_data; - gpr_mu_lock(&chand->mu_config); - GPR_ASSERT(!chand->resolver); - chand->resolver = resolver; - GRPC_RESOLVER_REF(resolver, "channel"); - if (!grpc_closure_list_empty(chand->waiting_for_config_closures) || - chand->exit_idle_when_lb_policy_arrives) { - chand->started_resolving = 1; - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); - grpc_resolver_next(exec_ctx, resolver, &chand->incoming_configuration, - &chand->on_config_changed); - } - gpr_mu_unlock(&chand->mu_config); -} - -grpc_connectivity_state grpc_client_channel_check_connectivity_state( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect) { - channel_data *chand = elem->channel_data; - grpc_connectivity_state out; - gpr_mu_lock(&chand->mu_config); - out = grpc_connectivity_state_check(&chand->state_tracker); - if (out == GRPC_CHANNEL_IDLE && try_to_connect) { - if (chand->lb_policy != NULL) { - grpc_lb_policy_exit_idle(exec_ctx, chand->lb_policy); - } else { - chand->exit_idle_when_lb_policy_arrives = 1; - if (!chand->started_resolving && chand->resolver != NULL) { - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); - chand->started_resolving = 1; - grpc_resolver_next(exec_ctx, chand->resolver, - &chand->incoming_configuration, - &chand->on_config_changed); - } - } - } - gpr_mu_unlock(&chand->mu_config); - return out; -} - -typedef struct { - channel_data *chand; - grpc_pollset *pollset; - grpc_closure *on_complete; - grpc_closure my_closure; -} external_connectivity_watcher; - -static void on_external_watch_complete(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_success) { - external_connectivity_watcher *w = arg; - grpc_closure *follow_up = w->on_complete; - grpc_pollset_set_del_pollset(exec_ctx, w->chand->interested_parties, - w->pollset); - GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack, - "external_connectivity_watcher"); - gpr_free(w); - follow_up->cb(exec_ctx, follow_up->cb_arg, iomgr_success); -} - -void grpc_client_channel_watch_connectivity_state( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset, - grpc_connectivity_state *state, grpc_closure *on_complete) { - channel_data *chand = elem->channel_data; - external_connectivity_watcher *w = gpr_malloc(sizeof(*w)); - w->chand = chand; - w->pollset = pollset; - w->on_complete = on_complete; - grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, pollset); - grpc_closure_init(&w->my_closure, on_external_watch_complete, w); - GRPC_CHANNEL_STACK_REF(w->chand->owning_stack, - "external_connectivity_watcher"); - gpr_mu_lock(&chand->mu_config); - grpc_connectivity_state_notify_on_state_change( - exec_ctx, &chand->state_tracker, state, &w->my_closure); - gpr_mu_unlock(&chand->mu_config); -} diff --git a/src/core/channel/client_channel.h b/src/core/channel/client_channel.h deleted file mode 100644 index 422f7f8374..0000000000 --- a/src/core/channel/client_channel.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * Copyright 2015-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_CHANNEL_CLIENT_CHANNEL_H -#define GRPC_CORE_CHANNEL_CLIENT_CHANNEL_H - -#include "src/core/channel/channel_stack.h" -#include "src/core/client_config/resolver.h" - -/* A client channel is a channel that begins disconnected, and can connect - to some endpoint on demand. If that endpoint disconnects, it will be - connected to again later. - - Calls on a disconnected client channel are queued until a connection is - established. */ - -extern const grpc_channel_filter grpc_client_channel_filter; - -/* post-construction initializer to let the client channel know which - transport setup it should cancel upon destruction, or initiate when it needs - a connection */ -void grpc_client_channel_set_resolver(grpc_exec_ctx *exec_ctx, - grpc_channel_stack *channel_stack, - grpc_resolver *resolver); - -grpc_connectivity_state grpc_client_channel_check_connectivity_state( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect); - -void grpc_client_channel_watch_connectivity_state( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset, - grpc_connectivity_state *state, grpc_closure *on_complete); - -#endif /* GRPC_CORE_CHANNEL_CLIENT_CHANNEL_H */ diff --git a/src/core/channel/compress_filter.c b/src/core/channel/compress_filter.c deleted file mode 100644 index 6f5a9740ad..0000000000 --- a/src/core/channel/compress_filter.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * - * Copyright 2015-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 -#include - -#include -#include -#include -#include - -#include "src/core/channel/channel_args.h" -#include "src/core/channel/compress_filter.h" -#include "src/core/compression/algorithm_metadata.h" -#include "src/core/compression/message_compress.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/transport/static_metadata.h" - -typedef struct call_data { - gpr_slice_buffer slices; /**< Buffers up input slices to be compressed */ - grpc_linked_mdelem compression_algorithm_storage; - grpc_linked_mdelem accept_encoding_storage; - uint32_t remaining_slice_bytes; - /** Compression algorithm we'll try to use. It may be given by incoming - * metadata, or by the channel's default compression settings. */ - grpc_compression_algorithm compression_algorithm; - /** If true, contents of \a compression_algorithm are authoritative */ - int has_compression_algorithm; - - grpc_transport_stream_op send_op; - uint32_t send_length; - uint32_t send_flags; - gpr_slice incoming_slice; - grpc_slice_buffer_stream replacement_stream; - grpc_closure *post_send; - grpc_closure send_done; - grpc_closure got_slice; -} call_data; - -typedef struct channel_data { - /** The default, channel-level, compression algorithm */ - grpc_compression_algorithm default_compression_algorithm; - /** Compression options for the channel */ - grpc_compression_options compression_options; - /** Supported compression algorithms */ - uint32_t supported_compression_algorithms; -} channel_data; - -/** For each \a md element from the incoming metadata, filter out the entry for - * "grpc-encoding", using its value to populate the call data's - * compression_algorithm field. */ -static grpc_mdelem *compression_md_filter(void *user_data, grpc_mdelem *md) { - grpc_call_element *elem = user_data; - call_data *calld = elem->call_data; - channel_data *channeld = elem->channel_data; - - if (md->key == GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST) { - const char *md_c_str = grpc_mdstr_as_c_string(md->value); - if (!grpc_compression_algorithm_parse(md_c_str, strlen(md_c_str), - &calld->compression_algorithm)) { - gpr_log(GPR_ERROR, - "Invalid compression algorithm: '%s' (unknown). Ignoring.", - md_c_str); - calld->compression_algorithm = GRPC_COMPRESS_NONE; - } - if (grpc_compression_options_is_algorithm_enabled( - &channeld->compression_options, calld->compression_algorithm) == - 0) { - gpr_log(GPR_ERROR, - "Invalid compression algorithm: '%s' (previously disabled). " - "Ignoring.", - md_c_str); - calld->compression_algorithm = GRPC_COMPRESS_NONE; - } - calld->has_compression_algorithm = 1; - return NULL; - } - - return md; -} - -static int skip_compression(grpc_call_element *elem) { - call_data *calld = elem->call_data; - channel_data *channeld = elem->channel_data; - if (calld->has_compression_algorithm) { - if (calld->compression_algorithm == GRPC_COMPRESS_NONE) { - return 1; - } - return 0; /* we have an actual call-specific algorithm */ - } - /* no per-call compression override */ - return channeld->default_compression_algorithm == GRPC_COMPRESS_NONE; -} - -/** Filter initial metadata */ -static void process_send_initial_metadata( - grpc_call_element *elem, grpc_metadata_batch *initial_metadata) { - call_data *calld = elem->call_data; - channel_data *channeld = elem->channel_data; - /* Parse incoming request for compression. If any, it'll be available - * at calld->compression_algorithm */ - grpc_metadata_batch_filter(initial_metadata, compression_md_filter, elem); - if (!calld->has_compression_algorithm) { - /* If no algorithm was found in the metadata and we aren't - * exceptionally skipping compression, fall back to the channel - * default */ - calld->compression_algorithm = channeld->default_compression_algorithm; - calld->has_compression_algorithm = 1; /* GPR_TRUE */ - } - /* hint compression algorithm */ - grpc_metadata_batch_add_tail( - initial_metadata, &calld->compression_algorithm_storage, - grpc_compression_encoding_mdelem(calld->compression_algorithm)); - - /* convey supported compression algorithms */ - grpc_metadata_batch_add_tail(initial_metadata, - &calld->accept_encoding_storage, - GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS( - channeld->supported_compression_algorithms)); -} - -static void continue_send_message(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem); - -static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, bool success) { - grpc_call_element *elem = elemp; - call_data *calld = elem->call_data; - gpr_slice_buffer_reset_and_unref(&calld->slices); - calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, success); -} - -static void finish_send_message(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - call_data *calld = elem->call_data; - int did_compress; - gpr_slice_buffer tmp; - gpr_slice_buffer_init(&tmp); - did_compress = - grpc_msg_compress(calld->compression_algorithm, &calld->slices, &tmp); - if (did_compress) { - gpr_slice_buffer_swap(&calld->slices, &tmp); - calld->send_flags |= GRPC_WRITE_INTERNAL_COMPRESS; - } - gpr_slice_buffer_destroy(&tmp); - - grpc_slice_buffer_stream_init(&calld->replacement_stream, &calld->slices, - calld->send_flags); - calld->send_op.send_message = &calld->replacement_stream.base; - calld->post_send = calld->send_op.on_complete; - calld->send_op.on_complete = &calld->send_done; - - grpc_call_next_op(exec_ctx, elem, &calld->send_op); -} - -static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, bool success) { - grpc_call_element *elem = elemp; - call_data *calld = elem->call_data; - gpr_slice_buffer_add(&calld->slices, calld->incoming_slice); - if (calld->send_length == calld->slices.length) { - finish_send_message(exec_ctx, elem); - } else { - continue_send_message(exec_ctx, elem); - } -} - -static void continue_send_message(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - call_data *calld = elem->call_data; - while (grpc_byte_stream_next(exec_ctx, calld->send_op.send_message, - &calld->incoming_slice, ~(size_t)0, - &calld->got_slice)) { - gpr_slice_buffer_add(&calld->slices, calld->incoming_slice); - if (calld->send_length == calld->slices.length) { - finish_send_message(exec_ctx, elem); - break; - } - } -} - -static void compress_start_transport_stream_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - call_data *calld = elem->call_data; - - GPR_TIMER_BEGIN("compress_start_transport_stream_op", 0); - - if (op->send_initial_metadata) { - process_send_initial_metadata(elem, op->send_initial_metadata); - } - if (op->send_message != NULL && !skip_compression(elem) && - 0 == (op->send_message->flags & GRPC_WRITE_NO_COMPRESS)) { - calld->send_op = *op; - calld->send_length = op->send_message->length; - calld->send_flags = op->send_message->flags; - continue_send_message(exec_ctx, elem); - } else { - /* pass control down the stack */ - grpc_call_next_op(exec_ctx, elem, op); - } - - GPR_TIMER_END("compress_start_transport_stream_op", 0); -} - -/* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { - /* grab pointers to our data from the call element */ - call_data *calld = elem->call_data; - - /* initialize members */ - gpr_slice_buffer_init(&calld->slices); - calld->has_compression_algorithm = 0; - grpc_closure_init(&calld->got_slice, got_slice, elem); - grpc_closure_init(&calld->send_done, send_done, elem); -} - -/* Destructor for call_data */ -static void destroy_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - /* grab pointers to our data from the call element */ - call_data *calld = elem->call_data; - gpr_slice_buffer_destroy(&calld->slices); -} - -/* Constructor for channel_data */ -static void init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - channel_data *channeld = elem->channel_data; - grpc_compression_algorithm algo_idx; - - grpc_compression_options_init(&channeld->compression_options); - channeld->compression_options.enabled_algorithms_bitset = - (uint32_t)grpc_channel_args_compression_algorithm_get_states( - args->channel_args); - - channeld->default_compression_algorithm = - grpc_channel_args_get_compression_algorithm(args->channel_args); - /* Make sure the default isn't disabled. */ - GPR_ASSERT(grpc_compression_options_is_algorithm_enabled( - &channeld->compression_options, channeld->default_compression_algorithm)); - channeld->compression_options.default_compression_algorithm = - channeld->default_compression_algorithm; - - channeld->supported_compression_algorithms = 0; - for (algo_idx = 0; algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) { - /* skip disabled algorithms */ - if (grpc_compression_options_is_algorithm_enabled( - &channeld->compression_options, algo_idx) == 0) { - continue; - } - channeld->supported_compression_algorithms |= 1u << algo_idx; - } - - GPR_ASSERT(!args->is_last); -} - -/* Destructor for channel data */ -static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) {} - -const grpc_channel_filter grpc_compress_filter = { - compress_start_transport_stream_op, - grpc_channel_next_op, - sizeof(call_data), - init_call_elem, - grpc_call_stack_ignore_set_pollset, - destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - grpc_call_next_get_peer, - "compress"}; diff --git a/src/core/channel/compress_filter.h b/src/core/channel/compress_filter.h deleted file mode 100644 index 8c208ac799..0000000000 --- a/src/core/channel/compress_filter.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * Copyright 2015-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_CHANNEL_COMPRESS_FILTER_H -#define GRPC_CORE_CHANNEL_COMPRESS_FILTER_H - -#include "src/core/channel/channel_stack.h" - -#define GRPC_COMPRESS_REQUEST_ALGORITHM_KEY "grpc-internal-encoding-request" - -/** Compression filter for outgoing data. - * - * See for the available compression settings. - * - * Compression settings may come from: - * - Channel configuration, as established at channel creation time. - * - The metadata accompanying the outgoing data to be compressed. This is - * taken as a request only. We may choose not to honor it. The metadata key - * is given by \a GRPC_COMPRESS_REQUEST_ALGORITHM_KEY. - * - * Compression can be disabled for concrete messages (for instance in order to - * prevent CRIME/BEAST type attacks) by having the GRPC_WRITE_NO_COMPRESS set in - * the BEGIN_MESSAGE flags. - * - * The attempted compression mechanism is added to the resulting initial - * metadata under the'grpc-encoding' key. - * - * If compression is actually performed, BEGIN_MESSAGE's flag is modified to - * incorporate GRPC_WRITE_INTERNAL_COMPRESS. Otherwise, and regardless of the - * aforementioned 'grpc-encoding' metadata value, data will pass through - * uncompressed. */ - -extern const grpc_channel_filter grpc_compress_filter; - -#endif /* GRPC_CORE_CHANNEL_COMPRESS_FILTER_H */ diff --git a/src/core/channel/connected_channel.c b/src/core/channel/connected_channel.c deleted file mode 100644 index df11d54297..0000000000 --- a/src/core/channel/connected_channel.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * - * Copyright 2015-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/channel/connected_channel.h" - -#include -#include -#include - -#include -#include -#include -#include -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/transport/transport.h" - -#define MAX_BUFFER_LENGTH 8192 - -typedef struct connected_channel_channel_data { - grpc_transport *transport; -} channel_data; - -typedef struct connected_channel_call_data { void *unused; } call_data; - -/* We perform a small hack to locate transport data alongside the connected - channel data in call allocations, to allow everything to be pulled in minimal - cache line requests */ -#define TRANSPORT_STREAM_FROM_CALL_DATA(calld) ((grpc_stream *)((calld) + 1)) -#define CALL_DATA_FROM_TRANSPORT_STREAM(transport_stream) \ - (((call_data *)(transport_stream)) - 1) - -/* Intercept a call operation and either push it directly up or translate it - into transport stream operations */ -static void con_start_transport_stream_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - GRPC_CALL_LOG_OP(GPR_INFO, elem, op); - - grpc_transport_perform_stream_op(exec_ctx, chand->transport, - TRANSPORT_STREAM_FROM_CALL_DATA(calld), op); -} - -static void con_start_transport_op(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_transport_op *op) { - channel_data *chand = elem->channel_data; - grpc_transport_perform_op(exec_ctx, chand->transport, op); -} - -/* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - int r; - - r = grpc_transport_init_stream( - exec_ctx, chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld), - &args->call_stack->refcount, args->server_transport_data); - GPR_ASSERT(r == 0); -} - -static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_pollset *pollset) { - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - grpc_transport_set_pollset(exec_ctx, chand->transport, - TRANSPORT_STREAM_FROM_CALL_DATA(calld), pollset); -} - -/* Destructor for call_data */ -static void destroy_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - grpc_transport_destroy_stream(exec_ctx, chand->transport, - TRANSPORT_STREAM_FROM_CALL_DATA(calld)); -} - -/* Constructor for channel_data */ -static void init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - channel_data *cd = (channel_data *)elem->channel_data; - GPR_ASSERT(args->is_last); - cd->transport = NULL; -} - -/* Destructor for channel_data */ -static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) { - channel_data *cd = (channel_data *)elem->channel_data; - grpc_transport_destroy(exec_ctx, cd->transport); -} - -static char *con_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { - channel_data *chand = elem->channel_data; - return grpc_transport_get_peer(exec_ctx, chand->transport); -} - -static const grpc_channel_filter connected_channel_filter = { - con_start_transport_stream_op, - con_start_transport_op, - sizeof(call_data), - init_call_elem, - set_pollset, - destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - con_get_peer, - "connected", -}; - -static void bind_transport(grpc_channel_stack *channel_stack, - grpc_channel_element *elem, void *t) { - channel_data *cd = (channel_data *)elem->channel_data; - GPR_ASSERT(elem->filter == &connected_channel_filter); - GPR_ASSERT(cd->transport == NULL); - cd->transport = t; - - /* HACK(ctiller): increase call stack size for the channel to make space - for channel data. We need a cleaner (but performant) way to do this, - and I'm not sure what that is yet. - This is only "safe" because call stacks place no additional data after - the last call element, and the last call element MUST be the connected - channel. */ - channel_stack->call_stack_size += grpc_transport_stream_size(t); -} - -bool grpc_add_connected_filter(grpc_channel_stack_builder *builder, - void *arg_must_be_null) { - GPR_ASSERT(arg_must_be_null == NULL); - grpc_transport *t = grpc_channel_stack_builder_get_transport(builder); - GPR_ASSERT(t != NULL); - return grpc_channel_stack_builder_append_filter( - builder, &connected_channel_filter, bind_transport, t); -} - -grpc_stream *grpc_connected_channel_get_stream(grpc_call_element *elem) { - call_data *calld = elem->call_data; - return TRANSPORT_STREAM_FROM_CALL_DATA(calld); -} diff --git a/src/core/channel/connected_channel.h b/src/core/channel/connected_channel.h deleted file mode 100644 index 7c0c8359a4..0000000000 --- a/src/core/channel/connected_channel.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright 2015-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_CHANNEL_CONNECTED_CHANNEL_H -#define GRPC_CORE_CHANNEL_CONNECTED_CHANNEL_H - -#include "src/core/channel/channel_stack_builder.h" - -bool grpc_add_connected_filter(grpc_channel_stack_builder *builder, - void *arg_must_be_null); - -#endif /* GRPC_CORE_CHANNEL_CONNECTED_CHANNEL_H */ diff --git a/src/core/channel/context.h b/src/core/channel/context.h deleted file mode 100644 index db217dc133..0000000000 --- a/src/core/channel/context.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright 2015-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_CHANNEL_CONTEXT_H -#define GRPC_CORE_CHANNEL_CONTEXT_H - -/* Call object context pointers */ -typedef enum { - GRPC_CONTEXT_SECURITY = 0, - GRPC_CONTEXT_TRACING, - GRPC_CONTEXT_COUNT -} grpc_context_index; - -typedef struct { - void *value; - void (*destroy)(void *); -} grpc_call_context_element; - -#endif /* GRPC_CORE_CHANNEL_CONTEXT_H */ diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c deleted file mode 100644 index 582427daf9..0000000000 --- a/src/core/channel/http_client_filter.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright 2015-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/channel/http_client_filter.h" -#include -#include -#include -#include -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/transport/static_metadata.h" - -typedef struct call_data { - grpc_linked_mdelem method; - grpc_linked_mdelem scheme; - grpc_linked_mdelem authority; - grpc_linked_mdelem te_trailers; - grpc_linked_mdelem content_type; - grpc_linked_mdelem user_agent; - - grpc_metadata_batch *recv_initial_metadata; - - /** Closure to call when finished with the hc_on_recv hook */ - grpc_closure *on_done_recv; - /** Receive closures are chained: we inject this closure as the on_done_recv - up-call on transport_op, and remember to call our on_done_recv member - after handling it. */ - grpc_closure hc_on_recv; -} call_data; - -typedef struct channel_data { - grpc_mdelem *static_scheme; - grpc_mdelem *user_agent; -} channel_data; - -typedef struct { - grpc_call_element *elem; - grpc_exec_ctx *exec_ctx; -} client_recv_filter_args; - -static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) { - client_recv_filter_args *a = user_data; - if (md == GRPC_MDELEM_STATUS_200) { - return NULL; - } else if (md->key == GRPC_MDSTR_STATUS) { - grpc_call_element_send_cancel(a->exec_ctx, a->elem); - return NULL; - } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) { - return NULL; - } - return md; -} - -static void hc_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, bool success) { - grpc_call_element *elem = user_data; - call_data *calld = elem->call_data; - client_recv_filter_args a; - a.elem = elem; - a.exec_ctx = exec_ctx; - grpc_metadata_batch_filter(calld->recv_initial_metadata, client_recv_filter, - &a); - calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, success); -} - -static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) { - /* eat the things we'd like to set ourselves */ - if (md->key == GRPC_MDSTR_METHOD) return NULL; - if (md->key == GRPC_MDSTR_SCHEME) return NULL; - if (md->key == GRPC_MDSTR_TE) return NULL; - if (md->key == GRPC_MDSTR_CONTENT_TYPE) return NULL; - if (md->key == GRPC_MDSTR_USER_AGENT) return NULL; - return md; -} - -static void hc_mutate_op(grpc_call_element *elem, - grpc_transport_stream_op *op) { - /* grab pointers to our data from the call element */ - call_data *calld = elem->call_data; - channel_data *channeld = elem->channel_data; - if (op->send_initial_metadata != NULL) { - grpc_metadata_batch_filter(op->send_initial_metadata, client_strip_filter, - elem); - /* Send : prefixed headers, which have to be before any application - layer headers. */ - grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method, - GRPC_MDELEM_METHOD_POST); - grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme, - channeld->static_scheme); - grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->te_trailers, - GRPC_MDELEM_TE_TRAILERS); - grpc_metadata_batch_add_tail( - op->send_initial_metadata, &calld->content_type, - GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC); - grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->user_agent, - GRPC_MDELEM_REF(channeld->user_agent)); - } - - if (op->recv_initial_metadata != NULL) { - /* substitute our callback for the higher callback */ - calld->recv_initial_metadata = op->recv_initial_metadata; - calld->on_done_recv = op->recv_initial_metadata_ready; - op->recv_initial_metadata_ready = &calld->hc_on_recv; - } -} - -static void hc_start_transport_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - GPR_TIMER_BEGIN("hc_start_transport_op", 0); - GRPC_CALL_LOG_OP(GPR_INFO, elem, op); - hc_mutate_op(elem, op); - GPR_TIMER_END("hc_start_transport_op", 0); - grpc_call_next_op(exec_ctx, elem, op); -} - -/* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { - call_data *calld = elem->call_data; - calld->on_done_recv = NULL; - grpc_closure_init(&calld->hc_on_recv, hc_on_recv, elem); -} - -/* Destructor for call_data */ -static void destroy_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) {} - -static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) { - unsigned i; - size_t j; - grpc_mdelem *valid_schemes[] = {GRPC_MDELEM_SCHEME_HTTP, - GRPC_MDELEM_SCHEME_HTTPS}; - if (args != NULL) { - for (i = 0; i < args->num_args; ++i) { - if (args->args[i].type == GRPC_ARG_STRING && - strcmp(args->args[i].key, GRPC_ARG_HTTP2_SCHEME) == 0) { - for (j = 0; j < GPR_ARRAY_SIZE(valid_schemes); j++) { - if (0 == strcmp(grpc_mdstr_as_c_string(valid_schemes[j]->value), - args->args[i].value.string)) { - return valid_schemes[j]; - } - } - } - } - } - return GRPC_MDELEM_SCHEME_HTTP; -} - -static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args) { - gpr_strvec v; - size_t i; - int is_first = 1; - char *tmp; - grpc_mdstr *result; - - gpr_strvec_init(&v); - - for (i = 0; args && i < args->num_args; i++) { - if (0 == strcmp(args->args[i].key, GRPC_ARG_PRIMARY_USER_AGENT_STRING)) { - if (args->args[i].type != GRPC_ARG_STRING) { - gpr_log(GPR_ERROR, "Channel argument '%s' should be a string", - GRPC_ARG_PRIMARY_USER_AGENT_STRING); - } else { - if (!is_first) gpr_strvec_add(&v, gpr_strdup(" ")); - is_first = 0; - gpr_strvec_add(&v, gpr_strdup(args->args[i].value.string)); - } - } - } - - gpr_asprintf(&tmp, "%sgrpc-c/%s (%s)", is_first ? "" : " ", - grpc_version_string(), GPR_PLATFORM_STRING); - is_first = 0; - gpr_strvec_add(&v, tmp); - - for (i = 0; args && i < args->num_args; i++) { - if (0 == strcmp(args->args[i].key, GRPC_ARG_SECONDARY_USER_AGENT_STRING)) { - if (args->args[i].type != GRPC_ARG_STRING) { - gpr_log(GPR_ERROR, "Channel argument '%s' should be a string", - GRPC_ARG_SECONDARY_USER_AGENT_STRING); - } else { - if (!is_first) gpr_strvec_add(&v, gpr_strdup(" ")); - is_first = 0; - gpr_strvec_add(&v, gpr_strdup(args->args[i].value.string)); - } - } - } - - tmp = gpr_strvec_flatten(&v, NULL); - gpr_strvec_destroy(&v); - result = grpc_mdstr_from_string(tmp); - gpr_free(tmp); - - return result; -} - -/* Constructor for channel_data */ -static void init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - channel_data *chand = elem->channel_data; - GPR_ASSERT(!args->is_last); - chand->static_scheme = scheme_from_args(args->channel_args); - chand->user_agent = grpc_mdelem_from_metadata_strings( - GRPC_MDSTR_USER_AGENT, user_agent_from_args(args->channel_args)); -} - -/* Destructor for channel data */ -static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) { - channel_data *chand = elem->channel_data; - GRPC_MDELEM_UNREF(chand->user_agent); -} - -const grpc_channel_filter grpc_http_client_filter = { - hc_start_transport_op, - grpc_channel_next_op, - sizeof(call_data), - init_call_elem, - grpc_call_stack_ignore_set_pollset, - destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - grpc_call_next_get_peer, - "http-client"}; diff --git a/src/core/channel/http_client_filter.h b/src/core/channel/http_client_filter.h deleted file mode 100644 index 6f619bbf00..0000000000 --- a/src/core/channel/http_client_filter.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * Copyright 2015-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_CHANNEL_HTTP_CLIENT_FILTER_H -#define GRPC_CORE_CHANNEL_HTTP_CLIENT_FILTER_H - -#include "src/core/channel/channel_stack.h" - -/* Processes metadata on the client side for HTTP2 transports */ -extern const grpc_channel_filter grpc_http_client_filter; - -#define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme" - -#endif /* GRPC_CORE_CHANNEL_HTTP_CLIENT_FILTER_H */ diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c deleted file mode 100644 index 1a2e0c5db3..0000000000 --- a/src/core/channel/http_server_filter.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * - * Copyright 2015-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/channel/http_server_filter.h" - -#include -#include -#include -#include "src/core/profiling/timers.h" -#include "src/core/transport/static_metadata.h" - -typedef struct call_data { - uint8_t seen_path; - uint8_t seen_post; - uint8_t sent_status; - uint8_t seen_scheme; - uint8_t seen_te_trailers; - uint8_t seen_authority; - grpc_linked_mdelem status; - grpc_linked_mdelem content_type; - - grpc_metadata_batch *recv_initial_metadata; - /** Closure to call when finished with the hs_on_recv hook */ - grpc_closure *on_done_recv; - /** Receive closures are chained: we inject this closure as the on_done_recv - up-call on transport_op, and remember to call our on_done_recv member - after handling it. */ - grpc_closure hs_on_recv; -} call_data; - -typedef struct channel_data { uint8_t unused; } channel_data; - -typedef struct { - grpc_call_element *elem; - grpc_exec_ctx *exec_ctx; -} server_filter_args; - -static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) { - server_filter_args *a = user_data; - grpc_call_element *elem = a->elem; - call_data *calld = elem->call_data; - - /* Check if it is one of the headers we care about. */ - if (md == GRPC_MDELEM_TE_TRAILERS || md == GRPC_MDELEM_METHOD_POST || - md == GRPC_MDELEM_SCHEME_HTTP || md == GRPC_MDELEM_SCHEME_HTTPS || - md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) { - /* swallow it */ - if (md == GRPC_MDELEM_METHOD_POST) { - calld->seen_post = 1; - } else if (md->key == GRPC_MDSTR_SCHEME) { - calld->seen_scheme = 1; - } else if (md == GRPC_MDELEM_TE_TRAILERS) { - calld->seen_te_trailers = 1; - } - /* TODO(klempner): Track that we've seen all the headers we should - require */ - return NULL; - } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) { - if (strncmp(grpc_mdstr_as_c_string(md->value), "application/grpc+", 17) == - 0) { - /* Although the C implementation doesn't (currently) generate them, - any custom +-suffix is explicitly valid. */ - /* TODO(klempner): We should consider preallocating common values such - as +proto or +json, or at least stashing them if we see them. */ - /* TODO(klempner): Should we be surfacing this to application code? */ - } else { - /* TODO(klempner): We're currently allowing this, but we shouldn't - see it without a proxy so log for now. */ - gpr_log(GPR_INFO, "Unexpected content-type %s", - grpc_mdstr_as_c_string(md->value)); - } - return NULL; - } else if (md->key == GRPC_MDSTR_TE || md->key == GRPC_MDSTR_METHOD || - md->key == GRPC_MDSTR_SCHEME) { - gpr_log(GPR_ERROR, "Invalid %s: header: '%s'", - grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value)); - /* swallow it and error everything out. */ - /* TODO(klempner): We ought to generate more descriptive error messages - on the wire here. */ - grpc_call_element_send_cancel(a->exec_ctx, elem); - return NULL; - } else if (md->key == GRPC_MDSTR_PATH) { - if (calld->seen_path) { - gpr_log(GPR_ERROR, "Received :path twice"); - return NULL; - } - calld->seen_path = 1; - return md; - } else if (md->key == GRPC_MDSTR_AUTHORITY) { - calld->seen_authority = 1; - return md; - } else if (md->key == GRPC_MDSTR_HOST) { - /* translate host to :authority since :authority may be - omitted */ - grpc_mdelem *authority = grpc_mdelem_from_metadata_strings( - GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value)); - calld->seen_authority = 1; - return authority; - } else { - return md; - } -} - -static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, bool success) { - grpc_call_element *elem = user_data; - call_data *calld = elem->call_data; - if (success) { - server_filter_args a; - a.elem = elem; - a.exec_ctx = exec_ctx; - grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, &a); - /* Have we seen the required http2 transport headers? - (:method, :scheme, content-type, with :path and :authority covered - at the channel level right now) */ - if (calld->seen_post && calld->seen_scheme && calld->seen_te_trailers && - calld->seen_path && calld->seen_authority) { - /* do nothing */ - } else { - if (!calld->seen_path) { - gpr_log(GPR_ERROR, "Missing :path header"); - } - if (!calld->seen_authority) { - gpr_log(GPR_ERROR, "Missing :authority header"); - } - if (!calld->seen_post) { - gpr_log(GPR_ERROR, "Missing :method header"); - } - if (!calld->seen_scheme) { - gpr_log(GPR_ERROR, "Missing :scheme header"); - } - if (!calld->seen_te_trailers) { - gpr_log(GPR_ERROR, "Missing te trailers header"); - } - /* Error this call out */ - success = 0; - grpc_call_element_send_cancel(exec_ctx, elem); - } - } - calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, success); -} - -static void hs_mutate_op(grpc_call_element *elem, - grpc_transport_stream_op *op) { - /* grab pointers to our data from the call element */ - call_data *calld = elem->call_data; - - if (op->send_initial_metadata != NULL && !calld->sent_status) { - calld->sent_status = 1; - grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->status, - GRPC_MDELEM_STATUS_200); - grpc_metadata_batch_add_tail( - op->send_initial_metadata, &calld->content_type, - GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC); - } - - if (op->recv_initial_metadata) { - /* substitute our callback for the higher callback */ - calld->recv_initial_metadata = op->recv_initial_metadata; - calld->on_done_recv = op->recv_initial_metadata_ready; - op->recv_initial_metadata_ready = &calld->hs_on_recv; - } -} - -static void hs_start_transport_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - GRPC_CALL_LOG_OP(GPR_INFO, elem, op); - GPR_TIMER_BEGIN("hs_start_transport_op", 0); - hs_mutate_op(elem, op); - grpc_call_next_op(exec_ctx, elem, op); - GPR_TIMER_END("hs_start_transport_op", 0); -} - -/* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { - /* grab pointers to our data from the call element */ - call_data *calld = elem->call_data; - /* initialize members */ - memset(calld, 0, sizeof(*calld)); - grpc_closure_init(&calld->hs_on_recv, hs_on_recv, elem); -} - -/* Destructor for call_data */ -static void destroy_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) {} - -/* Constructor for channel_data */ -static void init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - GPR_ASSERT(!args->is_last); -} - -/* Destructor for channel data */ -static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) {} - -const grpc_channel_filter grpc_http_server_filter = { - hs_start_transport_op, - grpc_channel_next_op, - sizeof(call_data), - init_call_elem, - grpc_call_stack_ignore_set_pollset, - destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - grpc_call_next_get_peer, - "http-server"}; diff --git a/src/core/channel/http_server_filter.h b/src/core/channel/http_server_filter.h deleted file mode 100644 index 528c8648fd..0000000000 --- a/src/core/channel/http_server_filter.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright 2015-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_CHANNEL_HTTP_SERVER_FILTER_H -#define GRPC_CORE_CHANNEL_HTTP_SERVER_FILTER_H - -#include "src/core/channel/channel_stack.h" - -/* Processes metadata on the client side for HTTP2 transports */ -extern const grpc_channel_filter grpc_http_server_filter; - -#endif /* GRPC_CORE_CHANNEL_HTTP_SERVER_FILTER_H */ diff --git a/src/core/channel/subchannel_call_holder.c b/src/core/channel/subchannel_call_holder.c deleted file mode 100644 index 9c087dc2a1..0000000000 --- a/src/core/channel/subchannel_call_holder.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * - * Copyright 2015-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/channel/subchannel_call_holder.h" - -#include - -#include "src/core/profiling/timers.h" - -#define GET_CALL(holder) \ - ((grpc_subchannel_call *)(gpr_atm_acq_load(&(holder)->subchannel_call))) - -#define CANCELLED_CALL ((grpc_subchannel_call *)1) - -static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *holder, - bool success); -static void retry_ops(grpc_exec_ctx *exec_ctx, void *retry_ops_args, - bool success); - -static void add_waiting_locked(grpc_subchannel_call_holder *holder, - grpc_transport_stream_op *op); -static void fail_locked(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder); -static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder); - -void grpc_subchannel_call_holder_init( - grpc_subchannel_call_holder *holder, - grpc_subchannel_call_holder_pick_subchannel pick_subchannel, - void *pick_subchannel_arg, grpc_call_stack *owning_call) { - gpr_atm_rel_store(&holder->subchannel_call, 0); - holder->pick_subchannel = pick_subchannel; - holder->pick_subchannel_arg = pick_subchannel_arg; - gpr_mu_init(&holder->mu); - holder->connected_subchannel = NULL; - holder->waiting_ops = NULL; - holder->waiting_ops_count = 0; - holder->waiting_ops_capacity = 0; - holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; - holder->owning_call = owning_call; -} - -void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder) { - grpc_subchannel_call *call = GET_CALL(holder); - if (call != NULL && call != CANCELLED_CALL) { - GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "holder"); - } - GPR_ASSERT(holder->creation_phase == - GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING); - gpr_mu_destroy(&holder->mu); - GPR_ASSERT(holder->waiting_ops_count == 0); - gpr_free(holder->waiting_ops); -} - -void grpc_subchannel_call_holder_perform_op(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder, - grpc_transport_stream_op *op) { - /* try to (atomically) get the call */ - grpc_subchannel_call *call = GET_CALL(holder); - GPR_TIMER_BEGIN("grpc_subchannel_call_holder_perform_op", 0); - if (call == CANCELLED_CALL) { - grpc_transport_stream_op_finish_with_failure(exec_ctx, op); - GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); - return; - } - if (call != NULL) { - grpc_subchannel_call_process_op(exec_ctx, call, op); - GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); - return; - } - /* we failed; lock and figure out what to do */ - gpr_mu_lock(&holder->mu); -retry: - /* need to recheck that another thread hasn't set the call */ - call = GET_CALL(holder); - if (call == CANCELLED_CALL) { - gpr_mu_unlock(&holder->mu); - grpc_transport_stream_op_finish_with_failure(exec_ctx, op); - GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); - return; - } - if (call != NULL) { - gpr_mu_unlock(&holder->mu); - grpc_subchannel_call_process_op(exec_ctx, call, op); - GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); - return; - } - /* if this is a cancellation, then we can raise our cancelled flag */ - if (op->cancel_with_status != GRPC_STATUS_OK) { - if (!gpr_atm_rel_cas(&holder->subchannel_call, 0, 1)) { - goto retry; - } else { - switch (holder->creation_phase) { - case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING: - fail_locked(exec_ctx, holder); - break; - case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL: - holder->pick_subchannel(exec_ctx, holder->pick_subchannel_arg, NULL, - &holder->connected_subchannel, NULL); - break; - } - gpr_mu_unlock(&holder->mu); - grpc_transport_stream_op_finish_with_failure(exec_ctx, op); - GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); - return; - } - } - /* if we don't have a subchannel, try to get one */ - if (holder->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && - holder->connected_subchannel == NULL && - op->send_initial_metadata != NULL) { - holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL; - grpc_closure_init(&holder->next_step, subchannel_ready, holder); - GRPC_CALL_STACK_REF(holder->owning_call, "pick_subchannel"); - if (holder->pick_subchannel( - exec_ctx, holder->pick_subchannel_arg, op->send_initial_metadata, - &holder->connected_subchannel, &holder->next_step)) { - holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; - GRPC_CALL_STACK_UNREF(exec_ctx, holder->owning_call, "pick_subchannel"); - } - } - /* if we've got a subchannel, then let's ask it to create a call */ - if (holder->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && - holder->connected_subchannel != NULL) { - gpr_atm_rel_store( - &holder->subchannel_call, - (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call( - exec_ctx, holder->connected_subchannel, holder->pollset)); - retry_waiting_locked(exec_ctx, holder); - goto retry; - } - /* nothing to be done but wait */ - add_waiting_locked(holder, op); - gpr_mu_unlock(&holder->mu); - GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); -} - -static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - grpc_subchannel_call_holder *holder = arg; - gpr_mu_lock(&holder->mu); - GPR_ASSERT(holder->creation_phase == - GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL); - holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; - if (holder->connected_subchannel == NULL) { - fail_locked(exec_ctx, holder); - } else if (1 == gpr_atm_acq_load(&holder->subchannel_call)) { - /* already cancelled before subchannel became ready */ - fail_locked(exec_ctx, holder); - } else { - gpr_atm_rel_store( - &holder->subchannel_call, - (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call( - exec_ctx, holder->connected_subchannel, holder->pollset)); - retry_waiting_locked(exec_ctx, holder); - } - gpr_mu_unlock(&holder->mu); - GRPC_CALL_STACK_UNREF(exec_ctx, holder->owning_call, "pick_subchannel"); -} - -typedef struct { - grpc_transport_stream_op *ops; - size_t nops; - grpc_subchannel_call *call; -} retry_ops_args; - -static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder) { - retry_ops_args *a = gpr_malloc(sizeof(*a)); - a->ops = holder->waiting_ops; - a->nops = holder->waiting_ops_count; - a->call = GET_CALL(holder); - if (a->call == CANCELLED_CALL) { - gpr_free(a); - fail_locked(exec_ctx, holder); - return; - } - holder->waiting_ops = NULL; - holder->waiting_ops_count = 0; - holder->waiting_ops_capacity = 0; - GRPC_SUBCHANNEL_CALL_REF(a->call, "retry_ops"); - grpc_exec_ctx_enqueue(exec_ctx, grpc_closure_create(retry_ops, a), true, - NULL); -} - -static void retry_ops(grpc_exec_ctx *exec_ctx, void *args, bool success) { - retry_ops_args *a = args; - size_t i; - for (i = 0; i < a->nops; i++) { - grpc_subchannel_call_process_op(exec_ctx, a->call, &a->ops[i]); - } - GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, a->call, "retry_ops"); - gpr_free(a->ops); - gpr_free(a); -} - -static void add_waiting_locked(grpc_subchannel_call_holder *holder, - grpc_transport_stream_op *op) { - GPR_TIMER_BEGIN("add_waiting_locked", 0); - if (holder->waiting_ops_count == holder->waiting_ops_capacity) { - holder->waiting_ops_capacity = GPR_MAX(3, 2 * holder->waiting_ops_capacity); - holder->waiting_ops = - gpr_realloc(holder->waiting_ops, holder->waiting_ops_capacity * - sizeof(*holder->waiting_ops)); - } - holder->waiting_ops[holder->waiting_ops_count++] = *op; - GPR_TIMER_END("add_waiting_locked", 0); -} - -static void fail_locked(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder) { - size_t i; - for (i = 0; i < holder->waiting_ops_count; i++) { - grpc_transport_stream_op_finish_with_failure(exec_ctx, - &holder->waiting_ops[i]); - } - holder->waiting_ops_count = 0; -} - -char *grpc_subchannel_call_holder_get_peer( - grpc_exec_ctx *exec_ctx, grpc_subchannel_call_holder *holder) { - grpc_subchannel_call *subchannel_call = GET_CALL(holder); - - if (subchannel_call) { - return grpc_subchannel_call_get_peer(exec_ctx, subchannel_call); - } else { - return NULL; - } -} diff --git a/src/core/channel/subchannel_call_holder.h b/src/core/channel/subchannel_call_holder.h deleted file mode 100644 index 84b4657db4..0000000000 --- a/src/core/channel/subchannel_call_holder.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * - * Copyright 2015-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_CHANNEL_SUBCHANNEL_CALL_HOLDER_H -#define GRPC_CORE_CHANNEL_SUBCHANNEL_CALL_HOLDER_H - -#include "src/core/client_config/subchannel.h" - -/** Pick a subchannel for grpc_subchannel_call_holder; - Return 1 if subchannel is available immediately (in which case on_ready - should not be called), or 0 otherwise (in which case on_ready should be - called when the subchannel is available) */ -typedef int (*grpc_subchannel_call_holder_pick_subchannel)( - grpc_exec_ctx *exec_ctx, void *arg, grpc_metadata_batch *initial_metadata, - grpc_connected_subchannel **connected_subchannel, grpc_closure *on_ready); - -typedef enum { - GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING, - GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL -} grpc_subchannel_call_holder_creation_phase; - -/** Wrapper for holding a pointer to grpc_subchannel_call, and the - associated machinery to create such a pointer. - Handles queueing of stream ops until a call object is ready, waiting - for initial metadata before trying to create a call object, - and handling cancellation gracefully. - - The channel filter uses this as their call_data. */ -typedef struct grpc_subchannel_call_holder { - /** either 0 for no call, 1 for cancelled, or a pointer to a - grpc_subchannel_call */ - gpr_atm subchannel_call; - /** Helper function to choose the subchannel on which to create - the call object. Channel filter delegates to the load - balancing policy (once it's ready). */ - grpc_subchannel_call_holder_pick_subchannel pick_subchannel; - void *pick_subchannel_arg; - - gpr_mu mu; - - grpc_subchannel_call_holder_creation_phase creation_phase; - grpc_connected_subchannel *connected_subchannel; - grpc_pollset *pollset; - - grpc_transport_stream_op *waiting_ops; - size_t waiting_ops_count; - size_t waiting_ops_capacity; - - grpc_closure next_step; - - grpc_call_stack *owning_call; -} grpc_subchannel_call_holder; - -void grpc_subchannel_call_holder_init( - grpc_subchannel_call_holder *holder, - grpc_subchannel_call_holder_pick_subchannel pick_subchannel, - void *pick_subchannel_arg, grpc_call_stack *owning_call); -void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder); - -void grpc_subchannel_call_holder_perform_op(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder, - grpc_transport_stream_op *op); -char *grpc_subchannel_call_holder_get_peer(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder); - -#endif /* GRPC_CORE_CHANNEL_SUBCHANNEL_CALL_HOLDER_H */ diff --git a/src/core/client_config/README.md b/src/core/client_config/README.md deleted file mode 100644 index fff7a5af5b..0000000000 --- a/src/core/client_config/README.md +++ /dev/null @@ -1,66 +0,0 @@ -Client Configuration Support for GRPC -===================================== - -This library provides high level configuration machinery to construct client -channels and load balance between them. - -Each grpc_channel is created with a grpc_resolver. It is the resolver's duty -to resolve a name into configuration data for the channel. Such configuration -data might include: - -- a list of (ip, port) addresses to connect to -- a load balancing policy to decide which server to send a request to -- a set of filters to mutate outgoing requests (say, by adding metadata) - -The resolver provides this data as a stream of grpc_client_config objects to -the channel. We represent configuration as a stream so that it can be changed -by the resolver during execution, by reacting to external events (such as a -new configuration file being pushed to some store). - - -Load Balancing --------------- - -Load balancing configuration is provided by a grpc_lb_policy object, stored as -part of grpc_client_config. - -The primary job of the load balancing policies is to pick a target server given only the -initial metadata for a request. It does this by providing a grpc_subchannel -object to the owning channel. - - -Sub-Channels ------------- - -A sub-channel provides a connection to a server for a client channel. It has a -connectivity state like a regular channel, and so can be connected or -disconnected. This connectivity state can be used to inform load balancing -decisions (for example, by avoiding disconnected backends). - -Configured sub-channels are fully setup to participate in the grpc data plane. -Their behavior is specified by a set of grpc channel filters defined at their -construction. To customize this behavior, resolvers build -grpc_subchannel_factory objects, which use the decorator pattern to customize -construction arguments for concrete grpc_subchannel instances. - - -Naming for GRPC -=============== - -Names in GRPC are represented by a URI (as defined in -[RFC 3986](https://tools.ietf.org/html/rfc3986)). - -The following schemes are currently supported: - -dns:///host:port - dns schemes are currently supported so long as authority is - empty (authority based dns resolution is expected in a future - release) - -unix:path - the unix scheme is used to create and connect to unix domain - sockets - the authority must be empty, and the path - represents the absolute or relative path to the desired - socket - -ipv4:host:port - a pre-resolved ipv4 dotted decimal address/port combination - -ipv6:[host]:port - a pre-resolved ipv6 address/port combination diff --git a/src/core/client_config/client_config.c b/src/core/client_config/client_config.c deleted file mode 100644 index c500af25ee..0000000000 --- a/src/core/client_config/client_config.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * Copyright 2015-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/client_config/client_config.h" - -#include - -#include - -struct grpc_client_config { - gpr_refcount refs; - grpc_lb_policy *lb_policy; -}; - -grpc_client_config *grpc_client_config_create() { - grpc_client_config *c = gpr_malloc(sizeof(*c)); - memset(c, 0, sizeof(*c)); - gpr_ref_init(&c->refs, 1); - return c; -} - -void grpc_client_config_ref(grpc_client_config *c) { gpr_ref(&c->refs); } - -void grpc_client_config_unref(grpc_exec_ctx *exec_ctx, grpc_client_config *c) { - if (gpr_unref(&c->refs)) { - if (c->lb_policy != NULL) { - GRPC_LB_POLICY_UNREF(exec_ctx, c->lb_policy, "client_config"); - } - gpr_free(c); - } -} - -void grpc_client_config_set_lb_policy(grpc_client_config *c, - grpc_lb_policy *lb_policy) { - GPR_ASSERT(c->lb_policy == NULL); - if (lb_policy) { - GRPC_LB_POLICY_REF(lb_policy, "client_config"); - } - c->lb_policy = lb_policy; -} - -grpc_lb_policy *grpc_client_config_get_lb_policy(grpc_client_config *c) { - return c->lb_policy; -} diff --git a/src/core/client_config/client_config.h b/src/core/client_config/client_config.h deleted file mode 100644 index 9b37fdc211..0000000000 --- a/src/core/client_config/client_config.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_CLIENT_CONFIG_H -#define GRPC_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H - -#include "src/core/client_config/lb_policy.h" - -/** Total configuration for a client. Provided, and updated, by - grpc_resolver */ -typedef struct grpc_client_config grpc_client_config; - -grpc_client_config *grpc_client_config_create(); -void grpc_client_config_ref(grpc_client_config *client_config); -void grpc_client_config_unref(grpc_exec_ctx *exec_ctx, - grpc_client_config *client_config); - -void grpc_client_config_set_lb_policy(grpc_client_config *client_config, - grpc_lb_policy *lb_policy); -grpc_lb_policy *grpc_client_config_get_lb_policy( - grpc_client_config *client_config); - -#endif /* GRPC_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H */ diff --git a/src/core/client_config/connector.c b/src/core/client_config/connector.c deleted file mode 100644 index aa34aa7fab..0000000000 --- a/src/core/client_config/connector.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright 2015-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/client_config/connector.h" - -grpc_connector* grpc_connector_ref(grpc_connector* connector) { - connector->vtable->ref(connector); - return connector; -} - -void grpc_connector_unref(grpc_exec_ctx* exec_ctx, grpc_connector* connector) { - connector->vtable->unref(exec_ctx, connector); -} - -void grpc_connector_connect(grpc_exec_ctx* exec_ctx, grpc_connector* connector, - const grpc_connect_in_args* in_args, - grpc_connect_out_args* out_args, - grpc_closure* notify) { - connector->vtable->connect(exec_ctx, connector, in_args, out_args, notify); -} - -void grpc_connector_shutdown(grpc_exec_ctx* exec_ctx, - grpc_connector* connector) { - connector->vtable->shutdown(exec_ctx, connector); -} diff --git a/src/core/client_config/connector.h b/src/core/client_config/connector.h deleted file mode 100644 index 93248fca4b..0000000000 --- a/src/core/client_config/connector.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_CONNECTOR_H -#define GRPC_CORE_CLIENT_CONFIG_CONNECTOR_H - -#include "src/core/channel/channel_stack.h" -#include "src/core/iomgr/sockaddr.h" -#include "src/core/transport/transport.h" - -typedef struct grpc_connector grpc_connector; -typedef struct grpc_connector_vtable grpc_connector_vtable; - -struct grpc_connector { - const grpc_connector_vtable *vtable; -}; - -typedef struct { - /** set of pollsets interested in this connection */ - grpc_pollset_set *interested_parties; - /** address to connect to */ - const struct sockaddr *addr; - size_t addr_len; - /** initial connect string to send */ - gpr_slice initial_connect_string; - /** deadline for connection */ - gpr_timespec deadline; - /** channel arguments (to be passed to transport) */ - const grpc_channel_args *channel_args; -} grpc_connect_in_args; - -typedef struct { - /** the connected transport */ - grpc_transport *transport; - - /** channel arguments (to be passed to the filters) */ - const grpc_channel_args *channel_args; -} grpc_connect_out_args; - -struct grpc_connector_vtable { - void (*ref)(grpc_connector *connector); - void (*unref)(grpc_exec_ctx *exec_ctx, grpc_connector *connector); - /** Implementation of grpc_connector_shutdown */ - void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_connector *connector); - /** Implementation of grpc_connector_connect */ - void (*connect)(grpc_exec_ctx *exec_ctx, grpc_connector *connector, - const grpc_connect_in_args *in_args, - grpc_connect_out_args *out_args, grpc_closure *notify); -}; - -grpc_connector *grpc_connector_ref(grpc_connector *connector); -void grpc_connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *connector); -/** Connect using the connector: max one outstanding call at a time */ -void grpc_connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *connector, - const grpc_connect_in_args *in_args, - grpc_connect_out_args *out_args, - grpc_closure *notify); -/** Cancel any pending connection */ -void grpc_connector_shutdown(grpc_exec_ctx *exec_ctx, - grpc_connector *connector); - -#endif /* GRPC_CORE_CLIENT_CONFIG_CONNECTOR_H */ diff --git a/src/core/client_config/default_initial_connect_string.c b/src/core/client_config/default_initial_connect_string.c deleted file mode 100644 index 6a4e23e6f2..0000000000 --- a/src/core/client_config/default_initial_connect_string.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * Copyright 2015, 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 -#include "src/core/iomgr/sockaddr.h" - -void grpc_set_default_initial_connect_string(struct sockaddr **addr, - size_t *addr_len, - gpr_slice *initial_str) {} diff --git a/src/core/client_config/initial_connect_string.c b/src/core/client_config/initial_connect_string.c deleted file mode 100644 index 19afa1675a..0000000000 --- a/src/core/client_config/initial_connect_string.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Copyright 2015, 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/client_config/initial_connect_string.h" - -#include - -extern void grpc_set_default_initial_connect_string(struct sockaddr **addr, - size_t *addr_len, - gpr_slice *initial_str); - -static grpc_set_initial_connect_string_func g_set_initial_connect_string_func = - grpc_set_default_initial_connect_string; - -void grpc_test_set_initial_connect_string_function( - grpc_set_initial_connect_string_func func) { - g_set_initial_connect_string_func = func; -} - -void grpc_set_initial_connect_string(struct sockaddr **addr, size_t *addr_len, - gpr_slice *initial_str) { - g_set_initial_connect_string_func(addr, addr_len, initial_str); -} diff --git a/src/core/client_config/initial_connect_string.h b/src/core/client_config/initial_connect_string.h deleted file mode 100644 index e6d2d8f8fe..0000000000 --- a/src/core/client_config/initial_connect_string.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H -#define GRPC_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H - -#include -#include "src/core/iomgr/sockaddr.h" - -typedef void (*grpc_set_initial_connect_string_func)(struct sockaddr **addr, - size_t *addr_len, - gpr_slice *initial_str); -void grpc_test_set_initial_connect_string_function( - grpc_set_initial_connect_string_func func); - -/** Set a string to be sent once connected. Optionally reset addr. */ -void grpc_set_initial_connect_string(struct sockaddr **addr, size_t *addr_len, - gpr_slice *connect_string); - -#endif /* GRPC_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H */ diff --git a/src/core/client_config/lb_policies/load_balancer_api.c b/src/core/client_config/lb_policies/load_balancer_api.c deleted file mode 100644 index a6b5785fe4..0000000000 --- a/src/core/client_config/lb_policies/load_balancer_api.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * - * 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/client_config/lb_policies/load_balancer_api.h" -#include "third_party/nanopb/pb_decode.h" -#include "third_party/nanopb/pb_encode.h" - -#include - -typedef struct decode_serverlist_arg { - int first_pass; - int i; - size_t num_servers; - grpc_grpclb_server **servers; -} decode_serverlist_arg; - -/* invoked once for every Server in ServerList */ -static bool decode_serverlist(pb_istream_t *stream, const pb_field_t *field, - void **arg) { - decode_serverlist_arg *dec_arg = *arg; - if (dec_arg->first_pass != 0) { /* first pass */ - grpc_grpclb_server server; - if (!pb_decode(stream, grpc_lb_v0_Server_fields, &server)) { - return false; - } - dec_arg->num_servers++; - } else { /* second pass */ - grpc_grpclb_server *server = gpr_malloc(sizeof(grpc_grpclb_server)); - GPR_ASSERT(dec_arg->num_servers > 0); - if (dec_arg->i == 0) { /* first iteration of second pass */ - dec_arg->servers = - gpr_malloc(sizeof(grpc_grpclb_server *) * dec_arg->num_servers); - } - if (!pb_decode(stream, grpc_lb_v0_Server_fields, server)) { - return false; - } - dec_arg->servers[dec_arg->i++] = server; - } - - return true; -} - -grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name) { - grpc_grpclb_request *req = gpr_malloc(sizeof(grpc_grpclb_request)); - - req->has_client_stats = 0; /* TODO(dgq): add support for stats once defined */ - req->has_initial_request = 1; - req->initial_request.has_name = 1; - strncpy(req->initial_request.name, lb_service_name, - GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH); - return req; -} - -gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request) { - size_t encoded_length; - pb_ostream_t sizestream; - pb_ostream_t outputstream; - gpr_slice slice; - memset(&sizestream, 0, sizeof(pb_ostream_t)); - pb_encode(&sizestream, grpc_lb_v0_LoadBalanceRequest_fields, request); - encoded_length = sizestream.bytes_written; - - slice = gpr_slice_malloc(encoded_length); - outputstream = - pb_ostream_from_buffer(GPR_SLICE_START_PTR(slice), encoded_length); - GPR_ASSERT(pb_encode(&outputstream, grpc_lb_v0_LoadBalanceRequest_fields, - request) != 0); - return slice; -} - -void grpc_grpclb_request_destroy(grpc_grpclb_request *request) { - gpr_free(request); -} - -grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response) { - bool status; - pb_istream_t stream = - pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response), - GPR_SLICE_LENGTH(encoded_response)); - grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response)); - memset(res, 0, sizeof(*res)); - status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res); - GPR_ASSERT(status == true); - return res; -} - -grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist( - gpr_slice encoded_response) { - grpc_grpclb_serverlist *sl = gpr_malloc(sizeof(grpc_grpclb_serverlist)); - bool status; - decode_serverlist_arg arg; - pb_istream_t stream = - pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response), - GPR_SLICE_LENGTH(encoded_response)); - pb_istream_t stream_at_start = stream; - grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response)); - memset(res, 0, sizeof(*res)); - memset(&arg, 0, sizeof(decode_serverlist_arg)); - - res->server_list.servers.funcs.decode = decode_serverlist; - res->server_list.servers.arg = &arg; - arg.first_pass = 1; - status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res); - GPR_ASSERT(status == true); - GPR_ASSERT(arg.num_servers > 0); - - arg.first_pass = 0; - status = - pb_decode(&stream_at_start, grpc_lb_v0_LoadBalanceResponse_fields, res); - GPR_ASSERT(status == true); - GPR_ASSERT(arg.servers != NULL); - - sl->num_servers = arg.num_servers; - sl->servers = arg.servers; - if (res->server_list.has_expiration_interval) { - sl->expiration_interval = res->server_list.expiration_interval; - } - grpc_grpclb_response_destroy(res); - return sl; -} - -void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist) { - size_t i; - for (i = 0; i < serverlist->num_servers; i++) { - gpr_free(serverlist->servers[i]); - } - gpr_free(serverlist->servers); - gpr_free(serverlist); -} - -void grpc_grpclb_response_destroy(grpc_grpclb_response *response) { - gpr_free(response); -} diff --git a/src/core/client_config/lb_policies/load_balancer_api.h b/src/core/client_config/lb_policies/load_balancer_api.h deleted file mode 100644 index b7a4c9c8f5..0000000000 --- a/src/core/client_config/lb_policies/load_balancer_api.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * 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_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H -#define GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H - -#include - -#include "src/core/client_config/lb_policy_factory.h" -#include "src/core/proto/grpc/lb/v0/load_balancer.pb.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128 - -typedef grpc_lb_v0_LoadBalanceRequest grpc_grpclb_request; -typedef grpc_lb_v0_LoadBalanceResponse grpc_grpclb_response; -typedef grpc_lb_v0_Server grpc_grpclb_server; -typedef grpc_lb_v0_Duration grpc_grpclb_duration; -typedef struct grpc_grpclb_serverlist { - grpc_grpclb_server **servers; - size_t num_servers; - grpc_grpclb_duration expiration_interval; -} grpc_grpclb_serverlist; - -/** Create a request for a gRPC LB service under \a lb_service_name */ -grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name); - -/** Protocol Buffers v3-encode \a request */ -gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request); - -/** Destroy \a request */ -void grpc_grpclb_request_destroy(grpc_grpclb_request *request); - -/** Parse (ie, decode) the bytes in \a encoded_response as a \a - * grpc_grpclb_response */ -grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response); - -/** Destroy \a serverlist */ -void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist); - -/** Parse the list of servers from an encoded \a grpc_grpclb_response */ -grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist( - gpr_slice encoded_response); - -/** Destroy \a response */ -void grpc_grpclb_response_destroy(grpc_grpclb_response *response); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H */ diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c deleted file mode 100644 index 2833f112f4..0000000000 --- a/src/core/client_config/lb_policies/pick_first.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * - * Copyright 2015-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/client_config/lb_policies/pick_first.h" -#include "src/core/client_config/lb_policy_factory.h" - -#include - -#include -#include "src/core/transport/connectivity_state.h" - -typedef struct pending_pick { - struct pending_pick *next; - grpc_pollset *pollset; - grpc_connected_subchannel **target; - grpc_closure *on_complete; -} pending_pick; - -typedef struct { - /** base policy: must be first */ - grpc_lb_policy base; - /** all our subchannels */ - grpc_subchannel **subchannels; - size_t num_subchannels; - - grpc_closure connectivity_changed; - - /** the selected channel (a grpc_connected_subchannel) */ - gpr_atm selected; - - /** mutex protecting remaining members */ - gpr_mu mu; - /** have we started picking? */ - int started_picking; - /** are we shut down? */ - int shutdown; - /** which subchannel are we watching? */ - size_t checking_subchannel; - /** what is the connectivity of that channel? */ - grpc_connectivity_state checking_connectivity; - /** list of picks that are waiting on connectivity */ - pending_pick *pending_picks; - - /** our connectivity state tracker */ - grpc_connectivity_state_tracker state_tracker; -} pick_first_lb_policy; - -#define GET_SELECTED(p) \ - ((grpc_connected_subchannel *)gpr_atm_acq_load(&(p)->selected)) - -void pf_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { - pick_first_lb_policy *p = (pick_first_lb_policy *)pol; - grpc_connected_subchannel *selected = GET_SELECTED(p); - size_t i; - GPR_ASSERT(p->pending_picks == NULL); - for (i = 0; i < p->num_subchannels; i++) { - GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[i], "pick_first"); - } - if (selected != NULL) { - GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, selected, "picked_first"); - } - grpc_connectivity_state_destroy(exec_ctx, &p->state_tracker); - gpr_free(p->subchannels); - gpr_mu_destroy(&p->mu); - gpr_free(p); -} - -void pf_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { - pick_first_lb_policy *p = (pick_first_lb_policy *)pol; - pending_pick *pp; - grpc_connected_subchannel *selected; - gpr_mu_lock(&p->mu); - selected = GET_SELECTED(p); - p->shutdown = 1; - pp = p->pending_picks; - p->pending_picks = NULL; - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - GRPC_CHANNEL_FATAL_FAILURE, "shutdown"); - /* cancel subscription */ - if (selected != NULL) { - grpc_connected_subchannel_notify_on_state_change( - exec_ctx, selected, NULL, NULL, &p->connectivity_changed); - } else { - grpc_subchannel_notify_on_state_change( - exec_ctx, p->subchannels[p->checking_subchannel], NULL, NULL, - &p->connectivity_changed); - } - gpr_mu_unlock(&p->mu); - while (pp != NULL) { - pending_pick *next = pp->next; - *pp->target = NULL; - grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties, - pp->pollset); - grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL); - gpr_free(pp); - pp = next; - } -} - -static void pf_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, - grpc_connected_subchannel **target) { - pick_first_lb_policy *p = (pick_first_lb_policy *)pol; - pending_pick *pp; - gpr_mu_lock(&p->mu); - pp = p->pending_picks; - p->pending_picks = NULL; - while (pp != NULL) { - pending_pick *next = pp->next; - if (pp->target == target) { - grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties, - pp->pollset); - *target = NULL; - grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL); - gpr_free(pp); - } else { - pp->next = p->pending_picks; - p->pending_picks = pp; - } - pp = next; - } - gpr_mu_unlock(&p->mu); -} - -static void start_picking(grpc_exec_ctx *exec_ctx, pick_first_lb_policy *p) { - p->started_picking = 1; - p->checking_subchannel = 0; - p->checking_connectivity = GRPC_CHANNEL_IDLE; - GRPC_LB_POLICY_WEAK_REF(&p->base, "pick_first_connectivity"); - grpc_subchannel_notify_on_state_change( - exec_ctx, p->subchannels[p->checking_subchannel], - p->base.interested_parties, &p->checking_connectivity, - &p->connectivity_changed); -} - -void pf_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { - pick_first_lb_policy *p = (pick_first_lb_policy *)pol; - gpr_mu_lock(&p->mu); - if (!p->started_picking) { - start_picking(exec_ctx, p); - } - gpr_mu_unlock(&p->mu); -} - -int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, grpc_pollset *pollset, - grpc_metadata_batch *initial_metadata, - grpc_connected_subchannel **target, grpc_closure *on_complete) { - pick_first_lb_policy *p = (pick_first_lb_policy *)pol; - pending_pick *pp; - - /* Check atomically for a selected channel */ - grpc_connected_subchannel *selected = GET_SELECTED(p); - if (selected != NULL) { - *target = selected; - return 1; - } - - /* No subchannel selected yet, so acquire lock and then attempt again */ - gpr_mu_lock(&p->mu); - selected = GET_SELECTED(p); - if (selected) { - gpr_mu_unlock(&p->mu); - *target = selected; - return 1; - } else { - if (!p->started_picking) { - start_picking(exec_ctx, p); - } - grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset); - pp = gpr_malloc(sizeof(*pp)); - pp->next = p->pending_picks; - pp->pollset = pollset; - pp->target = target; - pp->on_complete = on_complete; - p->pending_picks = pp; - gpr_mu_unlock(&p->mu); - return 0; - } -} - -static void destroy_subchannels(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_success) { - pick_first_lb_policy *p = arg; - size_t i; - size_t num_subchannels = p->num_subchannels; - grpc_subchannel **subchannels; - - gpr_mu_lock(&p->mu); - subchannels = p->subchannels; - p->num_subchannels = 0; - p->subchannels = NULL; - gpr_mu_unlock(&p->mu); - GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "destroy_subchannels"); - - for (i = 0; i < num_subchannels; i++) { - GRPC_SUBCHANNEL_UNREF(exec_ctx, subchannels[i], "pick_first"); - } - - gpr_free(subchannels); -} - -static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_success) { - pick_first_lb_policy *p = arg; - grpc_subchannel *selected_subchannel; - pending_pick *pp; - grpc_connected_subchannel *selected; - - gpr_mu_lock(&p->mu); - - selected = GET_SELECTED(p); - - if (p->shutdown) { - gpr_mu_unlock(&p->mu); - GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "pick_first_connectivity"); - return; - } else if (selected != NULL) { - if (p->checking_connectivity == GRPC_CHANNEL_TRANSIENT_FAILURE) { - /* if the selected channel goes bad, we're done */ - p->checking_connectivity = GRPC_CHANNEL_FATAL_FAILURE; - } - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - p->checking_connectivity, "selected_changed"); - if (p->checking_connectivity != GRPC_CHANNEL_FATAL_FAILURE) { - grpc_connected_subchannel_notify_on_state_change( - exec_ctx, selected, p->base.interested_parties, - &p->checking_connectivity, &p->connectivity_changed); - } else { - GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "pick_first_connectivity"); - } - } else { - loop: - switch (p->checking_connectivity) { - case GRPC_CHANNEL_READY: - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - GRPC_CHANNEL_READY, "connecting_ready"); - selected_subchannel = p->subchannels[p->checking_subchannel]; - selected = - grpc_subchannel_get_connected_subchannel(selected_subchannel); - GPR_ASSERT(selected != NULL); - GRPC_CONNECTED_SUBCHANNEL_REF(selected, "picked_first"); - /* drop the pick list: we are connected now */ - GRPC_LB_POLICY_WEAK_REF(&p->base, "destroy_subchannels"); - gpr_atm_rel_store(&p->selected, (gpr_atm)selected); - grpc_exec_ctx_enqueue( - exec_ctx, grpc_closure_create(destroy_subchannels, p), true, NULL); - /* update any calls that were waiting for a pick */ - while ((pp = p->pending_picks)) { - p->pending_picks = pp->next; - *pp->target = selected; - grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties, - pp->pollset); - grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL); - gpr_free(pp); - } - grpc_connected_subchannel_notify_on_state_change( - exec_ctx, selected, p->base.interested_parties, - &p->checking_connectivity, &p->connectivity_changed); - break; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - GRPC_CHANNEL_TRANSIENT_FAILURE, - "connecting_transient_failure"); - p->checking_subchannel = - (p->checking_subchannel + 1) % p->num_subchannels; - p->checking_connectivity = grpc_subchannel_check_connectivity( - p->subchannels[p->checking_subchannel]); - if (p->checking_connectivity == GRPC_CHANNEL_TRANSIENT_FAILURE) { - grpc_subchannel_notify_on_state_change( - exec_ctx, p->subchannels[p->checking_subchannel], - p->base.interested_parties, &p->checking_connectivity, - &p->connectivity_changed); - } else { - goto loop; - } - break; - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_IDLE: - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - GRPC_CHANNEL_CONNECTING, - "connecting_changed"); - grpc_subchannel_notify_on_state_change( - exec_ctx, p->subchannels[p->checking_subchannel], - p->base.interested_parties, &p->checking_connectivity, - &p->connectivity_changed); - break; - case GRPC_CHANNEL_FATAL_FAILURE: - p->num_subchannels--; - GPR_SWAP(grpc_subchannel *, p->subchannels[p->checking_subchannel], - p->subchannels[p->num_subchannels]); - GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[p->num_subchannels], - "pick_first"); - if (p->num_subchannels == 0) { - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - GRPC_CHANNEL_FATAL_FAILURE, - "no_more_channels"); - while ((pp = p->pending_picks)) { - p->pending_picks = pp->next; - *pp->target = NULL; - grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL); - gpr_free(pp); - } - GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, - "pick_first_connectivity"); - } else { - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - GRPC_CHANNEL_TRANSIENT_FAILURE, - "subchannel_failed"); - p->checking_subchannel %= p->num_subchannels; - p->checking_connectivity = grpc_subchannel_check_connectivity( - p->subchannels[p->checking_subchannel]); - goto loop; - } - } - } - - gpr_mu_unlock(&p->mu); -} - -static grpc_connectivity_state pf_check_connectivity(grpc_exec_ctx *exec_ctx, - grpc_lb_policy *pol) { - pick_first_lb_policy *p = (pick_first_lb_policy *)pol; - grpc_connectivity_state st; - gpr_mu_lock(&p->mu); - st = grpc_connectivity_state_check(&p->state_tracker); - gpr_mu_unlock(&p->mu); - return st; -} - -void pf_notify_on_state_change(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, - grpc_connectivity_state *current, - grpc_closure *notify) { - pick_first_lb_policy *p = (pick_first_lb_policy *)pol; - gpr_mu_lock(&p->mu); - grpc_connectivity_state_notify_on_state_change(exec_ctx, &p->state_tracker, - current, notify); - gpr_mu_unlock(&p->mu); -} - -void pf_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, - grpc_closure *closure) { - pick_first_lb_policy *p = (pick_first_lb_policy *)pol; - grpc_connected_subchannel *selected = GET_SELECTED(p); - if (selected) { - grpc_connected_subchannel_ping(exec_ctx, selected, closure); - } else { - grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL); - } -} - -static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = { - pf_destroy, - pf_shutdown, - pf_pick, - pf_cancel_pick, - pf_ping_one, - pf_exit_idle, - pf_check_connectivity, - pf_notify_on_state_change}; - -static void pick_first_factory_ref(grpc_lb_policy_factory *factory) {} - -static void pick_first_factory_unref(grpc_lb_policy_factory *factory) {} - -static grpc_lb_policy *create_pick_first(grpc_lb_policy_factory *factory, - grpc_lb_policy_args *args) { - if (args->num_subchannels == 0) return NULL; - pick_first_lb_policy *p = gpr_malloc(sizeof(*p)); - memset(p, 0, sizeof(*p)); - grpc_lb_policy_init(&p->base, &pick_first_lb_policy_vtable); - p->subchannels = - gpr_malloc(sizeof(grpc_subchannel *) * args->num_subchannels); - p->num_subchannels = args->num_subchannels; - grpc_connectivity_state_init(&p->state_tracker, GRPC_CHANNEL_IDLE, - "pick_first"); - memcpy(p->subchannels, args->subchannels, - sizeof(grpc_subchannel *) * args->num_subchannels); - grpc_closure_init(&p->connectivity_changed, pf_connectivity_changed, p); - gpr_mu_init(&p->mu); - return &p->base; -} - -static const grpc_lb_policy_factory_vtable pick_first_factory_vtable = { - pick_first_factory_ref, pick_first_factory_unref, create_pick_first, - "pick_first"}; - -static grpc_lb_policy_factory pick_first_lb_policy_factory = { - &pick_first_factory_vtable}; - -grpc_lb_policy_factory *grpc_pick_first_lb_factory_create() { - return &pick_first_lb_policy_factory; -} diff --git a/src/core/client_config/lb_policies/pick_first.h b/src/core/client_config/lb_policies/pick_first.h deleted file mode 100644 index 3a3f195df5..0000000000 --- a/src/core/client_config/lb_policies/pick_first.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H -#define GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H - -#include "src/core/client_config/lb_policy_factory.h" - -/** Returns a load balancing factory for the pick first policy, which picks up - * the first subchannel from \a subchannels to succesfully connect */ -grpc_lb_policy_factory *grpc_pick_first_lb_factory_create(); - -#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H */ diff --git a/src/core/client_config/lb_policies/round_robin.c b/src/core/client_config/lb_policies/round_robin.c deleted file mode 100644 index 114ece6e4d..0000000000 --- a/src/core/client_config/lb_policies/round_robin.c +++ /dev/null @@ -1,542 +0,0 @@ -/* - * - * Copyright 2015-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/client_config/lb_policies/round_robin.h" - -#include - -#include -#include "src/core/transport/connectivity_state.h" - -typedef struct round_robin_lb_policy round_robin_lb_policy; - -int grpc_lb_round_robin_trace = 0; - -/** List of entities waiting for a pick. - * - * Once a pick is available, \a target is updated and \a on_complete called. */ -typedef struct pending_pick { - struct pending_pick *next; - grpc_pollset *pollset; - grpc_connected_subchannel **target; - grpc_closure *on_complete; -} pending_pick; - -/** List of subchannels in a connectivity READY state */ -typedef struct ready_list { - grpc_subchannel *subchannel; - struct ready_list *next; - struct ready_list *prev; -} ready_list; - -typedef struct { - /** index within policy->subchannels */ - size_t index; - /** backpointer to owning policy */ - round_robin_lb_policy *policy; - /** subchannel itself */ - grpc_subchannel *subchannel; - /** notification that connectivity has changed on subchannel */ - grpc_closure connectivity_changed_closure; - /** this subchannels current position in subchannel->ready_list */ - ready_list *ready_list_node; - /** last observed connectivity */ - grpc_connectivity_state connectivity_state; -} subchannel_data; - -struct round_robin_lb_policy { - /** base policy: must be first */ - grpc_lb_policy base; - - /** all our subchannels */ - size_t num_subchannels; - subchannel_data **subchannels; - - /** mutex protecting remaining members */ - gpr_mu mu; - /** have we started picking? */ - int started_picking; - /** are we shutting down? */ - int shutdown; - /** List of picks that are waiting on connectivity */ - pending_pick *pending_picks; - - /** our connectivity state tracker */ - grpc_connectivity_state_tracker state_tracker; - - /** (Dummy) root of the doubly linked list containing READY subchannels */ - ready_list ready_list; - /** Last pick from the ready list. */ - ready_list *ready_list_last_pick; -}; - -/** Returns the next subchannel from the connected list or NULL if the list is - * empty. - * - * Note that this function does *not* advance p->ready_list_last_pick. Use \a - * advance_last_picked_locked() for that. */ -static ready_list *peek_next_connected_locked(const round_robin_lb_policy *p) { - ready_list *selected; - selected = p->ready_list_last_pick->next; - - while (selected != NULL) { - if (selected == &p->ready_list) { - GPR_ASSERT(selected->subchannel == NULL); - /* skip dummy root */ - selected = selected->next; - } else { - GPR_ASSERT(selected->subchannel != NULL); - return selected; - } - } - return NULL; -} - -/** Advance the \a ready_list picking head. */ -static void advance_last_picked_locked(round_robin_lb_policy *p) { - if (p->ready_list_last_pick->next != NULL) { /* non-empty list */ - p->ready_list_last_pick = p->ready_list_last_pick->next; - if (p->ready_list_last_pick == &p->ready_list) { - /* skip dummy root */ - p->ready_list_last_pick = p->ready_list_last_pick->next; - } - } else { /* should be an empty list */ - GPR_ASSERT(p->ready_list_last_pick == &p->ready_list); - } - - if (grpc_lb_round_robin_trace) { - gpr_log(GPR_DEBUG, "[READYLIST] ADVANCED LAST PICK. NOW AT NODE %p (SC %p)", - p->ready_list_last_pick, p->ready_list_last_pick->subchannel); - } -} - -/** Prepends (relative to the root at p->ready_list) the connected subchannel \a - * csc to the list of ready subchannels. */ -static ready_list *add_connected_sc_locked(round_robin_lb_policy *p, - grpc_subchannel *sc) { - ready_list *new_elem = gpr_malloc(sizeof(ready_list)); - new_elem->subchannel = sc; - if (p->ready_list.prev == NULL) { - /* first element */ - new_elem->next = &p->ready_list; - new_elem->prev = &p->ready_list; - p->ready_list.next = new_elem; - p->ready_list.prev = new_elem; - } else { - new_elem->next = &p->ready_list; - new_elem->prev = p->ready_list.prev; - p->ready_list.prev->next = new_elem; - p->ready_list.prev = new_elem; - } - if (grpc_lb_round_robin_trace) { - gpr_log(GPR_DEBUG, "[READYLIST] ADDING NODE %p (SC %p)", new_elem, sc); - } - return new_elem; -} - -/** Removes \a node from the list of connected subchannels */ -static void remove_disconnected_sc_locked(round_robin_lb_policy *p, - ready_list *node) { - if (node == NULL) { - return; - } - if (node == p->ready_list_last_pick) { - /* If removing the lastly picked node, reset the last pick pointer to the - * dummy root of the list */ - p->ready_list_last_pick = &p->ready_list; - } - - /* removing last item */ - if (node->next == &p->ready_list && node->prev == &p->ready_list) { - GPR_ASSERT(p->ready_list.next == node); - GPR_ASSERT(p->ready_list.prev == node); - p->ready_list.next = NULL; - p->ready_list.prev = NULL; - } else { - node->prev->next = node->next; - node->next->prev = node->prev; - } - - if (grpc_lb_round_robin_trace) { - gpr_log(GPR_DEBUG, "[READYLIST] REMOVED NODE %p (SC %p)", node, - node->subchannel); - } - - node->next = NULL; - node->prev = NULL; - node->subchannel = NULL; - - gpr_free(node); -} - -void rr_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { - round_robin_lb_policy *p = (round_robin_lb_policy *)pol; - size_t i; - ready_list *elem; - for (i = 0; i < p->num_subchannels; i++) { - subchannel_data *sd = p->subchannels[i]; - GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "round_robin"); - gpr_free(sd); - } - - grpc_connectivity_state_destroy(exec_ctx, &p->state_tracker); - gpr_free(p->subchannels); - gpr_mu_destroy(&p->mu); - - elem = p->ready_list.next; - while (elem != NULL && elem != &p->ready_list) { - ready_list *tmp; - tmp = elem->next; - elem->next = NULL; - elem->prev = NULL; - elem->subchannel = NULL; - gpr_free(elem); - elem = tmp; - } - gpr_free(p); -} - -void rr_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { - round_robin_lb_policy *p = (round_robin_lb_policy *)pol; - pending_pick *pp; - size_t i; - - gpr_mu_lock(&p->mu); - - p->shutdown = 1; - while ((pp = p->pending_picks)) { - p->pending_picks = pp->next; - *pp->target = NULL; - grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL); - gpr_free(pp); - } - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - GRPC_CHANNEL_FATAL_FAILURE, "shutdown"); - for (i = 0; i < p->num_subchannels; i++) { - subchannel_data *sd = p->subchannels[i]; - grpc_subchannel_notify_on_state_change(exec_ctx, sd->subchannel, NULL, NULL, - &sd->connectivity_changed_closure); - } - gpr_mu_unlock(&p->mu); -} - -static void rr_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, - grpc_connected_subchannel **target) { - round_robin_lb_policy *p = (round_robin_lb_policy *)pol; - pending_pick *pp; - gpr_mu_lock(&p->mu); - pp = p->pending_picks; - p->pending_picks = NULL; - while (pp != NULL) { - pending_pick *next = pp->next; - if (pp->target == target) { - grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties, - pp->pollset); - *target = NULL; - grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL); - gpr_free(pp); - } else { - pp->next = p->pending_picks; - p->pending_picks = pp; - } - pp = next; - } - gpr_mu_unlock(&p->mu); -} - -static void start_picking(grpc_exec_ctx *exec_ctx, round_robin_lb_policy *p) { - size_t i; - p->started_picking = 1; - - gpr_log(GPR_DEBUG, "LB_POLICY: p=%p num_subchannels=%d", p, - p->num_subchannels); - - for (i = 0; i < p->num_subchannels; i++) { - subchannel_data *sd = p->subchannels[i]; - sd->connectivity_state = GRPC_CHANNEL_IDLE; - grpc_subchannel_notify_on_state_change( - exec_ctx, sd->subchannel, p->base.interested_parties, - &sd->connectivity_state, &sd->connectivity_changed_closure); - GRPC_LB_POLICY_WEAK_REF(&p->base, "round_robin_connectivity"); - } -} - -void rr_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { - round_robin_lb_policy *p = (round_robin_lb_policy *)pol; - gpr_mu_lock(&p->mu); - if (!p->started_picking) { - start_picking(exec_ctx, p); - } - gpr_mu_unlock(&p->mu); -} - -int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, grpc_pollset *pollset, - grpc_metadata_batch *initial_metadata, - grpc_connected_subchannel **target, grpc_closure *on_complete) { - round_robin_lb_policy *p = (round_robin_lb_policy *)pol; - pending_pick *pp; - ready_list *selected; - gpr_mu_lock(&p->mu); - if ((selected = peek_next_connected_locked(p))) { - gpr_mu_unlock(&p->mu); - *target = grpc_subchannel_get_connected_subchannel(selected->subchannel); - if (grpc_lb_round_robin_trace) { - gpr_log(GPR_DEBUG, - "[RR PICK] TARGET <-- CONNECTED SUBCHANNEL %p (NODE %p)", - selected->subchannel, selected); - } - /* only advance the last picked pointer if the selection was used */ - advance_last_picked_locked(p); - return 1; - } else { - if (!p->started_picking) { - start_picking(exec_ctx, p); - } - grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset); - pp = gpr_malloc(sizeof(*pp)); - pp->next = p->pending_picks; - pp->pollset = pollset; - pp->target = target; - pp->on_complete = on_complete; - p->pending_picks = pp; - gpr_mu_unlock(&p->mu); - return 0; - } -} - -static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_success) { - subchannel_data *sd = arg; - round_robin_lb_policy *p = sd->policy; - pending_pick *pp; - ready_list *selected; - - int unref = 0; - - gpr_mu_lock(&p->mu); - - if (p->shutdown) { - unref = 1; - } else { - switch (sd->connectivity_state) { - case GRPC_CHANNEL_READY: - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - GRPC_CHANNEL_READY, "connecting_ready"); - /* add the newly connected subchannel to the list of connected ones. - * Note that it goes to the "end of the line". */ - sd->ready_list_node = add_connected_sc_locked(p, sd->subchannel); - /* at this point we know there's at least one suitable subchannel. Go - * ahead and pick one and notify the pending suitors in - * p->pending_picks. This preemtively replicates rr_pick()'s actions. */ - selected = peek_next_connected_locked(p); - if (p->pending_picks != NULL) { - /* if the selected subchannel is going to be used for the pending - * picks, update the last picked pointer */ - advance_last_picked_locked(p); - } - while ((pp = p->pending_picks)) { - p->pending_picks = pp->next; - *pp->target = - grpc_subchannel_get_connected_subchannel(selected->subchannel); - if (grpc_lb_round_robin_trace) { - gpr_log(GPR_DEBUG, - "[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)", - selected->subchannel, selected); - } - grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties, - pp->pollset); - grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL); - gpr_free(pp); - } - grpc_subchannel_notify_on_state_change( - exec_ctx, sd->subchannel, p->base.interested_parties, - &sd->connectivity_state, &sd->connectivity_changed_closure); - break; - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_IDLE: - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - sd->connectivity_state, - "connecting_changed"); - grpc_subchannel_notify_on_state_change( - exec_ctx, sd->subchannel, p->base.interested_parties, - &sd->connectivity_state, &sd->connectivity_changed_closure); - break; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - /* renew state notification */ - grpc_subchannel_notify_on_state_change( - exec_ctx, sd->subchannel, p->base.interested_parties, - &sd->connectivity_state, &sd->connectivity_changed_closure); - - /* remove from ready list if still present */ - if (sd->ready_list_node != NULL) { - remove_disconnected_sc_locked(p, sd->ready_list_node); - sd->ready_list_node = NULL; - } - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - GRPC_CHANNEL_TRANSIENT_FAILURE, - "connecting_transient_failure"); - break; - case GRPC_CHANNEL_FATAL_FAILURE: - if (sd->ready_list_node != NULL) { - remove_disconnected_sc_locked(p, sd->ready_list_node); - sd->ready_list_node = NULL; - } - - p->num_subchannels--; - GPR_SWAP(subchannel_data *, p->subchannels[sd->index], - p->subchannels[p->num_subchannels]); - GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "round_robin"); - p->subchannels[sd->index]->index = sd->index; - gpr_free(sd); - - unref = 1; - if (p->num_subchannels == 0) { - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - GRPC_CHANNEL_FATAL_FAILURE, - "no_more_channels"); - while ((pp = p->pending_picks)) { - p->pending_picks = pp->next; - *pp->target = NULL; - grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL); - gpr_free(pp); - } - } else { - grpc_connectivity_state_set(exec_ctx, &p->state_tracker, - GRPC_CHANNEL_TRANSIENT_FAILURE, - "subchannel_failed"); - } - } /* switch */ - } /* !unref */ - - gpr_mu_unlock(&p->mu); - - if (unref) { - GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "round_robin_connectivity"); - } -} - -static grpc_connectivity_state rr_check_connectivity(grpc_exec_ctx *exec_ctx, - grpc_lb_policy *pol) { - round_robin_lb_policy *p = (round_robin_lb_policy *)pol; - grpc_connectivity_state st; - gpr_mu_lock(&p->mu); - st = grpc_connectivity_state_check(&p->state_tracker); - gpr_mu_unlock(&p->mu); - return st; -} - -static void rr_notify_on_state_change(grpc_exec_ctx *exec_ctx, - grpc_lb_policy *pol, - grpc_connectivity_state *current, - grpc_closure *notify) { - round_robin_lb_policy *p = (round_robin_lb_policy *)pol; - gpr_mu_lock(&p->mu); - grpc_connectivity_state_notify_on_state_change(exec_ctx, &p->state_tracker, - current, notify); - gpr_mu_unlock(&p->mu); -} - -static void rr_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, - grpc_closure *closure) { - round_robin_lb_policy *p = (round_robin_lb_policy *)pol; - ready_list *selected; - grpc_connected_subchannel *target; - gpr_mu_lock(&p->mu); - if ((selected = peek_next_connected_locked(p))) { - gpr_mu_unlock(&p->mu); - target = grpc_subchannel_get_connected_subchannel(selected->subchannel); - grpc_connected_subchannel_ping(exec_ctx, target, closure); - } else { - gpr_mu_unlock(&p->mu); - grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL); - } -} - -static const grpc_lb_policy_vtable round_robin_lb_policy_vtable = { - rr_destroy, - rr_shutdown, - rr_pick, - rr_cancel_pick, - rr_ping_one, - rr_exit_idle, - rr_check_connectivity, - rr_notify_on_state_change}; - -static void round_robin_factory_ref(grpc_lb_policy_factory *factory) {} - -static void round_robin_factory_unref(grpc_lb_policy_factory *factory) {} - -static grpc_lb_policy *create_round_robin(grpc_lb_policy_factory *factory, - grpc_lb_policy_args *args) { - size_t i; - round_robin_lb_policy *p = gpr_malloc(sizeof(*p)); - GPR_ASSERT(args->num_subchannels > 0); - memset(p, 0, sizeof(*p)); - grpc_lb_policy_init(&p->base, &round_robin_lb_policy_vtable); - p->num_subchannels = args->num_subchannels; - p->subchannels = gpr_malloc(sizeof(*p->subchannels) * p->num_subchannels); - memset(p->subchannels, 0, sizeof(*p->subchannels) * p->num_subchannels); - grpc_connectivity_state_init(&p->state_tracker, GRPC_CHANNEL_IDLE, - "round_robin"); - - gpr_mu_init(&p->mu); - for (i = 0; i < args->num_subchannels; i++) { - subchannel_data *sd = gpr_malloc(sizeof(*sd)); - memset(sd, 0, sizeof(*sd)); - p->subchannels[i] = sd; - sd->policy = p; - sd->index = i; - sd->subchannel = args->subchannels[i]; - grpc_closure_init(&sd->connectivity_changed_closure, - rr_connectivity_changed, sd); - } - - /* The (dummy node) root of the ready list */ - p->ready_list.subchannel = NULL; - p->ready_list.prev = NULL; - p->ready_list.next = NULL; - p->ready_list_last_pick = &p->ready_list; - - return &p->base; -} - -static const grpc_lb_policy_factory_vtable round_robin_factory_vtable = { - round_robin_factory_ref, round_robin_factory_unref, create_round_robin, - "round_robin"}; - -static grpc_lb_policy_factory round_robin_lb_policy_factory = { - &round_robin_factory_vtable}; - -grpc_lb_policy_factory *grpc_round_robin_lb_factory_create() { - return &round_robin_lb_policy_factory; -} diff --git a/src/core/client_config/lb_policies/round_robin.h b/src/core/client_config/lb_policies/round_robin.h deleted file mode 100644 index 7e6f1769e4..0000000000 --- a/src/core/client_config/lb_policies/round_robin.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H -#define GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H - -#include "src/core/client_config/lb_policy.h" - -extern int grpc_lb_round_robin_trace; - -#include "src/core/client_config/lb_policy_factory.h" - -/** Returns a load balancing factory for the round robin policy */ -grpc_lb_policy_factory *grpc_round_robin_lb_factory_create(); - -#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H */ diff --git a/src/core/client_config/lb_policy.c b/src/core/client_config/lb_policy.c deleted file mode 100644 index 0d8b007336..0000000000 --- a/src/core/client_config/lb_policy.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * - * Copyright 2015-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/client_config/lb_policy.h" - -#define WEAK_REF_BITS 16 - -void grpc_lb_policy_init(grpc_lb_policy *policy, - const grpc_lb_policy_vtable *vtable) { - policy->vtable = vtable; - gpr_atm_no_barrier_store(&policy->ref_pair, 1 << WEAK_REF_BITS); - policy->interested_parties = grpc_pollset_set_create(); -} - -#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG -#define REF_FUNC_EXTRA_ARGS , const char *file, int line, const char *reason -#define REF_MUTATE_EXTRA_ARGS REF_FUNC_EXTRA_ARGS, const char *purpose -#define REF_FUNC_PASS_ARGS(new_reason) , file, line, new_reason -#define REF_MUTATE_PASS_ARGS(purpose) , file, line, reason, purpose -#else -#define REF_FUNC_EXTRA_ARGS -#define REF_MUTATE_EXTRA_ARGS -#define REF_FUNC_PASS_ARGS(new_reason) -#define REF_MUTATE_PASS_ARGS(x) -#endif - -static gpr_atm ref_mutate(grpc_lb_policy *c, gpr_atm delta, - int barrier REF_MUTATE_EXTRA_ARGS) { - gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta) - : gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta); -#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "LB_POLICY: %p % 12s 0x%08x -> 0x%08x [%s]", c, purpose, old_val, - old_val + delta, reason); -#endif - return old_val; -} - -void grpc_lb_policy_ref(grpc_lb_policy *policy REF_FUNC_EXTRA_ARGS) { - ref_mutate(policy, 1 << WEAK_REF_BITS, 0 REF_MUTATE_PASS_ARGS("STRONG_REF")); -} - -void grpc_lb_policy_unref(grpc_exec_ctx *exec_ctx, - grpc_lb_policy *policy REF_FUNC_EXTRA_ARGS) { - gpr_atm old_val = - ref_mutate(policy, (gpr_atm)1 - (gpr_atm)(1 << WEAK_REF_BITS), - 1 REF_MUTATE_PASS_ARGS("STRONG_UNREF")); - gpr_atm mask = ~(gpr_atm)((1 << WEAK_REF_BITS) - 1); - gpr_atm check = 1 << WEAK_REF_BITS; - if ((old_val & mask) == check) { - policy->vtable->shutdown(exec_ctx, policy); - } - grpc_lb_policy_weak_unref(exec_ctx, - policy REF_FUNC_PASS_ARGS("strong-unref")); -} - -void grpc_lb_policy_weak_ref(grpc_lb_policy *policy REF_FUNC_EXTRA_ARGS) { - ref_mutate(policy, 1, 0 REF_MUTATE_PASS_ARGS("WEAK_REF")); -} - -void grpc_lb_policy_weak_unref(grpc_exec_ctx *exec_ctx, - grpc_lb_policy *policy REF_FUNC_EXTRA_ARGS) { - gpr_atm old_val = - ref_mutate(policy, -(gpr_atm)1, 1 REF_MUTATE_PASS_ARGS("WEAK_UNREF")); - if (old_val == 1) { - grpc_pollset_set_destroy(policy->interested_parties); - policy->vtable->destroy(exec_ctx, policy); - } -} - -int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - grpc_pollset *pollset, - grpc_metadata_batch *initial_metadata, - grpc_connected_subchannel **target, - grpc_closure *on_complete) { - return policy->vtable->pick(exec_ctx, policy, pollset, initial_metadata, - target, on_complete); -} - -void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - grpc_connected_subchannel **target) { - policy->vtable->cancel_pick(exec_ctx, policy, target); -} - -void grpc_lb_policy_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy) { - policy->vtable->exit_idle(exec_ctx, policy); -} - -void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - grpc_closure *closure) { - policy->vtable->ping_one(exec_ctx, policy, closure); -} - -void grpc_lb_policy_notify_on_state_change(grpc_exec_ctx *exec_ctx, - grpc_lb_policy *policy, - grpc_connectivity_state *state, - grpc_closure *closure) { - policy->vtable->notify_on_state_change(exec_ctx, policy, state, closure); -} - -grpc_connectivity_state grpc_lb_policy_check_connectivity( - grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy) { - return policy->vtable->check_connectivity(exec_ctx, policy); -} diff --git a/src/core/client_config/lb_policy.h b/src/core/client_config/lb_policy.h deleted file mode 100644 index ffebc2a69c..0000000000 --- a/src/core/client_config/lb_policy.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_LB_POLICY_H -#define GRPC_CORE_CLIENT_CONFIG_LB_POLICY_H - -#include "src/core/client_config/subchannel.h" -#include "src/core/transport/connectivity_state.h" - -/** A load balancing policy: specified by a vtable and a struct (which - is expected to be extended to contain some parameters) */ -typedef struct grpc_lb_policy grpc_lb_policy; -typedef struct grpc_lb_policy_vtable grpc_lb_policy_vtable; - -typedef void (*grpc_lb_completion)(void *cb_arg, grpc_subchannel *subchannel, - grpc_status_code status, const char *errmsg); - -struct grpc_lb_policy { - const grpc_lb_policy_vtable *vtable; - gpr_atm ref_pair; - /* owned pointer to interested parties in load balancing decisions */ - grpc_pollset_set *interested_parties; -}; - -struct grpc_lb_policy_vtable { - void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); - - void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); - - /** implement grpc_lb_policy_pick */ - int (*pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - grpc_pollset *pollset, grpc_metadata_batch *initial_metadata, - grpc_connected_subchannel **target, grpc_closure *on_complete); - void (*cancel_pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - grpc_connected_subchannel **target); - - void (*ping_one)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - grpc_closure *closure); - - /** try to enter a READY connectivity state */ - void (*exit_idle)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); - - /** check the current connectivity of the lb_policy */ - grpc_connectivity_state (*check_connectivity)(grpc_exec_ctx *exec_ctx, - grpc_lb_policy *policy); - - /** call notify when the connectivity state of a channel changes from *state. - Updates *state with the new state of the policy */ - void (*notify_on_state_change)(grpc_exec_ctx *exec_ctx, - grpc_lb_policy *policy, - grpc_connectivity_state *state, - grpc_closure *closure); -}; - -/*#define GRPC_LB_POLICY_REFCOUNT_DEBUG*/ -#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG -#define GRPC_LB_POLICY_REF(p, r) \ - grpc_lb_policy_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_LB_POLICY_UNREF(exec_ctx, p, r) \ - grpc_lb_policy_unref((exec_ctx), (p), __FILE__, __LINE__, (r)) -#define GRPC_LB_POLICY_WEAK_REF(p, r) \ - grpc_lb_policy_weak_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, p, r) \ - grpc_lb_policy_weak_unref((exec_ctx), (p), __FILE__, __LINE__, (r)) -void grpc_lb_policy_ref(grpc_lb_policy *policy, const char *file, int line, - const char *reason); -void grpc_lb_policy_unref(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - const char *file, int line, const char *reason); -void grpc_lb_policy_weak_ref(grpc_lb_policy *policy, const char *file, int line, - const char *reason); -void grpc_lb_policy_weak_unref(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - const char *file, int line, const char *reason); -#else -#define GRPC_LB_POLICY_REF(p, r) grpc_lb_policy_ref((p)) -#define GRPC_LB_POLICY_UNREF(cl, p, r) grpc_lb_policy_unref((cl), (p)) -#define GRPC_LB_POLICY_WEAK_REF(p, r) grpc_lb_policy_weak_ref((p)) -#define GRPC_LB_POLICY_WEAK_UNREF(cl, p, r) grpc_lb_policy_weak_unref((cl), (p)) -void grpc_lb_policy_ref(grpc_lb_policy *policy); -void grpc_lb_policy_unref(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); -void grpc_lb_policy_weak_ref(grpc_lb_policy *policy); -void grpc_lb_policy_weak_unref(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); -#endif - -/** called by concrete implementations to initialize the base struct */ -void grpc_lb_policy_init(grpc_lb_policy *policy, - const grpc_lb_policy_vtable *vtable); - -/** Given initial metadata in \a initial_metadata, find an appropriate - target for this rpc, and 'return' it by calling \a on_complete after setting - \a target. - Picking can be asynchronous. Any IO should be done under \a pollset. */ -int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - grpc_pollset *pollset, - grpc_metadata_batch *initial_metadata, - grpc_connected_subchannel **target, - grpc_closure *on_complete); - -void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - grpc_closure *closure); - -void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, - grpc_connected_subchannel **target); - -void grpc_lb_policy_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); - -void grpc_lb_policy_notify_on_state_change(grpc_exec_ctx *exec_ctx, - grpc_lb_policy *policy, - grpc_connectivity_state *state, - grpc_closure *closure); - -grpc_connectivity_state grpc_lb_policy_check_connectivity( - grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); - -#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICY_H */ diff --git a/src/core/client_config/lb_policy_factory.c b/src/core/client_config/lb_policy_factory.c deleted file mode 100644 index e49de544e3..0000000000 --- a/src/core/client_config/lb_policy_factory.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright 2015, 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/client_config/lb_policy_factory.h" - -void grpc_lb_policy_factory_ref(grpc_lb_policy_factory* factory) { - factory->vtable->ref(factory); -} - -void grpc_lb_policy_factory_unref(grpc_lb_policy_factory* factory) { - factory->vtable->unref(factory); -} - -grpc_lb_policy* grpc_lb_policy_factory_create_lb_policy( - grpc_lb_policy_factory* factory, grpc_lb_policy_args* args) { - if (factory == NULL) return NULL; - return factory->vtable->create_lb_policy(factory, args); -} diff --git a/src/core/client_config/lb_policy_factory.h b/src/core/client_config/lb_policy_factory.h deleted file mode 100644 index 842ba96098..0000000000 --- a/src/core/client_config/lb_policy_factory.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_LB_POLICY_FACTORY_H -#define GRPC_CORE_CLIENT_CONFIG_LB_POLICY_FACTORY_H - -#include "src/core/client_config/lb_policy.h" -#include "src/core/client_config/subchannel.h" - -typedef struct grpc_lb_policy_factory grpc_lb_policy_factory; -typedef struct grpc_lb_policy_factory_vtable grpc_lb_policy_factory_vtable; - -/** grpc_lb_policy provides grpc_client_config objects to grpc_channel - objects */ -struct grpc_lb_policy_factory { - const grpc_lb_policy_factory_vtable *vtable; -}; - -typedef struct grpc_lb_policy_args { - grpc_subchannel **subchannels; - size_t num_subchannels; -} grpc_lb_policy_args; - -struct grpc_lb_policy_factory_vtable { - void (*ref)(grpc_lb_policy_factory *factory); - void (*unref)(grpc_lb_policy_factory *factory); - - /** Implementation of grpc_lb_policy_factory_create_lb_policy */ - grpc_lb_policy *(*create_lb_policy)(grpc_lb_policy_factory *factory, - grpc_lb_policy_args *args); - - /** Name for the LB policy this factory implements */ - const char *name; -}; - -void grpc_lb_policy_factory_ref(grpc_lb_policy_factory *factory); -void grpc_lb_policy_factory_unref(grpc_lb_policy_factory *factory); - -/** Create a lb_policy instance. */ -grpc_lb_policy *grpc_lb_policy_factory_create_lb_policy( - grpc_lb_policy_factory *factory, grpc_lb_policy_args *args); - -#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICY_FACTORY_H */ diff --git a/src/core/client_config/lb_policy_registry.c b/src/core/client_config/lb_policy_registry.c deleted file mode 100644 index fc302e82d7..0000000000 --- a/src/core/client_config/lb_policy_registry.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * - * Copyright 2015, 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/client_config/lb_policy_registry.h" - -#include - -#define MAX_POLICIES 10 - -static grpc_lb_policy_factory *g_all_of_the_lb_policies[MAX_POLICIES]; -static int g_number_of_lb_policies = 0; - -static grpc_lb_policy_factory *g_default_lb_policy_factory; - -void grpc_lb_policy_registry_init(grpc_lb_policy_factory *default_factory) { - g_number_of_lb_policies = 0; - g_default_lb_policy_factory = default_factory; -} - -void grpc_lb_policy_registry_shutdown(void) { - int i; - for (i = 0; i < g_number_of_lb_policies; i++) { - grpc_lb_policy_factory_unref(g_all_of_the_lb_policies[i]); - } -} - -void grpc_register_lb_policy(grpc_lb_policy_factory *factory) { - int i; - for (i = 0; i < g_number_of_lb_policies; i++) { - GPR_ASSERT(0 != strcmp(factory->vtable->name, - g_all_of_the_lb_policies[i]->vtable->name)); - } - GPR_ASSERT(g_number_of_lb_policies != MAX_POLICIES); - grpc_lb_policy_factory_ref(factory); - g_all_of_the_lb_policies[g_number_of_lb_policies++] = factory; -} - -static grpc_lb_policy_factory *lookup_factory(const char *name) { - int i; - - if (name == NULL) return NULL; - - for (i = 0; i < g_number_of_lb_policies; i++) { - if (0 == strcmp(name, g_all_of_the_lb_policies[i]->vtable->name)) { - return g_all_of_the_lb_policies[i]; - } - } - - return NULL; -} - -grpc_lb_policy *grpc_lb_policy_create(const char *name, - grpc_lb_policy_args *args) { - grpc_lb_policy_factory *factory = lookup_factory(name); - grpc_lb_policy *lb_policy = - grpc_lb_policy_factory_create_lb_policy(factory, args); - return lb_policy; -} diff --git a/src/core/client_config/lb_policy_registry.h b/src/core/client_config/lb_policy_registry.h deleted file mode 100644 index f3a08a3558..0000000000 --- a/src/core/client_config/lb_policy_registry.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_LB_POLICY_REGISTRY_H -#define GRPC_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H - -#include "src/core/client_config/lb_policy_factory.h" - -/** Initialize the registry and set \a default_factory as the factory to be - * returned when no name is provided in a lookup */ -void grpc_lb_policy_registry_init(grpc_lb_policy_factory *default_factory); -void grpc_lb_policy_registry_shutdown(void); - -/** Register a LB policy factory. */ -void grpc_register_lb_policy(grpc_lb_policy_factory *factory); - -/** Create a \a grpc_lb_policy instance. - * - * If \a name is NULL, the default factory from \a grpc_lb_policy_registry_init - * will be returned. */ -grpc_lb_policy *grpc_lb_policy_create(const char *name, - grpc_lb_policy_args *args); - -#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H */ diff --git a/src/core/client_config/resolver.c b/src/core/client_config/resolver.c deleted file mode 100644 index eda01e72ba..0000000000 --- a/src/core/client_config/resolver.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright 2015, 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/client_config/resolver.h" - -void grpc_resolver_init(grpc_resolver *resolver, - const grpc_resolver_vtable *vtable) { - resolver->vtable = vtable; - gpr_ref_init(&resolver->refs, 1); -} - -#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG -void grpc_resolver_ref(grpc_resolver *resolver, grpc_closure_list *closure_list, - const char *file, int line, const char *reason) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "RESOLVER:%p ref %d -> %d %s", - resolver, (int)resolver->refs.count, (int)resolver->refs.count + 1, - reason); -#else -void grpc_resolver_ref(grpc_resolver *resolver) { -#endif - gpr_ref(&resolver->refs); -} - -#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG -void grpc_resolver_unref(grpc_resolver *resolver, - grpc_closure_list *closure_list, const char *file, - int line, const char *reason) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "RESOLVER:%p unref %d -> %d %s", - resolver, (int)resolver->refs.count, (int)resolver->refs.count - 1, - reason); -#else -void grpc_resolver_unref(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) { -#endif - if (gpr_unref(&resolver->refs)) { - resolver->vtable->destroy(exec_ctx, resolver); - } -} - -void grpc_resolver_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) { - resolver->vtable->shutdown(exec_ctx, resolver); -} - -void grpc_resolver_channel_saw_error(grpc_exec_ctx *exec_ctx, - grpc_resolver *resolver) { - resolver->vtable->channel_saw_error(exec_ctx, resolver); -} - -void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, - grpc_client_config **target_config, - grpc_closure *on_complete) { - resolver->vtable->next(exec_ctx, resolver, target_config, on_complete); -} diff --git a/src/core/client_config/resolver.h b/src/core/client_config/resolver.h deleted file mode 100644 index 96f88fef84..0000000000 --- a/src/core/client_config/resolver.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_RESOLVER_H -#define GRPC_CORE_CLIENT_CONFIG_RESOLVER_H - -#include "src/core/client_config/client_config.h" -#include "src/core/client_config/subchannel.h" -#include "src/core/iomgr/iomgr.h" - -typedef struct grpc_resolver grpc_resolver; -typedef struct grpc_resolver_vtable grpc_resolver_vtable; - -/** grpc_resolver provides grpc_client_config objects to grpc_channel - objects */ -struct grpc_resolver { - const grpc_resolver_vtable *vtable; - gpr_refcount refs; -}; - -struct grpc_resolver_vtable { - void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver); - void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver); - void (*channel_saw_error)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver); - void (*next)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, - grpc_client_config **target_config, grpc_closure *on_complete); -}; - -#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG -#define GRPC_RESOLVER_REF(p, r) grpc_resolver_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_RESOLVER_UNREF(cl, p, r) \ - grpc_resolver_unref((cl), (p), __FILE__, __LINE__, (r)) -void grpc_resolver_ref(grpc_resolver *policy, const char *file, int line, - const char *reason); -void grpc_resolver_unref(grpc_resolver *policy, grpc_closure_list *closure_list, - const char *file, int line, const char *reason); -#else -#define GRPC_RESOLVER_REF(p, r) grpc_resolver_ref((p)) -#define GRPC_RESOLVER_UNREF(cl, p, r) grpc_resolver_unref((cl), (p)) -void grpc_resolver_ref(grpc_resolver *policy); -void grpc_resolver_unref(grpc_exec_ctx *exec_ctx, grpc_resolver *policy); -#endif - -void grpc_resolver_init(grpc_resolver *resolver, - const grpc_resolver_vtable *vtable); - -void grpc_resolver_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver); - -/** Notification that the channel has seen an error on some address. - Can be used as a hint that re-resolution is desirable soon. */ -void grpc_resolver_channel_saw_error(grpc_exec_ctx *exec_ctx, - grpc_resolver *resolver); - -/** Get the next client config. Called by the channel to fetch a new - configuration. Expected to set *target_config with a new configuration, - and then schedule on_complete for execution. - - If resolution is fatally broken, set *target_config to NULL and - schedule on_complete. */ -void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, - grpc_client_config **target_config, - grpc_closure *on_complete); - -#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVER_H */ diff --git a/src/core/client_config/resolver_factory.c b/src/core/client_config/resolver_factory.c deleted file mode 100644 index e7e9196ac4..0000000000 --- a/src/core/client_config/resolver_factory.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright 2015, 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/client_config/resolver_factory.h" - -void grpc_resolver_factory_ref(grpc_resolver_factory* factory) { - factory->vtable->ref(factory); -} - -void grpc_resolver_factory_unref(grpc_resolver_factory* factory) { - factory->vtable->unref(factory); -} - -/** Create a resolver instance for a name */ -grpc_resolver* grpc_resolver_factory_create_resolver( - grpc_resolver_factory* factory, grpc_resolver_args* args) { - if (factory == NULL) return NULL; - return factory->vtable->create_resolver(factory, args); -} - -char* grpc_resolver_factory_get_default_authority( - grpc_resolver_factory* factory, grpc_uri* uri) { - if (factory == NULL) return NULL; - return factory->vtable->get_default_authority(factory, uri); -} diff --git a/src/core/client_config/resolver_factory.h b/src/core/client_config/resolver_factory.h deleted file mode 100644 index 477f8db7f7..0000000000 --- a/src/core/client_config/resolver_factory.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_RESOLVER_FACTORY_H -#define GRPC_CORE_CLIENT_CONFIG_RESOLVER_FACTORY_H - -#include "src/core/client_config/resolver.h" -#include "src/core/client_config/subchannel_factory.h" -#include "src/core/client_config/uri_parser.h" - -typedef struct grpc_resolver_factory grpc_resolver_factory; -typedef struct grpc_resolver_factory_vtable grpc_resolver_factory_vtable; - -/** grpc_resolver provides grpc_client_config objects to grpc_channel - objects */ -struct grpc_resolver_factory { - const grpc_resolver_factory_vtable *vtable; -}; - -typedef struct grpc_resolver_args { - grpc_uri *uri; - grpc_subchannel_factory *subchannel_factory; -} grpc_resolver_args; - -struct grpc_resolver_factory_vtable { - void (*ref)(grpc_resolver_factory *factory); - void (*unref)(grpc_resolver_factory *factory); - - /** Implementation of grpc_resolver_factory_create_resolver */ - grpc_resolver *(*create_resolver)(grpc_resolver_factory *factory, - grpc_resolver_args *args); - - /** Implementation of grpc_resolver_factory_get_default_authority */ - char *(*get_default_authority)(grpc_resolver_factory *factory, grpc_uri *uri); - - /** URI scheme that this factory implements */ - const char *scheme; -}; - -void grpc_resolver_factory_ref(grpc_resolver_factory *resolver); -void grpc_resolver_factory_unref(grpc_resolver_factory *resolver); - -/** Create a resolver instance for a name */ -grpc_resolver *grpc_resolver_factory_create_resolver( - grpc_resolver_factory *factory, grpc_resolver_args *args); - -/** Return a (freshly allocated with gpr_malloc) string representing - the default authority to use for this scheme. */ -char *grpc_resolver_factory_get_default_authority( - grpc_resolver_factory *factory, grpc_uri *uri); - -#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVER_FACTORY_H */ diff --git a/src/core/client_config/resolver_registry.c b/src/core/client_config/resolver_registry.c deleted file mode 100644 index 89a945c2d3..0000000000 --- a/src/core/client_config/resolver_registry.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * - * Copyright 2015, 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/client_config/resolver_registry.h" - -#include - -#include -#include -#include - -#define MAX_RESOLVERS 10 - -static grpc_resolver_factory *g_all_of_the_resolvers[MAX_RESOLVERS]; -static int g_number_of_resolvers = 0; - -static char *g_default_resolver_prefix; - -void grpc_resolver_registry_init(const char *default_resolver_prefix) { - g_number_of_resolvers = 0; - g_default_resolver_prefix = gpr_strdup(default_resolver_prefix); -} - -void grpc_resolver_registry_shutdown(void) { - int i; - for (i = 0; i < g_number_of_resolvers; i++) { - grpc_resolver_factory_unref(g_all_of_the_resolvers[i]); - } - gpr_free(g_default_resolver_prefix); -} - -void grpc_register_resolver_type(grpc_resolver_factory *factory) { - int i; - for (i = 0; i < g_number_of_resolvers; i++) { - GPR_ASSERT(0 != strcmp(factory->vtable->scheme, - g_all_of_the_resolvers[i]->vtable->scheme)); - } - GPR_ASSERT(g_number_of_resolvers != MAX_RESOLVERS); - grpc_resolver_factory_ref(factory); - g_all_of_the_resolvers[g_number_of_resolvers++] = factory; -} - -static grpc_resolver_factory *lookup_factory(grpc_uri *uri) { - int i; - - /* handling NULL uri's here simplifies grpc_resolver_create */ - if (!uri) return NULL; - - for (i = 0; i < g_number_of_resolvers; i++) { - if (0 == strcmp(uri->scheme, g_all_of_the_resolvers[i]->vtable->scheme)) { - return g_all_of_the_resolvers[i]; - } - } - - return NULL; -} - -static grpc_resolver_factory *resolve_factory(const char *target, - grpc_uri **uri) { - char *tmp; - grpc_resolver_factory *factory = NULL; - - GPR_ASSERT(uri != NULL); - *uri = grpc_uri_parse(target, 1); - factory = lookup_factory(*uri); - if (factory == NULL) { - if (g_default_resolver_prefix != NULL) { - grpc_uri_destroy(*uri); - gpr_asprintf(&tmp, "%s%s", g_default_resolver_prefix, target); - *uri = grpc_uri_parse(tmp, 1); - factory = lookup_factory(*uri); - if (factory == NULL) { - grpc_uri_destroy(grpc_uri_parse(target, 0)); - grpc_uri_destroy(grpc_uri_parse(tmp, 0)); - gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target, - tmp); - } - gpr_free(tmp); - } else { - grpc_uri_destroy(grpc_uri_parse(target, 0)); - gpr_log(GPR_ERROR, "don't know how to resolve '%s'", target); - } - } - return factory; -} - -grpc_resolver *grpc_resolver_create( - const char *target, grpc_subchannel_factory *subchannel_factory) { - grpc_uri *uri = NULL; - grpc_resolver_factory *factory = resolve_factory(target, &uri); - grpc_resolver *resolver; - grpc_resolver_args args; - memset(&args, 0, sizeof(args)); - args.uri = uri; - args.subchannel_factory = subchannel_factory; - resolver = grpc_resolver_factory_create_resolver(factory, &args); - grpc_uri_destroy(uri); - return resolver; -} - -char *grpc_get_default_authority(const char *target) { - grpc_uri *uri = NULL; - grpc_resolver_factory *factory = resolve_factory(target, &uri); - char *authority = grpc_resolver_factory_get_default_authority(factory, uri); - grpc_uri_destroy(uri); - return authority; -} diff --git a/src/core/client_config/resolver_registry.h b/src/core/client_config/resolver_registry.h deleted file mode 100644 index 1e4cebee0b..0000000000 --- a/src/core/client_config/resolver_registry.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_RESOLVER_REGISTRY_H -#define GRPC_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H - -#include "src/core/client_config/resolver_factory.h" - -void grpc_resolver_registry_init(const char *default_prefix); -void grpc_resolver_registry_shutdown(void); - -/** Register a resolver type. - URI's of \a scheme will be resolved with the given resolver. - If \a priority is greater than zero, then the resolver will be eligible - to resolve names that are passed in with no scheme. Higher priority - resolvers will be tried before lower priority schemes. */ -void grpc_register_resolver_type(grpc_resolver_factory *factory); - -/** Create a resolver given \a target. - First tries to parse \a target as a URI. If this succeeds, tries - to locate a registered resolver factory based on the URI scheme. - If parsing or location fails, prefixes default_prefix from - grpc_resolver_registry_init to target, and tries again (if default_prefix - was not NULL). - If a resolver factory was found, use it to instantiate a resolver and - return it. - If a resolver factory was not found, return NULL. */ -grpc_resolver *grpc_resolver_create( - const char *target, grpc_subchannel_factory *subchannel_factory); - -/** 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); - -#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H */ diff --git a/src/core/client_config/resolvers/dns_resolver.c b/src/core/client_config/resolvers/dns_resolver.c deleted file mode 100644 index 2b2ee97e12..0000000000 --- a/src/core/client_config/resolvers/dns_resolver.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * - * Copyright 2015-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/client_config/resolvers/dns_resolver.h" - -#include - -#include -#include -#include - -#include "src/core/client_config/lb_policy_registry.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/timer.h" -#include "src/core/support/backoff.h" -#include "src/core/support/string.h" - -#define BACKOFF_MULTIPLIER 1.6 -#define BACKOFF_JITTER 0.2 -#define BACKOFF_MIN_SECONDS 1 -#define BACKOFF_MAX_SECONDS 120 - -typedef struct { - /** base class: must be first */ - grpc_resolver base; - /** refcount */ - gpr_refcount refs; - /** name to resolve */ - char *name; - /** default port to use */ - char *default_port; - /** subchannel factory */ - grpc_subchannel_factory *subchannel_factory; - /** load balancing policy name */ - char *lb_policy_name; - - /** mutex guarding the rest of the state */ - gpr_mu mu; - /** are we currently resolving? */ - int resolving; - /** which version of resolved_config have we published? */ - int published_version; - /** which version of resolved_config is current? */ - int resolved_version; - /** pending next completion, or NULL */ - grpc_closure *next_completion; - /** target config address for next completion */ - grpc_client_config **target_config; - /** current (fully resolved) config */ - grpc_client_config *resolved_config; - /** retry timer */ - bool have_retry_timer; - grpc_timer retry_timer; - /** retry backoff state */ - gpr_backoff backoff_state; -} dns_resolver; - -static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r); - -static void dns_start_resolving_locked(dns_resolver *r); -static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, - dns_resolver *r); - -static void dns_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r); -static void dns_channel_saw_error(grpc_exec_ctx *exec_ctx, grpc_resolver *r); -static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r, - grpc_client_config **target_config, - grpc_closure *on_complete); - -static const grpc_resolver_vtable dns_resolver_vtable = { - dns_destroy, dns_shutdown, dns_channel_saw_error, dns_next}; - -static void dns_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) { - dns_resolver *r = (dns_resolver *)resolver; - gpr_mu_lock(&r->mu); - if (r->have_retry_timer) { - grpc_timer_cancel(exec_ctx, &r->retry_timer); - } - if (r->next_completion != NULL) { - *r->target_config = NULL; - grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL); - r->next_completion = NULL; - } - gpr_mu_unlock(&r->mu); -} - -static void dns_channel_saw_error(grpc_exec_ctx *exec_ctx, - grpc_resolver *resolver) { - dns_resolver *r = (dns_resolver *)resolver; - gpr_mu_lock(&r->mu); - if (!r->resolving) { - gpr_backoff_reset(&r->backoff_state); - dns_start_resolving_locked(r); - } - gpr_mu_unlock(&r->mu); -} - -static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, - grpc_client_config **target_config, - grpc_closure *on_complete) { - dns_resolver *r = (dns_resolver *)resolver; - gpr_mu_lock(&r->mu); - GPR_ASSERT(!r->next_completion); - r->next_completion = on_complete; - r->target_config = target_config; - if (r->resolved_version == 0 && !r->resolving) { - gpr_backoff_reset(&r->backoff_state); - dns_start_resolving_locked(r); - } else { - dns_maybe_finish_next_locked(exec_ctx, r); - } - gpr_mu_unlock(&r->mu); -} - -static void dns_on_retry_timer(grpc_exec_ctx *exec_ctx, void *arg, - bool success) { - dns_resolver *r = arg; - - gpr_mu_lock(&r->mu); - r->have_retry_timer = false; - if (success) { - if (!r->resolving) { - dns_start_resolving_locked(r); - } - } - gpr_mu_unlock(&r->mu); - - GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "retry-timer"); -} - -static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg, - grpc_resolved_addresses *addresses) { - dns_resolver *r = arg; - grpc_client_config *config = NULL; - grpc_subchannel **subchannels; - grpc_subchannel_args args; - grpc_lb_policy *lb_policy; - size_t i; - gpr_mu_lock(&r->mu); - GPR_ASSERT(r->resolving); - r->resolving = 0; - if (addresses != NULL) { - grpc_lb_policy_args lb_policy_args; - config = grpc_client_config_create(); - subchannels = gpr_malloc(sizeof(grpc_subchannel *) * addresses->naddrs); - size_t naddrs = 0; - for (i = 0; i < addresses->naddrs; i++) { - memset(&args, 0, sizeof(args)); - args.addr = (struct sockaddr *)(addresses->addrs[i].addr); - args.addr_len = (size_t)addresses->addrs[i].len; - grpc_subchannel *subchannel = grpc_subchannel_factory_create_subchannel( - exec_ctx, r->subchannel_factory, &args); - if (subchannel != NULL) { - subchannels[naddrs++] = subchannel; - } - } - memset(&lb_policy_args, 0, sizeof(lb_policy_args)); - lb_policy_args.subchannels = subchannels; - lb_policy_args.num_subchannels = naddrs; - lb_policy = grpc_lb_policy_create(r->lb_policy_name, &lb_policy_args); - if (lb_policy != NULL) { - grpc_client_config_set_lb_policy(config, lb_policy); - GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "construction"); - } - grpc_resolved_addresses_destroy(addresses); - gpr_free(subchannels); - } else { - gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); - gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now); - gpr_timespec timeout = gpr_time_sub(next_try, now); - gpr_log(GPR_DEBUG, "dns resolution failed: retrying in %d.%09d seconds", - timeout.tv_sec, timeout.tv_nsec); - GPR_ASSERT(!r->have_retry_timer); - r->have_retry_timer = true; - GRPC_RESOLVER_REF(&r->base, "retry-timer"); - grpc_timer_init(exec_ctx, &r->retry_timer, next_try, dns_on_retry_timer, r, - now); - } - if (r->resolved_config) { - grpc_client_config_unref(exec_ctx, r->resolved_config); - } - r->resolved_config = config; - r->resolved_version++; - dns_maybe_finish_next_locked(exec_ctx, r); - gpr_mu_unlock(&r->mu); - - GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "dns-resolving"); -} - -static void dns_start_resolving_locked(dns_resolver *r) { - GRPC_RESOLVER_REF(&r->base, "dns-resolving"); - GPR_ASSERT(!r->resolving); - r->resolving = 1; - grpc_resolve_address(r->name, r->default_port, dns_on_resolved, r); -} - -static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, - dns_resolver *r) { - if (r->next_completion != NULL && - r->resolved_version != r->published_version) { - *r->target_config = r->resolved_config; - if (r->resolved_config) { - grpc_client_config_ref(r->resolved_config); - } - grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL); - r->next_completion = NULL; - r->published_version = r->resolved_version; - } -} - -static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) { - dns_resolver *r = (dns_resolver *)gr; - gpr_mu_destroy(&r->mu); - if (r->resolved_config) { - grpc_client_config_unref(exec_ctx, r->resolved_config); - } - grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory); - gpr_free(r->name); - gpr_free(r->default_port); - gpr_free(r->lb_policy_name); - gpr_free(r); -} - -static grpc_resolver *dns_create(grpc_resolver_args *args, - const char *default_port, - const char *lb_policy_name) { - dns_resolver *r; - const char *path = args->uri->path; - - if (0 != strcmp(args->uri->authority, "")) { - gpr_log(GPR_ERROR, "authority based dns uri's not supported"); - return NULL; - } - - if (path[0] == '/') ++path; - - r = gpr_malloc(sizeof(dns_resolver)); - memset(r, 0, sizeof(*r)); - gpr_ref_init(&r->refs, 1); - gpr_mu_init(&r->mu); - grpc_resolver_init(&r->base, &dns_resolver_vtable); - r->name = gpr_strdup(path); - r->default_port = gpr_strdup(default_port); - r->subchannel_factory = args->subchannel_factory; - gpr_backoff_init(&r->backoff_state, BACKOFF_MULTIPLIER, BACKOFF_JITTER, - BACKOFF_MIN_SECONDS * 1000, BACKOFF_MAX_SECONDS * 1000); - grpc_subchannel_factory_ref(r->subchannel_factory); - r->lb_policy_name = gpr_strdup(lb_policy_name); - return &r->base; -} - -/* - * FACTORY - */ - -static void dns_factory_ref(grpc_resolver_factory *factory) {} - -static void dns_factory_unref(grpc_resolver_factory *factory) {} - -static grpc_resolver *dns_factory_create_resolver( - grpc_resolver_factory *factory, grpc_resolver_args *args) { - return dns_create(args, "https", "pick_first"); -} - -char *dns_factory_get_default_host_name(grpc_resolver_factory *factory, - grpc_uri *uri) { - const char *path = uri->path; - if (path[0] == '/') ++path; - return gpr_strdup(path); -} - -static const grpc_resolver_factory_vtable dns_factory_vtable = { - dns_factory_ref, dns_factory_unref, dns_factory_create_resolver, - dns_factory_get_default_host_name, "dns"}; -static grpc_resolver_factory dns_resolver_factory = {&dns_factory_vtable}; - -grpc_resolver_factory *grpc_dns_resolver_factory_create() { - return &dns_resolver_factory; -} diff --git a/src/core/client_config/resolvers/dns_resolver.h b/src/core/client_config/resolvers/dns_resolver.h deleted file mode 100644 index b24280b507..0000000000 --- a/src/core/client_config/resolvers/dns_resolver.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H -#define GRPC_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H - -#include "src/core/client_config/resolver_factory.h" - -/** Create a dns resolver factory */ -grpc_resolver_factory *grpc_dns_resolver_factory_create(void); - -#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H */ diff --git a/src/core/client_config/resolvers/sockaddr_resolver.c b/src/core/client_config/resolvers/sockaddr_resolver.c deleted file mode 100644 index 3cb7d79b67..0000000000 --- a/src/core/client_config/resolvers/sockaddr_resolver.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include "src/core/client_config/resolvers/sockaddr_resolver.h" - -#include -#include - -#include -#include -#include - -#include "src/core/client_config/lb_policy_registry.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/unix_sockets_posix.h" -#include "src/core/support/string.h" - -typedef struct { - /** base class: must be first */ - grpc_resolver base; - /** refcount */ - gpr_refcount refs; - /** subchannel factory */ - grpc_subchannel_factory *subchannel_factory; - /** load balancing policy name */ - char *lb_policy_name; - - /** the addresses that we've 'resolved' */ - struct sockaddr_storage *addrs; - /** the corresponding length of the addresses */ - size_t *addrs_len; - /** how many elements in \a addrs */ - size_t num_addrs; - - /** mutex guarding the rest of the state */ - gpr_mu mu; - /** have we published? */ - int published; - /** pending next completion, or NULL */ - grpc_closure *next_completion; - /** target config address for next completion */ - grpc_client_config **target_config; -} sockaddr_resolver; - -static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r); - -static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, - sockaddr_resolver *r); - -static void sockaddr_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r); -static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx, - grpc_resolver *r); -static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r, - grpc_client_config **target_config, - grpc_closure *on_complete); - -static const grpc_resolver_vtable sockaddr_resolver_vtable = { - sockaddr_destroy, sockaddr_shutdown, sockaddr_channel_saw_error, - sockaddr_next}; - -static void sockaddr_shutdown(grpc_exec_ctx *exec_ctx, - grpc_resolver *resolver) { - sockaddr_resolver *r = (sockaddr_resolver *)resolver; - gpr_mu_lock(&r->mu); - if (r->next_completion != NULL) { - *r->target_config = NULL; - grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL); - r->next_completion = NULL; - } - gpr_mu_unlock(&r->mu); -} - -static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx, - grpc_resolver *resolver) { - sockaddr_resolver *r = (sockaddr_resolver *)resolver; - gpr_mu_lock(&r->mu); - r->published = 0; - sockaddr_maybe_finish_next_locked(exec_ctx, r); - gpr_mu_unlock(&r->mu); -} - -static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, - grpc_client_config **target_config, - grpc_closure *on_complete) { - sockaddr_resolver *r = (sockaddr_resolver *)resolver; - gpr_mu_lock(&r->mu); - GPR_ASSERT(!r->next_completion); - r->next_completion = on_complete; - r->target_config = target_config; - sockaddr_maybe_finish_next_locked(exec_ctx, r); - gpr_mu_unlock(&r->mu); -} - -static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, - sockaddr_resolver *r) { - grpc_client_config *cfg; - grpc_lb_policy *lb_policy; - grpc_lb_policy_args lb_policy_args; - grpc_subchannel **subchannels; - grpc_subchannel_args args; - - if (r->next_completion != NULL && !r->published) { - size_t i; - cfg = grpc_client_config_create(); - subchannels = gpr_malloc(sizeof(grpc_subchannel *) * r->num_addrs); - for (i = 0; i < r->num_addrs; i++) { - memset(&args, 0, sizeof(args)); - args.addr = (struct sockaddr *)&r->addrs[i]; - args.addr_len = r->addrs_len[i]; - subchannels[i] = grpc_subchannel_factory_create_subchannel( - exec_ctx, r->subchannel_factory, &args); - } - memset(&lb_policy_args, 0, sizeof(lb_policy_args)); - lb_policy_args.subchannels = subchannels; - lb_policy_args.num_subchannels = r->num_addrs; - lb_policy = grpc_lb_policy_create(r->lb_policy_name, &lb_policy_args); - gpr_free(subchannels); - grpc_client_config_set_lb_policy(cfg, lb_policy); - GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "sockaddr"); - r->published = 1; - *r->target_config = cfg; - grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL); - r->next_completion = NULL; - } -} - -static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) { - sockaddr_resolver *r = (sockaddr_resolver *)gr; - gpr_mu_destroy(&r->mu); - grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory); - gpr_free(r->addrs); - gpr_free(r->addrs_len); - gpr_free(r->lb_policy_name); - gpr_free(r); -} - -static char *ip_get_default_authority(grpc_uri *uri) { - const char *path = uri->path; - if (path[0] == '/') ++path; - return gpr_strdup(path); -} - -static char *ipv4_get_default_authority(grpc_resolver_factory *factory, - grpc_uri *uri) { - return ip_get_default_authority(uri); -} - -static char *ipv6_get_default_authority(grpc_resolver_factory *factory, - grpc_uri *uri) { - return ip_get_default_authority(uri); -} - -static int parse_ipv4(grpc_uri *uri, struct sockaddr_storage *addr, - size_t *len) { - const char *host_port = uri->path; - char *host; - char *port; - int port_num; - int result = 0; - struct sockaddr_in *in = (struct sockaddr_in *)addr; - - if (*host_port == '/') ++host_port; - if (!gpr_split_host_port(host_port, &host, &port)) { - return 0; - } - - memset(in, 0, sizeof(*in)); - *len = sizeof(*in); - in->sin_family = AF_INET; - if (inet_pton(AF_INET, host, &in->sin_addr) == 0) { - gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host); - goto done; - } - - if (port != NULL) { - if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || - port_num > 65535) { - gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port); - goto done; - } - in->sin_port = htons((uint16_t)port_num); - } else { - gpr_log(GPR_ERROR, "no port given for ipv4 scheme"); - goto done; - } - - result = 1; -done: - gpr_free(host); - gpr_free(port); - return result; -} - -static int parse_ipv6(grpc_uri *uri, struct sockaddr_storage *addr, - size_t *len) { - const char *host_port = uri->path; - char *host; - char *port; - int port_num; - int result = 0; - struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr; - - if (*host_port == '/') ++host_port; - if (!gpr_split_host_port(host_port, &host, &port)) { - return 0; - } - - memset(in6, 0, sizeof(*in6)); - *len = sizeof(*in6); - in6->sin6_family = AF_INET6; - if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) { - gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host); - goto done; - } - - if (port != NULL) { - if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || - port_num > 65535) { - gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port); - goto done; - } - in6->sin6_port = htons((uint16_t)port_num); - } else { - gpr_log(GPR_ERROR, "no port given for ipv6 scheme"); - goto done; - } - - result = 1; -done: - gpr_free(host); - gpr_free(port); - return result; -} - -static void do_nothing(void *ignored) {} - -static grpc_resolver *sockaddr_create( - grpc_resolver_args *args, const char *default_lb_policy_name, - int parse(grpc_uri *uri, struct sockaddr_storage *dst, size_t *len)) { - size_t i; - int errors_found = 0; /* GPR_FALSE */ - sockaddr_resolver *r; - gpr_slice path_slice; - gpr_slice_buffer path_parts; - - if (0 != strcmp(args->uri->authority, "")) { - gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme", - args->uri->scheme); - return NULL; - } - - r = gpr_malloc(sizeof(sockaddr_resolver)); - memset(r, 0, sizeof(*r)); - - r->lb_policy_name = NULL; - if (0 != strcmp(args->uri->query, "")) { - gpr_slice query_slice; - gpr_slice_buffer query_parts; - - query_slice = - gpr_slice_new(args->uri->query, strlen(args->uri->query), do_nothing); - gpr_slice_buffer_init(&query_parts); - gpr_slice_split(query_slice, "=", &query_parts); - GPR_ASSERT(query_parts.count == 2); - if (0 == gpr_slice_str_cmp(query_parts.slices[0], "lb_policy")) { - r->lb_policy_name = gpr_dump_slice(query_parts.slices[1], GPR_DUMP_ASCII); - } - gpr_slice_buffer_destroy(&query_parts); - gpr_slice_unref(query_slice); - } - if (r->lb_policy_name == NULL) { - r->lb_policy_name = gpr_strdup(default_lb_policy_name); - } - - path_slice = - gpr_slice_new(args->uri->path, strlen(args->uri->path), do_nothing); - gpr_slice_buffer_init(&path_parts); - - gpr_slice_split(path_slice, ",", &path_parts); - r->num_addrs = path_parts.count; - r->addrs = gpr_malloc(sizeof(struct sockaddr_storage) * r->num_addrs); - r->addrs_len = gpr_malloc(sizeof(*r->addrs_len) * r->num_addrs); - - for (i = 0; i < r->num_addrs; i++) { - grpc_uri ith_uri = *args->uri; - char *part_str = gpr_dump_slice(path_parts.slices[i], GPR_DUMP_ASCII); - ith_uri.path = part_str; - if (!parse(&ith_uri, &r->addrs[i], &r->addrs_len[i])) { - errors_found = 1; /* GPR_TRUE */ - } - gpr_free(part_str); - if (errors_found) break; - } - - gpr_slice_buffer_destroy(&path_parts); - gpr_slice_unref(path_slice); - if (errors_found) { - gpr_free(r->lb_policy_name); - gpr_free(r->addrs); - gpr_free(r->addrs_len); - gpr_free(r); - return NULL; - } - - gpr_ref_init(&r->refs, 1); - gpr_mu_init(&r->mu); - grpc_resolver_init(&r->base, &sockaddr_resolver_vtable); - r->subchannel_factory = args->subchannel_factory; - grpc_subchannel_factory_ref(r->subchannel_factory); - - return &r->base; -} - -/* - * FACTORY - */ - -static void sockaddr_factory_ref(grpc_resolver_factory *factory) {} - -static void sockaddr_factory_unref(grpc_resolver_factory *factory) {} - -#define DECL_FACTORY(name, prefix) \ - static grpc_resolver *name##_factory_create_resolver( \ - grpc_resolver_factory *factory, grpc_resolver_args *args) { \ - return sockaddr_create(args, "pick_first", prefix##parse_##name); \ - } \ - static const grpc_resolver_factory_vtable name##_factory_vtable = { \ - sockaddr_factory_ref, sockaddr_factory_unref, \ - name##_factory_create_resolver, prefix##name##_get_default_authority, \ - #name}; \ - static grpc_resolver_factory name##_resolver_factory = { \ - &name##_factory_vtable}; \ - grpc_resolver_factory *grpc_##name##_resolver_factory_create() { \ - return &name##_resolver_factory; \ - } - -#ifdef GPR_HAVE_UNIX_SOCKET -DECL_FACTORY(unix, grpc_) -#endif -DECL_FACTORY(ipv4, ) DECL_FACTORY(ipv6, ) diff --git a/src/core/client_config/resolvers/sockaddr_resolver.h b/src/core/client_config/resolvers/sockaddr_resolver.h deleted file mode 100644 index f050329431..0000000000 --- a/src/core/client_config/resolvers/sockaddr_resolver.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H -#define GRPC_CORE_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H - -#include - -#include "src/core/client_config/resolver_factory.h" - -grpc_resolver_factory *grpc_ipv4_resolver_factory_create(void); - -grpc_resolver_factory *grpc_ipv6_resolver_factory_create(void); - -#ifdef GPR_POSIX_SOCKET -/** Create a unix resolver factory */ -grpc_resolver_factory *grpc_unix_resolver_factory_create(void); -#endif - -#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H */ diff --git a/src/core/client_config/resolvers/zookeeper_resolver.c b/src/core/client_config/resolvers/zookeeper_resolver.c deleted file mode 100644 index e0e18792a2..0000000000 --- a/src/core/client_config/resolvers/zookeeper_resolver.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * - * Copyright 2015-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/client_config/resolvers/zookeeper_resolver.h" - -#include - -#include -#include - -#include -#include - -#include "src/core/client_config/lb_policy_registry.h" -#include "src/core/client_config/resolver_registry.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/json/json.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" - -/** Zookeeper session expiration time in milliseconds */ -#define GRPC_ZOOKEEPER_SESSION_TIMEOUT 15000 - -typedef struct { - /** base class: must be first */ - grpc_resolver base; - /** refcount */ - gpr_refcount refs; - /** name to resolve */ - char *name; - /** subchannel factory */ - grpc_subchannel_factory *subchannel_factory; - /** load balancing policy name */ - char *lb_policy_name; - - /** mutex guarding the rest of the state */ - gpr_mu mu; - /** are we currently resolving? */ - int resolving; - /** which version of resolved_config have we published? */ - int published_version; - /** which version of resolved_config is current? */ - int resolved_version; - /** pending next completion, or NULL */ - grpc_closure *next_completion; - /** target config address for next completion */ - grpc_client_config **target_config; - /** current (fully resolved) config */ - grpc_client_config *resolved_config; - - /** zookeeper handle */ - zhandle_t *zookeeper_handle; - /** zookeeper resolved addresses */ - grpc_resolved_addresses *resolved_addrs; - /** total number of addresses to be resolved */ - int resolved_total; - /** number of addresses resolved */ - int resolved_num; -} zookeeper_resolver; - -static void zookeeper_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r); - -static void zookeeper_start_resolving_locked(zookeeper_resolver *r); -static void zookeeper_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, - zookeeper_resolver *r); - -static void zookeeper_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r); -static void zookeeper_channel_saw_error(grpc_exec_ctx *exec_ctx, - grpc_resolver *r); -static void zookeeper_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r, - grpc_client_config **target_config, - grpc_closure *on_complete); - -static const grpc_resolver_vtable zookeeper_resolver_vtable = { - zookeeper_destroy, zookeeper_shutdown, zookeeper_channel_saw_error, - zookeeper_next}; - -static void zookeeper_shutdown(grpc_exec_ctx *exec_ctx, - grpc_resolver *resolver) { - zookeeper_resolver *r = (zookeeper_resolver *)resolver; - grpc_closure *call = NULL; - gpr_mu_lock(&r->mu); - if (r->next_completion != NULL) { - *r->target_config = NULL; - call = r->next_completion; - r->next_completion = NULL; - } - zookeeper_close(r->zookeeper_handle); - gpr_mu_unlock(&r->mu); - if (call != NULL) { - call->cb(exec_ctx, call->cb_arg, 1); - } -} - -static void zookeeper_channel_saw_error(grpc_exec_ctx *exec_ctx, - grpc_resolver *resolver) { - zookeeper_resolver *r = (zookeeper_resolver *)resolver; - gpr_mu_lock(&r->mu); - if (r->resolving == 0) { - zookeeper_start_resolving_locked(r); - } - gpr_mu_unlock(&r->mu); -} - -static void zookeeper_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, - grpc_client_config **target_config, - grpc_closure *on_complete) { - zookeeper_resolver *r = (zookeeper_resolver *)resolver; - gpr_mu_lock(&r->mu); - GPR_ASSERT(r->next_completion == NULL); - r->next_completion = on_complete; - r->target_config = target_config; - if (r->resolved_version == 0 && r->resolving == 0) { - zookeeper_start_resolving_locked(r); - } else { - zookeeper_maybe_finish_next_locked(exec_ctx, r); - } - gpr_mu_unlock(&r->mu); -} - -/** Zookeeper global watcher for connection management - TODO: better connection management besides logs */ -static void zookeeper_global_watcher(zhandle_t *zookeeper_handle, int type, - int state, const char *path, - void *watcher_ctx) { - if (type == ZOO_SESSION_EVENT) { - if (state == ZOO_EXPIRED_SESSION_STATE) { - gpr_log(GPR_ERROR, "Zookeeper session expired"); - } else if (state == ZOO_AUTH_FAILED_STATE) { - gpr_log(GPR_ERROR, "Zookeeper authentication failed"); - } - } -} - -/** Zookeeper watcher triggered by changes to watched nodes - Once triggered, it tries to resolve again to get updated addresses */ -static void zookeeper_watcher(zhandle_t *zookeeper_handle, int type, int state, - const char *path, void *watcher_ctx) { - if (watcher_ctx != NULL) { - zookeeper_resolver *r = (zookeeper_resolver *)watcher_ctx; - if (state == ZOO_CONNECTED_STATE) { - gpr_mu_lock(&r->mu); - if (r->resolving == 0) { - zookeeper_start_resolving_locked(r); - } - gpr_mu_unlock(&r->mu); - } - } -} - -/** Callback function after getting all resolved addresses - Creates a subchannel for each address */ -static void zookeeper_on_resolved(grpc_exec_ctx *exec_ctx, void *arg, - grpc_resolved_addresses *addresses) { - zookeeper_resolver *r = arg; - grpc_client_config *config = NULL; - grpc_subchannel **subchannels; - grpc_subchannel_args args; - grpc_lb_policy *lb_policy; - size_t i; - if (addresses != NULL) { - grpc_lb_policy_args lb_policy_args; - config = grpc_client_config_create(); - subchannels = gpr_malloc(sizeof(grpc_subchannel *) * addresses->naddrs); - for (i = 0; i < addresses->naddrs; i++) { - memset(&args, 0, sizeof(args)); - args.addr = (struct sockaddr *)(addresses->addrs[i].addr); - args.addr_len = addresses->addrs[i].len; - subchannels[i] = grpc_subchannel_factory_create_subchannel( - exec_ctx, r->subchannel_factory, &args); - } - lb_policy_args.subchannels = subchannels; - lb_policy_args.num_subchannels = addresses->naddrs; - lb_policy = grpc_lb_policy_create(r->lb_policy_name, &lb_policy_args); - grpc_client_config_set_lb_policy(config, lb_policy); - GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "construction"); - grpc_resolved_addresses_destroy(addresses); - gpr_free(subchannels); - } - gpr_mu_lock(&r->mu); - GPR_ASSERT(r->resolving == 1); - r->resolving = 0; - if (r->resolved_config != NULL) { - grpc_client_config_unref(exec_ctx, r->resolved_config); - } - r->resolved_config = config; - r->resolved_version++; - zookeeper_maybe_finish_next_locked(exec_ctx, r); - gpr_mu_unlock(&r->mu); - - GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "zookeeper-resolving"); -} - -/** Callback function for each DNS resolved address */ -static void zookeeper_dns_resolved(grpc_exec_ctx *exec_ctx, void *arg, - grpc_resolved_addresses *addresses) { - size_t i; - zookeeper_resolver *r = arg; - int resolve_done = 0; - - gpr_mu_lock(&r->mu); - r->resolved_num++; - r->resolved_addrs->addrs = - gpr_realloc(r->resolved_addrs->addrs, - sizeof(grpc_resolved_address) * - (r->resolved_addrs->naddrs + addresses->naddrs)); - for (i = 0; i < addresses->naddrs; i++) { - memcpy(r->resolved_addrs->addrs[i + r->resolved_addrs->naddrs].addr, - addresses->addrs[i].addr, addresses->addrs[i].len); - r->resolved_addrs->addrs[i + r->resolved_addrs->naddrs].len = - addresses->addrs[i].len; - } - - r->resolved_addrs->naddrs += addresses->naddrs; - grpc_resolved_addresses_destroy(addresses); - - /** Wait for all addresses to be resolved */ - resolve_done = (r->resolved_num == r->resolved_total); - gpr_mu_unlock(&r->mu); - if (resolve_done) { - zookeeper_on_resolved(exec_ctx, r, r->resolved_addrs); - } -} - -/** Parses JSON format address of a zookeeper node */ -static char *zookeeper_parse_address(const char *value, size_t value_len) { - grpc_json *json; - grpc_json *cur; - const char *host; - const char *port; - char *buffer; - char *address = NULL; - - buffer = gpr_malloc(value_len); - memcpy(buffer, value, value_len); - json = grpc_json_parse_string_with_len(buffer, value_len); - if (json != NULL) { - host = NULL; - port = NULL; - for (cur = json->child; cur != NULL; cur = cur->next) { - if (!strcmp(cur->key, "host")) { - host = cur->value; - if (port != NULL) { - break; - } - } else if (!strcmp(cur->key, "port")) { - port = cur->value; - if (host != NULL) { - break; - } - } - } - if (host != NULL && port != NULL) { - gpr_asprintf(&address, "%s:%s", host, port); - } - grpc_json_destroy(json); - } - gpr_free(buffer); - - return address; -} - -static void zookeeper_get_children_node_completion(int rc, const char *value, - int value_len, - const struct Stat *stat, - const void *arg) { - char *address = NULL; - zookeeper_resolver *r = (zookeeper_resolver *)arg; - int resolve_done = 0; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - if (rc != 0) { - gpr_log(GPR_ERROR, "Error in getting a child node of %s", r->name); - grpc_exec_ctx_finish(&exec_ctx); - return; - } - - address = zookeeper_parse_address(value, (size_t)value_len); - if (address != NULL) { - /** Further resolves address by DNS */ - grpc_resolve_address(address, NULL, zookeeper_dns_resolved, r); - gpr_free(address); - } else { - gpr_log(GPR_ERROR, "Error in resolving a child node of %s", r->name); - gpr_mu_lock(&r->mu); - r->resolved_total--; - resolve_done = (r->resolved_num == r->resolved_total); - gpr_mu_unlock(&r->mu); - if (resolve_done) { - zookeeper_on_resolved(&exec_ctx, r, r->resolved_addrs); - } - } - - grpc_exec_ctx_finish(&exec_ctx); -} - -static void zookeeper_get_children_completion( - int rc, const struct String_vector *children, const void *arg) { - char *path; - int status; - int i; - zookeeper_resolver *r = (zookeeper_resolver *)arg; - - if (rc != 0) { - gpr_log(GPR_ERROR, "Error in getting zookeeper children of %s", r->name); - return; - } - - if (children->count == 0) { - gpr_log(GPR_ERROR, "Error in resolving zookeeper address %s", r->name); - return; - } - - r->resolved_addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); - r->resolved_addrs->addrs = NULL; - r->resolved_addrs->naddrs = 0; - r->resolved_total = children->count; - - /** TODO: Replace expensive heap allocation with stack - if we can get maximum length of zookeeper path */ - for (i = 0; i < children->count; i++) { - gpr_asprintf(&path, "%s/%s", r->name, children->data[i]); - status = zoo_awget(r->zookeeper_handle, path, zookeeper_watcher, r, - zookeeper_get_children_node_completion, r); - gpr_free(path); - if (status != 0) { - gpr_log(GPR_ERROR, "Error in getting zookeeper node %s", path); - } - } -} - -static void zookeeper_get_node_completion(int rc, const char *value, - int value_len, - const struct Stat *stat, - const void *arg) { - int status; - char *address = NULL; - zookeeper_resolver *r = (zookeeper_resolver *)arg; - r->resolved_addrs = NULL; - r->resolved_total = 0; - r->resolved_num = 0; - - if (rc != 0) { - gpr_log(GPR_ERROR, "Error in getting zookeeper node %s", r->name); - return; - } - - /** If zookeeper node of path r->name does not have address - (i.e. service node), get its children */ - address = zookeeper_parse_address(value, (size_t)value_len); - if (address != NULL) { - r->resolved_addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); - r->resolved_addrs->addrs = NULL; - r->resolved_addrs->naddrs = 0; - r->resolved_total = 1; - /** Further resolves address by DNS */ - grpc_resolve_address(address, NULL, zookeeper_dns_resolved, r); - gpr_free(address); - return; - } - - status = zoo_awget_children(r->zookeeper_handle, r->name, zookeeper_watcher, - r, zookeeper_get_children_completion, r); - if (status != 0) { - gpr_log(GPR_ERROR, "Error in getting zookeeper children of %s", r->name); - } -} - -static void zookeeper_resolve_address(zookeeper_resolver *r) { - int status; - status = zoo_awget(r->zookeeper_handle, r->name, zookeeper_watcher, r, - zookeeper_get_node_completion, r); - if (status != 0) { - gpr_log(GPR_ERROR, "Error in getting zookeeper node %s", r->name); - } -} - -static void zookeeper_start_resolving_locked(zookeeper_resolver *r) { - GRPC_RESOLVER_REF(&r->base, "zookeeper-resolving"); - GPR_ASSERT(r->resolving == 0); - r->resolving = 1; - zookeeper_resolve_address(r); -} - -static void zookeeper_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, - zookeeper_resolver *r) { - if (r->next_completion != NULL && - r->resolved_version != r->published_version) { - *r->target_config = r->resolved_config; - if (r->resolved_config != NULL) { - grpc_client_config_ref(r->resolved_config); - } - grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL); - r->next_completion = NULL; - r->published_version = r->resolved_version; - } -} - -static void zookeeper_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) { - zookeeper_resolver *r = (zookeeper_resolver *)gr; - gpr_mu_destroy(&r->mu); - if (r->resolved_config != NULL) { - grpc_client_config_unref(exec_ctx, r->resolved_config); - } - grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory); - gpr_free(r->name); - gpr_free(r->lb_policy_name); - gpr_free(r); -} - -static grpc_resolver *zookeeper_create(grpc_resolver_args *args, - const char *lb_policy_name) { - zookeeper_resolver *r; - size_t length; - char *path = args->uri->path; - - if (0 == strcmp(args->uri->authority, "")) { - gpr_log(GPR_ERROR, "No authority specified in zookeeper uri"); - return NULL; - } - - /** Removes the trailing slash if exists */ - length = strlen(path); - if (length > 1 && path[length - 1] == '/') { - path[length - 1] = 0; - } - - r = gpr_malloc(sizeof(zookeeper_resolver)); - memset(r, 0, sizeof(*r)); - gpr_ref_init(&r->refs, 1); - gpr_mu_init(&r->mu); - grpc_resolver_init(&r->base, &zookeeper_resolver_vtable); - r->name = gpr_strdup(path); - - r->subchannel_factory = args->subchannel_factory; - grpc_subchannel_factory_ref(r->subchannel_factory); - - r->lb_policy_name = gpr_strdup(lb_policy_name); - - /** Initializes zookeeper client */ - zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); - r->zookeeper_handle = - zookeeper_init(args->uri->authority, zookeeper_global_watcher, - GRPC_ZOOKEEPER_SESSION_TIMEOUT, 0, 0, 0); - if (r->zookeeper_handle == NULL) { - gpr_log(GPR_ERROR, "Unable to connect to zookeeper server"); - return NULL; - } - - return &r->base; -} - -static void zookeeper_plugin_init() { - grpc_register_resolver_type(grpc_zookeeper_resolver_factory_create()); -} - -void grpc_zookeeper_register() { - GRPC_API_TRACE("grpc_zookeeper_register(void)", 0, ()); - grpc_register_plugin(zookeeper_plugin_init, NULL); -} - -/* - * FACTORY - */ - -static void zookeeper_factory_ref(grpc_resolver_factory *factory) {} - -static void zookeeper_factory_unref(grpc_resolver_factory *factory) {} - -static char *zookeeper_factory_get_default_hostname( - grpc_resolver_factory *factory, grpc_uri *uri) { - return NULL; -} - -static grpc_resolver *zookeeper_factory_create_resolver( - grpc_resolver_factory *factory, grpc_resolver_args *args) { - return zookeeper_create(args, "pick_first"); -} - -static const grpc_resolver_factory_vtable zookeeper_factory_vtable = { - zookeeper_factory_ref, zookeeper_factory_unref, - zookeeper_factory_create_resolver, zookeeper_factory_get_default_hostname, - "zookeeper"}; - -static grpc_resolver_factory zookeeper_resolver_factory = { - &zookeeper_factory_vtable}; - -grpc_resolver_factory *grpc_zookeeper_resolver_factory_create() { - return &zookeeper_resolver_factory; -} diff --git a/src/core/client_config/resolvers/zookeeper_resolver.h b/src/core/client_config/resolvers/zookeeper_resolver.h deleted file mode 100644 index 04bd3ca875..0000000000 --- a/src/core/client_config/resolvers/zookeeper_resolver.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H -#define GRPC_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H - -#include "src/core/client_config/resolver_factory.h" - -/** Create a zookeeper resolver factory */ -grpc_resolver_factory *grpc_zookeeper_resolver_factory_create(void); - -#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H */ diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c deleted file mode 100644 index c5cd504929..0000000000 --- a/src/core/client_config/subchannel.c +++ /dev/null @@ -1,678 +0,0 @@ -/* - * - * Copyright 2015-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/client_config/subchannel.h" - -#include - -#include -#include - -#include "src/core/channel/channel_args.h" -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/client_config/initial_connect_string.h" -#include "src/core/client_config/subchannel_index.h" -#include "src/core/iomgr/timer.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/backoff.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/channel_init.h" -#include "src/core/transport/connectivity_state.h" - -#define INTERNAL_REF_BITS 16 -#define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1)) - -#define GRPC_SUBCHANNEL_MIN_CONNECT_TIMEOUT_SECONDS 20 -#define GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS 1 -#define GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER 1.6 -#define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120 -#define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2 - -#define GET_CONNECTED_SUBCHANNEL(subchannel, barrier) \ - ((grpc_connected_subchannel *)(gpr_atm_##barrier##_load( \ - &(subchannel)->connected_subchannel))) - -typedef struct { - grpc_closure closure; - grpc_subchannel *subchannel; - grpc_connectivity_state connectivity_state; -} state_watcher; - -typedef struct external_state_watcher { - grpc_subchannel *subchannel; - grpc_pollset_set *pollset_set; - grpc_closure *notify; - grpc_closure closure; - struct external_state_watcher *next; - struct external_state_watcher *prev; -} external_state_watcher; - -struct grpc_subchannel { - grpc_connector *connector; - - /** refcount - - lower INTERNAL_REF_BITS bits are for internal references: - these do not keep the subchannel open. - - upper remaining bits are for public references: these do - keep the subchannel open */ - gpr_atm ref_pair; - - /** non-transport related channel filters */ - const grpc_channel_filter **filters; - size_t num_filters; - /** channel arguments */ - grpc_channel_args *args; - /** address to connect to */ - struct sockaddr *addr; - size_t addr_len; - - grpc_subchannel_key *key; - - /** initial string to send to peer */ - gpr_slice initial_connect_string; - - /** set during connection */ - grpc_connect_out_args connecting_result; - - /** callback for connection finishing */ - grpc_closure connected; - - /** pollset_set tracking who's interested in a connection - being setup */ - grpc_pollset_set *pollset_set; - - /** active connection, or null; of type grpc_connected_subchannel */ - gpr_atm connected_subchannel; - - /** mutex protecting remaining elements */ - gpr_mu mu; - - /** have we seen a disconnection? */ - int disconnected; - /** are we connecting */ - int connecting; - /** connectivity state tracking */ - grpc_connectivity_state_tracker state_tracker; - - external_state_watcher root_external_state_watcher; - - /** next connect attempt time */ - gpr_timespec next_attempt; - /** backoff state */ - gpr_backoff backoff_state; - /** do we have an active alarm? */ - int have_alarm; - /** our alarm */ - grpc_timer alarm; - /** current random value */ - uint32_t random; -}; - -struct grpc_subchannel_call { - grpc_connected_subchannel *connection; -}; - -#define SUBCHANNEL_CALL_TO_CALL_STACK(call) ((grpc_call_stack *)((call) + 1)) -#define CHANNEL_STACK_FROM_CONNECTION(con) ((grpc_channel_stack *)(con)) -#define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \ - (((grpc_subchannel_call *)(callstack)) - 1) - -static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *subchannel, - bool iomgr_success); - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -#define REF_REASON reason -#define REF_LOG(name, p) \ - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%s: %p ref %d -> %d %s", \ - (name), (p), (p)->refs.count, (p)->refs.count + 1, reason) -#define UNREF_LOG(name, p) \ - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%s: %p unref %d -> %d %s", \ - (name), (p), (p)->refs.count, (p)->refs.count - 1, reason) -#define REF_MUTATE_EXTRA_ARGS \ - GRPC_SUBCHANNEL_REF_EXTRA_ARGS, const char *purpose -#define REF_MUTATE_PURPOSE(x) , file, line, reason, x -#else -#define REF_REASON "" -#define REF_LOG(name, p) \ - do { \ - } while (0) -#define UNREF_LOG(name, p) \ - do { \ - } while (0) -#define REF_MUTATE_EXTRA_ARGS -#define REF_MUTATE_PURPOSE(x) -#endif - -/* - * connection implementation - */ - -static void connection_destroy(grpc_exec_ctx *exec_ctx, void *arg, - bool success) { - grpc_connected_subchannel *c = arg; - grpc_channel_stack_destroy(exec_ctx, CHANNEL_STACK_FROM_CONNECTION(c)); - gpr_free(c); -} - -void grpc_connected_subchannel_ref( - grpc_connected_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - GRPC_CHANNEL_STACK_REF(CHANNEL_STACK_FROM_CONNECTION(c), REF_REASON); -} - -void grpc_connected_subchannel_unref(grpc_exec_ctx *exec_ctx, - grpc_connected_subchannel *c - GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - GRPC_CHANNEL_STACK_UNREF(exec_ctx, CHANNEL_STACK_FROM_CONNECTION(c), - REF_REASON); -} - -/* - * grpc_subchannel implementation - */ - -static void subchannel_destroy(grpc_exec_ctx *exec_ctx, void *arg, - bool success) { - grpc_subchannel *c = arg; - gpr_free((void *)c->filters); - grpc_channel_args_destroy(c->args); - gpr_free(c->addr); - gpr_slice_unref(c->initial_connect_string); - grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker); - grpc_connector_unref(exec_ctx, c->connector); - grpc_pollset_set_destroy(c->pollset_set); - grpc_subchannel_key_destroy(exec_ctx, c->key); - gpr_free(c); -} - -static gpr_atm ref_mutate(grpc_subchannel *c, gpr_atm delta, - int barrier REF_MUTATE_EXTRA_ARGS) { - gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta) - : gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta); -#ifdef GRPC_STREAM_REFCOUNT_DEBUG - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SUBCHANNEL: %p % 12s 0x%08x -> 0x%08x [%s]", c, purpose, old_val, - old_val + delta, reason); -#endif - return old_val; -} - -grpc_subchannel *grpc_subchannel_ref( - grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, (1 << INTERNAL_REF_BITS), - 0 REF_MUTATE_PURPOSE("STRONG_REF")); - GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0); - return c; -} - -grpc_subchannel *grpc_subchannel_weak_ref( - grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, 1, 0 REF_MUTATE_PURPOSE("WEAK_REF")); - GPR_ASSERT(old_refs != 0); - return c; -} - -grpc_subchannel *grpc_subchannel_ref_from_weak_ref( - grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - if (!c) return NULL; - for (;;) { - gpr_atm old_refs = gpr_atm_acq_load(&c->ref_pair); - if (old_refs >= (1 << INTERNAL_REF_BITS)) { - gpr_atm new_refs = old_refs + (1 << INTERNAL_REF_BITS); - if (gpr_atm_rel_cas(&c->ref_pair, old_refs, new_refs)) { - return c; - } - } else { - return NULL; - } - } -} - -static void disconnect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) { - grpc_connected_subchannel *con; - grpc_subchannel_index_unregister(exec_ctx, c->key, c); - gpr_mu_lock(&c->mu); - GPR_ASSERT(!c->disconnected); - c->disconnected = 1; - grpc_connector_shutdown(exec_ctx, c->connector); - con = GET_CONNECTED_SUBCHANNEL(c, no_barrier); - if (con != NULL) { - GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, con, "connection"); - gpr_atm_no_barrier_store(&c->connected_subchannel, 0xdeadbeef); - } - gpr_mu_unlock(&c->mu); -} - -void grpc_subchannel_unref(grpc_exec_ctx *exec_ctx, - grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, (gpr_atm)1 - (gpr_atm)(1 << INTERNAL_REF_BITS), - 1 REF_MUTATE_PURPOSE("STRONG_UNREF")); - if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) { - disconnect(exec_ctx, c); - } - GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "strong-unref"); -} - -void grpc_subchannel_weak_unref(grpc_exec_ctx *exec_ctx, - grpc_subchannel *c - GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, -(gpr_atm)1, 1 REF_MUTATE_PURPOSE("WEAK_UNREF")); - if (old_refs == 1) { - grpc_exec_ctx_enqueue(exec_ctx, grpc_closure_create(subchannel_destroy, c), - true, NULL); - } -} - -static uint32_t random_seed() { - return (uint32_t)(gpr_time_to_millis(gpr_now(GPR_CLOCK_MONOTONIC))); -} - -grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx, - grpc_connector *connector, - grpc_subchannel_args *args) { - grpc_subchannel_key *key = grpc_subchannel_key_create(connector, args); - grpc_subchannel *c = grpc_subchannel_index_find(exec_ctx, key); - if (c) { - grpc_subchannel_key_destroy(exec_ctx, key); - return c; - } - - c = gpr_malloc(sizeof(*c)); - memset(c, 0, sizeof(*c)); - c->key = key; - gpr_atm_no_barrier_store(&c->ref_pair, 1 << INTERNAL_REF_BITS); - c->connector = connector; - grpc_connector_ref(c->connector); - c->num_filters = args->filter_count; - if (c->num_filters > 0) { - c->filters = gpr_malloc(sizeof(grpc_channel_filter *) * c->num_filters); - memcpy((void *)c->filters, args->filters, - sizeof(grpc_channel_filter *) * c->num_filters); - } else { - c->filters = NULL; - } - c->addr = gpr_malloc(args->addr_len); - memcpy(c->addr, args->addr, args->addr_len); - c->pollset_set = grpc_pollset_set_create(); - c->addr_len = args->addr_len; - grpc_set_initial_connect_string(&c->addr, &c->addr_len, - &c->initial_connect_string); - c->args = grpc_channel_args_copy(args->args); - c->random = random_seed(); - c->root_external_state_watcher.next = c->root_external_state_watcher.prev = - &c->root_external_state_watcher; - grpc_closure_init(&c->connected, subchannel_connected, c); - grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE, - "subchannel"); - gpr_backoff_init(&c->backoff_state, - GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER, - GRPC_SUBCHANNEL_RECONNECT_JITTER, - GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000, - GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS * 1000); - if (c->args) { - for (size_t i = 0; i < c->args->num_args; i++) { - if (0 == strcmp(c->args->args[i].key, - "grpc.testing.fixed_reconnect_backoff")) { - GPR_ASSERT(c->args->args[i].type == GRPC_ARG_INTEGER); - gpr_backoff_init(&c->backoff_state, 1.0, 0.0, - c->args->args[i].value.integer, - c->args->args[i].value.integer); - } - } - } - gpr_mu_init(&c->mu); - - return grpc_subchannel_index_register(exec_ctx, key, c); -} - -static void continue_connect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) { - grpc_connect_in_args args; - - args.interested_parties = c->pollset_set; - args.addr = c->addr; - args.addr_len = c->addr_len; - args.deadline = c->next_attempt; - args.channel_args = c->args; - args.initial_connect_string = c->initial_connect_string; - - grpc_connectivity_state_set(exec_ctx, &c->state_tracker, - GRPC_CHANNEL_CONNECTING, "state_change"); - grpc_connector_connect(exec_ctx, c->connector, &args, &c->connecting_result, - &c->connected); -} - -static void start_connect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) { - c->next_attempt = - gpr_backoff_begin(&c->backoff_state, gpr_now(GPR_CLOCK_MONOTONIC)); - continue_connect(exec_ctx, c); -} - -grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel *c) { - grpc_connectivity_state state; - gpr_mu_lock(&c->mu); - state = grpc_connectivity_state_check(&c->state_tracker); - gpr_mu_unlock(&c->mu); - return state; -} - -static void on_external_state_watcher_done(grpc_exec_ctx *exec_ctx, void *arg, - bool success) { - external_state_watcher *w = arg; - grpc_closure *follow_up = w->notify; - if (w->pollset_set != NULL) { - grpc_pollset_set_del_pollset_set(exec_ctx, w->subchannel->pollset_set, - w->pollset_set); - } - gpr_mu_lock(&w->subchannel->mu); - w->next->prev = w->prev; - w->prev->next = w->next; - gpr_mu_unlock(&w->subchannel->mu); - GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, w->subchannel, "external_state_watcher"); - gpr_free(w); - follow_up->cb(exec_ctx, follow_up->cb_arg, success); -} - -void grpc_subchannel_notify_on_state_change( - grpc_exec_ctx *exec_ctx, grpc_subchannel *c, - grpc_pollset_set *interested_parties, grpc_connectivity_state *state, - grpc_closure *notify) { - external_state_watcher *w; - - if (state == NULL) { - gpr_mu_lock(&c->mu); - for (w = c->root_external_state_watcher.next; - w != &c->root_external_state_watcher; w = w->next) { - if (w->notify == notify) { - grpc_connectivity_state_notify_on_state_change( - exec_ctx, &c->state_tracker, NULL, &w->closure); - } - } - gpr_mu_unlock(&c->mu); - } else { - w = gpr_malloc(sizeof(*w)); - w->subchannel = c; - w->pollset_set = interested_parties; - w->notify = notify; - grpc_closure_init(&w->closure, on_external_state_watcher_done, w); - if (interested_parties != NULL) { - grpc_pollset_set_add_pollset_set(exec_ctx, c->pollset_set, - interested_parties); - } - GRPC_SUBCHANNEL_WEAK_REF(c, "external_state_watcher"); - gpr_mu_lock(&c->mu); - w->next = &c->root_external_state_watcher; - w->prev = w->next->prev; - w->next->prev = w->prev->next = w; - if (grpc_connectivity_state_notify_on_state_change( - exec_ctx, &c->state_tracker, state, &w->closure)) { - c->connecting = 1; - /* released by connection */ - GRPC_SUBCHANNEL_WEAK_REF(c, "connecting"); - start_connect(exec_ctx, c); - } - gpr_mu_unlock(&c->mu); - } -} - -void grpc_connected_subchannel_process_transport_op( - grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con, - grpc_transport_op *op) { - grpc_channel_stack *channel_stack = CHANNEL_STACK_FROM_CONNECTION(con); - grpc_channel_element *top_elem = grpc_channel_stack_element(channel_stack, 0); - top_elem->filter->start_transport_op(exec_ctx, top_elem, op); -} - -static void subchannel_on_child_state_changed(grpc_exec_ctx *exec_ctx, void *p, - bool iomgr_success) { - state_watcher *sw = p; - grpc_subchannel *c = sw->subchannel; - gpr_mu *mu = &c->mu; - - gpr_mu_lock(mu); - - /* if we failed just leave this closure */ - if (iomgr_success) { - if (sw->connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { - /* any errors on a subchannel ==> we're done, create a new one */ - sw->connectivity_state = GRPC_CHANNEL_FATAL_FAILURE; - } - grpc_connectivity_state_set(exec_ctx, &c->state_tracker, - sw->connectivity_state, "reflect_child"); - if (sw->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) { - grpc_connected_subchannel_notify_on_state_change( - exec_ctx, GET_CONNECTED_SUBCHANNEL(c, no_barrier), NULL, - &sw->connectivity_state, &sw->closure); - GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher"); - sw = NULL; - } - } - - gpr_mu_unlock(mu); - GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "state_watcher"); - gpr_free(sw); -} - -static void connected_subchannel_state_op(grpc_exec_ctx *exec_ctx, - grpc_connected_subchannel *con, - grpc_pollset_set *interested_parties, - grpc_connectivity_state *state, - grpc_closure *closure) { - grpc_transport_op op; - grpc_channel_element *elem; - memset(&op, 0, sizeof(op)); - op.connectivity_state = state; - op.on_connectivity_state_change = closure; - op.bind_pollset_set = interested_parties; - elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(con), 0); - elem->filter->start_transport_op(exec_ctx, elem, &op); -} - -void grpc_connected_subchannel_notify_on_state_change( - grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con, - grpc_pollset_set *interested_parties, grpc_connectivity_state *state, - grpc_closure *closure) { - connected_subchannel_state_op(exec_ctx, con, interested_parties, state, - closure); -} - -void grpc_connected_subchannel_ping(grpc_exec_ctx *exec_ctx, - grpc_connected_subchannel *con, - grpc_closure *closure) { - grpc_transport_op op; - grpc_channel_element *elem; - memset(&op, 0, sizeof(op)); - op.send_ping = closure; - elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(con), 0); - elem->filter->start_transport_op(exec_ctx, elem, &op); -} - -static void publish_transport_locked(grpc_exec_ctx *exec_ctx, - grpc_subchannel *c) { - grpc_connected_subchannel *con; - grpc_channel_stack *stk; - state_watcher *sw_subchannel; - - /* construct channel stack */ - con = grpc_channel_init_create_stack( - exec_ctx, GRPC_CLIENT_SUBCHANNEL, 0, c->connecting_result.channel_args, 1, - connection_destroy, NULL, c->connecting_result.transport); - stk = CHANNEL_STACK_FROM_CONNECTION(con); - memset(&c->connecting_result, 0, sizeof(c->connecting_result)); - - /* initialize state watcher */ - sw_subchannel = gpr_malloc(sizeof(*sw_subchannel)); - sw_subchannel->subchannel = c; - sw_subchannel->connectivity_state = GRPC_CHANNEL_READY; - grpc_closure_init(&sw_subchannel->closure, subchannel_on_child_state_changed, - sw_subchannel); - - if (c->disconnected) { - gpr_free(sw_subchannel); - grpc_channel_stack_destroy(exec_ctx, stk); - gpr_free(con); - GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting"); - return; - } - - /* publish */ - /* TODO(ctiller): this full barrier seems to clear up a TSAN failure. - I'd have expected the rel_cas below to be enough, but - seemingly it's not. - Re-evaluate if we really need this. */ - gpr_atm_full_barrier(); - GPR_ASSERT(gpr_atm_rel_cas(&c->connected_subchannel, 0, (gpr_atm)con)); - c->connecting = 0; - - /* setup subchannel watching connected subchannel for changes; subchannel ref - for connecting is donated - to the state watcher */ - GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher"); - GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting"); - grpc_connected_subchannel_notify_on_state_change( - exec_ctx, con, c->pollset_set, &sw_subchannel->connectivity_state, - &sw_subchannel->closure); - - /* signal completion */ - grpc_connectivity_state_set(exec_ctx, &c->state_tracker, GRPC_CHANNEL_READY, - "connected"); -} - -static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, bool iomgr_success) { - grpc_subchannel *c = arg; - gpr_mu_lock(&c->mu); - c->have_alarm = 0; - if (c->disconnected) { - iomgr_success = 0; - } - if (iomgr_success) { - c->next_attempt = - gpr_backoff_step(&c->backoff_state, gpr_now(GPR_CLOCK_MONOTONIC)); - continue_connect(exec_ctx, c); - gpr_mu_unlock(&c->mu); - } else { - gpr_mu_unlock(&c->mu); - GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting"); - } -} - -static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_success) { - grpc_subchannel *c = arg; - - GRPC_SUBCHANNEL_WEAK_REF(c, "connected"); - gpr_mu_lock(&c->mu); - if (c->connecting_result.transport != NULL) { - publish_transport_locked(exec_ctx, c); - } else if (c->disconnected) { - GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting"); - } else { - gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); - GPR_ASSERT(!c->have_alarm); - c->have_alarm = 1; - grpc_connectivity_state_set(exec_ctx, &c->state_tracker, - GRPC_CHANNEL_TRANSIENT_FAILURE, - "connect_failed"); - grpc_timer_init(exec_ctx, &c->alarm, c->next_attempt, on_alarm, c, now); - } - gpr_mu_unlock(&c->mu); - GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting"); -} - -/* - * grpc_subchannel_call implementation - */ - -static void subchannel_call_destroy(grpc_exec_ctx *exec_ctx, void *call, - bool success) { - grpc_subchannel_call *c = call; - GPR_TIMER_BEGIN("grpc_subchannel_call_unref.destroy", 0); - grpc_call_stack_destroy(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c)); - GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, c->connection, "subchannel_call"); - gpr_free(c); - GPR_TIMER_END("grpc_subchannel_call_unref.destroy", 0); -} - -void grpc_subchannel_call_ref( - grpc_subchannel_call *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); -} - -void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call *c - GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - GRPC_CALL_STACK_UNREF(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); -} - -char *grpc_subchannel_call_get_peer(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call *call) { - grpc_call_stack *call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call); - grpc_call_element *top_elem = grpc_call_stack_element(call_stack, 0); - return top_elem->filter->get_peer(exec_ctx, top_elem); -} - -void grpc_subchannel_call_process_op(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call *call, - grpc_transport_stream_op *op) { - grpc_call_stack *call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call); - grpc_call_element *top_elem = grpc_call_stack_element(call_stack, 0); - top_elem->filter->start_transport_stream_op(exec_ctx, top_elem, op); -} - -grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel( - grpc_subchannel *c) { - return GET_CONNECTED_SUBCHANNEL(c, acq); -} - -grpc_subchannel_call *grpc_connected_subchannel_create_call( - grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con, - grpc_pollset *pollset) { - grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con); - grpc_subchannel_call *call = - gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size); - grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call); - call->connection = con; - GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call"); - grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, call, - NULL, NULL, callstk); - grpc_call_stack_set_pollset(exec_ctx, callstk, pollset); - return call; -} - -grpc_call_stack *grpc_subchannel_call_get_call_stack( - grpc_subchannel_call *subchannel_call) { - return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call); -} diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h deleted file mode 100644 index 83e1c58a4c..0000000000 --- a/src/core/client_config/subchannel.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_SUBCHANNEL_H -#define GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_H - -#include "src/core/channel/channel_stack.h" -#include "src/core/client_config/connector.h" -#include "src/core/transport/connectivity_state.h" - -/** A (sub-)channel that knows how to connect to exactly one target - address. Provides a target for load balancing. */ -typedef struct grpc_subchannel grpc_subchannel; -typedef struct grpc_connected_subchannel grpc_connected_subchannel; -typedef struct grpc_subchannel_call grpc_subchannel_call; -typedef struct grpc_subchannel_args grpc_subchannel_args; - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -#define GRPC_SUBCHANNEL_REF(p, r) \ - grpc_subchannel_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ - grpc_subchannel_ref_from_weak_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_UNREF(cl, p, r) \ - grpc_subchannel_unref((cl), (p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_WEAK_REF(p, r) \ - grpc_subchannel_weak_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_WEAK_UNREF(cl, p, r) \ - grpc_subchannel_weak_unref((cl), (p), __FILE__, __LINE__, (r)) -#define GRPC_CONNECTED_SUBCHANNEL_REF(p, r) \ - grpc_connected_subchannel_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_CONNECTED_SUBCHANNEL_UNREF(cl, p, r) \ - grpc_connected_subchannel_unref((cl), (p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_CALL_REF(p, r) \ - grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_CALL_UNREF(cl, p, r) \ - grpc_subchannel_call_unref((cl), (p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_REF_EXTRA_ARGS \ - , const char *file, int line, const char *reason -#else -#define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p)) -#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ - grpc_subchannel_ref_from_weak_ref((p)) -#define GRPC_SUBCHANNEL_UNREF(cl, p, r) grpc_subchannel_unref((cl), (p)) -#define GRPC_SUBCHANNEL_WEAK_REF(p, r) grpc_subchannel_weak_ref((p)) -#define GRPC_SUBCHANNEL_WEAK_UNREF(cl, p, r) \ - grpc_subchannel_weak_unref((cl), (p)) -#define GRPC_CONNECTED_SUBCHANNEL_REF(p, r) grpc_connected_subchannel_ref((p)) -#define GRPC_CONNECTED_SUBCHANNEL_UNREF(cl, p, r) \ - grpc_connected_subchannel_unref((cl), (p)) -#define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p)) -#define GRPC_SUBCHANNEL_CALL_UNREF(cl, p, r) \ - grpc_subchannel_call_unref((cl), (p)) -#define GRPC_SUBCHANNEL_REF_EXTRA_ARGS -#endif - -grpc_subchannel *grpc_subchannel_ref( - grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -grpc_subchannel *grpc_subchannel_ref_from_weak_ref( - grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_unref(grpc_exec_ctx *exec_ctx, - grpc_subchannel *channel - GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -grpc_subchannel *grpc_subchannel_weak_ref( - grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_weak_unref(grpc_exec_ctx *exec_ctx, - grpc_subchannel *channel - GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_connected_subchannel_ref( - grpc_connected_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_connected_subchannel_unref(grpc_exec_ctx *exec_ctx, - grpc_connected_subchannel *channel - GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_call_ref( - grpc_subchannel_call *call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call *call - GRPC_SUBCHANNEL_REF_EXTRA_ARGS); - -/** construct a subchannel call */ -grpc_subchannel_call *grpc_connected_subchannel_create_call( - grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel, - grpc_pollset *pollset); - -/** process a transport level op */ -void grpc_connected_subchannel_process_transport_op( - grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *subchannel, - grpc_transport_op *op); - -/** poll the current connectivity state of a channel */ -grpc_connectivity_state grpc_subchannel_check_connectivity( - grpc_subchannel *channel); - -/** call notify when the connectivity state of a channel changes from *state. - Updates *state with the new state of the channel */ -void grpc_subchannel_notify_on_state_change( - grpc_exec_ctx *exec_ctx, grpc_subchannel *channel, - grpc_pollset_set *interested_parties, grpc_connectivity_state *state, - grpc_closure *notify); -void grpc_connected_subchannel_notify_on_state_change( - grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *channel, - grpc_pollset_set *interested_parties, grpc_connectivity_state *state, - grpc_closure *notify); -void grpc_connected_subchannel_ping(grpc_exec_ctx *exec_ctx, - grpc_connected_subchannel *channel, - grpc_closure *notify); - -/** retrieve the grpc_connected_subchannel - or NULL if called before - the subchannel becomes connected */ -grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel( - grpc_subchannel *subchannel); - -/** continue processing a transport op */ -void grpc_subchannel_call_process_op(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call *subchannel_call, - grpc_transport_stream_op *op); - -/** continue querying for peer */ -char *grpc_subchannel_call_get_peer(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call *subchannel_call); - -grpc_call_stack *grpc_subchannel_call_get_call_stack( - grpc_subchannel_call *subchannel_call); - -struct grpc_subchannel_args { - /* When updating this struct, also update subchannel_index.c */ - - /** Channel filters for this channel - wrapped factories will likely - want to mutate this */ - const grpc_channel_filter **filters; - /** The number of filters in the above array */ - size_t filter_count; - /** Channel arguments to be supplied to the newly created channel */ - const grpc_channel_args *args; - /** Address to connect to */ - struct sockaddr *addr; - size_t addr_len; -}; - -/** create a subchannel given a connector */ -grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx, - grpc_connector *connector, - grpc_subchannel_args *args); - -#endif /* GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_H */ diff --git a/src/core/client_config/subchannel_factory.c b/src/core/client_config/subchannel_factory.c deleted file mode 100644 index 2c64219e8b..0000000000 --- a/src/core/client_config/subchannel_factory.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright 2015, 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/client_config/subchannel_factory.h" - -void grpc_subchannel_factory_ref(grpc_subchannel_factory* factory) { - factory->vtable->ref(factory); -} - -void grpc_subchannel_factory_unref(grpc_exec_ctx* exec_ctx, - grpc_subchannel_factory* factory) { - factory->vtable->unref(exec_ctx, factory); -} - -grpc_subchannel* grpc_subchannel_factory_create_subchannel( - grpc_exec_ctx* exec_ctx, grpc_subchannel_factory* factory, - grpc_subchannel_args* args) { - return factory->vtable->create_subchannel(exec_ctx, factory, args); -} diff --git a/src/core/client_config/subchannel_factory.h b/src/core/client_config/subchannel_factory.h deleted file mode 100644 index c638f377a6..0000000000 --- a/src/core/client_config/subchannel_factory.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H -#define GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H - -#include "src/core/channel/channel_stack.h" -#include "src/core/client_config/subchannel.h" - -typedef struct grpc_subchannel_factory grpc_subchannel_factory; -typedef struct grpc_subchannel_factory_vtable grpc_subchannel_factory_vtable; - -/** Constructor for new configured channels. - Creating decorators around this type is encouraged to adapt behavior. */ -struct grpc_subchannel_factory { - const grpc_subchannel_factory_vtable *vtable; -}; - -struct grpc_subchannel_factory_vtable { - void (*ref)(grpc_subchannel_factory *factory); - void (*unref)(grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory); - grpc_subchannel *(*create_subchannel)(grpc_exec_ctx *exec_ctx, - grpc_subchannel_factory *factory, - grpc_subchannel_args *args); -}; - -void grpc_subchannel_factory_ref(grpc_subchannel_factory *factory); -void grpc_subchannel_factory_unref(grpc_exec_ctx *exec_ctx, - grpc_subchannel_factory *factory); - -/** Create a new grpc_subchannel */ -grpc_subchannel *grpc_subchannel_factory_create_subchannel( - grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory, - grpc_subchannel_args *args); - -#endif /* GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H */ diff --git a/src/core/client_config/subchannel_index.c b/src/core/client_config/subchannel_index.c deleted file mode 100644 index 24cc76cf22..0000000000 --- a/src/core/client_config/subchannel_index.c +++ /dev/null @@ -1,262 +0,0 @@ -// -// -// 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/client_config/subchannel_index.h" - -#include -#include - -#include -#include -#include - -#include "src/core/channel/channel_args.h" - -// a map of subchannel_key --> subchannel, used for detecting connections -// to the same destination in order to share them -static gpr_avl g_subchannel_index; - -static gpr_mu g_mu; - -struct grpc_subchannel_key { - grpc_connector *connector; - grpc_subchannel_args args; -}; - -GPR_TLS_DECL(subchannel_index_exec_ctx); - -static void enter_ctx(grpc_exec_ctx *exec_ctx) { - GPR_ASSERT(gpr_tls_get(&subchannel_index_exec_ctx) == 0); - gpr_tls_set(&subchannel_index_exec_ctx, (intptr_t)exec_ctx); -} - -static void leave_ctx(grpc_exec_ctx *exec_ctx) { - GPR_ASSERT(gpr_tls_get(&subchannel_index_exec_ctx) == (intptr_t)exec_ctx); - gpr_tls_set(&subchannel_index_exec_ctx, 0); -} - -static grpc_exec_ctx *current_ctx() { - grpc_exec_ctx *c = (grpc_exec_ctx *)gpr_tls_get(&subchannel_index_exec_ctx); - GPR_ASSERT(c != NULL); - return c; -} - -static grpc_subchannel_key *create_key( - grpc_connector *connector, grpc_subchannel_args *args, - grpc_channel_args *(*copy_channel_args)(const grpc_channel_args *args)) { - grpc_subchannel_key *k = gpr_malloc(sizeof(*k)); - k->connector = grpc_connector_ref(connector); - k->args.filter_count = args->filter_count; - k->args.filters = gpr_malloc(sizeof(*k->args.filters) * k->args.filter_count); - memcpy((grpc_channel_filter *)k->args.filters, args->filters, - sizeof(*k->args.filters) * k->args.filter_count); - k->args.addr_len = args->addr_len; - k->args.addr = gpr_malloc(args->addr_len); - memcpy(k->args.addr, args->addr, k->args.addr_len); - k->args.args = copy_channel_args(args->args); - return k; -} - -grpc_subchannel_key *grpc_subchannel_key_create(grpc_connector *connector, - grpc_subchannel_args *args) { - return create_key(connector, args, grpc_channel_args_normalize); -} - -static grpc_subchannel_key *subchannel_key_copy(grpc_subchannel_key *k) { - return create_key(k->connector, &k->args, grpc_channel_args_copy); -} - -static int subchannel_key_compare(grpc_subchannel_key *a, - grpc_subchannel_key *b) { - int c = GPR_ICMP(a->connector, b->connector); - if (c != 0) return c; - c = GPR_ICMP(a->args.addr_len, b->args.addr_len); - if (c != 0) return c; - c = GPR_ICMP(a->args.filter_count, b->args.filter_count); - if (c != 0) return c; - c = memcmp(a->args.addr, b->args.addr, a->args.addr_len); - if (c != 0) return c; - c = memcmp(a->args.filters, b->args.filters, - a->args.filter_count * sizeof(*a->args.filters)); - if (c != 0) return c; - return grpc_channel_args_compare(a->args.args, b->args.args); -} - -void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx, - grpc_subchannel_key *k) { - grpc_connector_unref(exec_ctx, k->connector); - gpr_free(k->args.addr); - gpr_free((grpc_channel_args *)k->args.filters); - grpc_channel_args_destroy((grpc_channel_args *)k->args.args); - gpr_free(k); -} - -static void sck_avl_destroy(void *p) { - grpc_subchannel_key_destroy(current_ctx(), p); -} - -static void *sck_avl_copy(void *p) { return subchannel_key_copy(p); } - -static long sck_avl_compare(void *a, void *b) { - return subchannel_key_compare(a, b); -} - -static void scv_avl_destroy(void *p) { - GRPC_SUBCHANNEL_WEAK_UNREF(current_ctx(), p, "subchannel_index"); -} - -static void *scv_avl_copy(void *p) { - GRPC_SUBCHANNEL_WEAK_REF(p, "subchannel_index"); - return p; -} - -static const gpr_avl_vtable subchannel_avl_vtable = { - .destroy_key = sck_avl_destroy, - .copy_key = sck_avl_copy, - .compare_keys = sck_avl_compare, - .destroy_value = scv_avl_destroy, - .copy_value = scv_avl_copy}; - -void grpc_subchannel_index_init(void) { - g_subchannel_index = gpr_avl_create(&subchannel_avl_vtable); - gpr_mu_init(&g_mu); - gpr_tls_init(&subchannel_index_exec_ctx); -} - -void grpc_subchannel_index_shutdown(void) { - gpr_mu_destroy(&g_mu); - gpr_avl_unref(g_subchannel_index); - gpr_tls_destroy(&subchannel_index_exec_ctx); -} - -grpc_subchannel *grpc_subchannel_index_find(grpc_exec_ctx *exec_ctx, - grpc_subchannel_key *key) { - enter_ctx(exec_ctx); - - // Lock, and take a reference to the subchannel index. - // We don't need to do the search under a lock as avl's are immutable. - gpr_mu_lock(&g_mu); - gpr_avl index = gpr_avl_ref(g_subchannel_index); - gpr_mu_unlock(&g_mu); - - grpc_subchannel *c = - GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(gpr_avl_get(index, key), "index_find"); - gpr_avl_unref(index); - - leave_ctx(exec_ctx); - return c; -} - -grpc_subchannel *grpc_subchannel_index_register(grpc_exec_ctx *exec_ctx, - grpc_subchannel_key *key, - grpc_subchannel *constructed) { - enter_ctx(exec_ctx); - - grpc_subchannel *c = NULL; - - while (c == NULL) { - // Compare and swap loop: - // - take a reference to the current index - gpr_mu_lock(&g_mu); - gpr_avl index = gpr_avl_ref(g_subchannel_index); - gpr_mu_unlock(&g_mu); - - // - Check to see if a subchannel already exists - c = gpr_avl_get(index, key); - if (c != NULL) { - // yes -> we're done - GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, constructed, "index_register"); - } else { - // no -> update the avl and compare/swap - gpr_avl updated = - gpr_avl_add(gpr_avl_ref(index), subchannel_key_copy(key), - GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register")); - - // it may happen (but it's expected to be unlikely) - // that some other thread has changed the index: - // compare/swap here to check that, and retry as necessary - gpr_mu_lock(&g_mu); - if (index.root == g_subchannel_index.root) { - GPR_SWAP(gpr_avl, updated, g_subchannel_index); - c = constructed; - } - gpr_mu_unlock(&g_mu); - - gpr_avl_unref(updated); - } - gpr_avl_unref(index); - } - - leave_ctx(exec_ctx); - - return c; -} - -void grpc_subchannel_index_unregister(grpc_exec_ctx *exec_ctx, - grpc_subchannel_key *key, - grpc_subchannel *constructed) { - enter_ctx(exec_ctx); - - bool done = false; - while (!done) { - // Compare and swap loop: - // - take a reference to the current index - gpr_mu_lock(&g_mu); - gpr_avl index = gpr_avl_ref(g_subchannel_index); - gpr_mu_unlock(&g_mu); - - // Check to see if this key still refers to the previously - // registered subchannel - grpc_subchannel *c = gpr_avl_get(index, key); - if (c != constructed) { - gpr_avl_unref(index); - break; - } - - // compare and swap the update (some other thread may have - // mutated the index behind us) - gpr_avl updated = gpr_avl_remove(gpr_avl_ref(index), key); - - gpr_mu_lock(&g_mu); - if (index.root == g_subchannel_index.root) { - GPR_SWAP(gpr_avl, updated, g_subchannel_index); - done = true; - } - gpr_mu_unlock(&g_mu); - - gpr_avl_unref(updated); - gpr_avl_unref(index); - } - - leave_ctx(exec_ctx); -} diff --git a/src/core/client_config/subchannel_index.h b/src/core/client_config/subchannel_index.h deleted file mode 100644 index 3cd5d12349..0000000000 --- a/src/core/client_config/subchannel_index.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * - * 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_CLIENT_CONFIG_SUBCHANNEL_INDEX_H -#define GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H - -#include "src/core/client_config/connector.h" -#include "src/core/client_config/subchannel.h" - -/** \file Provides an index of active subchannels so that they can be - shared amongst channels */ - -typedef struct grpc_subchannel_key grpc_subchannel_key; - -/** Create a key that can be used to uniquely identify a subchannel */ -grpc_subchannel_key *grpc_subchannel_key_create(grpc_connector *con, - grpc_subchannel_args *args); - -/** Destroy a subchannel key */ -void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx, - grpc_subchannel_key *key); - -/** Given a subchannel key, find the subchannel registered for it. - Returns NULL if no such channel exists. - Thread-safe. */ -grpc_subchannel *grpc_subchannel_index_find(grpc_exec_ctx *exec_ctx, - grpc_subchannel_key *key); - -/** Register a subchannel against a key. - Takes ownership of \a constructed. - Returns the registered subchannel. This may be different from - \a constructed in the case of a registration race. */ -grpc_subchannel *grpc_subchannel_index_register(grpc_exec_ctx *exec_ctx, - grpc_subchannel_key *key, - grpc_subchannel *constructed); - -/** Remove \a constructed as the registered subchannel for \a key. */ -void grpc_subchannel_index_unregister(grpc_exec_ctx *exec_ctx, - grpc_subchannel_key *key, - grpc_subchannel *constructed); - -/** Initialize the subchannel index (global) */ -void grpc_subchannel_index_init(void); -/** Shutdown the subchannel index (global) */ -void grpc_subchannel_index_shutdown(void); - -#endif /* GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H */ diff --git a/src/core/client_config/uri_parser.c b/src/core/client_config/uri_parser.c deleted file mode 100644 index cbdfffcf8e..0000000000 --- a/src/core/client_config/uri_parser.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * - * Copyright 2015, 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/client_config/uri_parser.h" - -#include - -#include -#include -#include -#include - -/** a size_t default value... maps to all 1's */ -#define NOT_SET (~(size_t)0) - -static grpc_uri *bad_uri(const char *uri_text, size_t pos, const char *section, - int suppress_errors) { - char *line_prefix; - size_t pfx_len; - - if (!suppress_errors) { - gpr_asprintf(&line_prefix, "bad uri.%s: '", section); - pfx_len = strlen(line_prefix) + pos; - gpr_log(GPR_ERROR, "%s%s'", line_prefix, uri_text); - gpr_free(line_prefix); - - line_prefix = gpr_malloc(pfx_len + 1); - memset(line_prefix, ' ', pfx_len); - line_prefix[pfx_len] = 0; - gpr_log(GPR_ERROR, "%s^ here", line_prefix); - gpr_free(line_prefix); - } - - return NULL; -} - -/** Returns a copy of \a src[begin, end) */ -static char *copy_component(const char *src, size_t begin, size_t end) { - char *out = gpr_malloc(end - begin + 1); - memcpy(out, src + begin, end - begin); - out[end - begin] = 0; - return out; -} - -/** Returns how many chars to advance if \a uri_text[i] begins a valid \a pchar - * production. If \a uri_text[i] introduces an invalid \a pchar (such as percent - * sign not followed by two hex digits), NOT_SET is returned. */ -static size_t parse_pchar(const char *uri_text, size_t i) { - /* pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - * pct-encoded = "%" HEXDIG HEXDIG - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - / "*" / "+" / "," / ";" / "=" */ - char c = uri_text[i]; - if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || - ((c >= '0') && (c <= '9')) || - (c == '-' || c == '.' || c == '_' || c == '~') || /* unreserved */ - (c == '!' || c == '$' || c == '&' || c == '\'' || c == '$' || c == '&' || - c == '(' || c == ')' || c == '*' || c == '+' || c == ',' || c == ';' || - c == '=') /* sub-delims */) { - return 1; - } - if (c == '%') { /* pct-encoded */ - size_t j; - if (uri_text[i + 1] == 0 || uri_text[i + 2] == 0) { - return NOT_SET; - } - for (j = i + 1; j < 2; j++) { - c = uri_text[j]; - if (!(((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f')) || - ((c >= 'A') && (c <= 'F')))) { - return NOT_SET; - } - } - return 2; - } - return 0; -} - -/* *( pchar / "?" / "/" ) */ -static int parse_fragment_or_query(const char *uri_text, size_t *i) { - char c; - while ((c = uri_text[*i]) != 0) { - const size_t advance = parse_pchar(uri_text, *i); /* pchar */ - switch (advance) { - case 0: /* uri_text[i] isn't in pchar */ - /* maybe it's ? or / */ - if (uri_text[*i] == '?' || uri_text[*i] == '/') { - (*i)++; - break; - } else { - return 1; - } - GPR_UNREACHABLE_CODE(return 0); - default: - (*i) += advance; - break; - case NOT_SET: /* uri_text[i] introduces an invalid URI */ - return 0; - } - } - /* *i is the first uri_text position past the \a query production, maybe \0 */ - return 1; -} - -grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) { - grpc_uri *uri; - size_t scheme_begin = 0; - size_t scheme_end = NOT_SET; - size_t authority_begin = NOT_SET; - size_t authority_end = NOT_SET; - size_t path_begin = NOT_SET; - size_t path_end = NOT_SET; - size_t query_begin = NOT_SET; - size_t query_end = NOT_SET; - size_t fragment_begin = NOT_SET; - size_t fragment_end = NOT_SET; - size_t i; - - for (i = scheme_begin; uri_text[i] != 0; i++) { - if (uri_text[i] == ':') { - scheme_end = i; - break; - } - if (uri_text[i] >= 'a' && uri_text[i] <= 'z') continue; - if (uri_text[i] >= 'A' && uri_text[i] <= 'Z') continue; - if (i != scheme_begin) { - if (uri_text[i] >= '0' && uri_text[i] <= '9') continue; - if (uri_text[i] == '+') continue; - if (uri_text[i] == '-') continue; - if (uri_text[i] == '.') continue; - } - break; - } - if (scheme_end == NOT_SET) { - return bad_uri(uri_text, i, "scheme", suppress_errors); - } - - if (uri_text[scheme_end + 1] == '/' && uri_text[scheme_end + 2] == '/') { - authority_begin = scheme_end + 3; - for (i = authority_begin; uri_text[i] != 0 && authority_end == NOT_SET; - i++) { - if (uri_text[i] == '/' || uri_text[i] == '?' || uri_text[i] == '#') { - authority_end = i; - } - } - if (authority_end == NOT_SET && uri_text[i] == 0) { - authority_end = i; - } - if (authority_end == NOT_SET) { - return bad_uri(uri_text, i, "authority", suppress_errors); - } - /* TODO(ctiller): parse the authority correctly */ - path_begin = authority_end; - } else { - path_begin = scheme_end + 1; - } - - for (i = path_begin; uri_text[i] != 0; i++) { - if (uri_text[i] == '?' || uri_text[i] == '#') { - path_end = i; - break; - } - } - if (path_end == NOT_SET && uri_text[i] == 0) { - path_end = i; - } - if (path_end == NOT_SET) { - return bad_uri(uri_text, i, "path", suppress_errors); - } - - if (uri_text[i] == '?') { - query_begin = ++i; - if (!parse_fragment_or_query(uri_text, &i)) { - return bad_uri(uri_text, i, "query", suppress_errors); - } else if (uri_text[i] != 0 && uri_text[i] != '#') { - /* We must be at the end or at the beginning of a fragment */ - return bad_uri(uri_text, i, "query", suppress_errors); - } - query_end = i; - } - if (uri_text[i] == '#') { - fragment_begin = ++i; - if (!parse_fragment_or_query(uri_text, &i)) { - return bad_uri(uri_text, i - fragment_end, "fragment", suppress_errors); - } else if (uri_text[i] != 0) { - /* We must be at the end */ - return bad_uri(uri_text, i, "fragment", suppress_errors); - } - fragment_end = i; - } - - uri = gpr_malloc(sizeof(*uri)); - memset(uri, 0, sizeof(*uri)); - uri->scheme = copy_component(uri_text, scheme_begin, scheme_end); - uri->authority = copy_component(uri_text, authority_begin, authority_end); - uri->path = copy_component(uri_text, path_begin, path_end); - uri->query = copy_component(uri_text, query_begin, query_end); - uri->fragment = copy_component(uri_text, fragment_begin, fragment_end); - - return uri; -} - -void grpc_uri_destroy(grpc_uri *uri) { - if (!uri) return; - gpr_free(uri->scheme); - gpr_free(uri->authority); - gpr_free(uri->path); - gpr_free(uri->query); - gpr_free(uri->fragment); - gpr_free(uri); -} diff --git a/src/core/client_config/uri_parser.h b/src/core/client_config/uri_parser.h deleted file mode 100644 index af013d8cac..0000000000 --- a/src/core/client_config/uri_parser.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright 2015-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_CLIENT_CONFIG_URI_PARSER_H -#define GRPC_CORE_CLIENT_CONFIG_URI_PARSER_H - -typedef struct { - char *scheme; - char *authority; - char *path; - char *query; - char *fragment; -} grpc_uri; - -/** parse a uri, return NULL on failure */ -grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors); - -/** destroy a uri */ -void grpc_uri_destroy(grpc_uri *uri); - -#endif /* GRPC_CORE_CLIENT_CONFIG_URI_PARSER_H */ diff --git a/src/core/compression/algorithm_metadata.h b/src/core/compression/algorithm_metadata.h deleted file mode 100644 index 34abf1dba2..0000000000 --- a/src/core/compression/algorithm_metadata.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Copyright 2015-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_COMPRESSION_ALGORITHM_METADATA_H -#define GRPC_CORE_COMPRESSION_ALGORITHM_METADATA_H - -#include -#include "src/core/transport/metadata.h" - -/** Return compression algorithm based metadata value */ -grpc_mdstr *grpc_compression_algorithm_mdstr( - grpc_compression_algorithm algorithm); - -/** Return compression algorithm based metadata element (grpc-encoding: xxx) */ -grpc_mdelem *grpc_compression_encoding_mdelem( - grpc_compression_algorithm algorithm); - -/** Find compression algorithm based on passed in mdstr - returns - * GRPC_COMPRESS_ALGORITHM_COUNT on failure */ -grpc_compression_algorithm grpc_compression_algorithm_from_mdstr( - grpc_mdstr *str); - -#endif /* GRPC_CORE_COMPRESSION_ALGORITHM_METADATA_H */ diff --git a/src/core/compression/compression_algorithm.c b/src/core/compression/compression_algorithm.c deleted file mode 100644 index 2810a38b68..0000000000 --- a/src/core/compression/compression_algorithm.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * - * Copyright 2015-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 -#include - -#include -#include - -#include "src/core/compression/algorithm_metadata.h" -#include "src/core/surface/api_trace.h" -#include "src/core/transport/static_metadata.h" - -int grpc_compression_algorithm_parse(const char *name, size_t name_length, - grpc_compression_algorithm *algorithm) { - /* we use strncmp not only because it's safer (even though in this case it - * doesn't matter, given that we are comparing against string literals, but - * because this way we needn't have "name" nil-terminated (useful for slice - * data, for example) */ - GRPC_API_TRACE( - "grpc_compression_algorithm_parse(" - "name=%*.*s, name_length=%lu, algorithm=%p)", - 5, ((int)name_length, (int)name_length, name, (unsigned long)name_length, - algorithm)); - if (name_length == 0) { - return 0; - } - if (strncmp(name, "identity", name_length) == 0) { - *algorithm = GRPC_COMPRESS_NONE; - } else if (strncmp(name, "gzip", name_length) == 0) { - *algorithm = GRPC_COMPRESS_GZIP; - } else if (strncmp(name, "deflate", name_length) == 0) { - *algorithm = GRPC_COMPRESS_DEFLATE; - } else { - return 0; - } - return 1; -} - -int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm, - char **name) { - GRPC_API_TRACE("grpc_compression_algorithm_parse(algorithm=%d, name=%p)", 2, - ((int)algorithm, name)); - switch (algorithm) { - case GRPC_COMPRESS_NONE: - *name = "identity"; - return 1; - case GRPC_COMPRESS_DEFLATE: - *name = "deflate"; - return 1; - case GRPC_COMPRESS_GZIP: - *name = "gzip"; - return 1; - case GRPC_COMPRESS_ALGORITHMS_COUNT: - return 0; - } - return 0; -} - -grpc_compression_algorithm grpc_compression_algorithm_from_mdstr( - grpc_mdstr *str) { - if (str == GRPC_MDSTR_IDENTITY) return GRPC_COMPRESS_NONE; - if (str == GRPC_MDSTR_DEFLATE) return GRPC_COMPRESS_DEFLATE; - if (str == GRPC_MDSTR_GZIP) return GRPC_COMPRESS_GZIP; - return GRPC_COMPRESS_ALGORITHMS_COUNT; -} - -grpc_mdstr *grpc_compression_algorithm_mdstr( - grpc_compression_algorithm algorithm) { - switch (algorithm) { - case GRPC_COMPRESS_NONE: - return GRPC_MDSTR_IDENTITY; - case GRPC_COMPRESS_DEFLATE: - return GRPC_MDSTR_DEFLATE; - case GRPC_COMPRESS_GZIP: - return GRPC_MDSTR_GZIP; - case GRPC_COMPRESS_ALGORITHMS_COUNT: - return NULL; - } - return NULL; -} - -grpc_mdelem *grpc_compression_encoding_mdelem( - grpc_compression_algorithm algorithm) { - switch (algorithm) { - case GRPC_COMPRESS_NONE: - return GRPC_MDELEM_GRPC_ENCODING_IDENTITY; - case GRPC_COMPRESS_DEFLATE: - return GRPC_MDELEM_GRPC_ENCODING_DEFLATE; - case GRPC_COMPRESS_GZIP: - return GRPC_MDELEM_GRPC_ENCODING_GZIP; - default: - break; - } - return NULL; -} - -/* TODO(dgq): Add the ability to specify parameters to the individual - * compression algorithms */ -grpc_compression_algorithm grpc_compression_algorithm_for_level( - grpc_compression_level level, uint32_t accepted_encodings) { - GRPC_API_TRACE("grpc_compression_algorithm_for_level(level=%d)", 1, - ((int)level)); - if (level > GRPC_COMPRESS_LEVEL_HIGH) { - gpr_log(GPR_ERROR, "Unknown compression level %d.", (int)level); - abort(); - } - - const size_t num_supported = - GPR_BITCOUNT(accepted_encodings) - 1; /* discard NONE */ - if (level == GRPC_COMPRESS_LEVEL_NONE || num_supported == 0) { - return GRPC_COMPRESS_NONE; - } - - GPR_ASSERT(level > 0); - - /* Establish a "ranking" or compression algorithms in increasing order of - * compression. - * This is simplistic and we will probably want to introduce other dimensions - * in the future (cpu/memory cost, etc). */ - const grpc_compression_algorithm algos_ranking[] = {GRPC_COMPRESS_GZIP, - GRPC_COMPRESS_DEFLATE}; - - /* intersect algos_ranking with the supported ones keeping the ranked order */ - grpc_compression_algorithm - sorted_supported_algos[GRPC_COMPRESS_ALGORITHMS_COUNT]; - size_t algos_supported_idx = 0; - for (size_t i = 0; i < GPR_ARRAY_SIZE(algos_ranking); i++) { - const grpc_compression_algorithm alg = algos_ranking[i]; - for (size_t j = 0; j < num_supported; j++) { - if (GPR_BITGET(accepted_encodings, alg) == 1) { - /* if \a alg in supported */ - sorted_supported_algos[algos_supported_idx++] = alg; - break; - } - } - if (algos_supported_idx == num_supported) break; - } - - switch (level) { - case GRPC_COMPRESS_LEVEL_NONE: - abort(); /* should have been handled already */ - case GRPC_COMPRESS_LEVEL_LOW: - return sorted_supported_algos[0]; - case GRPC_COMPRESS_LEVEL_MED: - return sorted_supported_algos[num_supported / 2]; - case GRPC_COMPRESS_LEVEL_HIGH: - return sorted_supported_algos[num_supported - 1]; - default: - abort(); - }; -} - -void grpc_compression_options_init(grpc_compression_options *opts) { - opts->enabled_algorithms_bitset = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; - opts->default_compression_algorithm = GRPC_COMPRESS_NONE; -} - -void grpc_compression_options_enable_algorithm( - grpc_compression_options *opts, grpc_compression_algorithm algorithm) { - GPR_BITSET(&opts->enabled_algorithms_bitset, algorithm); -} - -void grpc_compression_options_disable_algorithm( - grpc_compression_options *opts, grpc_compression_algorithm algorithm) { - GPR_BITCLEAR(&opts->enabled_algorithms_bitset, algorithm); -} - -int grpc_compression_options_is_algorithm_enabled( - const grpc_compression_options *opts, - grpc_compression_algorithm algorithm) { - return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm); -} diff --git a/src/core/compression/message_compress.c b/src/core/compression/message_compress.c deleted file mode 100644 index edc21a9eb7..0000000000 --- a/src/core/compression/message_compress.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * - * Copyright 2015, 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/compression/message_compress.h" - -#include - -#include -#include - -#include - -#define OUTPUT_BLOCK_SIZE 1024 - -static int zlib_body(z_stream* zs, gpr_slice_buffer* input, - gpr_slice_buffer* output, - int (*flate)(z_stream* zs, int flush)) { - int r; - int flush; - size_t i; - gpr_slice outbuf = gpr_slice_malloc(OUTPUT_BLOCK_SIZE); - const uInt uint_max = ~(uInt)0; - - GPR_ASSERT(GPR_SLICE_LENGTH(outbuf) <= uint_max); - zs->avail_out = (uInt)GPR_SLICE_LENGTH(outbuf); - zs->next_out = GPR_SLICE_START_PTR(outbuf); - flush = Z_NO_FLUSH; - for (i = 0; i < input->count; i++) { - if (i == input->count - 1) flush = Z_FINISH; - GPR_ASSERT(GPR_SLICE_LENGTH(input->slices[i]) <= uint_max); - zs->avail_in = (uInt)GPR_SLICE_LENGTH(input->slices[i]); - zs->next_in = GPR_SLICE_START_PTR(input->slices[i]); - do { - if (zs->avail_out == 0) { - gpr_slice_buffer_add_indexed(output, outbuf); - outbuf = gpr_slice_malloc(OUTPUT_BLOCK_SIZE); - GPR_ASSERT(GPR_SLICE_LENGTH(outbuf) <= uint_max); - zs->avail_out = (uInt)GPR_SLICE_LENGTH(outbuf); - zs->next_out = GPR_SLICE_START_PTR(outbuf); - } - r = flate(zs, flush); - if (r < 0 && r != Z_BUF_ERROR /* not fatal */) { - gpr_log(GPR_INFO, "zlib error (%d)", r); - goto error; - } - } while (zs->avail_out == 0); - if (zs->avail_in) { - gpr_log(GPR_INFO, "zlib: not all input consumed"); - goto error; - } - } - - GPR_ASSERT(outbuf.refcount); - outbuf.data.refcounted.length -= zs->avail_out; - gpr_slice_buffer_add_indexed(output, outbuf); - - return 1; - -error: - gpr_slice_unref(outbuf); - return 0; -} - -static void* zalloc_gpr(void* opaque, unsigned int items, unsigned int size) { - return gpr_malloc(items * size); -} - -static void zfree_gpr(void* opaque, void* address) { gpr_free(address); } - -static int zlib_compress(gpr_slice_buffer* input, gpr_slice_buffer* output, - int gzip) { - z_stream zs; - int r; - size_t i; - size_t count_before = output->count; - size_t length_before = output->length; - memset(&zs, 0, sizeof(zs)); - zs.zalloc = zalloc_gpr; - zs.zfree = zfree_gpr; - r = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | (gzip ? 16 : 0), - 8, Z_DEFAULT_STRATEGY); - GPR_ASSERT(r == Z_OK); - r = zlib_body(&zs, input, output, deflate) && output->length < input->length; - if (!r) { - for (i = count_before; i < output->count; i++) { - gpr_slice_unref(output->slices[i]); - } - output->count = count_before; - output->length = length_before; - } - deflateEnd(&zs); - return r; -} - -static int zlib_decompress(gpr_slice_buffer* input, gpr_slice_buffer* output, - int gzip) { - z_stream zs; - int r; - size_t i; - size_t count_before = output->count; - size_t length_before = output->length; - memset(&zs, 0, sizeof(zs)); - zs.zalloc = zalloc_gpr; - zs.zfree = zfree_gpr; - r = inflateInit2(&zs, 15 | (gzip ? 16 : 0)); - GPR_ASSERT(r == Z_OK); - r = zlib_body(&zs, input, output, inflate); - if (!r) { - for (i = count_before; i < output->count; i++) { - gpr_slice_unref(output->slices[i]); - } - output->count = count_before; - output->length = length_before; - } - inflateEnd(&zs); - return r; -} - -static int copy(gpr_slice_buffer* input, gpr_slice_buffer* output) { - size_t i; - for (i = 0; i < input->count; i++) { - gpr_slice_buffer_add(output, gpr_slice_ref(input->slices[i])); - } - return 1; -} - -static int compress_inner(grpc_compression_algorithm algorithm, - gpr_slice_buffer* input, gpr_slice_buffer* output) { - switch (algorithm) { - case GRPC_COMPRESS_NONE: - /* the fallback path always needs to be send uncompressed: we simply - rely on that here */ - return 0; - case GRPC_COMPRESS_DEFLATE: - return zlib_compress(input, output, 0); - case GRPC_COMPRESS_GZIP: - return zlib_compress(input, output, 1); - case GRPC_COMPRESS_ALGORITHMS_COUNT: - break; - } - gpr_log(GPR_ERROR, "invalid compression algorithm %d", algorithm); - return 0; -} - -int grpc_msg_compress(grpc_compression_algorithm algorithm, - gpr_slice_buffer* input, gpr_slice_buffer* output) { - if (!compress_inner(algorithm, input, output)) { - copy(input, output); - return 0; - } - return 1; -} - -int grpc_msg_decompress(grpc_compression_algorithm algorithm, - gpr_slice_buffer* input, gpr_slice_buffer* output) { - switch (algorithm) { - case GRPC_COMPRESS_NONE: - return copy(input, output); - case GRPC_COMPRESS_DEFLATE: - return zlib_decompress(input, output, 0); - case GRPC_COMPRESS_GZIP: - return zlib_decompress(input, output, 1); - case GRPC_COMPRESS_ALGORITHMS_COUNT: - break; - } - gpr_log(GPR_ERROR, "invalid compression algorithm %d", algorithm); - return 0; -} diff --git a/src/core/compression/message_compress.h b/src/core/compression/message_compress.h deleted file mode 100644 index 20b78c063b..0000000000 --- a/src/core/compression/message_compress.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright 2015-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_COMPRESSION_MESSAGE_COMPRESS_H -#define GRPC_CORE_COMPRESSION_MESSAGE_COMPRESS_H - -#include -#include - -/* compress 'input' to 'output' using 'algorithm'. - On success, appends compressed slices to output and returns 1. - On failure, appends uncompressed slices to output and returns 0. */ -int grpc_msg_compress(grpc_compression_algorithm algorithm, - gpr_slice_buffer* input, gpr_slice_buffer* output); - -/* decompress 'input' to 'output' using 'algorithm'. - On success, appends slices to output and returns 1. - On failure, output is unchanged, and returns 0. */ -int grpc_msg_decompress(grpc_compression_algorithm algorithm, - gpr_slice_buffer* input, gpr_slice_buffer* output); - -#endif /* GRPC_CORE_COMPRESSION_MESSAGE_COMPRESS_H */ diff --git a/src/core/debug/trace.c b/src/core/debug/trace.c deleted file mode 100644 index 3b35d81cd8..0000000000 --- a/src/core/debug/trace.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * - * Copyright 2015, 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/debug/trace.h" - -#include - -#include -#include -#include -#include "src/core/support/env.h" - -typedef struct tracer { - const char *name; - int *flag; - struct tracer *next; -} tracer; -static tracer *tracers; - -void grpc_register_tracer(const char *name, int *flag) { - tracer *t = gpr_malloc(sizeof(*t)); - t->name = name; - t->flag = flag; - t->next = tracers; - *flag = 0; - tracers = t; -} - -static void add(const char *beg, const char *end, char ***ss, size_t *ns) { - size_t n = *ns; - size_t np = n + 1; - char *s; - size_t len; - GPR_ASSERT(end >= beg); - len = (size_t)(end - beg); - s = gpr_malloc(len + 1); - memcpy(s, beg, len); - s[len] = 0; - *ss = gpr_realloc(*ss, sizeof(char **) * np); - (*ss)[n] = s; - *ns = np; -} - -static void split(const char *s, char ***ss, size_t *ns) { - const char *c = strchr(s, ','); - if (c == NULL) { - add(s, s + strlen(s), ss, ns); - } else { - add(s, c, ss, ns); - split(c + 1, ss, ns); - } -} - -static void parse(const char *s) { - char **strings = NULL; - size_t nstrings = 0; - size_t i; - split(s, &strings, &nstrings); - - for (i = 0; i < nstrings; i++) { - grpc_tracer_set_enabled(strings[i], 1); - } - - for (i = 0; i < nstrings; i++) { - gpr_free(strings[i]); - } - gpr_free(strings); -} - -void grpc_tracer_init(const char *env_var) { - char *e = gpr_getenv(env_var); - if (e != NULL) { - parse(e); - gpr_free(e); - } -} - -void grpc_tracer_shutdown(void) { - while (tracers) { - tracer *t = tracers; - tracers = t->next; - gpr_free(t); - } -} - -int grpc_tracer_set_enabled(const char *name, int enabled) { - tracer *t; - if (0 == strcmp(name, "all")) { - for (t = tracers; t; t = t->next) { - *t->flag = 1; - } - } else { - int found = 0; - for (t = tracers; t; t = t->next) { - if (0 == strcmp(name, t->name)) { - *t->flag = enabled; - found = 1; - } - } - if (!found) { - gpr_log(GPR_ERROR, "Unknown trace var: '%s'", name); - return 0; /* early return */ - } - } - return 1; -} diff --git a/src/core/debug/trace.h b/src/core/debug/trace.h deleted file mode 100644 index 91ec14052e..0000000000 --- a/src/core/debug/trace.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * Copyright 2015-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_DEBUG_TRACE_H -#define GRPC_CORE_DEBUG_TRACE_H - -#include - -void grpc_register_tracer(const char *name, int *flag); -void grpc_tracer_init(const char *env_var_name); -void grpc_tracer_shutdown(void); - -#endif /* GRPC_CORE_DEBUG_TRACE_H */ diff --git a/src/core/http/format_request.c b/src/core/http/format_request.c deleted file mode 100644 index ac9bb8aeb8..0000000000 --- a/src/core/http/format_request.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * - * Copyright 2015-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/http/format_request.h" - -#include -#include -#include - -#include -#include -#include -#include -#include "src/core/support/string.h" - -static void fill_common_header(const grpc_httpcli_request *request, - gpr_strvec *buf) { - size_t i; - gpr_strvec_add(buf, gpr_strdup(request->http.path)); - gpr_strvec_add(buf, gpr_strdup(" HTTP/1.0\r\n")); - /* just in case some crazy server really expects HTTP/1.1 */ - gpr_strvec_add(buf, gpr_strdup("Host: ")); - gpr_strvec_add(buf, gpr_strdup(request->host)); - gpr_strvec_add(buf, gpr_strdup("\r\n")); - gpr_strvec_add(buf, gpr_strdup("Connection: close\r\n")); - gpr_strvec_add(buf, - gpr_strdup("User-Agent: " GRPC_HTTPCLI_USER_AGENT "\r\n")); - /* user supplied headers */ - for (i = 0; i < request->http.hdr_count; i++) { - gpr_strvec_add(buf, gpr_strdup(request->http.hdrs[i].key)); - gpr_strvec_add(buf, gpr_strdup(": ")); - gpr_strvec_add(buf, gpr_strdup(request->http.hdrs[i].value)); - gpr_strvec_add(buf, gpr_strdup("\r\n")); - } -} - -gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request) { - gpr_strvec out; - char *flat; - size_t flat_len; - - gpr_strvec_init(&out); - gpr_strvec_add(&out, gpr_strdup("GET ")); - fill_common_header(request, &out); - gpr_strvec_add(&out, gpr_strdup("\r\n")); - - flat = gpr_strvec_flatten(&out, &flat_len); - gpr_strvec_destroy(&out); - - return gpr_slice_new(flat, flat_len, gpr_free); -} - -gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, - const char *body_bytes, - size_t body_size) { - gpr_strvec out; - char *tmp; - size_t out_len; - size_t i; - - gpr_strvec_init(&out); - - gpr_strvec_add(&out, gpr_strdup("POST ")); - fill_common_header(request, &out); - if (body_bytes) { - uint8_t has_content_type = 0; - for (i = 0; i < request->http.hdr_count; i++) { - if (strcmp(request->http.hdrs[i].key, "Content-Type") == 0) { - has_content_type = 1; - break; - } - } - if (!has_content_type) { - gpr_strvec_add(&out, gpr_strdup("Content-Type: text/plain\r\n")); - } - gpr_asprintf(&tmp, "Content-Length: %lu\r\n", (unsigned long)body_size); - gpr_strvec_add(&out, tmp); - } - gpr_strvec_add(&out, gpr_strdup("\r\n")); - tmp = gpr_strvec_flatten(&out, &out_len); - gpr_strvec_destroy(&out); - - if (body_bytes) { - tmp = gpr_realloc(tmp, out_len + body_size); - memcpy(tmp + out_len, body_bytes, body_size); - out_len += body_size; - } - - return gpr_slice_new(tmp, out_len, gpr_free); -} diff --git a/src/core/http/format_request.h b/src/core/http/format_request.h deleted file mode 100644 index dfd6fadbde..0000000000 --- a/src/core/http/format_request.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Copyright 2015-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_HTTP_FORMAT_REQUEST_H -#define GRPC_CORE_HTTP_FORMAT_REQUEST_H - -#include -#include "src/core/http/httpcli.h" - -gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request); -gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, - const char *body_bytes, - size_t body_size); - -#endif /* GRPC_CORE_HTTP_FORMAT_REQUEST_H */ diff --git a/src/core/http/httpcli.c b/src/core/http/httpcli.c deleted file mode 100644 index 1c0d3336ea..0000000000 --- a/src/core/http/httpcli.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * - * Copyright 2015-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/http/httpcli.h" -#include "src/core/iomgr/sockaddr.h" - -#include - -#include -#include -#include - -#include "src/core/http/format_request.h" -#include "src/core/http/parser.h" -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/support/string.h" - -typedef struct { - gpr_slice request_text; - grpc_http_parser parser; - grpc_resolved_addresses *addresses; - size_t next_address; - grpc_endpoint *ep; - char *host; - char *ssl_host_override; - gpr_timespec deadline; - int have_read_byte; - const grpc_httpcli_handshaker *handshaker; - grpc_httpcli_response_cb on_response; - void *user_data; - grpc_httpcli_context *context; - grpc_pollset *pollset; - grpc_iomgr_object iomgr_obj; - gpr_slice_buffer incoming; - gpr_slice_buffer outgoing; - grpc_closure on_read; - grpc_closure done_write; - grpc_closure connected; -} internal_request; - -static grpc_httpcli_get_override g_get_override = NULL; -static grpc_httpcli_post_override g_post_override = NULL; - -static void plaintext_handshake(grpc_exec_ctx *exec_ctx, void *arg, - grpc_endpoint *endpoint, const char *host, - void (*on_done)(grpc_exec_ctx *exec_ctx, - void *arg, - grpc_endpoint *endpoint)) { - on_done(exec_ctx, arg, endpoint); -} - -const grpc_httpcli_handshaker grpc_httpcli_plaintext = {"http", - plaintext_handshake}; - -void grpc_httpcli_context_init(grpc_httpcli_context *context) { - context->pollset_set = grpc_pollset_set_create(); -} - -void grpc_httpcli_context_destroy(grpc_httpcli_context *context) { - grpc_pollset_set_destroy(context->pollset_set); -} - -static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req); - -static void finish(grpc_exec_ctx *exec_ctx, internal_request *req, - int success) { - grpc_pollset_set_del_pollset(exec_ctx, req->context->pollset_set, - req->pollset); - req->on_response(exec_ctx, req->user_data, - success ? &req->parser.http.response : NULL); - grpc_http_parser_destroy(&req->parser); - if (req->addresses != NULL) { - grpc_resolved_addresses_destroy(req->addresses); - } - if (req->ep != NULL) { - grpc_endpoint_destroy(exec_ctx, req->ep); - } - gpr_slice_unref(req->request_text); - gpr_free(req->host); - gpr_free(req->ssl_host_override); - grpc_iomgr_unregister_object(&req->iomgr_obj); - gpr_slice_buffer_destroy(&req->incoming); - gpr_slice_buffer_destroy(&req->outgoing); - gpr_free(req); -} - -static void on_read(grpc_exec_ctx *exec_ctx, void *user_data, bool success); - -static void do_read(grpc_exec_ctx *exec_ctx, internal_request *req) { - grpc_endpoint_read(exec_ctx, req->ep, &req->incoming, &req->on_read); -} - -static void on_read(grpc_exec_ctx *exec_ctx, void *user_data, bool success) { - internal_request *req = user_data; - size_t i; - - for (i = 0; i < req->incoming.count; i++) { - if (GPR_SLICE_LENGTH(req->incoming.slices[i])) { - req->have_read_byte = 1; - if (!grpc_http_parser_parse(&req->parser, req->incoming.slices[i])) { - finish(exec_ctx, req, 0); - return; - } - } - } - - if (success) { - do_read(exec_ctx, req); - } else if (!req->have_read_byte) { - next_address(exec_ctx, req); - } else { - int parse_success = grpc_http_parser_eof(&req->parser); - if (parse_success && (req->parser.type != GRPC_HTTP_RESPONSE)) { - parse_success = 0; - } - finish(exec_ctx, req, parse_success); - } -} - -static void on_written(grpc_exec_ctx *exec_ctx, internal_request *req) { - do_read(exec_ctx, req); -} - -static void done_write(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - internal_request *req = arg; - if (success) { - on_written(exec_ctx, req); - } else { - next_address(exec_ctx, req); - } -} - -static void start_write(grpc_exec_ctx *exec_ctx, internal_request *req) { - gpr_slice_ref(req->request_text); - gpr_slice_buffer_add(&req->outgoing, req->request_text); - grpc_endpoint_write(exec_ctx, req->ep, &req->outgoing, &req->done_write); -} - -static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, - grpc_endpoint *ep) { - internal_request *req = arg; - - if (!ep) { - next_address(exec_ctx, req); - return; - } - - req->ep = ep; - start_write(exec_ctx, req); -} - -static void on_connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - internal_request *req = arg; - - if (!req->ep) { - next_address(exec_ctx, req); - return; - } - req->handshaker->handshake( - exec_ctx, req, req->ep, - req->ssl_host_override ? req->ssl_host_override : req->host, - on_handshake_done); -} - -static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req) { - grpc_resolved_address *addr; - if (req->next_address == req->addresses->naddrs) { - finish(exec_ctx, req, 0); - return; - } - addr = &req->addresses->addrs[req->next_address++]; - grpc_closure_init(&req->connected, on_connected, req); - grpc_tcp_client_connect( - exec_ctx, &req->connected, &req->ep, req->context->pollset_set, - (struct sockaddr *)&addr->addr, addr->len, req->deadline); -} - -static void on_resolved(grpc_exec_ctx *exec_ctx, void *arg, - grpc_resolved_addresses *addresses) { - internal_request *req = arg; - if (!addresses) { - finish(exec_ctx, req, 0); - return; - } - req->addresses = addresses; - req->next_address = 0; - next_address(exec_ctx, req); -} - -static void internal_request_begin( - grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, - grpc_pollset *pollset, const grpc_httpcli_request *request, - gpr_timespec deadline, grpc_httpcli_response_cb on_response, - void *user_data, const char *name, gpr_slice request_text) { - internal_request *req = gpr_malloc(sizeof(internal_request)); - memset(req, 0, sizeof(*req)); - req->request_text = request_text; - grpc_http_parser_init(&req->parser); - req->on_response = on_response; - req->user_data = user_data; - req->deadline = deadline; - req->handshaker = - request->handshaker ? request->handshaker : &grpc_httpcli_plaintext; - req->context = context; - req->pollset = pollset; - grpc_closure_init(&req->on_read, on_read, req); - grpc_closure_init(&req->done_write, done_write, req); - gpr_slice_buffer_init(&req->incoming); - gpr_slice_buffer_init(&req->outgoing); - grpc_iomgr_register_object(&req->iomgr_obj, name); - req->host = gpr_strdup(request->host); - req->ssl_host_override = gpr_strdup(request->ssl_host_override); - - grpc_pollset_set_add_pollset(exec_ctx, req->context->pollset_set, - req->pollset); - grpc_resolve_address(request->host, req->handshaker->default_port, - on_resolved, req); -} - -void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, - grpc_pollset *pollset, - const grpc_httpcli_request *request, - gpr_timespec deadline, - grpc_httpcli_response_cb on_response, void *user_data) { - char *name; - if (g_get_override && - g_get_override(exec_ctx, request, deadline, on_response, user_data)) { - return; - } - gpr_asprintf(&name, "HTTP:GET:%s:%s", request->host, request->http.path); - internal_request_begin(exec_ctx, context, pollset, request, deadline, - on_response, user_data, name, - grpc_httpcli_format_get_request(request)); - gpr_free(name); -} - -void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, - grpc_pollset *pollset, - const grpc_httpcli_request *request, - const char *body_bytes, size_t body_size, - gpr_timespec deadline, - grpc_httpcli_response_cb on_response, void *user_data) { - char *name; - if (g_post_override && - g_post_override(exec_ctx, request, body_bytes, body_size, deadline, - on_response, user_data)) { - return; - } - gpr_asprintf(&name, "HTTP:POST:%s:%s", request->host, request->http.path); - internal_request_begin( - exec_ctx, context, pollset, request, deadline, on_response, user_data, - name, grpc_httpcli_format_post_request(request, body_bytes, body_size)); - gpr_free(name); -} - -void grpc_httpcli_set_override(grpc_httpcli_get_override get, - grpc_httpcli_post_override post) { - g_get_override = get; - g_post_override = post; -} diff --git a/src/core/http/httpcli.h b/src/core/http/httpcli.h deleted file mode 100644 index 0bf4f2f445..0000000000 --- a/src/core/http/httpcli.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * - * Copyright 2015-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_HTTP_HTTPCLI_H -#define GRPC_CORE_HTTP_HTTPCLI_H - -#include - -#include - -#include "src/core/http/parser.h" -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/pollset_set.h" - -/* User agent this library reports */ -#define GRPC_HTTPCLI_USER_AGENT "grpc-httpcli/0.0" - -/* Tracks in-progress http requests - TODO(ctiller): allow caching and capturing multiple requests for the - same content and combining them */ -typedef struct grpc_httpcli_context { - grpc_pollset_set *pollset_set; -} grpc_httpcli_context; - -typedef struct { - const char *default_port; - void (*handshake)(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *endpoint, - const char *host, - void (*on_done)(grpc_exec_ctx *exec_ctx, void *arg, - grpc_endpoint *endpoint)); -} grpc_httpcli_handshaker; - -extern const grpc_httpcli_handshaker grpc_httpcli_plaintext; -extern const grpc_httpcli_handshaker grpc_httpcli_ssl; - -/* A request */ -typedef struct grpc_httpcli_request { - /* The host name to connect to */ - char *host; - /* The host to verify in the SSL handshake (or NULL) */ - char *ssl_host_override; - /* The main part of the request - The following headers are supplied automatically and MUST NOT be set here: - Host, Connection, User-Agent */ - grpc_http_request http; - /* handshaker to use ssl for the request */ - const grpc_httpcli_handshaker *handshaker; -} grpc_httpcli_request; - -/* Expose the parser response type as a httpcli response too */ -typedef struct grpc_http_response grpc_httpcli_response; - -/* Callback for grpc_httpcli_get and grpc_httpcli_post. */ -typedef void (*grpc_httpcli_response_cb)(grpc_exec_ctx *exec_ctx, - void *user_data, - const grpc_http_response *response); - -void grpc_httpcli_context_init(grpc_httpcli_context *context); -void grpc_httpcli_context_destroy(grpc_httpcli_context *context); - -/* Asynchronously perform a HTTP GET. - 'context' specifies the http context under which to do the get - 'pollset' indicates a grpc_pollset that is interested in the result - of the get - work on this pollset may be used to progress the get - operation - 'request' contains request parameters - these are caller owned and can be - destroyed once the call returns - 'deadline' contains a deadline for the request (or gpr_inf_future) - 'on_response' is a callback to report results to (and 'user_data' is a user - supplied pointer to pass to said call) */ -void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, - grpc_pollset *pollset, - const grpc_httpcli_request *request, - gpr_timespec deadline, - grpc_httpcli_response_cb on_response, void *user_data); - -/* Asynchronously perform a HTTP POST. - 'context' specifies the http context under which to do the post - 'pollset' indicates a grpc_pollset that is interested in the result - of the post - work on this pollset may be used to progress the post - operation - 'request' contains request parameters - these are caller owned and can be - destroyed once the call returns - 'body_bytes' and 'body_size' specify the payload for the post. - When there is no body, pass in NULL as body_bytes. - 'deadline' contains a deadline for the request (or gpr_inf_future) - 'em' points to a caller owned event manager that must be alive for the - lifetime of the request - 'on_response' is a callback to report results to (and 'user_data' is a user - supplied pointer to pass to said call) - Does not support ?var1=val1&var2=val2 in the path. */ -void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, - grpc_pollset *pollset, - const grpc_httpcli_request *request, - const char *body_bytes, size_t body_size, - gpr_timespec deadline, - grpc_httpcli_response_cb on_response, void *user_data); - -/* override functions return 1 if they handled the request, 0 otherwise */ -typedef int (*grpc_httpcli_get_override)(grpc_exec_ctx *exec_ctx, - const grpc_httpcli_request *request, - gpr_timespec deadline, - grpc_httpcli_response_cb on_response, - void *user_data); -typedef int (*grpc_httpcli_post_override)( - grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - const char *body_bytes, size_t body_size, gpr_timespec deadline, - grpc_httpcli_response_cb on_response, void *user_data); - -void grpc_httpcli_set_override(grpc_httpcli_get_override get, - grpc_httpcli_post_override post); - -#endif /* GRPC_CORE_HTTP_HTTPCLI_H */ diff --git a/src/core/http/httpcli_security_connector.c b/src/core/http/httpcli_security_connector.c deleted file mode 100644 index a1a32f7558..0000000000 --- a/src/core/http/httpcli_security_connector.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * - * Copyright 2015-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/http/httpcli.h" - -#include - -#include -#include -#include -#include "src/core/security/handshake.h" -#include "src/core/support/string.h" -#include "src/core/tsi/ssl_transport_security.h" - -typedef struct { - grpc_channel_security_connector base; - tsi_ssl_handshaker_factory *handshaker_factory; - char *secure_peer_name; -} grpc_httpcli_ssl_channel_security_connector; - -static void httpcli_ssl_destroy(grpc_security_connector *sc) { - grpc_httpcli_ssl_channel_security_connector *c = - (grpc_httpcli_ssl_channel_security_connector *)sc; - if (c->handshaker_factory != NULL) { - tsi_ssl_handshaker_factory_destroy(c->handshaker_factory); - } - if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name); - gpr_free(sc); -} - -static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, - grpc_channel_security_connector *sc, - grpc_endpoint *nonsecure_endpoint, - grpc_security_handshake_done_cb cb, - void *user_data) { - grpc_httpcli_ssl_channel_security_connector *c = - (grpc_httpcli_ssl_channel_security_connector *)sc; - tsi_result result = TSI_OK; - tsi_handshaker *handshaker; - if (c->handshaker_factory == NULL) { - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); - return; - } - result = tsi_ssl_handshaker_factory_create_handshaker( - c->handshaker_factory, c->secure_peer_name, &handshaker); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); - } else { - grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true, - nonsecure_endpoint, cb, user_data); - } -} - -static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx, - grpc_security_connector *sc, tsi_peer peer, - grpc_security_peer_check_cb cb, - void *user_data) { - grpc_httpcli_ssl_channel_security_connector *c = - (grpc_httpcli_ssl_channel_security_connector *)sc; - grpc_security_status status = GRPC_SECURITY_OK; - - /* Check the peer name. */ - if (c->secure_peer_name != NULL && - !tsi_ssl_peer_matches_name(&peer, c->secure_peer_name)) { - gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", - c->secure_peer_name); - status = GRPC_SECURITY_ERROR; - } - cb(exec_ctx, user_data, status, NULL); - tsi_peer_destruct(&peer); -} - -static grpc_security_connector_vtable httpcli_ssl_vtable = { - httpcli_ssl_destroy, httpcli_ssl_check_peer}; - -static grpc_security_status httpcli_ssl_channel_security_connector_create( - const unsigned char *pem_root_certs, size_t pem_root_certs_size, - const char *secure_peer_name, grpc_channel_security_connector **sc) { - tsi_result result = TSI_OK; - grpc_httpcli_ssl_channel_security_connector *c; - - if (secure_peer_name != NULL && pem_root_certs == NULL) { - gpr_log(GPR_ERROR, - "Cannot assert a secure peer name without a trust root."); - return GRPC_SECURITY_ERROR; - } - - c = gpr_malloc(sizeof(grpc_httpcli_ssl_channel_security_connector)); - memset(c, 0, sizeof(grpc_httpcli_ssl_channel_security_connector)); - - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &httpcli_ssl_vtable; - if (secure_peer_name != NULL) { - c->secure_peer_name = gpr_strdup(secure_peer_name); - } - result = tsi_create_ssl_client_handshaker_factory( - NULL, 0, NULL, 0, pem_root_certs, pem_root_certs_size, NULL, NULL, NULL, - 0, &c->handshaker_factory); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - httpcli_ssl_destroy(&c->base.base); - *sc = NULL; - return GRPC_SECURITY_ERROR; - } - c->base.do_handshake = httpcli_ssl_do_handshake; - *sc = &c->base; - return GRPC_SECURITY_OK; -} - -/* handshaker */ - -typedef struct { - void (*func)(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *endpoint); - void *arg; -} on_done_closure; - -static void on_secure_transport_setup_done(grpc_exec_ctx *exec_ctx, void *rp, - grpc_security_status status, - grpc_endpoint *secure_endpoint, - grpc_auth_context *auth_context) { - on_done_closure *c = rp; - if (status != GRPC_SECURITY_OK) { - gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status); - c->func(exec_ctx, c->arg, NULL); - } else { - c->func(exec_ctx, c->arg, secure_endpoint); - } - gpr_free(c); -} - -static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg, - grpc_endpoint *tcp, const char *host, - void (*on_done)(grpc_exec_ctx *exec_ctx, void *arg, - grpc_endpoint *endpoint)) { - grpc_channel_security_connector *sc = NULL; - const unsigned char *pem_root_certs = NULL; - on_done_closure *c = gpr_malloc(sizeof(*c)); - size_t pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs); - if (pem_root_certs == NULL || pem_root_certs_size == 0) { - gpr_log(GPR_ERROR, "Could not get default pem root certs."); - on_done(exec_ctx, arg, NULL); - gpr_free(c); - return; - } - c->func = on_done; - c->arg = arg; - GPR_ASSERT(httpcli_ssl_channel_security_connector_create( - pem_root_certs, pem_root_certs_size, host, &sc) == - GRPC_SECURITY_OK); - grpc_channel_security_connector_do_handshake( - exec_ctx, sc, tcp, on_secure_transport_setup_done, c); - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); -} - -const grpc_httpcli_handshaker grpc_httpcli_ssl = {"https", ssl_handshake}; diff --git a/src/core/http/parser.c b/src/core/http/parser.c deleted file mode 100644 index ebec8a5157..0000000000 --- a/src/core/http/parser.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * - * Copyright 2015-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/http/parser.h" - -#include - -#include -#include -#include - -static char *buf2str(void *buffer, size_t length) { - char *out = gpr_malloc(length + 1); - memcpy(out, buffer, length); - out[length] = 0; - return out; -} - -static int handle_response_line(grpc_http_parser *parser) { - uint8_t *beg = parser->cur_line; - uint8_t *cur = beg; - uint8_t *end = beg + parser->cur_line_length; - - if (cur == end || *cur++ != 'H') goto error; - if (cur == end || *cur++ != 'T') goto error; - if (cur == end || *cur++ != 'T') goto error; - if (cur == end || *cur++ != 'P') goto error; - if (cur == end || *cur++ != '/') goto error; - if (cur == end || *cur++ != '1') goto error; - if (cur == end || *cur++ != '.') goto error; - if (cur == end || *cur < '0' || *cur++ > '1') goto error; - if (cur == end || *cur++ != ' ') goto error; - if (cur == end || *cur < '1' || *cur++ > '9') goto error; - if (cur == end || *cur < '0' || *cur++ > '9') goto error; - if (cur == end || *cur < '0' || *cur++ > '9') goto error; - parser->http.response.status = - (cur[-3] - '0') * 100 + (cur[-2] - '0') * 10 + (cur[-1] - '0'); - if (cur == end || *cur++ != ' ') goto error; - - /* we don't really care about the status code message */ - - return 1; - -error: - gpr_log(GPR_ERROR, "Failed parsing response line"); - return 0; -} - -static int handle_request_line(grpc_http_parser *parser) { - uint8_t *beg = parser->cur_line; - uint8_t *cur = beg; - uint8_t *end = beg + parser->cur_line_length; - uint8_t vers_major = 0; - uint8_t vers_minor = 0; - - while (cur != end && *cur++ != ' ') - ; - if (cur == end) goto error; - parser->http.request.method = buf2str(beg, (size_t)(cur - beg - 1)); - - beg = cur; - while (cur != end && *cur++ != ' ') - ; - if (cur == end) goto error; - parser->http.request.path = buf2str(beg, (size_t)(cur - beg - 1)); - - if (cur == end || *cur++ != 'H') goto error; - if (cur == end || *cur++ != 'T') goto error; - if (cur == end || *cur++ != 'T') goto error; - if (cur == end || *cur++ != 'P') goto error; - if (cur == end || *cur++ != '/') goto error; - vers_major = (uint8_t)(*cur++ - '1' + 1); - ++cur; - if (cur == end) goto error; - vers_minor = (uint8_t)(*cur++ - '1' + 1); - - if (vers_major == 1) { - if (vers_minor == 0) { - parser->http.request.version = GRPC_HTTP_HTTP10; - } else if (vers_minor == 1) { - parser->http.request.version = GRPC_HTTP_HTTP11; - } else { - goto error; - } - } else if (vers_major == 2) { - if (vers_minor == 0) { - parser->http.request.version = GRPC_HTTP_HTTP20; - } else { - goto error; - } - } else { - goto error; - } - - return 1; - -error: - gpr_log(GPR_ERROR, "Failed parsing request line"); - return 0; -} - -static int handle_first_line(grpc_http_parser *parser) { - if (parser->cur_line[0] == 'H') { - parser->type = GRPC_HTTP_RESPONSE; - return handle_response_line(parser); - } else { - parser->type = GRPC_HTTP_REQUEST; - return handle_request_line(parser); - } -} - -static int add_header(grpc_http_parser *parser) { - uint8_t *beg = parser->cur_line; - uint8_t *cur = beg; - uint8_t *end = beg + parser->cur_line_length; - size_t *hdr_count = NULL; - grpc_http_header **hdrs = NULL; - grpc_http_header hdr = {NULL, NULL}; - - GPR_ASSERT(cur != end); - - if (*cur == ' ' || *cur == '\t') { - gpr_log(GPR_ERROR, "Continued header lines not supported yet"); - goto error; - } - - while (cur != end && *cur != ':') { - cur++; - } - if (cur == end) { - gpr_log(GPR_ERROR, "Didn't find ':' in header string"); - goto error; - } - GPR_ASSERT(cur >= beg); - hdr.key = buf2str(beg, (size_t)(cur - beg)); - cur++; /* skip : */ - - while (cur != end && (*cur == ' ' || *cur == '\t')) { - cur++; - } - GPR_ASSERT(end - cur >= 2); - hdr.value = buf2str(cur, (size_t)(end - cur) - 2); - - if (parser->type == GRPC_HTTP_RESPONSE) { - hdr_count = &parser->http.response.hdr_count; - hdrs = &parser->http.response.hdrs; - } else if (parser->type == GRPC_HTTP_REQUEST) { - hdr_count = &parser->http.request.hdr_count; - hdrs = &parser->http.request.hdrs; - } else { - return 0; - } - - if (*hdr_count == parser->hdr_capacity) { - parser->hdr_capacity = - GPR_MAX(parser->hdr_capacity + 1, parser->hdr_capacity * 3 / 2); - *hdrs = gpr_realloc(*hdrs, parser->hdr_capacity * sizeof(**hdrs)); - } - (*hdrs)[(*hdr_count)++] = hdr; - return 1; - -error: - gpr_free(hdr.key); - gpr_free(hdr.value); - return 0; -} - -static int finish_line(grpc_http_parser *parser) { - switch (parser->state) { - case GRPC_HTTP_FIRST_LINE: - if (!handle_first_line(parser)) { - return 0; - } - parser->state = GRPC_HTTP_HEADERS; - break; - case GRPC_HTTP_HEADERS: - if (parser->cur_line_length == 2) { - parser->state = GRPC_HTTP_BODY; - break; - } - if (!add_header(parser)) { - return 0; - } - break; - case GRPC_HTTP_BODY: - GPR_UNREACHABLE_CODE(return 0); - } - - parser->cur_line_length = 0; - return 1; -} - -static int addbyte_body(grpc_http_parser *parser, uint8_t byte) { - size_t *body_length = NULL; - char **body = NULL; - - if (parser->type == GRPC_HTTP_RESPONSE) { - body_length = &parser->http.response.body_length; - body = &parser->http.response.body; - } else if (parser->type == GRPC_HTTP_REQUEST) { - body_length = &parser->http.request.body_length; - body = &parser->http.request.body; - } else { - return 0; - } - - if (*body_length == parser->body_capacity) { - parser->body_capacity = GPR_MAX(8, parser->body_capacity * 3 / 2); - *body = gpr_realloc((void *)*body, parser->body_capacity); - } - (*body)[*body_length] = (char)byte; - (*body_length)++; - - return 1; -} - -static int addbyte(grpc_http_parser *parser, uint8_t byte) { - switch (parser->state) { - case GRPC_HTTP_FIRST_LINE: - case GRPC_HTTP_HEADERS: - if (parser->cur_line_length >= GRPC_HTTP_PARSER_MAX_HEADER_LENGTH) { - gpr_log(GPR_ERROR, "HTTP client max line length (%d) exceeded", - GRPC_HTTP_PARSER_MAX_HEADER_LENGTH); - return 0; - } - parser->cur_line[parser->cur_line_length] = byte; - parser->cur_line_length++; - if (parser->cur_line_length >= 2 && - parser->cur_line[parser->cur_line_length - 2] == '\r' && - parser->cur_line[parser->cur_line_length - 1] == '\n') { - return finish_line(parser); - } else { - return 1; - } - GPR_UNREACHABLE_CODE(return 0); - case GRPC_HTTP_BODY: - return addbyte_body(parser, byte); - } - GPR_UNREACHABLE_CODE(return 0); -} - -void grpc_http_parser_init(grpc_http_parser *parser) { - memset(parser, 0, sizeof(*parser)); - parser->state = GRPC_HTTP_FIRST_LINE; - parser->type = GRPC_HTTP_UNKNOWN; -} - -void grpc_http_parser_destroy(grpc_http_parser *parser) { - size_t i; - if (parser->type == GRPC_HTTP_RESPONSE) { - gpr_free(parser->http.response.body); - for (i = 0; i < parser->http.response.hdr_count; i++) { - gpr_free(parser->http.response.hdrs[i].key); - gpr_free(parser->http.response.hdrs[i].value); - } - gpr_free(parser->http.response.hdrs); - } else if (parser->type == GRPC_HTTP_REQUEST) { - gpr_free(parser->http.request.body); - for (i = 0; i < parser->http.request.hdr_count; i++) { - gpr_free(parser->http.request.hdrs[i].key); - gpr_free(parser->http.request.hdrs[i].value); - } - gpr_free(parser->http.request.hdrs); - gpr_free(parser->http.request.method); - gpr_free(parser->http.request.path); - } -} - -int grpc_http_parser_parse(grpc_http_parser *parser, gpr_slice slice) { - size_t i; - - for (i = 0; i < GPR_SLICE_LENGTH(slice); i++) { - if (!addbyte(parser, GPR_SLICE_START_PTR(slice)[i])) { - return 0; - } - } - - return 1; -} - -int grpc_http_parser_eof(grpc_http_parser *parser) { - return parser->state == GRPC_HTTP_BODY; -} diff --git a/src/core/http/parser.h b/src/core/http/parser.h deleted file mode 100644 index 39517e485a..0000000000 --- a/src/core/http/parser.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * - * Copyright 2015-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_HTTP_PARSER_H -#define GRPC_CORE_HTTP_PARSER_H - -#include -#include - -/* Maximum length of a header string of the form 'Key: Value\r\n' */ -#define GRPC_HTTP_PARSER_MAX_HEADER_LENGTH 4096 - -/* A single header to be passed in a request */ -typedef struct grpc_http_header { - char *key; - char *value; -} grpc_http_header; - -typedef enum { - GRPC_HTTP_FIRST_LINE, - GRPC_HTTP_HEADERS, - GRPC_HTTP_BODY -} grpc_http_parser_state; - -typedef enum { - GRPC_HTTP_HTTP10, - GRPC_HTTP_HTTP11, - GRPC_HTTP_HTTP20, -} grpc_http_version; - -typedef enum { - GRPC_HTTP_RESPONSE, - GRPC_HTTP_REQUEST, - GRPC_HTTP_UNKNOWN -} grpc_http_type; - -/* A request */ -typedef struct grpc_http_request { - /* Method of the request (e.g. GET, POST) */ - char *method; - /* The path of the resource to fetch */ - char *path; - /* HTTP version to use */ - grpc_http_version version; - /* Headers attached to the request */ - size_t hdr_count; - grpc_http_header *hdrs; - /* Body: length and contents; contents are NOT null-terminated */ - size_t body_length; - char *body; -} grpc_http_request; - -/* A response */ -typedef struct grpc_http_response { - /* HTTP status code */ - int status; - /* Headers: count and key/values */ - size_t hdr_count; - grpc_http_header *hdrs; - /* Body: length and contents; contents are NOT null-terminated */ - size_t body_length; - char *body; -} grpc_http_response; - -typedef struct { - grpc_http_parser_state state; - grpc_http_type type; - - union { - grpc_http_response response; - grpc_http_request request; - } http; - size_t body_capacity; - size_t hdr_capacity; - - uint8_t cur_line[GRPC_HTTP_PARSER_MAX_HEADER_LENGTH]; - size_t cur_line_length; -} grpc_http_parser; - -void grpc_http_parser_init(grpc_http_parser *parser); -void grpc_http_parser_destroy(grpc_http_parser *parser); - -int grpc_http_parser_parse(grpc_http_parser *parser, gpr_slice slice); -int grpc_http_parser_eof(grpc_http_parser *parser); - -#endif /* GRPC_CORE_HTTP_PARSER_H */ diff --git a/src/core/iomgr/closure.c b/src/core/iomgr/closure.c deleted file mode 100644 index 3a96f7385f..0000000000 --- a/src/core/iomgr/closure.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * - * Copyright 2015-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/iomgr/closure.h" - -#include - -void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb, - void *cb_arg) { - closure->cb = cb; - closure->cb_arg = cb_arg; - closure->final_data = 0; -} - -void grpc_closure_list_add(grpc_closure_list *closure_list, - grpc_closure *closure, bool success) { - if (closure == NULL) return; - closure->final_data = (success != 0); - if (closure_list->head == NULL) { - closure_list->head = closure; - } else { - closure_list->tail->final_data |= (uintptr_t)closure; - } - closure_list->tail = closure; -} - -bool grpc_closure_list_empty(grpc_closure_list closure_list) { - return closure_list.head == NULL; -} - -void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst) { - if (src->head == NULL) { - return; - } - if (dst->head == NULL) { - *dst = *src; - } else { - dst->tail->final_data |= (uintptr_t)src->head; - dst->tail = src->tail; - } - src->head = src->tail = NULL; -} - -typedef struct { - grpc_iomgr_cb_func cb; - void *cb_arg; - grpc_closure wrapper; -} wrapped_closure; - -static void closure_wrapper(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - wrapped_closure *wc = arg; - grpc_iomgr_cb_func cb = wc->cb; - void *cb_arg = wc->cb_arg; - gpr_free(wc); - cb(exec_ctx, cb_arg, success); -} - -grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg) { - wrapped_closure *wc = gpr_malloc(sizeof(*wc)); - wc->cb = cb; - wc->cb_arg = cb_arg; - grpc_closure_init(&wc->wrapper, closure_wrapper, wc); - return &wc->wrapper; -} - -grpc_closure *grpc_closure_next(grpc_closure *closure) { - return (grpc_closure *)(closure->final_data & ~(uintptr_t)1); -} diff --git a/src/core/iomgr/closure.h b/src/core/iomgr/closure.h deleted file mode 100644 index d5e1f455b9..0000000000 --- a/src/core/iomgr/closure.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_CLOSURE_H -#define GRPC_CORE_IOMGR_CLOSURE_H - -#include -#include - -struct grpc_closure; -typedef struct grpc_closure grpc_closure; - -/* forward declaration for exec_ctx.h */ -struct grpc_exec_ctx; -typedef struct grpc_exec_ctx grpc_exec_ctx; - -typedef struct grpc_closure_list { - grpc_closure *head; - grpc_closure *tail; -} grpc_closure_list; - -/** gRPC Callback definition. - * - * \param arg Arbitrary input. - * \param success An indication on the state of the iomgr. On false, cleanup - * actions should be taken (eg, shutdown). */ -typedef void (*grpc_iomgr_cb_func)(grpc_exec_ctx *exec_ctx, void *arg, - bool success); - -/** A closure over a grpc_iomgr_cb_func. */ -struct grpc_closure { - /** Bound callback. */ - grpc_iomgr_cb_func cb; - - /** Arguments to be passed to "cb". */ - void *cb_arg; - - /** Once enqueued, contains in the lower bit the success of the closure, - and in the upper bits the pointer to the next closure in the list. - Before enqueing for execution, this is usable for scratch data. */ - uintptr_t final_data; -}; - -/** Initializes \a closure with \a cb and \a cb_arg. */ -void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb, - void *cb_arg); - -/* Create a heap allocated closure: try to avoid except for very rare events */ -grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg); - -#define GRPC_CLOSURE_LIST_INIT \ - { NULL, NULL } - -/** add \a closure to the end of \a list and set \a closure's success to \a - * success */ -void grpc_closure_list_add(grpc_closure_list *list, grpc_closure *closure, - bool success); - -/** append all closures from \a src to \a dst and empty \a src. */ -void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst); - -/** return whether \a list is empty. */ -bool grpc_closure_list_empty(grpc_closure_list list); - -/** return the next pointer for a queued closure list */ -grpc_closure *grpc_closure_next(grpc_closure *closure); - -#endif /* GRPC_CORE_IOMGR_CLOSURE_H */ diff --git a/src/core/iomgr/endpoint.c b/src/core/iomgr/endpoint.c deleted file mode 100644 index bd64707669..0000000000 --- a/src/core/iomgr/endpoint.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * Copyright 2015, 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/iomgr/endpoint.h" - -void grpc_endpoint_read(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep, - gpr_slice_buffer* slices, grpc_closure* cb) { - ep->vtable->read(exec_ctx, ep, slices, cb); -} - -void grpc_endpoint_write(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep, - gpr_slice_buffer* slices, grpc_closure* cb) { - ep->vtable->write(exec_ctx, ep, slices, cb); -} - -void grpc_endpoint_add_to_pollset(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep, - grpc_pollset* pollset) { - ep->vtable->add_to_pollset(exec_ctx, ep, pollset); -} - -void grpc_endpoint_add_to_pollset_set(grpc_exec_ctx* exec_ctx, - grpc_endpoint* ep, - grpc_pollset_set* pollset_set) { - ep->vtable->add_to_pollset_set(exec_ctx, ep, pollset_set); -} - -void grpc_endpoint_shutdown(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep) { - ep->vtable->shutdown(exec_ctx, ep); -} - -void grpc_endpoint_destroy(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep) { - ep->vtable->destroy(exec_ctx, ep); -} - -char* grpc_endpoint_get_peer(grpc_endpoint* ep) { - return ep->vtable->get_peer(ep); -} diff --git a/src/core/iomgr/endpoint.h b/src/core/iomgr/endpoint.h deleted file mode 100644 index b4be852e33..0000000000 --- a/src/core/iomgr/endpoint.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_ENDPOINT_H -#define GRPC_CORE_IOMGR_ENDPOINT_H - -#include -#include -#include -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/pollset_set.h" - -/* An endpoint caps a streaming channel between two communicating processes. - Examples may be: a tcp socket, , or some shared memory. */ - -typedef struct grpc_endpoint grpc_endpoint; -typedef struct grpc_endpoint_vtable grpc_endpoint_vtable; - -struct grpc_endpoint_vtable { - void (*read)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - gpr_slice_buffer *slices, grpc_closure *cb); - void (*write)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - gpr_slice_buffer *slices, grpc_closure *cb); - void (*add_to_pollset)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - grpc_pollset *pollset); - void (*add_to_pollset_set)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - grpc_pollset_set *pollset); - void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep); - void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep); - char *(*get_peer)(grpc_endpoint *ep); -}; - -/* When data is available on the connection, calls the callback with slices. - Callback success indicates that the endpoint can accept more reads, failure - indicates the endpoint is closed. - Valid slices may be placed into \a slices even on callback success == 0. */ -void grpc_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - gpr_slice_buffer *slices, grpc_closure *cb); - -char *grpc_endpoint_get_peer(grpc_endpoint *ep); - -/* Write slices out to the socket. - - If the connection is ready for more data after the end of the call, it - returns GRPC_ENDPOINT_DONE. - Otherwise it returns GRPC_ENDPOINT_PENDING and calls cb when the - connection is ready for more data. - \a slices may be mutated at will by the endpoint until cb is called. - No guarantee is made to the content of slices after a write EXCEPT that - it is a valid slice buffer. - */ -void grpc_endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - gpr_slice_buffer *slices, grpc_closure *cb); - -/* Causes any pending read/write callbacks to run immediately with - success==0 */ -void grpc_endpoint_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep); -void grpc_endpoint_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep); - -/* Add an endpoint to a pollset, so that when the pollset is polled, events from - this endpoint are considered */ -void grpc_endpoint_add_to_pollset(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - grpc_pollset *pollset); -void grpc_endpoint_add_to_pollset_set(grpc_exec_ctx *exec_ctx, - grpc_endpoint *ep, - grpc_pollset_set *pollset_set); - -struct grpc_endpoint { - const grpc_endpoint_vtable *vtable; -}; - -#endif /* GRPC_CORE_IOMGR_ENDPOINT_H */ diff --git a/src/core/iomgr/endpoint_pair.h b/src/core/iomgr/endpoint_pair.h deleted file mode 100644 index 59015d8ffb..0000000000 --- a/src/core/iomgr/endpoint_pair.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_ENDPOINT_PAIR_H -#define GRPC_CORE_IOMGR_ENDPOINT_PAIR_H - -#include "src/core/iomgr/endpoint.h" - -typedef struct { - grpc_endpoint *client; - grpc_endpoint *server; -} grpc_endpoint_pair; - -grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name, - size_t read_slice_size); - -#endif /* GRPC_CORE_IOMGR_ENDPOINT_PAIR_H */ diff --git a/src/core/iomgr/endpoint_pair_posix.c b/src/core/iomgr/endpoint_pair_posix.c deleted file mode 100644 index 66d19a486c..0000000000 --- a/src/core/iomgr/endpoint_pair_posix.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * - * 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 - -#ifdef GPR_POSIX_SOCKET - -#include "src/core/iomgr/endpoint_pair.h" -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/iomgr/unix_sockets_posix.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include "src/core/iomgr/tcp_posix.h" -#include "src/core/support/string.h" - -static void create_sockets(int sv[2]) { - int flags; - grpc_create_socketpair_if_unix(sv); - flags = fcntl(sv[0], F_GETFL, 0); - GPR_ASSERT(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK) == 0); - flags = fcntl(sv[1], F_GETFL, 0); - GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0); - GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv[0])); - GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv[1])); -} - -grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name, - size_t read_slice_size) { - int sv[2]; - grpc_endpoint_pair p; - char *final_name; - create_sockets(sv); - - gpr_asprintf(&final_name, "%s:client", name); - p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name), read_slice_size, - "socketpair-server"); - gpr_free(final_name); - gpr_asprintf(&final_name, "%s:server", name); - p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name), read_slice_size, - "socketpair-client"); - gpr_free(final_name); - return p; -} - -#endif diff --git a/src/core/iomgr/endpoint_pair_windows.c b/src/core/iomgr/endpoint_pair_windows.c deleted file mode 100644 index 2024f58143..0000000000 --- a/src/core/iomgr/endpoint_pair_windows.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_WINSOCK_SOCKET -#include "src/core/iomgr/endpoint_pair.h" -#include "src/core/iomgr/sockaddr_utils.h" - -#include -#include -#include - -#include -#include "src/core/iomgr/socket_windows.h" -#include "src/core/iomgr/tcp_windows.h" - -static void create_sockets(SOCKET sv[2]) { - SOCKET svr_sock = INVALID_SOCKET; - SOCKET lst_sock = INVALID_SOCKET; - SOCKET cli_sock = INVALID_SOCKET; - SOCKADDR_IN addr; - int addr_len = sizeof(addr); - - lst_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); - GPR_ASSERT(lst_sock != INVALID_SOCKET); - - memset(&addr, 0, sizeof(addr)); - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - addr.sin_family = AF_INET; - GPR_ASSERT(bind(lst_sock, (struct sockaddr *)&addr, sizeof(addr)) != - SOCKET_ERROR); - GPR_ASSERT(listen(lst_sock, SOMAXCONN) != SOCKET_ERROR); - GPR_ASSERT(getsockname(lst_sock, (struct sockaddr *)&addr, &addr_len) != - SOCKET_ERROR); - - cli_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); - GPR_ASSERT(cli_sock != INVALID_SOCKET); - - GPR_ASSERT(WSAConnect(cli_sock, (struct sockaddr *)&addr, addr_len, NULL, - NULL, NULL, NULL) == 0); - svr_sock = accept(lst_sock, (struct sockaddr *)&addr, &addr_len); - GPR_ASSERT(svr_sock != INVALID_SOCKET); - - closesocket(lst_sock); - grpc_tcp_prepare_socket(cli_sock); - grpc_tcp_prepare_socket(svr_sock); - - sv[1] = cli_sock; - sv[0] = svr_sock; -} - -grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name, - size_t read_slice_size) { - SOCKET sv[2]; - grpc_endpoint_pair p; - create_sockets(sv); - p.client = grpc_tcp_create(grpc_winsocket_create(sv[1], "endpoint:client"), - "endpoint:server"); - p.server = grpc_tcp_create(grpc_winsocket_create(sv[0], "endpoint:server"), - "endpoint:client"); - return p; -} - -#endif diff --git a/src/core/iomgr/exec_ctx.c b/src/core/iomgr/exec_ctx.c deleted file mode 100644 index 893fe4515c..0000000000 --- a/src/core/iomgr/exec_ctx.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * - * Copyright 2015-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/iomgr/exec_ctx.h" - -#include -#include -#include - -#include "src/core/profiling/timers.h" - -#ifndef GRPC_EXECUTION_CONTEXT_SANITIZER -bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { - bool did_something = 0; - GPR_TIMER_BEGIN("grpc_exec_ctx_flush", 0); - while (!grpc_closure_list_empty(exec_ctx->closure_list)) { - grpc_closure *c = exec_ctx->closure_list.head; - exec_ctx->closure_list.head = exec_ctx->closure_list.tail = NULL; - while (c != NULL) { - bool success = (bool)(c->final_data & 1); - grpc_closure *next = (grpc_closure *)(c->final_data & ~(uintptr_t)1); - did_something = true; - GPR_TIMER_BEGIN("grpc_exec_ctx_flush.cb", 0); - c->cb(exec_ctx, c->cb_arg, success); - GPR_TIMER_END("grpc_exec_ctx_flush.cb", 0); - c = next; - } - } - GPR_TIMER_END("grpc_exec_ctx_flush", 0); - return did_something; -} - -void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) { - grpc_exec_ctx_flush(exec_ctx); -} - -void grpc_exec_ctx_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure, - bool success, - grpc_workqueue *offload_target_or_null) { - GPR_ASSERT(offload_target_or_null == NULL); - grpc_closure_list_add(&exec_ctx->closure_list, closure, success); -} - -void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx, - grpc_closure_list *list, - grpc_workqueue *offload_target_or_null) { - GPR_ASSERT(offload_target_or_null == NULL); - grpc_closure_list_move(list, &exec_ctx->closure_list); -} - -void grpc_exec_ctx_global_init(void) {} -void grpc_exec_ctx_global_shutdown(void) {} -#else -static gpr_mu g_mu; -static gpr_cv g_cv; -static int g_threads = 0; - -static void run_closure(void *arg) { - grpc_closure *closure = arg; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - closure->cb(&exec_ctx, closure->cb_arg, (closure->final_data & 1) != 0); - grpc_exec_ctx_finish(&exec_ctx); - gpr_mu_lock(&g_mu); - if (--g_threads == 0) { - gpr_cv_signal(&g_cv); - } - gpr_mu_unlock(&g_mu); -} - -static void start_closure(grpc_closure *closure) { - gpr_thd_id id; - gpr_mu_lock(&g_mu); - g_threads++; - gpr_mu_unlock(&g_mu); - gpr_thd_new(&id, run_closure, closure, NULL); -} - -bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { return false; } - -void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) {} - -void grpc_exec_ctx_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure, - bool success, - grpc_workqueue *offload_target_or_null) { - GPR_ASSERT(offload_target_or_null == NULL); - if (closure == NULL) return; - closure->final_data = success; - start_closure(closure); -} - -void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx, - grpc_closure_list *list, - grpc_workqueue *offload_target_or_null) { - GPR_ASSERT(offload_target_or_null == NULL); - if (list == NULL) return; - grpc_closure *p = list->head; - while (p) { - grpc_closure *start = p; - p = grpc_closure_next(start); - start_closure(start); - } - grpc_closure_list r = GRPC_CLOSURE_LIST_INIT; - *list = r; -} - -void grpc_exec_ctx_global_init(void) { - gpr_mu_init(&g_mu); - gpr_cv_init(&g_cv); -} - -void grpc_exec_ctx_global_shutdown(void) { - gpr_mu_lock(&g_mu); - while (g_threads != 0) { - gpr_cv_wait(&g_cv, &g_mu, gpr_inf_future(GPR_CLOCK_REALTIME)); - } - gpr_mu_unlock(&g_mu); - - gpr_mu_destroy(&g_mu); - gpr_cv_destroy(&g_cv); -} -#endif diff --git a/src/core/iomgr/exec_ctx.h b/src/core/iomgr/exec_ctx.h deleted file mode 100644 index 07b54a0ab8..0000000000 --- a/src/core/iomgr/exec_ctx.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_EXEC_CTX_H -#define GRPC_CORE_IOMGR_EXEC_CTX_H - -#include "src/core/iomgr/closure.h" - -/* #define GRPC_EXECUTION_CONTEXT_SANITIZER 1 */ - -/** A workqueue represents a list of work to be executed asynchronously. - Forward declared here to avoid a circular dependency with workqueue.h. */ -struct grpc_workqueue; -typedef struct grpc_workqueue grpc_workqueue; - -#ifndef GRPC_EXECUTION_CONTEXT_SANITIZER -/** Execution context. - * A bag of data that collects information along a callstack. - * Generally created at public API entry points, and passed down as - * pointer to child functions that manipulate it. - * - * Specific responsibilities (this may grow in the future): - * - track a list of work that needs to be delayed until the top of the - * call stack (this provides a convenient mechanism to run callbacks - * without worrying about locking issues) - * - * CONVENTIONS: - * Instance of this must ALWAYS be constructed on the stack, never - * heap allocated. Instances and pointers to them must always be called - * exec_ctx. Instances are always passed as the first argument - * to a function that takes it, and always as a pointer (grpc_exec_ctx - * is never copied). - */ -struct grpc_exec_ctx { - grpc_closure_list closure_list; -}; - -#define GRPC_EXEC_CTX_INIT \ - { GRPC_CLOSURE_LIST_INIT } -#else -struct grpc_exec_ctx { - int unused; -}; -#define GRPC_EXEC_CTX_INIT \ - { 0 } -#endif - -/** Flush any work that has been enqueued onto this grpc_exec_ctx. - * Caller must guarantee that no interfering locks are held. - * Returns true if work was performed, false otherwise. */ -bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx); -/** Finish any pending work for a grpc_exec_ctx. Must be called before - * the instance is destroyed, or work may be lost. */ -void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx); -/** Add a closure to be executed at the next flush/finish point */ -void grpc_exec_ctx_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure, - bool success, - grpc_workqueue *offload_target_or_null); -/** Add a list of closures to be executed at the next flush/finish point. - * Leaves \a list empty. */ -void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx, - grpc_closure_list *list, - grpc_workqueue *offload_target_or_null); - -void grpc_exec_ctx_global_init(void); -void grpc_exec_ctx_global_shutdown(void); - -#endif /* GRPC_CORE_IOMGR_EXEC_CTX_H */ diff --git a/src/core/iomgr/executor.c b/src/core/iomgr/executor.c deleted file mode 100644 index f22d8f30ac..0000000000 --- a/src/core/iomgr/executor.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * - * Copyright 2015-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/iomgr/executor.h" - -#include - -#include -#include -#include -#include -#include "src/core/iomgr/exec_ctx.h" - -typedef struct grpc_executor_data { - int busy; /**< is the thread currently running? */ - int shutting_down; /**< has \a grpc_shutdown() been invoked? */ - int pending_join; /**< has the thread finished but not been joined? */ - grpc_closure_list closures; /**< collection of pending work */ - gpr_thd_id tid; /**< thread id of the thread, only valid if \a busy or \a - pending_join are true */ - gpr_thd_options options; - gpr_mu mu; -} grpc_executor; - -static grpc_executor g_executor; - -void grpc_executor_init() { - memset(&g_executor, 0, sizeof(grpc_executor)); - gpr_mu_init(&g_executor.mu); - g_executor.options = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&g_executor.options); -} - -/* thread body */ -static void closure_exec_thread_func(void *ignored) { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - while (1) { - gpr_mu_lock(&g_executor.mu); - if (g_executor.shutting_down != 0) { - gpr_mu_unlock(&g_executor.mu); - break; - } - if (grpc_closure_list_empty(g_executor.closures)) { - /* no more work, time to die */ - GPR_ASSERT(g_executor.busy == 1); - g_executor.busy = 0; - gpr_mu_unlock(&g_executor.mu); - break; - } else { - grpc_exec_ctx_enqueue_list(&exec_ctx, &g_executor.closures, NULL); - } - gpr_mu_unlock(&g_executor.mu); - grpc_exec_ctx_flush(&exec_ctx); - } - grpc_exec_ctx_finish(&exec_ctx); -} - -/* Spawn the thread if new work has arrived a no thread is up */ -static void maybe_spawn_locked() { - if (grpc_closure_list_empty(g_executor.closures) == 1) { - return; - } - if (g_executor.shutting_down == 1) { - return; - } - - if (g_executor.busy != 0) { - /* Thread still working. New work will be picked up by already running - * thread. Not spawning anything. */ - return; - } else if (g_executor.pending_join != 0) { - /* Pickup the remains of the previous incarnations of the thread. */ - gpr_thd_join(g_executor.tid); - g_executor.pending_join = 0; - } - - /* All previous instances of the thread should have been joined at this point. - * Spawn time! */ - g_executor.busy = 1; - gpr_thd_new(&g_executor.tid, closure_exec_thread_func, NULL, - &g_executor.options); - g_executor.pending_join = 1; -} - -void grpc_executor_enqueue(grpc_closure *closure, bool success) { - gpr_mu_lock(&g_executor.mu); - if (g_executor.shutting_down == 0) { - grpc_closure_list_add(&g_executor.closures, closure, success); - maybe_spawn_locked(); - } - gpr_mu_unlock(&g_executor.mu); -} - -void grpc_executor_shutdown() { - int pending_join; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - gpr_mu_lock(&g_executor.mu); - pending_join = g_executor.pending_join; - g_executor.shutting_down = 1; - gpr_mu_unlock(&g_executor.mu); - /* we can release the lock at this point despite the access to the closure - * list below because we aren't accepting new work */ - - /* Execute pending callbacks, some may be performing cleanups */ - grpc_exec_ctx_enqueue_list(&exec_ctx, &g_executor.closures, NULL); - grpc_exec_ctx_finish(&exec_ctx); - GPR_ASSERT(grpc_closure_list_empty(g_executor.closures)); - if (pending_join) { - gpr_thd_join(g_executor.tid); - } - gpr_mu_destroy(&g_executor.mu); -} diff --git a/src/core/iomgr/executor.h b/src/core/iomgr/executor.h deleted file mode 100644 index f66b3560e3..0000000000 --- a/src/core/iomgr/executor.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_EXECUTOR_H -#define GRPC_CORE_IOMGR_EXECUTOR_H - -#include "src/core/iomgr/closure.h" - -/** Initialize the global executor. - * - * This mechanism is meant to outsource work (grpc_closure instances) to a - * thread, for those cases where blocking isn't an option but there isn't a - * non-blocking solution available. */ -void grpc_executor_init(); - -/** Enqueue \a closure for its eventual execution of \a f(arg) on a separate - * thread */ -void grpc_executor_enqueue(grpc_closure *closure, bool success); - -/** Shutdown the executor, running all pending work as part of the call */ -void grpc_executor_shutdown(); - -#endif /* GRPC_CORE_IOMGR_EXECUTOR_H */ diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c deleted file mode 100644 index b4d038a3a1..0000000000 --- a/src/core/iomgr/fd_posix.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_SOCKET - -#include "src/core/iomgr/fd_posix.h" - -#include -#include -#include - -#include -#include -#include -#include - -#include "src/core/iomgr/pollset_posix.h" - -#define CLOSURE_NOT_READY ((grpc_closure *)0) -#define CLOSURE_READY ((grpc_closure *)1) - -/* We need to keep a freelist not because of any concerns of malloc performance - * but instead so that implementations with multiple threads in (for example) - * epoll_wait deal with the race between pollset removal and incoming poll - * notifications. - * - * The problem is that the poller ultimately holds a reference to this - * object, so it is very difficult to know when is safe to free it, at least - * without some expensive synchronization. - * - * If we keep the object freelisted, in the worst case losing this race just - * becomes a spurious read notification on a reused fd. - */ -/* TODO(klempner): We could use some form of polling generation count to know - * when these are safe to free. */ -/* TODO(klempner): Consider disabling freelisting if we don't have multiple - * threads in poll on the same fd */ -/* TODO(klempner): Batch these allocations to reduce fragmentation */ -static grpc_fd *fd_freelist = NULL; -static gpr_mu fd_freelist_mu; - -static void freelist_fd(grpc_fd *fd) { - gpr_mu_lock(&fd_freelist_mu); - fd->freelist_next = fd_freelist; - fd_freelist = fd; - grpc_iomgr_unregister_object(&fd->iomgr_object); - gpr_mu_unlock(&fd_freelist_mu); -} - -static grpc_fd *alloc_fd(int fd) { - grpc_fd *r = NULL; - gpr_mu_lock(&fd_freelist_mu); - if (fd_freelist != NULL) { - r = fd_freelist; - fd_freelist = fd_freelist->freelist_next; - } - gpr_mu_unlock(&fd_freelist_mu); - if (r == NULL) { - r = gpr_malloc(sizeof(grpc_fd)); - gpr_mu_init(&r->mu); - } - - gpr_mu_lock(&r->mu); - r->shutdown = 0; - r->read_closure = CLOSURE_NOT_READY; - r->write_closure = CLOSURE_NOT_READY; - r->fd = fd; - r->inactive_watcher_root.next = r->inactive_watcher_root.prev = - &r->inactive_watcher_root; - r->freelist_next = NULL; - r->read_watcher = r->write_watcher = NULL; - r->on_done_closure = NULL; - r->closed = 0; - r->released = 0; - gpr_atm_rel_store(&r->refst, 1); - gpr_mu_unlock(&r->mu); - - return r; -} - -static void destroy(grpc_fd *fd) { - gpr_mu_destroy(&fd->mu); - gpr_free(fd); -} - -#ifdef GRPC_FD_REF_COUNT_DEBUG -#define REF_BY(fd, n, reason) ref_by(fd, n, reason, __FILE__, __LINE__) -#define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__) -static void ref_by(grpc_fd *fd, int n, const char *reason, const char *file, - int line) { - gpr_log(GPR_DEBUG, "FD %d %p ref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n, - gpr_atm_no_barrier_load(&fd->refst), - gpr_atm_no_barrier_load(&fd->refst) + n, reason, file, line); -#else -#define REF_BY(fd, n, reason) ref_by(fd, n) -#define UNREF_BY(fd, n, reason) unref_by(fd, n) -static void ref_by(grpc_fd *fd, int n) { -#endif - GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0); -} - -#ifdef GRPC_FD_REF_COUNT_DEBUG -static void unref_by(grpc_fd *fd, int n, const char *reason, const char *file, - int line) { - gpr_atm old; - gpr_log(GPR_DEBUG, "FD %d %p unref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n, - gpr_atm_no_barrier_load(&fd->refst), - gpr_atm_no_barrier_load(&fd->refst) - n, reason, file, line); -#else -static void unref_by(grpc_fd *fd, int n) { - gpr_atm old; -#endif - old = gpr_atm_full_fetch_add(&fd->refst, -n); - if (old == n) { - freelist_fd(fd); - } else { - GPR_ASSERT(old > n); - } -} - -void grpc_fd_global_init(void) { gpr_mu_init(&fd_freelist_mu); } - -void grpc_fd_global_shutdown(void) { - gpr_mu_lock(&fd_freelist_mu); - gpr_mu_unlock(&fd_freelist_mu); - while (fd_freelist != NULL) { - grpc_fd *fd = fd_freelist; - fd_freelist = fd_freelist->freelist_next; - destroy(fd); - } - gpr_mu_destroy(&fd_freelist_mu); -} - -grpc_fd *grpc_fd_create(int fd, const char *name) { - grpc_fd *r = alloc_fd(fd); - char *name2; - gpr_asprintf(&name2, "%s fd=%d", name, fd); - grpc_iomgr_register_object(&r->iomgr_object, name2); - gpr_free(name2); -#ifdef GRPC_FD_REF_COUNT_DEBUG - gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, r, name); -#endif - return r; -} - -int grpc_fd_is_orphaned(grpc_fd *fd) { - return (gpr_atm_acq_load(&fd->refst) & 1) == 0; -} - -static void pollset_kick_locked(grpc_fd_watcher *watcher) { - gpr_mu_lock(&watcher->pollset->mu); - GPR_ASSERT(watcher->worker); - grpc_pollset_kick_ext(watcher->pollset, watcher->worker, - GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP); - gpr_mu_unlock(&watcher->pollset->mu); -} - -static void maybe_wake_one_watcher_locked(grpc_fd *fd) { - if (fd->inactive_watcher_root.next != &fd->inactive_watcher_root) { - pollset_kick_locked(fd->inactive_watcher_root.next); - } else if (fd->read_watcher) { - pollset_kick_locked(fd->read_watcher); - } else if (fd->write_watcher) { - pollset_kick_locked(fd->write_watcher); - } -} - -static void wake_all_watchers_locked(grpc_fd *fd) { - grpc_fd_watcher *watcher; - for (watcher = fd->inactive_watcher_root.next; - watcher != &fd->inactive_watcher_root; watcher = watcher->next) { - pollset_kick_locked(watcher); - } - if (fd->read_watcher) { - pollset_kick_locked(fd->read_watcher); - } - if (fd->write_watcher && fd->write_watcher != fd->read_watcher) { - pollset_kick_locked(fd->write_watcher); - } -} - -static int has_watchers(grpc_fd *fd) { - return fd->read_watcher != NULL || fd->write_watcher != NULL || - fd->inactive_watcher_root.next != &fd->inactive_watcher_root; -} - -static void close_fd_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { - fd->closed = 1; - if (!fd->released) { - close(fd->fd); - } else { - grpc_remove_fd_from_all_epoll_sets(fd->fd); - } - grpc_exec_ctx_enqueue(exec_ctx, fd->on_done_closure, true, NULL); -} - -int grpc_fd_wrapped_fd(grpc_fd *fd) { - if (fd->released || fd->closed) { - return -1; - } else { - return fd->fd; - } -} - -void grpc_fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done, - int *release_fd, const char *reason) { - fd->on_done_closure = on_done; - fd->released = release_fd != NULL; - if (!fd->released) { - shutdown(fd->fd, SHUT_RDWR); - } else { - *release_fd = fd->fd; - } - gpr_mu_lock(&fd->mu); - REF_BY(fd, 1, reason); /* remove active status, but keep referenced */ - if (!has_watchers(fd)) { - close_fd_locked(exec_ctx, fd); - } else { - wake_all_watchers_locked(fd); - } - gpr_mu_unlock(&fd->mu); - UNREF_BY(fd, 2, reason); /* drop the reference */ -} - -/* increment refcount by two to avoid changing the orphan bit */ -#ifdef GRPC_FD_REF_COUNT_DEBUG -void grpc_fd_ref(grpc_fd *fd, const char *reason, const char *file, int line) { - ref_by(fd, 2, reason, file, line); -} - -void grpc_fd_unref(grpc_fd *fd, const char *reason, const char *file, - int line) { - unref_by(fd, 2, reason, file, line); -} -#else -void grpc_fd_ref(grpc_fd *fd) { ref_by(fd, 2); } - -void grpc_fd_unref(grpc_fd *fd) { unref_by(fd, 2); } -#endif - -static void notify_on_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd, - grpc_closure **st, grpc_closure *closure) { - if (*st == CLOSURE_NOT_READY) { - /* not ready ==> switch to a waiting state by setting the closure */ - *st = closure; - } else if (*st == CLOSURE_READY) { - /* already ready ==> queue the closure to run immediately */ - *st = CLOSURE_NOT_READY; - grpc_exec_ctx_enqueue(exec_ctx, closure, !fd->shutdown, NULL); - maybe_wake_one_watcher_locked(fd); - } else { - /* upcallptr was set to a different closure. This is an error! */ - gpr_log(GPR_ERROR, - "User called a notify_on function with a previous callback still " - "pending"); - abort(); - } -} - -/* returns 1 if state becomes not ready */ -static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd, - grpc_closure **st) { - if (*st == CLOSURE_READY) { - /* duplicate ready ==> ignore */ - return 0; - } else if (*st == CLOSURE_NOT_READY) { - /* not ready, and not waiting ==> flag ready */ - *st = CLOSURE_READY; - return 0; - } else { - /* waiting ==> queue closure */ - grpc_exec_ctx_enqueue(exec_ctx, *st, !fd->shutdown, NULL); - *st = CLOSURE_NOT_READY; - return 1; - } -} - -static void set_ready(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure **st) { - /* only one set_ready can be active at once (but there may be a racing - notify_on) */ - gpr_mu_lock(&fd->mu); - set_ready_locked(exec_ctx, fd, st); - gpr_mu_unlock(&fd->mu); -} - -void grpc_fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { - gpr_mu_lock(&fd->mu); - GPR_ASSERT(!fd->shutdown); - fd->shutdown = 1; - set_ready_locked(exec_ctx, fd, &fd->read_closure); - set_ready_locked(exec_ctx, fd, &fd->write_closure); - gpr_mu_unlock(&fd->mu); -} - -void grpc_fd_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_fd *fd, - grpc_closure *closure) { - gpr_mu_lock(&fd->mu); - notify_on_locked(exec_ctx, fd, &fd->read_closure, closure); - gpr_mu_unlock(&fd->mu); -} - -void grpc_fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd, - grpc_closure *closure) { - gpr_mu_lock(&fd->mu); - notify_on_locked(exec_ctx, fd, &fd->write_closure, closure); - gpr_mu_unlock(&fd->mu); -} - -uint32_t grpc_fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset, - grpc_pollset_worker *worker, uint32_t read_mask, - uint32_t write_mask, grpc_fd_watcher *watcher) { - uint32_t mask = 0; - grpc_closure *cur; - int requested; - /* keep track of pollers that have requested our events, in case they change - */ - GRPC_FD_REF(fd, "poll"); - - gpr_mu_lock(&fd->mu); - - /* if we are shutdown, then don't add to the watcher set */ - if (fd->shutdown) { - watcher->fd = NULL; - watcher->pollset = NULL; - watcher->worker = NULL; - gpr_mu_unlock(&fd->mu); - GRPC_FD_UNREF(fd, "poll"); - return 0; - } - - /* if there is nobody polling for read, but we need to, then start doing so */ - cur = fd->read_closure; - requested = cur != CLOSURE_READY; - if (read_mask && fd->read_watcher == NULL && requested) { - fd->read_watcher = watcher; - mask |= read_mask; - } - /* if there is nobody polling for write, but we need to, then start doing so - */ - cur = fd->write_closure; - requested = cur != CLOSURE_READY; - if (write_mask && fd->write_watcher == NULL && requested) { - fd->write_watcher = watcher; - mask |= write_mask; - } - /* if not polling, remember this watcher in case we need someone to later */ - if (mask == 0 && worker != NULL) { - watcher->next = &fd->inactive_watcher_root; - watcher->prev = watcher->next->prev; - watcher->next->prev = watcher->prev->next = watcher; - } - watcher->pollset = pollset; - watcher->worker = worker; - watcher->fd = fd; - gpr_mu_unlock(&fd->mu); - - return mask; -} - -void grpc_fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher, - int got_read, int got_write) { - int was_polling = 0; - int kick = 0; - grpc_fd *fd = watcher->fd; - - if (fd == NULL) { - return; - } - - gpr_mu_lock(&fd->mu); - - if (watcher == fd->read_watcher) { - /* remove read watcher, kick if we still need a read */ - was_polling = 1; - if (!got_read) { - kick = 1; - } - fd->read_watcher = NULL; - } - if (watcher == fd->write_watcher) { - /* remove write watcher, kick if we still need a write */ - was_polling = 1; - if (!got_write) { - kick = 1; - } - fd->write_watcher = NULL; - } - if (!was_polling && watcher->worker != NULL) { - /* remove from inactive list */ - watcher->next->prev = watcher->prev; - watcher->prev->next = watcher->next; - } - if (got_read) { - if (set_ready_locked(exec_ctx, fd, &fd->read_closure)) { - kick = 1; - } - } - if (got_write) { - if (set_ready_locked(exec_ctx, fd, &fd->write_closure)) { - kick = 1; - } - } - if (kick) { - maybe_wake_one_watcher_locked(fd); - } - if (grpc_fd_is_orphaned(fd) && !has_watchers(fd) && !fd->closed) { - close_fd_locked(exec_ctx, fd); - } - gpr_mu_unlock(&fd->mu); - - GRPC_FD_UNREF(fd, "poll"); -} - -void grpc_fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { - set_ready(exec_ctx, fd, &fd->read_closure); -} - -void grpc_fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { - set_ready(exec_ctx, fd, &fd->write_closure); -} - -#endif diff --git a/src/core/iomgr/fd_posix.h b/src/core/iomgr/fd_posix.h deleted file mode 100644 index 1993ada79f..0000000000 --- a/src/core/iomgr/fd_posix.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_FD_POSIX_H -#define GRPC_CORE_IOMGR_FD_POSIX_H - -#include -#include -#include -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/pollset.h" - -typedef struct grpc_fd grpc_fd; - -typedef struct grpc_fd_watcher { - struct grpc_fd_watcher *next; - struct grpc_fd_watcher *prev; - grpc_pollset *pollset; - grpc_pollset_worker *worker; - grpc_fd *fd; -} grpc_fd_watcher; - -struct grpc_fd { - int fd; - /* refst format: - bit0: 1=active/0=orphaned - bit1-n: refcount - meaning that mostly we ref by two to avoid altering the orphaned bit, - and just unref by 1 when we're ready to flag the object as orphaned */ - gpr_atm refst; - - gpr_mu mu; - int shutdown; - int closed; - int released; - - /* The watcher list. - - The following watcher related fields are protected by watcher_mu. - - An fd_watcher is an ephemeral object created when an fd wants to - begin polling, and destroyed after the poll. - - It denotes the fd's interest in whether to read poll or write poll - or both or neither on this fd. - - If a watcher is asked to poll for reads or writes, the read_watcher - or write_watcher fields are set respectively. A watcher may be asked - to poll for both, in which case both fields will be set. - - read_watcher and write_watcher may be NULL if no watcher has been - asked to poll for reads or writes. - - If an fd_watcher is not asked to poll for reads or writes, it's added - to a linked list of inactive watchers, rooted at inactive_watcher_root. - If at a later time there becomes need of a poller to poll, one of - the inactive pollers may be kicked out of their poll loops to take - that responsibility. */ - grpc_fd_watcher inactive_watcher_root; - grpc_fd_watcher *read_watcher; - grpc_fd_watcher *write_watcher; - - grpc_closure *read_closure; - grpc_closure *write_closure; - - struct grpc_fd *freelist_next; - - grpc_closure *on_done_closure; - - grpc_iomgr_object iomgr_object; -}; - -/* Create a wrapped file descriptor. - Requires fd is a non-blocking file descriptor. - This takes ownership of closing fd. */ -grpc_fd *grpc_fd_create(int fd, const char *name); - -/* Return the wrapped fd, or -1 if it has been released or closed. */ -int grpc_fd_wrapped_fd(grpc_fd *fd); - -/* Releases fd to be asynchronously destroyed. - on_done is called when the underlying file descriptor is definitely close()d. - If on_done is NULL, no callback will be made. - If release_fd is not NULL, it's set to fd and fd will not be closed. - Requires: *fd initialized; no outstanding notify_on_read or - notify_on_write. - MUST NOT be called with a pollset lock taken */ -void grpc_fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done, - int *release_fd, const char *reason); - -/* Begin polling on an fd. - Registers that the given pollset is interested in this fd - so that if read - or writability interest changes, the pollset can be kicked to pick up that - new interest. - Return value is: - (fd_needs_read? read_mask : 0) | (fd_needs_write? write_mask : 0) - i.e. a combination of read_mask and write_mask determined by the fd's current - interest in said events. - Polling strategies that do not need to alter their behavior depending on the - fd's current interest (such as epoll) do not need to call this function. - MUST NOT be called with a pollset lock taken */ -uint32_t grpc_fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset, - grpc_pollset_worker *worker, uint32_t read_mask, - uint32_t write_mask, grpc_fd_watcher *rec); -/* Complete polling previously started with grpc_fd_begin_poll - MUST NOT be called with a pollset lock taken - if got_read or got_write are 1, also does the become_{readable,writable} as - appropriate. */ -void grpc_fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *rec, - int got_read, int got_write); - -/* Return 1 if this fd is orphaned, 0 otherwise */ -int grpc_fd_is_orphaned(grpc_fd *fd); - -/* Cause any current callbacks to error out with GRPC_CALLBACK_CANCELLED. */ -void grpc_fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd); - -/* Register read interest, causing read_cb to be called once when fd becomes - readable, on deadline specified by deadline, or on shutdown triggered by - grpc_fd_shutdown. - read_cb will be called with read_cb_arg when *fd becomes readable. - read_cb is Called with status of GRPC_CALLBACK_SUCCESS if readable, - GRPC_CALLBACK_TIMED_OUT if the call timed out, - and CANCELLED if the call was cancelled. - - Requires:This method must not be called before the read_cb for any previous - call runs. Edge triggered events are used whenever they are supported by the - underlying platform. This means that users must drain fd in read_cb before - calling notify_on_read again. Users are also expected to handle spurious - events, i.e read_cb is called while nothing can be readable from fd */ -void grpc_fd_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_fd *fd, - grpc_closure *closure); - -/* Exactly the same semantics as above, except based on writable events. */ -void grpc_fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd, - grpc_closure *closure); - -/* Notification from the poller to an fd that it has become readable or - writable. - If allow_synchronous_callback is 1, allow running the fd callback inline - in this callstack, otherwise register an asynchronous callback and return */ -void grpc_fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd); -void grpc_fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd); - -/* Reference counting for fds */ -/*#define GRPC_FD_REF_COUNT_DEBUG*/ -#ifdef GRPC_FD_REF_COUNT_DEBUG -void grpc_fd_ref(grpc_fd *fd, const char *reason, const char *file, int line); -void grpc_fd_unref(grpc_fd *fd, const char *reason, const char *file, int line); -#define GRPC_FD_REF(fd, reason) grpc_fd_ref(fd, reason, __FILE__, __LINE__) -#define GRPC_FD_UNREF(fd, reason) grpc_fd_unref(fd, reason, __FILE__, __LINE__) -#else -void grpc_fd_ref(grpc_fd *fd); -void grpc_fd_unref(grpc_fd *fd); -#define GRPC_FD_REF(fd, reason) grpc_fd_ref(fd) -#define GRPC_FD_UNREF(fd, reason) grpc_fd_unref(fd) -#endif - -void grpc_fd_global_init(void); -void grpc_fd_global_shutdown(void); - -#endif /* GRPC_CORE_IOMGR_FD_POSIX_H */ diff --git a/src/core/iomgr/iocp_windows.c b/src/core/iomgr/iocp_windows.c deleted file mode 100644 index 37e277dcc1..0000000000 --- a/src/core/iomgr/iocp_windows.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_WINSOCK_SOCKET - -#include - -#include -#include -#include -#include - -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/socket_windows.h" -#include "src/core/iomgr/timer.h" - -static ULONG g_iocp_kick_token; -static OVERLAPPED g_iocp_custom_overlap; - -static gpr_atm g_custom_events = 0; - -static HANDLE g_iocp; - -static DWORD deadline_to_millis_timeout(gpr_timespec deadline, - gpr_timespec now) { - gpr_timespec timeout; - static const int64_t max_spin_polling_us = 10; - if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) == 0) { - return INFINITE; - } - if (gpr_time_cmp(deadline, gpr_time_add(now, gpr_time_from_micros( - max_spin_polling_us, - GPR_TIMESPAN))) <= 0) { - return 0; - } - timeout = gpr_time_sub(deadline, now); - return (DWORD)gpr_time_to_millis(gpr_time_add( - timeout, gpr_time_from_nanos(GPR_NS_PER_MS - 1, GPR_TIMESPAN))); -} - -grpc_iocp_work_status grpc_iocp_work(grpc_exec_ctx *exec_ctx, - gpr_timespec deadline) { - BOOL success; - DWORD bytes = 0; - DWORD flags = 0; - ULONG_PTR completion_key; - 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))); - if (success == 0 && overlapped == NULL) { - return GRPC_IOCP_WORK_TIMEOUT; - } - GPR_ASSERT(completion_key && overlapped); - if (overlapped == &g_iocp_custom_overlap) { - gpr_atm_full_fetch_add(&g_custom_events, -1); - if (completion_key == (ULONG_PTR)&g_iocp_kick_token) { - /* We were awoken from a kick. */ - return GRPC_IOCP_WORK_KICK; - } - gpr_log(GPR_ERROR, "Unknown custom completion key."); - abort(); - } - - socket = (grpc_winsocket *)completion_key; - if (overlapped == &socket->write_info.overlapped) { - info = &socket->write_info; - } else if (overlapped == &socket->read_info.overlapped) { - info = &socket->read_info; - } else { - gpr_log(GPR_ERROR, "Unknown IOCP operation"); - abort(); - } - success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes, - FALSE, &flags); - info->bytes_transfered = bytes; - info->wsa_error = success ? 0 : WSAGetLastError(); - GPR_ASSERT(overlapped == &info->overlapped); - GPR_ASSERT(!info->has_pending_iocp); - gpr_mu_lock(&socket->state_mu); - if (info->closure) { - closure = info->closure; - info->closure = NULL; - } else { - info->has_pending_iocp = 1; - } - gpr_mu_unlock(&socket->state_mu); - grpc_exec_ctx_enqueue(exec_ctx, closure, true, NULL); - return GRPC_IOCP_WORK_WORK; -} - -void grpc_iocp_init(void) { - g_iocp = - CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, (ULONG_PTR)NULL, 0); - GPR_ASSERT(g_iocp); -} - -void grpc_iocp_kick(void) { - BOOL success; - - gpr_atm_full_fetch_add(&g_custom_events, 1); - success = PostQueuedCompletionStatus(g_iocp, 0, (ULONG_PTR)&g_iocp_kick_token, - &g_iocp_custom_overlap); - GPR_ASSERT(success); -} - -void grpc_iocp_flush(void) { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_iocp_work_status work_status; - - do { - work_status = grpc_iocp_work(&exec_ctx, gpr_inf_past(GPR_CLOCK_MONOTONIC)); - } while (work_status == GRPC_IOCP_WORK_KICK || - grpc_exec_ctx_flush(&exec_ctx)); -} - -void grpc_iocp_shutdown(void) { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - while (gpr_atm_acq_load(&g_custom_events)) { - grpc_iocp_work(&exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC)); - grpc_exec_ctx_flush(&exec_ctx); - } - grpc_exec_ctx_finish(&exec_ctx); - GPR_ASSERT(CloseHandle(g_iocp)); -} - -void grpc_iocp_add_socket(grpc_winsocket *socket) { - HANDLE ret; - if (socket->added_to_iocp) return; - ret = CreateIoCompletionPort((HANDLE)socket->socket, g_iocp, - (uintptr_t)socket, 0); - if (!ret) { - char *utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, "Unable to add socket to iocp: %s", utf8_message); - gpr_free(utf8_message); - __debugbreak(); - abort(); - } - socket->added_to_iocp = 1; - GPR_ASSERT(ret == g_iocp); -} - -/* Calling notify_on_read or write means either of two things: - -) The IOCP already completed in the background, and we need to call - the callback now. - -) The IOCP hasn't completed yet, and we're queuing it for later. */ -static void socket_notify_on_iocp(grpc_exec_ctx *exec_ctx, - grpc_winsocket *socket, grpc_closure *closure, - grpc_winsocket_callback_info *info) { - GPR_ASSERT(info->closure == NULL); - gpr_mu_lock(&socket->state_mu); - if (info->has_pending_iocp) { - info->has_pending_iocp = 0; - grpc_exec_ctx_enqueue(exec_ctx, closure, true, NULL); - } else { - info->closure = closure; - } - gpr_mu_unlock(&socket->state_mu); -} - -void grpc_socket_notify_on_write(grpc_exec_ctx *exec_ctx, - grpc_winsocket *socket, - grpc_closure *closure) { - socket_notify_on_iocp(exec_ctx, socket, closure, &socket->write_info); -} - -void grpc_socket_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_winsocket *socket, - grpc_closure *closure) { - socket_notify_on_iocp(exec_ctx, socket, closure, &socket->read_info); -} - -#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/iomgr/iocp_windows.h b/src/core/iomgr/iocp_windows.h deleted file mode 100644 index 570b8925aa..0000000000 --- a/src/core/iomgr/iocp_windows.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_IOCP_WINDOWS_H -#define GRPC_CORE_IOMGR_IOCP_WINDOWS_H - -#include - -#include "src/core/iomgr/socket_windows.h" - -typedef enum { - GRPC_IOCP_WORK_WORK, - GRPC_IOCP_WORK_TIMEOUT, - GRPC_IOCP_WORK_KICK -} grpc_iocp_work_status; - -grpc_iocp_work_status grpc_iocp_work(grpc_exec_ctx *exec_ctx, - gpr_timespec deadline); -void grpc_iocp_init(void); -void grpc_iocp_kick(void); -void grpc_iocp_flush(void); -void grpc_iocp_shutdown(void); -void grpc_iocp_add_socket(grpc_winsocket *); - -void grpc_socket_notify_on_write(grpc_exec_ctx *exec_ctx, - grpc_winsocket *winsocket, - grpc_closure *closure); - -void grpc_socket_notify_on_read(grpc_exec_ctx *exec_ctx, - grpc_winsocket *winsocket, - grpc_closure *closure); - -#endif /* GRPC_CORE_IOMGR_IOCP_WINDOWS_H */ diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c deleted file mode 100644 index 3ab4430668..0000000000 --- a/src/core/iomgr/iomgr.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * - * Copyright 2015-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/iomgr/iomgr.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/timer.h" -#include "src/core/support/env.h" -#include "src/core/support/string.h" - -static gpr_mu g_mu; -static gpr_cv g_rcv; -static int g_shutdown; -static grpc_iomgr_object g_root_object; - -void grpc_iomgr_init(void) { - g_shutdown = 0; - gpr_mu_init(&g_mu); - gpr_cv_init(&g_rcv); - grpc_exec_ctx_global_init(); - grpc_timer_list_init(gpr_now(GPR_CLOCK_MONOTONIC)); - g_root_object.next = g_root_object.prev = &g_root_object; - g_root_object.name = "root"; - grpc_iomgr_platform_init(); - grpc_pollset_global_init(); -} - -static size_t count_objects(void) { - grpc_iomgr_object *obj; - size_t n = 0; - for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) { - n++; - } - return n; -} - -static void dump_objects(const char *kind) { - grpc_iomgr_object *obj; - for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) { - gpr_log(GPR_DEBUG, "%s OBJECT: %s %p", kind, obj->name, obj); - } -} - -void grpc_iomgr_shutdown(void) { - gpr_timespec shutdown_deadline = gpr_time_add( - gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(10, GPR_TIMESPAN)); - gpr_timespec last_warning_time = gpr_now(GPR_CLOCK_REALTIME); - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - grpc_iomgr_platform_flush(); - - gpr_mu_lock(&g_mu); - g_shutdown = 1; - while (g_root_object.next != &g_root_object) { - if (gpr_time_cmp( - gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), last_warning_time), - gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) { - if (g_root_object.next != &g_root_object) { - gpr_log(GPR_DEBUG, "Waiting for %d iomgr objects to be destroyed", - count_objects()); - } - last_warning_time = gpr_now(GPR_CLOCK_REALTIME); - } - if (grpc_timer_check(&exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC), - NULL)) { - gpr_mu_unlock(&g_mu); - grpc_exec_ctx_flush(&exec_ctx); - gpr_mu_lock(&g_mu); - continue; - } - if (g_root_object.next != &g_root_object) { - gpr_timespec short_deadline = gpr_time_add( - gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(100, GPR_TIMESPAN)); - if (gpr_cv_wait(&g_rcv, &g_mu, short_deadline)) { - if (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), shutdown_deadline) > 0) { - if (g_root_object.next != &g_root_object) { - gpr_log(GPR_DEBUG, - "Failed to free %d iomgr objects before shutdown deadline: " - "memory leaks are likely", - count_objects()); - dump_objects("LEAKED"); - if (grpc_iomgr_abort_on_leaks()) { - abort(); - } - } - break; - } - } - } - } - gpr_mu_unlock(&g_mu); - - grpc_timer_list_shutdown(&exec_ctx); - grpc_exec_ctx_finish(&exec_ctx); - - /* ensure all threads have left g_mu */ - gpr_mu_lock(&g_mu); - gpr_mu_unlock(&g_mu); - - grpc_pollset_global_shutdown(); - grpc_iomgr_platform_shutdown(); - grpc_exec_ctx_global_shutdown(); - gpr_mu_destroy(&g_mu); - gpr_cv_destroy(&g_rcv); -} - -void grpc_iomgr_register_object(grpc_iomgr_object *obj, const char *name) { - obj->name = gpr_strdup(name); - gpr_mu_lock(&g_mu); - obj->next = &g_root_object; - obj->prev = g_root_object.prev; - obj->next->prev = obj->prev->next = obj; - gpr_mu_unlock(&g_mu); -} - -void grpc_iomgr_unregister_object(grpc_iomgr_object *obj) { - gpr_mu_lock(&g_mu); - obj->next->prev = obj->prev; - obj->prev->next = obj->next; - gpr_cv_signal(&g_rcv); - gpr_mu_unlock(&g_mu); - gpr_free(obj->name); -} - -bool grpc_iomgr_abort_on_leaks(void) { - char *env = gpr_getenv("GRPC_ABORT_ON_LEAKS"); - if (env == NULL) return false; - static const char *truthy[] = {"yes", "Yes", "YES", "true", - "True", "TRUE", "1"}; - for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) { - if (0 == strcmp(env, truthy[i])) return true; - } - return false; -} diff --git a/src/core/iomgr/iomgr.h b/src/core/iomgr/iomgr.h deleted file mode 100644 index e1237a4533..0000000000 --- a/src/core/iomgr/iomgr.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_IOMGR_H -#define GRPC_CORE_IOMGR_IOMGR_H - -/** Initializes the iomgr. */ -void grpc_iomgr_init(void); - -/** Signals the intention to shutdown the iomgr. */ -void grpc_iomgr_shutdown(void); - -#endif /* GRPC_CORE_IOMGR_IOMGR_H */ diff --git a/src/core/iomgr/iomgr_internal.h b/src/core/iomgr/iomgr_internal.h deleted file mode 100644 index 1cad3182ec..0000000000 --- a/src/core/iomgr/iomgr_internal.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_IOMGR_INTERNAL_H -#define GRPC_CORE_IOMGR_IOMGR_INTERNAL_H - -#include - -#include -#include "src/core/iomgr/iomgr.h" - -typedef struct grpc_iomgr_object { - char *name; - struct grpc_iomgr_object *next; - struct grpc_iomgr_object *prev; -} grpc_iomgr_object; - -void grpc_pollset_global_init(void); -void grpc_pollset_global_shutdown(void); - -void grpc_iomgr_register_object(grpc_iomgr_object *obj, const char *name); -void grpc_iomgr_unregister_object(grpc_iomgr_object *obj); - -void grpc_iomgr_platform_init(void); -/** flush any globally queued work from iomgr */ -void grpc_iomgr_platform_flush(void); -/** tear down all platform specific global iomgr structures */ -void grpc_iomgr_platform_shutdown(void); - -bool grpc_iomgr_abort_on_leaks(void); - -#endif /* GRPC_CORE_IOMGR_IOMGR_INTERNAL_H */ diff --git a/src/core/iomgr/iomgr_posix.c b/src/core/iomgr/iomgr_posix.c deleted file mode 100644 index 2f7f34746b..0000000000 --- a/src/core/iomgr/iomgr_posix.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_SOCKET - -#include "src/core/debug/trace.h" -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/iomgr_posix.h" -#include "src/core/iomgr/tcp_posix.h" - -void grpc_iomgr_platform_init(void) { - grpc_fd_global_init(); - grpc_register_tracer("tcp", &grpc_tcp_trace); -} - -void grpc_iomgr_platform_flush(void) {} - -void grpc_iomgr_platform_shutdown(void) { grpc_fd_global_shutdown(); } - -#endif /* GRPC_POSIX_SOCKET */ diff --git a/src/core/iomgr/iomgr_posix.h b/src/core/iomgr/iomgr_posix.h deleted file mode 100644 index 698fb6aee7..0000000000 --- a/src/core/iomgr/iomgr_posix.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_IOMGR_POSIX_H -#define GRPC_CORE_IOMGR_IOMGR_POSIX_H - -#include "src/core/iomgr/iomgr_internal.h" - -#endif /* GRPC_CORE_IOMGR_IOMGR_POSIX_H */ diff --git a/src/core/iomgr/iomgr_windows.c b/src/core/iomgr/iomgr_windows.c deleted file mode 100644 index 2d104130f7..0000000000 --- a/src/core/iomgr/iomgr_windows.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_WINSOCK_SOCKET - -#include "src/core/iomgr/sockaddr_win32.h" - -#include - -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/iomgr/socket_windows.h" - -/* Windows' io manager is going to be fully designed using IO completion - ports. All of what we're doing here is basically make sure that - Windows sockets are initialized in and out. */ - -static void winsock_init(void) { - WSADATA wsaData; - int status = WSAStartup(MAKEWORD(2, 0), &wsaData); - GPR_ASSERT(status == 0); -} - -static void winsock_shutdown(void) { - int status = WSACleanup(); - GPR_ASSERT(status == 0); -} - -void grpc_iomgr_platform_init(void) { - winsock_init(); - grpc_iocp_init(); -} - -void grpc_iomgr_platform_flush(void) { grpc_iocp_flush(); } - -void grpc_iomgr_platform_shutdown(void) { - grpc_iocp_shutdown(); - winsock_shutdown(); -} - -#endif /* GRPC_WINSOCK_SOCKET */ diff --git a/src/core/iomgr/pollset.h b/src/core/iomgr/pollset.h deleted file mode 100644 index 9500b1a73a..0000000000 --- a/src/core/iomgr/pollset.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_POLLSET_H -#define GRPC_CORE_IOMGR_POLLSET_H - -#include -#include -#include - -#include "src/core/iomgr/exec_ctx.h" - -#define GRPC_POLLSET_KICK_BROADCAST ((grpc_pollset_worker *)1) - -/* A grpc_pollset is a set of file descriptors that a higher level item is - interested in. For example: - - a server will typically keep a pollset containing all connected channels, - so that it can find new calls to service - - a completion queue might keep a pollset with an entry for each transport - that is servicing a call that it's tracking */ - -typedef struct grpc_pollset grpc_pollset; -typedef struct grpc_pollset_worker grpc_pollset_worker; - -size_t grpc_pollset_size(void); -void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu); -/* Begin shutting down the pollset, and call closure when done. - * pollset's mutex must be held */ -void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, - grpc_closure *closure); -/** Reset the pollset to its initial state (perhaps with some cached objects); - * must have been previously shutdown */ -void grpc_pollset_reset(grpc_pollset *pollset); -void grpc_pollset_destroy(grpc_pollset *pollset); - -/* Do some work on a pollset. - May involve invoking asynchronous callbacks, or actually polling file - descriptors. - Requires pollset's mutex locked. - May unlock its mutex during its execution. - - worker is a (platform-specific) handle that can be used to wake up - from grpc_pollset_work before any events are received and before the timeout - has expired. It is both initialized and destroyed by grpc_pollset_work. - Initialization of worker is guaranteed to occur BEFORE the - pollset's mutex is released for the first time by grpc_pollset_work - and it is guaranteed that it will not be released by grpc_pollset_work - AFTER worker has been destroyed. - - Tries not to block past deadline. - May call grpc_closure_list_run on grpc_closure_list, without holding the - pollset - lock */ -void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, - grpc_pollset_worker **worker, gpr_timespec now, - gpr_timespec deadline); - -/* Break one polling thread out of polling work for this pollset. - If specific_worker is GRPC_POLLSET_KICK_BROADCAST, kick ALL the workers. - Otherwise, if specific_worker is non-NULL, then kick that worker. */ -void grpc_pollset_kick(grpc_pollset *pollset, - grpc_pollset_worker *specific_worker); - -#endif /* GRPC_CORE_IOMGR_POLLSET_H */ diff --git a/src/core/iomgr/pollset_multipoller_with_epoll.c b/src/core/iomgr/pollset_multipoller_with_epoll.c deleted file mode 100644 index 2e0f27fab8..0000000000 --- a/src/core/iomgr/pollset_multipoller_with_epoll.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_LINUX_MULTIPOLL_WITH_EPOLL - -#include -#include -#include -#include -#include - -#include -#include -#include -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/block_annotate.h" - -struct epoll_fd_list { - int *epoll_fds; - size_t count; - size_t capacity; -}; - -static struct epoll_fd_list epoll_fd_global_list; -static gpr_once init_epoll_fd_list_mu = GPR_ONCE_INIT; -static gpr_mu epoll_fd_list_mu; - -static void init_mu(void) { gpr_mu_init(&epoll_fd_list_mu); } - -static void add_epoll_fd_to_global_list(int epoll_fd) { - gpr_once_init(&init_epoll_fd_list_mu, init_mu); - - gpr_mu_lock(&epoll_fd_list_mu); - if (epoll_fd_global_list.count == epoll_fd_global_list.capacity) { - epoll_fd_global_list.capacity = - GPR_MAX((size_t)8, epoll_fd_global_list.capacity * 2); - epoll_fd_global_list.epoll_fds = - gpr_realloc(epoll_fd_global_list.epoll_fds, - epoll_fd_global_list.capacity * sizeof(int)); - } - epoll_fd_global_list.epoll_fds[epoll_fd_global_list.count++] = epoll_fd; - gpr_mu_unlock(&epoll_fd_list_mu); -} - -static void remove_epoll_fd_from_global_list(int epoll_fd) { - gpr_mu_lock(&epoll_fd_list_mu); - GPR_ASSERT(epoll_fd_global_list.count > 0); - for (size_t i = 0; i < epoll_fd_global_list.count; i++) { - if (epoll_fd == epoll_fd_global_list.epoll_fds[i]) { - epoll_fd_global_list.epoll_fds[i] = - epoll_fd_global_list.epoll_fds[--(epoll_fd_global_list.count)]; - break; - } - } - gpr_mu_unlock(&epoll_fd_list_mu); -} - -void grpc_remove_fd_from_all_epoll_sets(int fd) { - int err; - gpr_once_init(&init_epoll_fd_list_mu, init_mu); - gpr_mu_lock(&epoll_fd_list_mu); - if (epoll_fd_global_list.count == 0) { - gpr_mu_unlock(&epoll_fd_list_mu); - return; - } - for (size_t i = 0; i < epoll_fd_global_list.count; i++) { - err = epoll_ctl(epoll_fd_global_list.epoll_fds[i], EPOLL_CTL_DEL, fd, NULL); - if (err < 0 && errno != ENOENT) { - gpr_log(GPR_ERROR, "epoll_ctl del for %d failed: %s", fd, - strerror(errno)); - } - } - gpr_mu_unlock(&epoll_fd_list_mu); -} - -typedef struct { - grpc_pollset *pollset; - grpc_fd *fd; - grpc_closure closure; -} delayed_add; - -typedef struct { int epoll_fd; } pollset_hdr; - -static void finally_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, - grpc_fd *fd) { - pollset_hdr *h = pollset->data.ptr; - struct epoll_event ev; - int err; - grpc_fd_watcher watcher; - - /* We pretend to be polling whilst adding an fd to keep the fd from being - closed during the add. This may result in a spurious wakeup being assigned - to this pollset whilst adding, but that should be benign. */ - GPR_ASSERT(grpc_fd_begin_poll(fd, pollset, NULL, 0, 0, &watcher) == 0); - if (watcher.fd != NULL) { - ev.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET); - ev.data.ptr = fd; - err = epoll_ctl(h->epoll_fd, EPOLL_CTL_ADD, fd->fd, &ev); - if (err < 0) { - /* FDs may be added to a pollset multiple times, so EEXIST is normal. */ - if (errno != EEXIST) { - gpr_log(GPR_ERROR, "epoll_ctl add for %d failed: %s", fd->fd, - strerror(errno)); - } - } - } - grpc_fd_end_poll(exec_ctx, &watcher, 0, 0); -} - -static void perform_delayed_add(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_status) { - delayed_add *da = arg; - - if (!grpc_fd_is_orphaned(da->fd)) { - finally_add_fd(exec_ctx, da->pollset, da->fd); - } - - gpr_mu_lock(&da->pollset->mu); - da->pollset->in_flight_cbs--; - if (da->pollset->shutting_down) { - /* We don't care about this pollset anymore. */ - if (da->pollset->in_flight_cbs == 0 && !da->pollset->called_shutdown) { - da->pollset->called_shutdown = 1; - grpc_exec_ctx_enqueue(exec_ctx, da->pollset->shutdown_done, true, NULL); - } - } - gpr_mu_unlock(&da->pollset->mu); - - GRPC_FD_UNREF(da->fd, "delayed_add"); - - gpr_free(da); -} - -static void multipoll_with_epoll_pollset_add_fd(grpc_exec_ctx *exec_ctx, - grpc_pollset *pollset, - grpc_fd *fd, - int and_unlock_pollset) { - if (and_unlock_pollset) { - gpr_mu_unlock(&pollset->mu); - finally_add_fd(exec_ctx, pollset, fd); - } else { - delayed_add *da = gpr_malloc(sizeof(*da)); - da->pollset = pollset; - da->fd = fd; - GRPC_FD_REF(fd, "delayed_add"); - grpc_closure_init(&da->closure, perform_delayed_add, da); - pollset->in_flight_cbs++; - grpc_exec_ctx_enqueue(exec_ctx, &da->closure, true, NULL); - } -} - -/* TODO(klempner): We probably want to turn this down a bit */ -#define GRPC_EPOLL_MAX_EVENTS 1000 - -static void multipoll_with_epoll_pollset_maybe_work_and_unlock( - grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker *worker, - gpr_timespec deadline, gpr_timespec now) { - struct epoll_event ep_ev[GRPC_EPOLL_MAX_EVENTS]; - int ep_rv; - int poll_rv; - pollset_hdr *h = pollset->data.ptr; - int timeout_ms; - struct pollfd pfds[2]; - - /* If you want to ignore epoll's ability to sanely handle parallel pollers, - * for a more apples-to-apples performance comparison with poll, add a - * if (pollset->counter != 0) { return 0; } - * here. - */ - - gpr_mu_unlock(&pollset->mu); - - timeout_ms = grpc_poll_deadline_to_millis_timeout(deadline, now); - - pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd->fd); - pfds[0].events = POLLIN; - pfds[0].revents = 0; - pfds[1].fd = h->epoll_fd; - pfds[1].events = POLLIN; - pfds[1].revents = 0; - - /* TODO(vpai): Consider first doing a 0 timeout poll here to avoid - even going into the blocking annotation if possible */ - GPR_TIMER_BEGIN("poll", 0); - GRPC_SCHEDULING_START_BLOCKING_REGION; - poll_rv = grpc_poll_function(pfds, 2, timeout_ms); - GRPC_SCHEDULING_END_BLOCKING_REGION; - GPR_TIMER_END("poll", 0); - - if (poll_rv < 0) { - if (errno != EINTR) { - gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); - } - } else if (poll_rv == 0) { - /* do nothing */ - } else { - if (pfds[0].revents) { - grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd); - } - if (pfds[1].revents) { - do { - /* The following epoll_wait never blocks; it has a timeout of 0 */ - ep_rv = epoll_wait(h->epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, 0); - if (ep_rv < 0) { - if (errno != EINTR) { - gpr_log(GPR_ERROR, "epoll_wait() failed: %s", strerror(errno)); - } - } else { - int i; - for (i = 0; i < ep_rv; ++i) { - grpc_fd *fd = ep_ev[i].data.ptr; - /* TODO(klempner): We might want to consider making err and pri - * separate events */ - int cancel = ep_ev[i].events & (EPOLLERR | EPOLLHUP); - int read_ev = ep_ev[i].events & (EPOLLIN | EPOLLPRI); - int write_ev = ep_ev[i].events & EPOLLOUT; - if (fd == NULL) { - grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd); - } else { - if (read_ev || cancel) { - grpc_fd_become_readable(exec_ctx, fd); - } - if (write_ev || cancel) { - grpc_fd_become_writable(exec_ctx, fd); - } - } - } - } - } while (ep_rv == GRPC_EPOLL_MAX_EVENTS); - } - } -} - -static void multipoll_with_epoll_pollset_finish_shutdown( - grpc_pollset *pollset) {} - -static void multipoll_with_epoll_pollset_destroy(grpc_pollset *pollset) { - pollset_hdr *h = pollset->data.ptr; - close(h->epoll_fd); - remove_epoll_fd_from_global_list(h->epoll_fd); - gpr_free(h); -} - -static const grpc_pollset_vtable multipoll_with_epoll_pollset = { - multipoll_with_epoll_pollset_add_fd, - multipoll_with_epoll_pollset_maybe_work_and_unlock, - multipoll_with_epoll_pollset_finish_shutdown, - multipoll_with_epoll_pollset_destroy}; - -static void epoll_become_multipoller(grpc_exec_ctx *exec_ctx, - grpc_pollset *pollset, grpc_fd **fds, - size_t nfds) { - size_t i; - pollset_hdr *h = gpr_malloc(sizeof(pollset_hdr)); - struct epoll_event ev; - int err; - - pollset->vtable = &multipoll_with_epoll_pollset; - pollset->data.ptr = h; - h->epoll_fd = epoll_create1(EPOLL_CLOEXEC); - if (h->epoll_fd < 0) { - /* TODO(klempner): Fall back to poll here, especially on ENOSYS */ - gpr_log(GPR_ERROR, "epoll_create1 failed: %s", strerror(errno)); - abort(); - } - add_epoll_fd_to_global_list(h->epoll_fd); - - ev.events = (uint32_t)(EPOLLIN | EPOLLET); - ev.data.ptr = NULL; - err = epoll_ctl(h->epoll_fd, EPOLL_CTL_ADD, - GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd), &ev); - if (err < 0) { - gpr_log(GPR_ERROR, "epoll_ctl add for %d failed: %s", - GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd), - strerror(errno)); - } - - for (i = 0; i < nfds; i++) { - multipoll_with_epoll_pollset_add_fd(exec_ctx, pollset, fds[i], 0); - } -} - -grpc_platform_become_multipoller_type grpc_platform_become_multipoller = - epoll_become_multipoller; - -#else /* GPR_LINUX_MULTIPOLL_WITH_EPOLL */ - -void grpc_remove_fd_from_all_epoll_sets(int fd) {} - -#endif /* GPR_LINUX_MULTIPOLL_WITH_EPOLL */ diff --git a/src/core/iomgr/pollset_multipoller_with_poll_posix.c b/src/core/iomgr/pollset_multipoller_with_poll_posix.c deleted file mode 100644 index 92d6fb7241..0000000000 --- a/src/core/iomgr/pollset_multipoller_with_poll_posix.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_SOCKET - -#include "src/core/iomgr/pollset_posix.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/support/block_annotate.h" - -typedef struct { - /* all polled fds */ - size_t fd_count; - size_t fd_capacity; - grpc_fd **fds; - /* fds that have been removed from the pollset explicitly */ - size_t del_count; - size_t del_capacity; - grpc_fd **dels; -} pollset_hdr; - -static void multipoll_with_poll_pollset_add_fd(grpc_exec_ctx *exec_ctx, - grpc_pollset *pollset, - grpc_fd *fd, - int and_unlock_pollset) { - size_t i; - pollset_hdr *h = pollset->data.ptr; - /* TODO(ctiller): this is O(num_fds^2); maybe switch to a hash set here */ - for (i = 0; i < h->fd_count; i++) { - if (h->fds[i] == fd) goto exit; - } - if (h->fd_count == h->fd_capacity) { - h->fd_capacity = GPR_MAX(h->fd_capacity + 8, h->fd_count * 3 / 2); - h->fds = gpr_realloc(h->fds, sizeof(grpc_fd *) * h->fd_capacity); - } - h->fds[h->fd_count++] = fd; - GRPC_FD_REF(fd, "multipoller"); -exit: - if (and_unlock_pollset) { - gpr_mu_unlock(&pollset->mu); - } -} - -static void multipoll_with_poll_pollset_maybe_work_and_unlock( - grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker *worker, - gpr_timespec deadline, gpr_timespec now) { -#define POLLOUT_CHECK (POLLOUT | POLLHUP | POLLERR) -#define POLLIN_CHECK (POLLIN | POLLHUP | POLLERR) - - int timeout; - int r; - size_t i, j, fd_count; - nfds_t pfd_count; - pollset_hdr *h; - /* TODO(ctiller): inline some elements to avoid an allocation */ - grpc_fd_watcher *watchers; - struct pollfd *pfds; - - h = pollset->data.ptr; - timeout = grpc_poll_deadline_to_millis_timeout(deadline, now); - /* TODO(ctiller): perform just one malloc here if we exceed the inline case */ - pfds = gpr_malloc(sizeof(*pfds) * (h->fd_count + 2)); - watchers = gpr_malloc(sizeof(*watchers) * (h->fd_count + 2)); - fd_count = 0; - pfd_count = 2; - pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd); - pfds[0].events = POLLIN; - pfds[0].revents = 0; - pfds[1].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd->fd); - pfds[1].events = POLLIN; - pfds[1].revents = 0; - for (i = 0; i < h->fd_count; i++) { - int remove = grpc_fd_is_orphaned(h->fds[i]); - for (j = 0; !remove && j < h->del_count; j++) { - if (h->fds[i] == h->dels[j]) remove = 1; - } - if (remove) { - GRPC_FD_UNREF(h->fds[i], "multipoller"); - } else { - h->fds[fd_count++] = h->fds[i]; - watchers[pfd_count].fd = h->fds[i]; - GRPC_FD_REF(watchers[pfd_count].fd, "multipoller_start"); - pfds[pfd_count].fd = h->fds[i]->fd; - pfds[pfd_count].revents = 0; - pfd_count++; - } - } - for (j = 0; j < h->del_count; j++) { - GRPC_FD_UNREF(h->dels[j], "multipoller_del"); - } - h->del_count = 0; - h->fd_count = fd_count; - gpr_mu_unlock(&pollset->mu); - - for (i = 2; i < pfd_count; i++) { - grpc_fd *fd = watchers[i].fd; - pfds[i].events = (short)grpc_fd_begin_poll(fd, pollset, worker, POLLIN, - POLLOUT, &watchers[i]); - GRPC_FD_UNREF(fd, "multipoller_start"); - } - - /* TODO(vpai): Consider first doing a 0 timeout poll here to avoid - even going into the blocking annotation if possible */ - GRPC_SCHEDULING_START_BLOCKING_REGION; - r = grpc_poll_function(pfds, pfd_count, timeout); - GRPC_SCHEDULING_END_BLOCKING_REGION; - - if (r < 0) { - if (errno != EINTR) { - gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); - } - for (i = 2; i < pfd_count; i++) { - grpc_fd_end_poll(exec_ctx, &watchers[i], 0, 0); - } - } else if (r == 0) { - for (i = 2; i < pfd_count; i++) { - grpc_fd_end_poll(exec_ctx, &watchers[i], 0, 0); - } - } else { - if (pfds[0].revents & POLLIN_CHECK) { - grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd); - } - if (pfds[1].revents & POLLIN_CHECK) { - grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd); - } - for (i = 2; i < pfd_count; i++) { - if (watchers[i].fd == NULL) { - grpc_fd_end_poll(exec_ctx, &watchers[i], 0, 0); - continue; - } - grpc_fd_end_poll(exec_ctx, &watchers[i], pfds[i].revents & POLLIN_CHECK, - pfds[i].revents & POLLOUT_CHECK); - } - } - - gpr_free(pfds); - gpr_free(watchers); -} - -static void multipoll_with_poll_pollset_finish_shutdown(grpc_pollset *pollset) { - size_t i; - pollset_hdr *h = pollset->data.ptr; - for (i = 0; i < h->fd_count; i++) { - GRPC_FD_UNREF(h->fds[i], "multipoller"); - } - for (i = 0; i < h->del_count; i++) { - GRPC_FD_UNREF(h->dels[i], "multipoller_del"); - } - h->fd_count = 0; - h->del_count = 0; -} - -static void multipoll_with_poll_pollset_destroy(grpc_pollset *pollset) { - pollset_hdr *h = pollset->data.ptr; - multipoll_with_poll_pollset_finish_shutdown(pollset); - gpr_free(h->fds); - gpr_free(h->dels); - gpr_free(h); -} - -static const grpc_pollset_vtable multipoll_with_poll_pollset = { - multipoll_with_poll_pollset_add_fd, - multipoll_with_poll_pollset_maybe_work_and_unlock, - multipoll_with_poll_pollset_finish_shutdown, - multipoll_with_poll_pollset_destroy}; - -void grpc_poll_become_multipoller(grpc_exec_ctx *exec_ctx, - grpc_pollset *pollset, grpc_fd **fds, - size_t nfds) { - size_t i; - pollset_hdr *h = gpr_malloc(sizeof(pollset_hdr)); - pollset->vtable = &multipoll_with_poll_pollset; - pollset->data.ptr = h; - h->fd_count = nfds; - h->fd_capacity = nfds; - h->fds = gpr_malloc(nfds * sizeof(grpc_fd *)); - h->del_count = 0; - h->del_capacity = 0; - h->dels = NULL; - for (i = 0; i < nfds; i++) { - h->fds[i] = fds[i]; - GRPC_FD_REF(fds[i], "multipoller"); - } -} - -#endif /* GPR_POSIX_SOCKET */ - -#ifdef GPR_POSIX_MULTIPOLL_WITH_POLL -grpc_platform_become_multipoller_type grpc_platform_become_multipoller = - grpc_poll_become_multipoller; -#endif diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c deleted file mode 100644 index e895a77884..0000000000 --- a/src/core/iomgr/pollset_posix.c +++ /dev/null @@ -1,633 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_SOCKET - -#include "src/core/iomgr/pollset_posix.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/block_annotate.h" - -GPR_TLS_DECL(g_current_thread_poller); -GPR_TLS_DECL(g_current_thread_worker); - -/** Default poll() function - a pointer so that it can be overridden by some - * tests */ -grpc_poll_function_type grpc_poll_function = poll; - -/** The alarm system needs to be able to wakeup 'some poller' sometimes - * (specifically when a new alarm needs to be triggered earlier than the next - * alarm 'epoch'). - * This wakeup_fd gives us something to alert on when such a case occurs. */ -grpc_wakeup_fd grpc_global_wakeup_fd; - -static void remove_worker(grpc_pollset *p, grpc_pollset_worker *worker) { - worker->prev->next = worker->next; - worker->next->prev = worker->prev; -} - -int grpc_pollset_has_workers(grpc_pollset *p) { - return p->root_worker.next != &p->root_worker; -} - -static grpc_pollset_worker *pop_front_worker(grpc_pollset *p) { - if (grpc_pollset_has_workers(p)) { - grpc_pollset_worker *w = p->root_worker.next; - remove_worker(p, w); - return w; - } else { - return NULL; - } -} - -static void push_back_worker(grpc_pollset *p, grpc_pollset_worker *worker) { - worker->next = &p->root_worker; - worker->prev = worker->next->prev; - worker->prev->next = worker->next->prev = worker; -} - -static void push_front_worker(grpc_pollset *p, grpc_pollset_worker *worker) { - worker->prev = &p->root_worker; - worker->next = worker->prev->next; - worker->prev->next = worker->next->prev = worker; -} - -size_t grpc_pollset_size(void) { return sizeof(grpc_pollset); } - -void grpc_pollset_kick_ext(grpc_pollset *p, - grpc_pollset_worker *specific_worker, - uint32_t flags) { - GPR_TIMER_BEGIN("grpc_pollset_kick_ext", 0); - - /* pollset->mu already held */ - if (specific_worker != NULL) { - if (specific_worker == GRPC_POLLSET_KICK_BROADCAST) { - GPR_TIMER_BEGIN("grpc_pollset_kick_ext.broadcast", 0); - GPR_ASSERT((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) == 0); - for (specific_worker = p->root_worker.next; - specific_worker != &p->root_worker; - specific_worker = specific_worker->next) { - grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd); - } - p->kicked_without_pollers = 1; - GPR_TIMER_END("grpc_pollset_kick_ext.broadcast", 0); - } else if (gpr_tls_get(&g_current_thread_worker) != - (intptr_t)specific_worker) { - GPR_TIMER_MARK("different_thread_worker", 0); - if ((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) != 0) { - specific_worker->reevaluate_polling_on_wakeup = 1; - } - specific_worker->kicked_specifically = 1; - grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd); - } else if ((flags & GRPC_POLLSET_CAN_KICK_SELF) != 0) { - GPR_TIMER_MARK("kick_yoself", 0); - if ((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) != 0) { - specific_worker->reevaluate_polling_on_wakeup = 1; - } - specific_worker->kicked_specifically = 1; - grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd); - } - } else if (gpr_tls_get(&g_current_thread_poller) != (intptr_t)p) { - GPR_ASSERT((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) == 0); - GPR_TIMER_MARK("kick_anonymous", 0); - specific_worker = pop_front_worker(p); - if (specific_worker != NULL) { - if (gpr_tls_get(&g_current_thread_worker) == (intptr_t)specific_worker) { - GPR_TIMER_MARK("kick_anonymous_not_self", 0); - push_back_worker(p, specific_worker); - specific_worker = pop_front_worker(p); - if ((flags & GRPC_POLLSET_CAN_KICK_SELF) == 0 && - gpr_tls_get(&g_current_thread_worker) == - (intptr_t)specific_worker) { - push_back_worker(p, specific_worker); - specific_worker = NULL; - } - } - if (specific_worker != NULL) { - GPR_TIMER_MARK("finally_kick", 0); - push_back_worker(p, specific_worker); - grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd); - } - } else { - GPR_TIMER_MARK("kicked_no_pollers", 0); - p->kicked_without_pollers = 1; - } - } - - GPR_TIMER_END("grpc_pollset_kick_ext", 0); -} - -void grpc_pollset_kick(grpc_pollset *p, grpc_pollset_worker *specific_worker) { - grpc_pollset_kick_ext(p, specific_worker, 0); -} - -/* global state management */ - -void grpc_pollset_global_init(void) { - gpr_tls_init(&g_current_thread_poller); - gpr_tls_init(&g_current_thread_worker); - grpc_wakeup_fd_global_init(); - grpc_wakeup_fd_init(&grpc_global_wakeup_fd); -} - -void grpc_pollset_global_shutdown(void) { - grpc_wakeup_fd_destroy(&grpc_global_wakeup_fd); - gpr_tls_destroy(&g_current_thread_poller); - gpr_tls_destroy(&g_current_thread_worker); - grpc_wakeup_fd_global_destroy(); -} - -void grpc_kick_poller(void) { grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd); } - -/* main interface */ - -static void become_basic_pollset(grpc_pollset *pollset, grpc_fd *fd_or_null); - -void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) { - gpr_mu_init(&pollset->mu); - *mu = &pollset->mu; - pollset->root_worker.next = pollset->root_worker.prev = &pollset->root_worker; - pollset->in_flight_cbs = 0; - pollset->shutting_down = 0; - pollset->called_shutdown = 0; - pollset->kicked_without_pollers = 0; - pollset->idle_jobs.head = pollset->idle_jobs.tail = NULL; - pollset->local_wakeup_cache = NULL; - pollset->kicked_without_pollers = 0; - become_basic_pollset(pollset, NULL); -} - -void grpc_pollset_destroy(grpc_pollset *pollset) { - GPR_ASSERT(pollset->in_flight_cbs == 0); - GPR_ASSERT(!grpc_pollset_has_workers(pollset)); - GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail); - pollset->vtable->destroy(pollset); - while (pollset->local_wakeup_cache) { - grpc_cached_wakeup_fd *next = pollset->local_wakeup_cache->next; - grpc_wakeup_fd_destroy(&pollset->local_wakeup_cache->fd); - gpr_free(pollset->local_wakeup_cache); - pollset->local_wakeup_cache = next; - } -} - -void grpc_pollset_reset(grpc_pollset *pollset) { - GPR_ASSERT(pollset->shutting_down); - GPR_ASSERT(pollset->in_flight_cbs == 0); - GPR_ASSERT(!grpc_pollset_has_workers(pollset)); - GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail); - pollset->vtable->destroy(pollset); - pollset->shutting_down = 0; - pollset->called_shutdown = 0; - pollset->kicked_without_pollers = 0; - become_basic_pollset(pollset, NULL); -} - -void grpc_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, - grpc_fd *fd) { - gpr_mu_lock(&pollset->mu); - pollset->vtable->add_fd(exec_ctx, pollset, fd, 1); -/* the following (enabled only in debug) will reacquire and then release - our lock - meaning that if the unlocking flag passed to add_fd above is - not respected, the code will deadlock (in a way that we have a chance of - debugging) */ -#ifndef NDEBUG - gpr_mu_lock(&pollset->mu); - gpr_mu_unlock(&pollset->mu); -#endif -} - -static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset) { - GPR_ASSERT(grpc_closure_list_empty(pollset->idle_jobs)); - pollset->vtable->finish_shutdown(pollset); - grpc_exec_ctx_enqueue(exec_ctx, pollset->shutdown_done, true, NULL); -} - -void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, - grpc_pollset_worker **worker_hdl, gpr_timespec now, - gpr_timespec deadline) { - grpc_pollset_worker worker; - *worker_hdl = &worker; - - /* pollset->mu already held */ - int added_worker = 0; - int locked = 1; - int queued_work = 0; - int keep_polling = 0; - GPR_TIMER_BEGIN("grpc_pollset_work", 0); - /* this must happen before we (potentially) drop pollset->mu */ - worker.next = worker.prev = NULL; - worker.reevaluate_polling_on_wakeup = 0; - if (pollset->local_wakeup_cache != NULL) { - worker.wakeup_fd = pollset->local_wakeup_cache; - pollset->local_wakeup_cache = worker.wakeup_fd->next; - } else { - worker.wakeup_fd = gpr_malloc(sizeof(*worker.wakeup_fd)); - grpc_wakeup_fd_init(&worker.wakeup_fd->fd); - } - worker.kicked_specifically = 0; - /* If there's work waiting for the pollset to be idle, and the - pollset is idle, then do that work */ - if (!grpc_pollset_has_workers(pollset) && - !grpc_closure_list_empty(pollset->idle_jobs)) { - GPR_TIMER_MARK("grpc_pollset_work.idle_jobs", 0); - grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL); - goto done; - } - /* If we're shutting down then we don't execute any extended work */ - if (pollset->shutting_down) { - GPR_TIMER_MARK("grpc_pollset_work.shutting_down", 0); - goto done; - } - /* Give do_promote priority so we don't starve it out */ - if (pollset->in_flight_cbs) { - GPR_TIMER_MARK("grpc_pollset_work.in_flight_cbs", 0); - gpr_mu_unlock(&pollset->mu); - locked = 0; - goto done; - } - /* Start polling, and keep doing so while we're being asked to - re-evaluate our pollers (this allows poll() based pollers to - ensure they don't miss wakeups) */ - keep_polling = 1; - while (keep_polling) { - keep_polling = 0; - if (!pollset->kicked_without_pollers) { - if (!added_worker) { - push_front_worker(pollset, &worker); - added_worker = 1; - gpr_tls_set(&g_current_thread_worker, (intptr_t)&worker); - } - gpr_tls_set(&g_current_thread_poller, (intptr_t)pollset); - GPR_TIMER_BEGIN("maybe_work_and_unlock", 0); - pollset->vtable->maybe_work_and_unlock(exec_ctx, pollset, &worker, - deadline, now); - GPR_TIMER_END("maybe_work_and_unlock", 0); - locked = 0; - gpr_tls_set(&g_current_thread_poller, 0); - } else { - GPR_TIMER_MARK("grpc_pollset_work.kicked_without_pollers", 0); - pollset->kicked_without_pollers = 0; - } - /* Finished execution - start cleaning up. - Note that we may arrive here from outside the enclosing while() loop. - In that case we won't loop though as we haven't added worker to the - worker list, which means nobody could ask us to re-evaluate polling). */ - done: - if (!locked) { - queued_work |= grpc_exec_ctx_flush(exec_ctx); - gpr_mu_lock(&pollset->mu); - locked = 1; - } - /* If we're forced to re-evaluate polling (via grpc_pollset_kick with - GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) then we land here and force - a loop */ - if (worker.reevaluate_polling_on_wakeup) { - worker.reevaluate_polling_on_wakeup = 0; - pollset->kicked_without_pollers = 0; - if (queued_work || worker.kicked_specifically) { - /* If there's queued work on the list, then set the deadline to be - immediate so we get back out of the polling loop quickly */ - deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC); - } - keep_polling = 1; - } - } - if (added_worker) { - remove_worker(pollset, &worker); - gpr_tls_set(&g_current_thread_worker, 0); - } - /* release wakeup fd to the local pool */ - worker.wakeup_fd->next = pollset->local_wakeup_cache; - pollset->local_wakeup_cache = worker.wakeup_fd; - /* check shutdown conditions */ - if (pollset->shutting_down) { - if (grpc_pollset_has_workers(pollset)) { - grpc_pollset_kick(pollset, NULL); - } else if (!pollset->called_shutdown && pollset->in_flight_cbs == 0) { - pollset->called_shutdown = 1; - gpr_mu_unlock(&pollset->mu); - finish_shutdown(exec_ctx, pollset); - grpc_exec_ctx_flush(exec_ctx); - /* Continuing to access pollset here is safe -- it is the caller's - * responsibility to not destroy when it has outstanding calls to - * grpc_pollset_work. - * TODO(dklempner): Can we refactor the shutdown logic to avoid this? */ - gpr_mu_lock(&pollset->mu); - } else if (!grpc_closure_list_empty(pollset->idle_jobs)) { - grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL); - gpr_mu_unlock(&pollset->mu); - grpc_exec_ctx_flush(exec_ctx); - gpr_mu_lock(&pollset->mu); - } - } - *worker_hdl = NULL; - GPR_TIMER_END("grpc_pollset_work", 0); -} - -void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, - grpc_closure *closure) { - GPR_ASSERT(!pollset->shutting_down); - pollset->shutting_down = 1; - pollset->shutdown_done = closure; - grpc_pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST); - if (!grpc_pollset_has_workers(pollset)) { - grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL); - } - if (!pollset->called_shutdown && pollset->in_flight_cbs == 0 && - !grpc_pollset_has_workers(pollset)) { - pollset->called_shutdown = 1; - finish_shutdown(exec_ctx, pollset); - } -} - -int grpc_poll_deadline_to_millis_timeout(gpr_timespec deadline, - gpr_timespec now) { - gpr_timespec timeout; - static const int64_t max_spin_polling_us = 10; - if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) == 0) { - return -1; - } - if (gpr_time_cmp(deadline, gpr_time_add(now, gpr_time_from_micros( - max_spin_polling_us, - GPR_TIMESPAN))) <= 0) { - return 0; - } - timeout = gpr_time_sub(deadline, now); - return gpr_time_to_millis(gpr_time_add( - timeout, gpr_time_from_nanos(GPR_NS_PER_MS - 1, GPR_TIMESPAN))); -} - -/* - * basic_pollset - a vtable that provides polling for zero or one file - * descriptor via poll() - */ - -typedef struct grpc_unary_promote_args { - const grpc_pollset_vtable *original_vtable; - grpc_pollset *pollset; - grpc_fd *fd; - grpc_closure promotion_closure; -} grpc_unary_promote_args; - -static void basic_do_promote(grpc_exec_ctx *exec_ctx, void *args, - bool success) { - grpc_unary_promote_args *up_args = args; - const grpc_pollset_vtable *original_vtable = up_args->original_vtable; - grpc_pollset *pollset = up_args->pollset; - grpc_fd *fd = up_args->fd; - - /* - * This is quite tricky. There are a number of cases to keep in mind here: - * 1. fd may have been orphaned - * 2. The pollset may no longer be a unary poller (and we can't let case #1 - * leak to other pollset types!) - * 3. pollset's fd (which may have changed) may have been orphaned - * 4. The pollset may be shutting down. - */ - - gpr_mu_lock(&pollset->mu); - /* First we need to ensure that nobody is polling concurrently */ - GPR_ASSERT(!grpc_pollset_has_workers(pollset)); - - gpr_free(up_args); - /* At this point the pollset may no longer be a unary poller. In that case - * we should just call the right add function and be done. */ - /* TODO(klempner): If we're not careful this could cause infinite recursion. - * That's not a problem for now because empty_pollset has a trivial poller - * and we don't have any mechanism to unbecome multipoller. */ - pollset->in_flight_cbs--; - if (pollset->shutting_down) { - /* We don't care about this pollset anymore. */ - if (pollset->in_flight_cbs == 0 && !pollset->called_shutdown) { - pollset->called_shutdown = 1; - finish_shutdown(exec_ctx, pollset); - } - } else if (grpc_fd_is_orphaned(fd)) { - /* Don't try to add it to anything, we'll drop our ref on it below */ - } else if (pollset->vtable != original_vtable) { - pollset->vtable->add_fd(exec_ctx, pollset, fd, 0); - } else if (fd != pollset->data.ptr) { - grpc_fd *fds[2]; - fds[0] = pollset->data.ptr; - fds[1] = fd; - - if (fds[0] && !grpc_fd_is_orphaned(fds[0])) { - grpc_platform_become_multipoller(exec_ctx, pollset, fds, - GPR_ARRAY_SIZE(fds)); - GRPC_FD_UNREF(fds[0], "basicpoll"); - } else { - /* old fd is orphaned and we haven't cleaned it up until now, so remain a - * unary poller */ - /* Note that it is possible that fds[1] is also orphaned at this point. - * That's okay, we'll correct it at the next add or poll. */ - if (fds[0]) GRPC_FD_UNREF(fds[0], "basicpoll"); - pollset->data.ptr = fd; - GRPC_FD_REF(fd, "basicpoll"); - } - } - - gpr_mu_unlock(&pollset->mu); - - /* Matching ref in basic_pollset_add_fd */ - GRPC_FD_UNREF(fd, "basicpoll_add"); -} - -static void basic_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, - grpc_fd *fd, int and_unlock_pollset) { - grpc_unary_promote_args *up_args; - GPR_ASSERT(fd); - if (fd == pollset->data.ptr) goto exit; - - if (!grpc_pollset_has_workers(pollset)) { - /* Fast path -- no in flight cbs */ - /* TODO(klempner): Comment this out and fix any test failures or establish - * they are due to timing issues */ - grpc_fd *fds[2]; - fds[0] = pollset->data.ptr; - fds[1] = fd; - - if (fds[0] == NULL) { - pollset->data.ptr = fd; - GRPC_FD_REF(fd, "basicpoll"); - } else if (!grpc_fd_is_orphaned(fds[0])) { - grpc_platform_become_multipoller(exec_ctx, pollset, fds, - GPR_ARRAY_SIZE(fds)); - GRPC_FD_UNREF(fds[0], "basicpoll"); - } else { - /* old fd is orphaned and we haven't cleaned it up until now, so remain a - * unary poller */ - GRPC_FD_UNREF(fds[0], "basicpoll"); - pollset->data.ptr = fd; - GRPC_FD_REF(fd, "basicpoll"); - } - goto exit; - } - - /* Now we need to promote. This needs to happen when we're not polling. Since - * this may be called from poll, the wait needs to happen asynchronously. */ - GRPC_FD_REF(fd, "basicpoll_add"); - pollset->in_flight_cbs++; - up_args = gpr_malloc(sizeof(*up_args)); - up_args->fd = fd; - up_args->original_vtable = pollset->vtable; - up_args->pollset = pollset; - up_args->promotion_closure.cb = basic_do_promote; - up_args->promotion_closure.cb_arg = up_args; - - grpc_closure_list_add(&pollset->idle_jobs, &up_args->promotion_closure, 1); - grpc_pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST); - -exit: - if (and_unlock_pollset) { - gpr_mu_unlock(&pollset->mu); - } -} - -static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx, - grpc_pollset *pollset, - grpc_pollset_worker *worker, - gpr_timespec deadline, - gpr_timespec now) { -#define POLLOUT_CHECK (POLLOUT | POLLHUP | POLLERR) -#define POLLIN_CHECK (POLLIN | POLLHUP | POLLERR) - - struct pollfd pfd[3]; - grpc_fd *fd; - grpc_fd_watcher fd_watcher; - int timeout; - int r; - nfds_t nfds; - - fd = pollset->data.ptr; - if (fd && grpc_fd_is_orphaned(fd)) { - GRPC_FD_UNREF(fd, "basicpoll"); - fd = pollset->data.ptr = NULL; - } - timeout = grpc_poll_deadline_to_millis_timeout(deadline, now); - pfd[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd); - pfd[0].events = POLLIN; - pfd[0].revents = 0; - pfd[1].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd->fd); - pfd[1].events = POLLIN; - pfd[1].revents = 0; - nfds = 2; - if (fd) { - pfd[2].fd = fd->fd; - pfd[2].revents = 0; - GRPC_FD_REF(fd, "basicpoll_begin"); - gpr_mu_unlock(&pollset->mu); - pfd[2].events = (short)grpc_fd_begin_poll(fd, pollset, worker, POLLIN, - POLLOUT, &fd_watcher); - if (pfd[2].events != 0) { - nfds++; - } - } else { - gpr_mu_unlock(&pollset->mu); - } - - /* TODO(vpai): Consider first doing a 0 timeout poll here to avoid - even going into the blocking annotation if possible */ - /* poll fd count (argument 2) is shortened by one if we have no events - to poll on - such that it only includes the kicker */ - GPR_TIMER_BEGIN("poll", 0); - GRPC_SCHEDULING_START_BLOCKING_REGION; - r = grpc_poll_function(pfd, nfds, timeout); - GRPC_SCHEDULING_END_BLOCKING_REGION; - GPR_TIMER_END("poll", 0); - - if (r < 0) { - if (errno != EINTR) { - gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); - } - if (fd) { - grpc_fd_end_poll(exec_ctx, &fd_watcher, 0, 0); - } - } else if (r == 0) { - if (fd) { - grpc_fd_end_poll(exec_ctx, &fd_watcher, 0, 0); - } - } else { - if (pfd[0].revents & POLLIN_CHECK) { - grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd); - } - if (pfd[1].revents & POLLIN_CHECK) { - grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd); - } - if (nfds > 2) { - grpc_fd_end_poll(exec_ctx, &fd_watcher, pfd[2].revents & POLLIN_CHECK, - pfd[2].revents & POLLOUT_CHECK); - } else if (fd) { - grpc_fd_end_poll(exec_ctx, &fd_watcher, 0, 0); - } - } - - if (fd) { - GRPC_FD_UNREF(fd, "basicpoll_begin"); - } -} - -static void basic_pollset_destroy(grpc_pollset *pollset) { - if (pollset->data.ptr != NULL) { - GRPC_FD_UNREF(pollset->data.ptr, "basicpoll"); - pollset->data.ptr = NULL; - } -} - -static const grpc_pollset_vtable basic_pollset = { - basic_pollset_add_fd, basic_pollset_maybe_work_and_unlock, - basic_pollset_destroy, basic_pollset_destroy}; - -static void become_basic_pollset(grpc_pollset *pollset, grpc_fd *fd_or_null) { - pollset->vtable = &basic_pollset; - pollset->data.ptr = fd_or_null; - if (fd_or_null != NULL) { - GRPC_FD_REF(fd_or_null, "basicpoll"); - } -} - -#endif /* GPR_POSIX_POLLSET */ diff --git a/src/core/iomgr/pollset_posix.h b/src/core/iomgr/pollset_posix.h deleted file mode 100644 index e0cfc44395..0000000000 --- a/src/core/iomgr/pollset_posix.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_POLLSET_POSIX_H -#define GRPC_CORE_IOMGR_POLLSET_POSIX_H - -#include - -#include - -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/wakeup_fd_posix.h" - -typedef struct grpc_pollset_vtable grpc_pollset_vtable; - -/* forward declare only in this file to avoid leaking impl details via - pollset.h; real users of grpc_fd should always include 'fd_posix.h' and not - use the struct tag */ -struct grpc_fd; - -typedef struct grpc_cached_wakeup_fd { - grpc_wakeup_fd fd; - struct grpc_cached_wakeup_fd *next; -} grpc_cached_wakeup_fd; - -struct grpc_pollset_worker { - grpc_cached_wakeup_fd *wakeup_fd; - int reevaluate_polling_on_wakeup; - int kicked_specifically; - struct grpc_pollset_worker *next; - struct grpc_pollset_worker *prev; -}; - -struct grpc_pollset { - /* pollsets under posix can mutate representation as fds are added and - removed. - For example, we may choose a poll() based implementation on linux for - few fds, and an epoll() based implementation for many fds */ - const grpc_pollset_vtable *vtable; - gpr_mu mu; - grpc_pollset_worker root_worker; - int in_flight_cbs; - int shutting_down; - int called_shutdown; - int kicked_without_pollers; - grpc_closure *shutdown_done; - grpc_closure_list idle_jobs; - union { - int fd; - void *ptr; - } data; - /* Local cache of eventfds for workers */ - grpc_cached_wakeup_fd *local_wakeup_cache; -}; - -struct grpc_pollset_vtable { - void (*add_fd)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, - struct grpc_fd *fd, int and_unlock_pollset); - void (*maybe_work_and_unlock)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, - grpc_pollset_worker *worker, - gpr_timespec deadline, gpr_timespec now); - void (*finish_shutdown)(grpc_pollset *pollset); - void (*destroy)(grpc_pollset *pollset); -}; - -/* Add an fd to a pollset */ -void grpc_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, - struct grpc_fd *fd); - -/* Returns the fd to listen on for kicks */ -int grpc_kick_read_fd(grpc_pollset *p); -/* Call after polling has been kicked to leave the kicked state */ -void grpc_kick_drain(grpc_pollset *p); - -/* Convert a timespec to milliseconds: - - very small or negative poll times are clamped to zero to do a - non-blocking poll (which becomes spin polling) - - other small values are rounded up to one millisecond - - longer than a millisecond polls are rounded up to the next nearest - millisecond to avoid spinning - - infinite timeouts are converted to -1 */ -int grpc_poll_deadline_to_millis_timeout(gpr_timespec deadline, - gpr_timespec now); - -/* Allow kick to wakeup the currently polling worker */ -#define GRPC_POLLSET_CAN_KICK_SELF 1 -/* Force the wakee to repoll when awoken */ -#define GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP 2 -/* As per grpc_pollset_kick, with an extended set of flags (defined above) - -- mostly for fd_posix's use. */ -void grpc_pollset_kick_ext(grpc_pollset *p, - grpc_pollset_worker *specific_worker, - uint32_t flags); - -/* turn a pollset into a multipoller: platform specific */ -typedef void (*grpc_platform_become_multipoller_type)(grpc_exec_ctx *exec_ctx, - grpc_pollset *pollset, - struct grpc_fd **fds, - size_t fd_count); -extern grpc_platform_become_multipoller_type grpc_platform_become_multipoller; - -void grpc_poll_become_multipoller(grpc_exec_ctx *exec_ctx, - grpc_pollset *pollset, struct grpc_fd **fds, - size_t fd_count); - -/* Return 1 if the pollset has active threads in grpc_pollset_work (pollset must - * be locked) */ -int grpc_pollset_has_workers(grpc_pollset *pollset); - -void grpc_remove_fd_from_all_epoll_sets(int fd); - -/* override to allow tests to hook poll() usage */ -/* NOTE: Any changes to grpc_poll_function must take place when the gRPC - is certainly not doing any polling anywhere. - Otherwise, there might be a race between changing the variable and actually - doing a polling operation */ -typedef int (*grpc_poll_function_type)(struct pollfd *, nfds_t, int); -extern grpc_poll_function_type grpc_poll_function; -extern grpc_wakeup_fd grpc_global_wakeup_fd; - -#endif /* GRPC_CORE_IOMGR_POLLSET_POSIX_H */ diff --git a/src/core/iomgr/pollset_set.h b/src/core/iomgr/pollset_set.h deleted file mode 100644 index 204c625933..0000000000 --- a/src/core/iomgr/pollset_set.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_POLLSET_SET_H -#define GRPC_CORE_IOMGR_POLLSET_SET_H - -#include "src/core/iomgr/pollset.h" - -/* A grpc_pollset_set is a set of pollsets that are interested in an - action. Adding a pollset to a pollset_set automatically adds any - fd's (etc) that have been registered with the set_set to that pollset. - Registering fd's automatically adds them to all current pollsets. */ - -typedef struct grpc_pollset_set grpc_pollset_set; - -grpc_pollset_set *grpc_pollset_set_create(void); -void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set); -void grpc_pollset_set_add_pollset(grpc_exec_ctx *exec_ctx, - grpc_pollset_set *pollset_set, - grpc_pollset *pollset); -void grpc_pollset_set_del_pollset(grpc_exec_ctx *exec_ctx, - grpc_pollset_set *pollset_set, - grpc_pollset *pollset); -void grpc_pollset_set_add_pollset_set(grpc_exec_ctx *exec_ctx, - grpc_pollset_set *bag, - grpc_pollset_set *item); -void grpc_pollset_set_del_pollset_set(grpc_exec_ctx *exec_ctx, - grpc_pollset_set *bag, - grpc_pollset_set *item); - -#endif /* GRPC_CORE_IOMGR_POLLSET_SET_H */ diff --git a/src/core/iomgr/pollset_set_posix.c b/src/core/iomgr/pollset_set_posix.c deleted file mode 100644 index 9dc9aff4a8..0000000000 --- a/src/core/iomgr/pollset_set_posix.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_SOCKET - -#include -#include - -#include -#include - -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/iomgr/pollset_set_posix.h" - -struct grpc_pollset_set { - gpr_mu mu; - - size_t pollset_count; - size_t pollset_capacity; - grpc_pollset **pollsets; - - size_t pollset_set_count; - size_t pollset_set_capacity; - struct grpc_pollset_set **pollset_sets; - - size_t fd_count; - size_t fd_capacity; - grpc_fd **fds; -}; - -grpc_pollset_set *grpc_pollset_set_create(void) { - grpc_pollset_set *pollset_set = gpr_malloc(sizeof(*pollset_set)); - memset(pollset_set, 0, sizeof(*pollset_set)); - gpr_mu_init(&pollset_set->mu); - return pollset_set; -} - -void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set) { - size_t i; - gpr_mu_destroy(&pollset_set->mu); - for (i = 0; i < pollset_set->fd_count; i++) { - GRPC_FD_UNREF(pollset_set->fds[i], "pollset_set"); - } - gpr_free(pollset_set->pollsets); - gpr_free(pollset_set->pollset_sets); - gpr_free(pollset_set->fds); - gpr_free(pollset_set); -} - -void grpc_pollset_set_add_pollset(grpc_exec_ctx *exec_ctx, - grpc_pollset_set *pollset_set, - grpc_pollset *pollset) { - size_t i, j; - gpr_mu_lock(&pollset_set->mu); - if (pollset_set->pollset_count == pollset_set->pollset_capacity) { - pollset_set->pollset_capacity = - GPR_MAX(8, 2 * pollset_set->pollset_capacity); - pollset_set->pollsets = - gpr_realloc(pollset_set->pollsets, pollset_set->pollset_capacity * - sizeof(*pollset_set->pollsets)); - } - pollset_set->pollsets[pollset_set->pollset_count++] = pollset; - for (i = 0, j = 0; i < pollset_set->fd_count; i++) { - if (grpc_fd_is_orphaned(pollset_set->fds[i])) { - GRPC_FD_UNREF(pollset_set->fds[i], "pollset_set"); - } else { - grpc_pollset_add_fd(exec_ctx, pollset, pollset_set->fds[i]); - pollset_set->fds[j++] = pollset_set->fds[i]; - } - } - pollset_set->fd_count = j; - gpr_mu_unlock(&pollset_set->mu); -} - -void grpc_pollset_set_del_pollset(grpc_exec_ctx *exec_ctx, - grpc_pollset_set *pollset_set, - grpc_pollset *pollset) { - size_t i; - gpr_mu_lock(&pollset_set->mu); - for (i = 0; i < pollset_set->pollset_count; i++) { - if (pollset_set->pollsets[i] == pollset) { - pollset_set->pollset_count--; - GPR_SWAP(grpc_pollset *, pollset_set->pollsets[i], - pollset_set->pollsets[pollset_set->pollset_count]); - break; - } - } - gpr_mu_unlock(&pollset_set->mu); -} - -void grpc_pollset_set_add_pollset_set(grpc_exec_ctx *exec_ctx, - grpc_pollset_set *bag, - grpc_pollset_set *item) { - size_t i, j; - gpr_mu_lock(&bag->mu); - if (bag->pollset_set_count == bag->pollset_set_capacity) { - bag->pollset_set_capacity = GPR_MAX(8, 2 * bag->pollset_set_capacity); - bag->pollset_sets = - gpr_realloc(bag->pollset_sets, - bag->pollset_set_capacity * sizeof(*bag->pollset_sets)); - } - bag->pollset_sets[bag->pollset_set_count++] = item; - for (i = 0, j = 0; i < bag->fd_count; i++) { - if (grpc_fd_is_orphaned(bag->fds[i])) { - GRPC_FD_UNREF(bag->fds[i], "pollset_set"); - } else { - grpc_pollset_set_add_fd(exec_ctx, item, bag->fds[i]); - bag->fds[j++] = bag->fds[i]; - } - } - bag->fd_count = j; - gpr_mu_unlock(&bag->mu); -} - -void grpc_pollset_set_del_pollset_set(grpc_exec_ctx *exec_ctx, - grpc_pollset_set *bag, - grpc_pollset_set *item) { - size_t i; - gpr_mu_lock(&bag->mu); - for (i = 0; i < bag->pollset_set_count; i++) { - if (bag->pollset_sets[i] == item) { - bag->pollset_set_count--; - GPR_SWAP(grpc_pollset_set *, bag->pollset_sets[i], - bag->pollset_sets[bag->pollset_set_count]); - break; - } - } - gpr_mu_unlock(&bag->mu); -} - -void grpc_pollset_set_add_fd(grpc_exec_ctx *exec_ctx, - grpc_pollset_set *pollset_set, grpc_fd *fd) { - size_t i; - gpr_mu_lock(&pollset_set->mu); - if (pollset_set->fd_count == pollset_set->fd_capacity) { - pollset_set->fd_capacity = GPR_MAX(8, 2 * pollset_set->fd_capacity); - pollset_set->fds = gpr_realloc( - pollset_set->fds, pollset_set->fd_capacity * sizeof(*pollset_set->fds)); - } - GRPC_FD_REF(fd, "pollset_set"); - pollset_set->fds[pollset_set->fd_count++] = fd; - for (i = 0; i < pollset_set->pollset_count; i++) { - grpc_pollset_add_fd(exec_ctx, pollset_set->pollsets[i], fd); - } - for (i = 0; i < pollset_set->pollset_set_count; i++) { - grpc_pollset_set_add_fd(exec_ctx, pollset_set->pollset_sets[i], fd); - } - gpr_mu_unlock(&pollset_set->mu); -} - -void grpc_pollset_set_del_fd(grpc_exec_ctx *exec_ctx, - grpc_pollset_set *pollset_set, grpc_fd *fd) { - size_t i; - gpr_mu_lock(&pollset_set->mu); - for (i = 0; i < pollset_set->fd_count; i++) { - if (pollset_set->fds[i] == fd) { - pollset_set->fd_count--; - GPR_SWAP(grpc_fd *, pollset_set->fds[i], - pollset_set->fds[pollset_set->fd_count]); - GRPC_FD_UNREF(fd, "pollset_set"); - break; - } - } - for (i = 0; i < pollset_set->pollset_set_count; i++) { - grpc_pollset_set_del_fd(exec_ctx, pollset_set->pollset_sets[i], fd); - } - gpr_mu_unlock(&pollset_set->mu); -} - -#endif /* GPR_POSIX_SOCKET */ diff --git a/src/core/iomgr/pollset_set_posix.h b/src/core/iomgr/pollset_set_posix.h deleted file mode 100644 index 80f487718e..0000000000 --- a/src/core/iomgr/pollset_set_posix.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_POLLSET_SET_POSIX_H -#define GRPC_CORE_IOMGR_POLLSET_SET_POSIX_H - -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/pollset_set.h" - -void grpc_pollset_set_add_fd(grpc_exec_ctx *exec_ctx, - grpc_pollset_set *pollset_set, grpc_fd *fd); -void grpc_pollset_set_del_fd(grpc_exec_ctx *exec_ctx, - grpc_pollset_set *pollset_set, grpc_fd *fd); - -#endif /* GRPC_CORE_IOMGR_POLLSET_SET_POSIX_H */ diff --git a/src/core/iomgr/pollset_set_windows.c b/src/core/iomgr/pollset_set_windows.c deleted file mode 100644 index 3b8eca28e6..0000000000 --- a/src/core/iomgr/pollset_set_windows.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_WINSOCK_SOCKET - -#include "src/core/iomgr/pollset_set_windows.h" - -grpc_pollset_set* grpc_pollset_set_create(pollset_set) { return NULL; } - -void grpc_pollset_set_destroy(grpc_pollset_set* pollset_set) {} - -void grpc_pollset_set_add_pollset(grpc_exec_ctx* exec_ctx, - grpc_pollset_set* pollset_set, - grpc_pollset* pollset) {} - -void grpc_pollset_set_del_pollset(grpc_exec_ctx* exec_ctx, - grpc_pollset_set* pollset_set, - grpc_pollset* pollset) {} - -void grpc_pollset_set_add_pollset_set(grpc_exec_ctx* exec_ctx, - grpc_pollset_set* bag, - grpc_pollset_set* item) {} - -void grpc_pollset_set_del_pollset_set(grpc_exec_ctx* exec_ctx, - grpc_pollset_set* bag, - grpc_pollset_set* item) {} - -#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/iomgr/pollset_set_windows.h b/src/core/iomgr/pollset_set_windows.h deleted file mode 100644 index 0f040fef82..0000000000 --- a/src/core/iomgr/pollset_set_windows.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_POLLSET_SET_WINDOWS_H -#define GRPC_CORE_IOMGR_POLLSET_SET_WINDOWS_H - -#include "src/core/iomgr/pollset_set.h" - -#endif /* GRPC_CORE_IOMGR_POLLSET_SET_WINDOWS_H */ diff --git a/src/core/iomgr/pollset_windows.c b/src/core/iomgr/pollset_windows.c deleted file mode 100644 index 1a99224c80..0000000000 --- a/src/core/iomgr/pollset_windows.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_WINSOCK_SOCKET - -#include -#include - -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/pollset_windows.h" - -gpr_mu grpc_polling_mu; -static grpc_pollset_worker *g_active_poller; -static grpc_pollset_worker g_global_root_worker; - -void grpc_pollset_global_init() { - gpr_mu_init(&grpc_polling_mu); - g_active_poller = NULL; - g_global_root_worker.links[GRPC_POLLSET_WORKER_LINK_GLOBAL].next = - g_global_root_worker.links[GRPC_POLLSET_WORKER_LINK_GLOBAL].prev = - &g_global_root_worker; -} - -void grpc_pollset_global_shutdown() { gpr_mu_destroy(&grpc_polling_mu); } - -static void remove_worker(grpc_pollset_worker *worker, - grpc_pollset_worker_link_type type) { - worker->links[type].prev->links[type].next = worker->links[type].next; - worker->links[type].next->links[type].prev = worker->links[type].prev; - worker->links[type].next = worker->links[type].prev = worker; -} - -static int has_workers(grpc_pollset_worker *root, - grpc_pollset_worker_link_type type) { - return root->links[type].next != root; -} - -static grpc_pollset_worker *pop_front_worker( - grpc_pollset_worker *root, grpc_pollset_worker_link_type type) { - if (has_workers(root, type)) { - grpc_pollset_worker *w = root->links[type].next; - remove_worker(w, type); - return w; - } else { - return NULL; - } -} - -static void push_front_worker(grpc_pollset_worker *root, - grpc_pollset_worker_link_type type, - grpc_pollset_worker *worker) { - worker->links[type].prev = root; - worker->links[type].next = worker->links[type].prev->links[type].next; - worker->links[type].prev->links[type].next = - worker->links[type].next->links[type].prev = worker; -} - -size_t grpc_pollset_size(void) { return sizeof(grpc_pollset); } - -/* There isn't really any such thing as a pollset under Windows, due to the - nature of the IO completion ports. We're still going to provide a minimal - set of features for the sake of the rest of grpc. But grpc_pollset_work - won't actually do any polling, and return as quickly as possible. */ - -void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) { - *mu = &grpc_polling_mu; - memset(pollset, 0, sizeof(*pollset)); - pollset->root_worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].next = - pollset->root_worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].prev = - &pollset->root_worker; -} - -void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, - grpc_closure *closure) { - pollset->shutting_down = 1; - grpc_pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST); - if (!pollset->is_iocp_worker) { - grpc_exec_ctx_enqueue(exec_ctx, closure, true, NULL); - } else { - pollset->on_shutdown = closure; - } -} - -void grpc_pollset_destroy(grpc_pollset *pollset) {} - -void grpc_pollset_reset(grpc_pollset *pollset) { - GPR_ASSERT(pollset->shutting_down); - GPR_ASSERT( - !has_workers(&pollset->root_worker, GRPC_POLLSET_WORKER_LINK_POLLSET)); - pollset->shutting_down = 0; - pollset->is_iocp_worker = 0; - pollset->kicked_without_pollers = 0; - pollset->on_shutdown = NULL; -} - -void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, - grpc_pollset_worker **worker_hdl, gpr_timespec now, - gpr_timespec deadline) { - grpc_pollset_worker worker; - *worker_hdl = &worker; - - int added_worker = 0; - worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].next = - worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].prev = - worker.links[GRPC_POLLSET_WORKER_LINK_GLOBAL].next = - worker.links[GRPC_POLLSET_WORKER_LINK_GLOBAL].prev = NULL; - worker.kicked = 0; - worker.pollset = pollset; - gpr_cv_init(&worker.cv); - if (!pollset->kicked_without_pollers && !pollset->shutting_down) { - if (g_active_poller == NULL) { - grpc_pollset_worker *next_worker; - /* become poller */ - pollset->is_iocp_worker = 1; - g_active_poller = &worker; - gpr_mu_unlock(&grpc_polling_mu); - grpc_iocp_work(exec_ctx, deadline); - grpc_exec_ctx_flush(exec_ctx); - gpr_mu_lock(&grpc_polling_mu); - pollset->is_iocp_worker = 0; - g_active_poller = NULL; - /* try to get a worker from this pollsets worker list */ - next_worker = pop_front_worker(&pollset->root_worker, - GRPC_POLLSET_WORKER_LINK_POLLSET); - if (next_worker == NULL) { - /* try to get a worker from the global list */ - next_worker = pop_front_worker(&g_global_root_worker, - GRPC_POLLSET_WORKER_LINK_GLOBAL); - } - if (next_worker != NULL) { - next_worker->kicked = 1; - gpr_cv_signal(&next_worker->cv); - } - - if (pollset->shutting_down && pollset->on_shutdown != NULL) { - grpc_exec_ctx_enqueue(exec_ctx, pollset->on_shutdown, true, NULL); - pollset->on_shutdown = NULL; - } - goto done; - } - push_front_worker(&g_global_root_worker, GRPC_POLLSET_WORKER_LINK_GLOBAL, - &worker); - push_front_worker(&pollset->root_worker, GRPC_POLLSET_WORKER_LINK_POLLSET, - &worker); - added_worker = 1; - while (!worker.kicked) { - if (gpr_cv_wait(&worker.cv, &grpc_polling_mu, deadline)) { - break; - } - } - } else { - pollset->kicked_without_pollers = 0; - } -done: - if (!grpc_closure_list_empty(exec_ctx->closure_list)) { - gpr_mu_unlock(&grpc_polling_mu); - grpc_exec_ctx_flush(exec_ctx); - gpr_mu_lock(&grpc_polling_mu); - } - if (added_worker) { - remove_worker(&worker, GRPC_POLLSET_WORKER_LINK_GLOBAL); - remove_worker(&worker, GRPC_POLLSET_WORKER_LINK_POLLSET); - } - gpr_cv_destroy(&worker.cv); - *worker_hdl = NULL; -} - -void grpc_pollset_kick(grpc_pollset *p, grpc_pollset_worker *specific_worker) { - if (specific_worker != NULL) { - if (specific_worker == GRPC_POLLSET_KICK_BROADCAST) { - for (specific_worker = - p->root_worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].next; - specific_worker != &p->root_worker; - specific_worker = - specific_worker->links[GRPC_POLLSET_WORKER_LINK_POLLSET].next) { - specific_worker->kicked = 1; - gpr_cv_signal(&specific_worker->cv); - } - p->kicked_without_pollers = 1; - if (p->is_iocp_worker) { - grpc_iocp_kick(); - } - } else { - if (p->is_iocp_worker && g_active_poller == specific_worker) { - grpc_iocp_kick(); - } else { - specific_worker->kicked = 1; - gpr_cv_signal(&specific_worker->cv); - } - } - } else { - specific_worker = - pop_front_worker(&p->root_worker, GRPC_POLLSET_WORKER_LINK_POLLSET); - if (specific_worker != NULL) { - grpc_pollset_kick(p, specific_worker); - } else if (p->is_iocp_worker) { - grpc_iocp_kick(); - } else { - p->kicked_without_pollers = 1; - } - } -} - -void grpc_kick_poller(void) { grpc_iocp_kick(); } - -#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/iomgr/pollset_windows.h b/src/core/iomgr/pollset_windows.h deleted file mode 100644 index f1d1585922..0000000000 --- a/src/core/iomgr/pollset_windows.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_POLLSET_WINDOWS_H -#define GRPC_CORE_IOMGR_POLLSET_WINDOWS_H - -#include - -#include "src/core/iomgr/socket_windows.h" - -/* There isn't really any such thing as a pollset under Windows, due to the - nature of the IO completion ports. A Windows "pollset" is merely a mutex - used to synchronize with the IOCP, and workers are condition variables - used to block threads until work is ready. */ - -typedef enum { - GRPC_POLLSET_WORKER_LINK_POLLSET = 0, - GRPC_POLLSET_WORKER_LINK_GLOBAL, - GRPC_POLLSET_WORKER_LINK_TYPES -} grpc_pollset_worker_link_type; - -typedef struct grpc_pollset_worker_link { - struct grpc_pollset_worker *next; - struct grpc_pollset_worker *prev; -} grpc_pollset_worker_link; - -struct grpc_pollset; -typedef struct grpc_pollset grpc_pollset; - -typedef struct grpc_pollset_worker { - gpr_cv cv; - int kicked; - struct grpc_pollset *pollset; - grpc_pollset_worker_link links[GRPC_POLLSET_WORKER_LINK_TYPES]; -} grpc_pollset_worker; - -struct grpc_pollset { - int shutting_down; - int kicked_without_pollers; - int is_iocp_worker; - grpc_pollset_worker root_worker; - grpc_closure *on_shutdown; -}; - -#endif /* GRPC_CORE_IOMGR_POLLSET_WINDOWS_H */ diff --git a/src/core/iomgr/resolve_address.h b/src/core/iomgr/resolve_address.h deleted file mode 100644 index aa0d7d194b..0000000000 --- a/src/core/iomgr/resolve_address.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_RESOLVE_ADDRESS_H -#define GRPC_CORE_IOMGR_RESOLVE_ADDRESS_H - -#include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/iomgr/iomgr.h" - -#define GRPC_MAX_SOCKADDR_SIZE 128 - -typedef struct { - char addr[GRPC_MAX_SOCKADDR_SIZE]; - size_t len; -} grpc_resolved_address; - -typedef struct { - size_t naddrs; - grpc_resolved_address *addrs; -} grpc_resolved_addresses; - -/* Async result callback: - On success: addresses is the result, and the callee must call - grpc_resolved_addresses_destroy when it's done with them - On failure: addresses is NULL */ -typedef void (*grpc_resolve_cb)(grpc_exec_ctx *exec_ctx, void *arg, - grpc_resolved_addresses *addresses); -/* Asynchronously resolve addr. Use default_port if a port isn't designated - in addr, otherwise use the port in addr. */ -/* TODO(ctiller): add a timeout here */ -void grpc_resolve_address(const char *addr, const char *default_port, - grpc_resolve_cb cb, void *arg); -/* Destroy resolved addresses */ -void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addresses); - -/* Resolve addr in a blocking fashion. Returns NULL on failure. On success, - result must be freed with grpc_resolved_addresses_destroy. */ -extern grpc_resolved_addresses *(*grpc_blocking_resolve_address)( - const char *name, const char *default_port); - -#endif /* GRPC_CORE_IOMGR_RESOLVE_ADDRESS_H */ diff --git a/src/core/iomgr/resolve_address_posix.c b/src/core/iomgr/resolve_address_posix.c deleted file mode 100644 index 26b3aa8189..0000000000 --- a/src/core/iomgr/resolve_address_posix.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * - * Copyright 2015-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 -#ifdef GPR_POSIX_SOCKET - -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/sockaddr.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include "src/core/iomgr/executor.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/unix_sockets_posix.h" -#include "src/core/support/block_annotate.h" -#include "src/core/support/string.h" - -typedef struct { - char *name; - char *default_port; - grpc_resolve_cb cb; - grpc_closure request_closure; - void *arg; -} request; - -static grpc_resolved_addresses *blocking_resolve_address_impl( - const char *name, const char *default_port) { - struct addrinfo hints; - struct addrinfo *result = NULL, *resp; - char *host; - char *port; - int s; - size_t i; - grpc_resolved_addresses *addrs = NULL; - - if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' && - name[4] == ':' && name[5] != 0) { - return grpc_resolve_unix_domain_address(name + 5); - } - - /* parse name, splitting it into host and port parts */ - gpr_split_host_port(name, &host, &port); - if (host == NULL) { - gpr_log(GPR_ERROR, "unparseable host:port: '%s'", name); - goto done; - } - if (port == NULL) { - if (default_port == NULL) { - gpr_log(GPR_ERROR, "no port in name '%s'", name); - goto done; - } - port = gpr_strdup(default_port); - } - - /* Call getaddrinfo */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */ - hints.ai_socktype = SOCK_STREAM; /* stream socket */ - hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ - - GRPC_SCHEDULING_START_BLOCKING_REGION; - s = getaddrinfo(host, port, &hints, &result); - GRPC_SCHEDULING_END_BLOCKING_REGION; - - if (s != 0) { - /* Retry if well-known service name is recognized */ - char *svc[][2] = {{"http", "80"}, {"https", "443"}}; - for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) { - if (strcmp(port, svc[i][0]) == 0) { - GRPC_SCHEDULING_START_BLOCKING_REGION; - s = getaddrinfo(host, svc[i][1], &hints, &result); - GRPC_SCHEDULING_END_BLOCKING_REGION; - break; - } - } - } - - if (s != 0) { - gpr_log(GPR_ERROR, "getaddrinfo: %s", gai_strerror(s)); - goto done; - } - - /* Success path: set addrs non-NULL, fill it in */ - addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); - addrs->naddrs = 0; - for (resp = result; resp != NULL; resp = resp->ai_next) { - addrs->naddrs++; - } - addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address) * addrs->naddrs); - i = 0; - for (resp = result; resp != NULL; resp = resp->ai_next) { - memcpy(&addrs->addrs[i].addr, resp->ai_addr, resp->ai_addrlen); - addrs->addrs[i].len = resp->ai_addrlen; - i++; - } - -done: - gpr_free(host); - gpr_free(port); - if (result) { - freeaddrinfo(result); - } - return addrs; -} - -grpc_resolved_addresses *(*grpc_blocking_resolve_address)( - const char *name, const char *default_port) = blocking_resolve_address_impl; - -/* Callback to be passed to grpc_executor to asynch-ify - * grpc_blocking_resolve_address */ -static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp, bool success) { - request *r = rp; - grpc_resolved_addresses *resolved = - grpc_blocking_resolve_address(r->name, r->default_port); - void *arg = r->arg; - grpc_resolve_cb cb = r->cb; - gpr_free(r->name); - gpr_free(r->default_port); - cb(exec_ctx, arg, resolved); - gpr_free(r); -} - -void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) { - gpr_free(addrs->addrs); - gpr_free(addrs); -} - -void grpc_resolve_address(const char *name, const char *default_port, - grpc_resolve_cb cb, void *arg) { - request *r = gpr_malloc(sizeof(request)); - grpc_closure_init(&r->request_closure, do_request_thread, r); - r->name = gpr_strdup(name); - r->default_port = gpr_strdup(default_port); - r->cb = cb; - r->arg = arg; - grpc_executor_enqueue(&r->request_closure, 1); -} - -#endif diff --git a/src/core/iomgr/resolve_address_windows.c b/src/core/iomgr/resolve_address_windows.c deleted file mode 100644 index 472e797163..0000000000 --- a/src/core/iomgr/resolve_address_windows.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * - * Copyright 2015-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 -#ifdef GPR_WINSOCK_SOCKET - -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/sockaddr.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include "src/core/iomgr/executor.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/support/block_annotate.h" -#include "src/core/support/string.h" - -typedef struct { - char *name; - char *default_port; - grpc_resolve_cb cb; - grpc_closure request_closure; - void *arg; -} request; - -static grpc_resolved_addresses *blocking_resolve_address_impl( - const char *name, const char *default_port) { - struct addrinfo hints; - struct addrinfo *result = NULL, *resp; - char *host; - char *port; - int s; - size_t i; - grpc_resolved_addresses *addrs = NULL; - - /* parse name, splitting it into host and port parts */ - gpr_split_host_port(name, &host, &port); - if (host == NULL) { - gpr_log(GPR_ERROR, "unparseable host:port: '%s'", name); - goto done; - } - if (port == NULL) { - if (default_port == NULL) { - gpr_log(GPR_ERROR, "no port in name '%s'", name); - goto done; - } - port = gpr_strdup(default_port); - } - - /* Call getaddrinfo */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */ - hints.ai_socktype = SOCK_STREAM; /* stream socket */ - hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ - - GRPC_SCHEDULING_START_BLOCKING_REGION; - s = getaddrinfo(host, port, &hints, &result); - GRPC_SCHEDULING_END_BLOCKING_REGION; - if (s != 0) { - char *error_message = gpr_format_message(s); - gpr_log(GPR_ERROR, "getaddrinfo: %s", error_message); - gpr_free(error_message); - goto done; - } - - /* Success path: set addrs non-NULL, fill it in */ - addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); - addrs->naddrs = 0; - for (resp = result; resp != NULL; resp = resp->ai_next) { - addrs->naddrs++; - } - addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address) * addrs->naddrs); - i = 0; - for (resp = result; resp != NULL; resp = resp->ai_next) { - memcpy(&addrs->addrs[i].addr, resp->ai_addr, resp->ai_addrlen); - addrs->addrs[i].len = resp->ai_addrlen; - i++; - } - - { - for (i = 0; i < addrs->naddrs; i++) { - char *buf; - grpc_sockaddr_to_string(&buf, (struct sockaddr *)&addrs->addrs[i].addr, - 0); - gpr_free(buf); - } - } - -done: - gpr_free(host); - gpr_free(port); - if (result) { - freeaddrinfo(result); - } - return addrs; -} - -grpc_resolved_addresses *(*grpc_blocking_resolve_address)( - const char *name, const char *default_port) = blocking_resolve_address_impl; - -/* Callback to be passed to grpc_executor to asynch-ify - * grpc_blocking_resolve_address */ -static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp, bool success) { - request *r = rp; - grpc_resolved_addresses *resolved = - grpc_blocking_resolve_address(r->name, r->default_port); - void *arg = r->arg; - grpc_resolve_cb cb = r->cb; - gpr_free(r->name); - gpr_free(r->default_port); - cb(exec_ctx, arg, resolved); - gpr_free(r); -} - -void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) { - gpr_free(addrs->addrs); - gpr_free(addrs); -} - -void grpc_resolve_address(const char *name, const char *default_port, - grpc_resolve_cb cb, void *arg) { - request *r = gpr_malloc(sizeof(request)); - grpc_closure_init(&r->request_closure, do_request_thread, r); - r->name = gpr_strdup(name); - r->default_port = gpr_strdup(default_port); - r->cb = cb; - r->arg = arg; - grpc_executor_enqueue(&r->request_closure, 1); -} - -#endif diff --git a/src/core/iomgr/sockaddr.h b/src/core/iomgr/sockaddr.h deleted file mode 100644 index 68241bdd55..0000000000 --- a/src/core/iomgr/sockaddr.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_SOCKADDR_H -#define GRPC_CORE_IOMGR_SOCKADDR_H - -#include - -#ifdef GPR_WIN32 -#include "src/core/iomgr/sockaddr_win32.h" -#endif - -#ifdef GPR_POSIX_SOCKETADDR -#include "src/core/iomgr/sockaddr_posix.h" -#endif - -#endif /* GRPC_CORE_IOMGR_SOCKADDR_H */ diff --git a/src/core/iomgr/sockaddr_posix.h b/src/core/iomgr/sockaddr_posix.h deleted file mode 100644 index a398096837..0000000000 --- a/src/core/iomgr/sockaddr_posix.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_SOCKADDR_POSIX_H -#define GRPC_CORE_IOMGR_SOCKADDR_POSIX_H - -#include -#include -#include -#include -#include -#include - -#endif /* GRPC_CORE_IOMGR_SOCKADDR_POSIX_H */ diff --git a/src/core/iomgr/sockaddr_utils.c b/src/core/iomgr/sockaddr_utils.c deleted file mode 100644 index a3c3a874c1..0000000000 --- a/src/core/iomgr/sockaddr_utils.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * - * 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/iomgr/sockaddr_utils.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include "src/core/iomgr/unix_sockets_posix.h" -#include "src/core/support/string.h" - -static const uint8_t kV4MappedPrefix[] = {0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xff, 0xff}; - -int grpc_sockaddr_is_v4mapped(const struct sockaddr *addr, - struct sockaddr_in *addr4_out) { - GPR_ASSERT(addr != (struct sockaddr *)addr4_out); - if (addr->sa_family == AF_INET6) { - const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; - if (memcmp(addr6->sin6_addr.s6_addr, kV4MappedPrefix, - sizeof(kV4MappedPrefix)) == 0) { - if (addr4_out != NULL) { - /* Normalize ::ffff:0.0.0.0/96 to IPv4. */ - memset(addr4_out, 0, sizeof(*addr4_out)); - addr4_out->sin_family = AF_INET; - /* s6_addr32 would be nice, but it's non-standard. */ - memcpy(&addr4_out->sin_addr, &addr6->sin6_addr.s6_addr[12], 4); - addr4_out->sin_port = addr6->sin6_port; - } - return 1; - } - } - return 0; -} - -int grpc_sockaddr_to_v4mapped(const struct sockaddr *addr, - struct sockaddr_in6 *addr6_out) { - GPR_ASSERT(addr != (struct sockaddr *)addr6_out); - if (addr->sa_family == AF_INET) { - const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr; - memset(addr6_out, 0, sizeof(*addr6_out)); - addr6_out->sin6_family = AF_INET6; - memcpy(&addr6_out->sin6_addr.s6_addr[0], kV4MappedPrefix, 12); - memcpy(&addr6_out->sin6_addr.s6_addr[12], &addr4->sin_addr, 4); - addr6_out->sin6_port = addr4->sin_port; - return 1; - } - return 0; -} - -int grpc_sockaddr_is_wildcard(const struct sockaddr *addr, int *port_out) { - struct sockaddr_in addr4_normalized; - if (grpc_sockaddr_is_v4mapped(addr, &addr4_normalized)) { - addr = (struct sockaddr *)&addr4_normalized; - } - if (addr->sa_family == AF_INET) { - /* Check for 0.0.0.0 */ - const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr; - if (addr4->sin_addr.s_addr != 0) { - return 0; - } - *port_out = ntohs(addr4->sin_port); - return 1; - } else if (addr->sa_family == AF_INET6) { - /* Check for :: */ - const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; - int i; - for (i = 0; i < 16; i++) { - if (addr6->sin6_addr.s6_addr[i] != 0) { - return 0; - } - } - *port_out = ntohs(addr6->sin6_port); - return 1; - } else { - return 0; - } -} - -void grpc_sockaddr_make_wildcards(int port, struct sockaddr_in *wild4_out, - struct sockaddr_in6 *wild6_out) { - grpc_sockaddr_make_wildcard4(port, wild4_out); - grpc_sockaddr_make_wildcard6(port, wild6_out); -} - -void grpc_sockaddr_make_wildcard4(int port, struct sockaddr_in *wild_out) { - GPR_ASSERT(port >= 0 && port < 65536); - memset(wild_out, 0, sizeof(*wild_out)); - wild_out->sin_family = AF_INET; - wild_out->sin_port = htons((uint16_t)port); -} - -void grpc_sockaddr_make_wildcard6(int port, struct sockaddr_in6 *wild_out) { - GPR_ASSERT(port >= 0 && port < 65536); - memset(wild_out, 0, sizeof(*wild_out)); - wild_out->sin6_family = AF_INET6; - wild_out->sin6_port = htons((uint16_t)port); -} - -int grpc_sockaddr_to_string(char **out, const struct sockaddr *addr, - int normalize) { - const int save_errno = errno; - struct sockaddr_in addr_normalized; - char ntop_buf[INET6_ADDRSTRLEN]; - const void *ip = NULL; - int port; - int ret; - - *out = NULL; - if (normalize && grpc_sockaddr_is_v4mapped(addr, &addr_normalized)) { - addr = (const struct sockaddr *)&addr_normalized; - } - if (addr->sa_family == AF_INET) { - const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr; - ip = &addr4->sin_addr; - port = ntohs(addr4->sin_port); - } else if (addr->sa_family == AF_INET6) { - const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; - ip = &addr6->sin6_addr; - port = ntohs(addr6->sin6_port); - } - /* Windows inet_ntop wants a mutable ip pointer */ - if (ip != NULL && - inet_ntop(addr->sa_family, (void *)ip, ntop_buf, sizeof(ntop_buf)) != - NULL) { - ret = gpr_join_host_port(out, ntop_buf, port); - } else { - ret = gpr_asprintf(out, "(sockaddr family=%d)", addr->sa_family); - } - /* This is probably redundant, but we wouldn't want to log the wrong error. */ - errno = save_errno; - return ret; -} - -char *grpc_sockaddr_to_uri(const struct sockaddr *addr) { - char *temp; - char *result; - struct sockaddr_in addr_normalized; - - if (grpc_sockaddr_is_v4mapped(addr, &addr_normalized)) { - addr = (const struct sockaddr *)&addr_normalized; - } - - switch (addr->sa_family) { - case AF_INET: - grpc_sockaddr_to_string(&temp, addr, 0); - gpr_asprintf(&result, "ipv4:%s", temp); - gpr_free(temp); - return result; - case AF_INET6: - grpc_sockaddr_to_string(&temp, addr, 0); - gpr_asprintf(&result, "ipv6:%s", temp); - gpr_free(temp); - return result; - default: - return grpc_sockaddr_to_uri_unix_if_possible(addr); - } -} - -int grpc_sockaddr_get_port(const struct sockaddr *addr) { - switch (addr->sa_family) { - case AF_INET: - return ntohs(((struct sockaddr_in *)addr)->sin_port); - case AF_INET6: - return ntohs(((struct sockaddr_in6 *)addr)->sin6_port); - default: - if (grpc_is_unix_socket(addr)) { - return 1; - } - gpr_log(GPR_ERROR, "Unknown socket family %d in grpc_sockaddr_get_port", - addr->sa_family); - return 0; - } -} - -int grpc_sockaddr_set_port(const struct sockaddr *addr, int port) { - switch (addr->sa_family) { - case AF_INET: - GPR_ASSERT(port >= 0 && port < 65536); - ((struct sockaddr_in *)addr)->sin_port = htons((uint16_t)port); - return 1; - case AF_INET6: - GPR_ASSERT(port >= 0 && port < 65536); - ((struct sockaddr_in6 *)addr)->sin6_port = htons((uint16_t)port); - return 1; - default: - gpr_log(GPR_ERROR, "Unknown socket family %d in grpc_sockaddr_set_port", - addr->sa_family); - return 0; - } -} diff --git a/src/core/iomgr/sockaddr_utils.h b/src/core/iomgr/sockaddr_utils.h deleted file mode 100644 index 43dc7a45ec..0000000000 --- a/src/core/iomgr/sockaddr_utils.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_SOCKADDR_UTILS_H -#define GRPC_CORE_IOMGR_SOCKADDR_UTILS_H - -#include "src/core/iomgr/sockaddr.h" - -/* Returns true if addr is an IPv4-mapped IPv6 address within the - ::ffff:0.0.0.0/96 range, or false otherwise. - - If addr4_out is non-NULL, the inner IPv4 address will be copied here when - returning true. */ -int grpc_sockaddr_is_v4mapped(const struct sockaddr *addr, - struct sockaddr_in *addr4_out); - -/* If addr is an AF_INET address, writes the corresponding ::ffff:0.0.0.0/96 - address to addr6_out and returns true. Otherwise returns false. */ -int grpc_sockaddr_to_v4mapped(const struct sockaddr *addr, - struct sockaddr_in6 *addr6_out); - -/* If addr is ::, 0.0.0.0, or ::ffff:0.0.0.0, writes the port number to - *port_out (if not NULL) and returns true, otherwise returns false. */ -int grpc_sockaddr_is_wildcard(const struct sockaddr *addr, int *port_out); - -/* Writes 0.0.0.0:port and [::]:port to separate sockaddrs. */ -void grpc_sockaddr_make_wildcards(int port, struct sockaddr_in *wild4_out, - struct sockaddr_in6 *wild6_out); - -/* Writes 0.0.0.0:port. */ -void grpc_sockaddr_make_wildcard4(int port, struct sockaddr_in *wild_out); - -/* Writes [::]:port. */ -void grpc_sockaddr_make_wildcard6(int port, struct sockaddr_in6 *wild_out); - -/* Return the IP port number of a sockaddr */ -int grpc_sockaddr_get_port(const struct sockaddr *addr); - -/* Set IP port number of a sockaddr */ -int grpc_sockaddr_set_port(const struct sockaddr *addr, int port); - -/* Converts a sockaddr into a newly-allocated human-readable string. - - Currently, only the AF_INET and AF_INET6 families are recognized. - If the normalize flag is enabled, ::ffff:0.0.0.0/96 IPv6 addresses are - displayed as plain IPv4. - - Usage is similar to gpr_asprintf: returns the number of bytes written - (excluding the final '\0'), and *out points to a string which must later be - destroyed using gpr_free(). - - In the unlikely event of an error, returns -1 and sets *out to NULL. - The existing value of errno is always preserved. */ -int grpc_sockaddr_to_string(char **out, const struct sockaddr *addr, - int normalize); - -char *grpc_sockaddr_to_uri(const struct sockaddr *addr); - -#endif /* GRPC_CORE_IOMGR_SOCKADDR_UTILS_H */ diff --git a/src/core/iomgr/sockaddr_win32.h b/src/core/iomgr/sockaddr_win32.h deleted file mode 100644 index ef306e3cc3..0000000000 --- a/src/core/iomgr/sockaddr_win32.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_SOCKADDR_WIN32_H -#define GRPC_CORE_IOMGR_SOCKADDR_WIN32_H - -#include -#include - -// must be included after the above -#include - -#endif /* GRPC_CORE_IOMGR_SOCKADDR_WIN32_H */ diff --git a/src/core/iomgr/socket_utils_common_posix.c b/src/core/iomgr/socket_utils_common_posix.c deleted file mode 100644 index 570daccc9e..0000000000 --- a/src/core/iomgr/socket_utils_common_posix.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_SOCKET - -#include "src/core/iomgr/socket_utils_posix.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/support/string.h" - -/* set a socket to non blocking mode */ -int grpc_set_socket_nonblocking(int fd, int non_blocking) { - int oldflags = fcntl(fd, F_GETFL, 0); - if (oldflags < 0) { - return 0; - } - - if (non_blocking) { - oldflags |= O_NONBLOCK; - } else { - oldflags &= ~O_NONBLOCK; - } - - if (fcntl(fd, F_SETFL, oldflags) != 0) { - return 0; - } - - return 1; -} - -int grpc_set_socket_no_sigpipe_if_possible(int fd) { -#ifdef GPR_HAVE_SO_NOSIGPIPE - int val = 1; - int newval; - socklen_t intlen = sizeof(newval); - return 0 == setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val)) && - 0 == getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &newval, &intlen) && - (newval != 0) == val; -#else - return 1; -#endif -} - -/* set a socket to close on exec */ -int grpc_set_socket_cloexec(int fd, int close_on_exec) { - int oldflags = fcntl(fd, F_GETFD, 0); - if (oldflags < 0) { - return 0; - } - - if (close_on_exec) { - oldflags |= FD_CLOEXEC; - } else { - oldflags &= ~FD_CLOEXEC; - } - - if (fcntl(fd, F_SETFD, oldflags) != 0) { - return 0; - } - - return 1; -} - -/* set a socket to reuse old addresses */ -int grpc_set_socket_reuse_addr(int fd, int reuse) { - int val = (reuse != 0); - int newval; - socklen_t intlen = sizeof(newval); - return 0 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) && - 0 == getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &newval, &intlen) && - (newval != 0) == val; -} - -/* disable nagle */ -int grpc_set_socket_low_latency(int fd, int low_latency) { - int val = (low_latency != 0); - int newval; - socklen_t intlen = sizeof(newval); - return 0 == setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) && - 0 == getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &newval, &intlen) && - (newval != 0) == val; -} - -static gpr_once g_probe_ipv6_once = GPR_ONCE_INIT; -static int g_ipv6_loopback_available; - -static void probe_ipv6_once(void) { - int fd = socket(AF_INET6, SOCK_STREAM, 0); - g_ipv6_loopback_available = 0; - if (fd < 0) { - gpr_log(GPR_INFO, "Disabling AF_INET6 sockets because socket() failed."); - } else { - struct sockaddr_in6 addr; - memset(&addr, 0, sizeof(addr)); - addr.sin6_family = AF_INET6; - addr.sin6_addr.s6_addr[15] = 1; /* [::1]:0 */ - if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == 0) { - g_ipv6_loopback_available = 1; - } else { - gpr_log(GPR_INFO, - "Disabling AF_INET6 sockets because ::1 is not available."); - } - close(fd); - } -} - -int grpc_ipv6_loopback_available(void) { - gpr_once_init(&g_probe_ipv6_once, probe_ipv6_once); - return g_ipv6_loopback_available; -} - -/* This should be 0 in production, but it may be enabled for testing or - debugging purposes, to simulate an environment where IPv6 sockets can't - also speak IPv4. */ -int grpc_forbid_dualstack_sockets_for_testing = 0; - -static int set_socket_dualstack(int fd) { - if (!grpc_forbid_dualstack_sockets_for_testing) { - const int off = 0; - return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off)); - } else { - /* Force an IPv6-only socket, for testing purposes. */ - const int on = 1; - setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); - return 0; - } -} - -int grpc_create_dualstack_socket(const struct sockaddr *addr, int type, - int protocol, grpc_dualstack_mode *dsmode) { - int family = addr->sa_family; - if (family == AF_INET6) { - int fd; - if (grpc_ipv6_loopback_available()) { - fd = socket(family, type, protocol); - } else { - fd = -1; - errno = EAFNOSUPPORT; - } - /* Check if we've got a valid dualstack socket. */ - if (fd >= 0 && set_socket_dualstack(fd)) { - *dsmode = GRPC_DSMODE_DUALSTACK; - return fd; - } - /* If this isn't an IPv4 address, then return whatever we've got. */ - if (!grpc_sockaddr_is_v4mapped(addr, NULL)) { - *dsmode = GRPC_DSMODE_IPV6; - return fd; - } - /* Fall back to AF_INET. */ - if (fd >= 0) { - close(fd); - } - family = AF_INET; - } - *dsmode = family == AF_INET ? GRPC_DSMODE_IPV4 : GRPC_DSMODE_NONE; - return socket(family, type, protocol); -} - -#endif diff --git a/src/core/iomgr/socket_utils_linux.c b/src/core/iomgr/socket_utils_linux.c deleted file mode 100644 index e16885f231..0000000000 --- a/src/core/iomgr/socket_utils_linux.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_LINUX_SOCKETUTILS - -#include "src/core/iomgr/socket_utils_posix.h" - -#include -#include - -int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, - int nonblock, int cloexec) { - int flags = 0; - flags |= nonblock ? SOCK_NONBLOCK : 0; - flags |= cloexec ? SOCK_CLOEXEC : 0; - return accept4(sockfd, addr, addrlen, flags); -} - -#endif diff --git a/src/core/iomgr/socket_utils_posix.c b/src/core/iomgr/socket_utils_posix.c deleted file mode 100644 index 3c56b46744..0000000000 --- a/src/core/iomgr/socket_utils_posix.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * Copyright 2015, 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 - -#ifdef GPR_POSIX_SOCKETUTILS - -#include "src/core/iomgr/socket_utils_posix.h" - -#include -#include -#include - -#include - -int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, - int nonblock, int cloexec) { - int fd, flags; - - fd = accept(sockfd, addr, addrlen); - if (fd >= 0) { - if (nonblock) { - flags = fcntl(fd, F_GETFL, 0); - if (flags < 0) goto close_and_error; - if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) goto close_and_error; - } - if (cloexec) { - flags = fcntl(fd, F_GETFD, 0); - if (flags < 0) goto close_and_error; - if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != 0) goto close_and_error; - } - } - return fd; - -close_and_error: - close(fd); - return -1; -} - -#endif /* GPR_POSIX_SOCKETUTILS */ diff --git a/src/core/iomgr/socket_utils_posix.h b/src/core/iomgr/socket_utils_posix.h deleted file mode 100644 index 3908550380..0000000000 --- a/src/core/iomgr/socket_utils_posix.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_SOCKET_UTILS_POSIX_H -#define GRPC_CORE_IOMGR_SOCKET_UTILS_POSIX_H - -#include -#include - -/* a wrapper for accept or accept4 */ -int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, - int nonblock, int cloexec); - -/* set a socket to non blocking mode */ -int grpc_set_socket_nonblocking(int fd, int non_blocking); - -/* set a socket to close on exec */ -int grpc_set_socket_cloexec(int fd, int close_on_exec); - -/* set a socket to reuse old addresses */ -int grpc_set_socket_reuse_addr(int fd, int reuse); - -/* disable nagle */ -int grpc_set_socket_low_latency(int fd, int low_latency); - -/* Returns true if this system can create AF_INET6 sockets bound to ::1. - The value is probed once, and cached for the life of the process. - - This is more restrictive than checking for socket(AF_INET6) to succeed, - because Linux with "net.ipv6.conf.all.disable_ipv6 = 1" is able to create - and bind IPv6 sockets, but cannot connect to a getsockname() of [::]:port - without a valid loopback interface. Rather than expose this half-broken - state to library users, we turn off IPv6 sockets. */ -int grpc_ipv6_loopback_available(void); - -/* Tries to set SO_NOSIGPIPE if available on this platform. - Returns 1 on success, 0 on failure. - If SO_NO_SIGPIPE is not available, returns 1. */ -int grpc_set_socket_no_sigpipe_if_possible(int fd); - -/* An enum to keep track of IPv4/IPv6 socket modes. - - Currently, this information is only used when a socket is first created, but - in the future we may wish to store it alongside the fd. This would let calls - like sendto() know which family to use without asking the kernel first. */ -typedef enum grpc_dualstack_mode { - /* Uninitialized, or a non-IP socket. */ - GRPC_DSMODE_NONE, - /* AF_INET only. */ - GRPC_DSMODE_IPV4, - /* AF_INET6 only, because IPV6_V6ONLY could not be cleared. */ - GRPC_DSMODE_IPV6, - /* AF_INET6, which also supports ::ffff-mapped IPv4 addresses. */ - GRPC_DSMODE_DUALSTACK -} grpc_dualstack_mode; - -/* Only tests should use this flag. */ -extern int grpc_forbid_dualstack_sockets_for_testing; - -/* Creates a new socket for connecting to (or listening on) an address. - - If addr is AF_INET6, this creates an IPv6 socket first. If that fails, - and addr is within ::ffff:0.0.0.0/96, then it automatically falls back to - an IPv4 socket. - - If addr is AF_INET, AF_UNIX, or anything else, then this is similar to - calling socket() directly. - - Returns an fd on success, otherwise returns -1 with errno set to the result - of a failed socket() call. - - The *dsmode output indicates which address family was actually created. - The recommended way to use this is: - - First convert to IPv6 using grpc_sockaddr_to_v4mapped(). - - Create the socket. - - If *dsmode is IPV4, use grpc_sockaddr_is_v4mapped() to convert back to - IPv4, so that bind() or connect() see the correct family. - Also, it's important to distinguish between DUALSTACK and IPV6 when - listening on the [::] wildcard address. */ -int grpc_create_dualstack_socket(const struct sockaddr *addr, int type, - int protocol, grpc_dualstack_mode *dsmode); - -#endif /* GRPC_CORE_IOMGR_SOCKET_UTILS_POSIX_H */ diff --git a/src/core/iomgr/socket_windows.c b/src/core/iomgr/socket_windows.c deleted file mode 100644 index c1f419e273..0000000000 --- a/src/core/iomgr/socket_windows.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_WINSOCK_SOCKET - -#include - -// must be included after winsock2.h -#include - -#include -#include -#include -#include - -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/pollset_windows.h" -#include "src/core/iomgr/socket_windows.h" - -grpc_winsocket *grpc_winsocket_create(SOCKET socket, const char *name) { - char *final_name; - grpc_winsocket *r = gpr_malloc(sizeof(grpc_winsocket)); - memset(r, 0, sizeof(grpc_winsocket)); - r->socket = socket; - gpr_mu_init(&r->state_mu); - gpr_asprintf(&final_name, "%s:socket=0x%p", name, r); - grpc_iomgr_register_object(&r->iomgr_object, final_name); - gpr_free(final_name); - grpc_iocp_add_socket(r); - return r; -} - -/* Schedule a shutdown of the socket operations. Will call the pending - operations to abort them. We need to do that this way because of the - various callsites of that function, which happens to be in various - mutex hold states, and that'd be unsafe to call them directly. */ -void grpc_winsocket_shutdown(grpc_winsocket *winsocket) { - /* Grab the function pointer for DisconnectEx for that specific socket. - It may change depending on the interface. */ - int status; - GUID guid = WSAID_DISCONNECTEX; - LPFN_DISCONNECTEX DisconnectEx; - DWORD ioctl_num_bytes; - - status = WSAIoctl(winsocket->socket, SIO_GET_EXTENSION_FUNCTION_POINTER, - &guid, sizeof(guid), &DisconnectEx, sizeof(DisconnectEx), - &ioctl_num_bytes, NULL, NULL); - - if (status == 0) { - DisconnectEx(winsocket->socket, NULL, 0, 0); - } else { - char *utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, "Unable to retrieve DisconnectEx pointer : %s", - utf8_message); - gpr_free(utf8_message); - } - closesocket(winsocket->socket); -} - -void grpc_winsocket_destroy(grpc_winsocket *winsocket) { - grpc_iomgr_unregister_object(&winsocket->iomgr_object); - gpr_mu_destroy(&winsocket->state_mu); - gpr_free(winsocket); -} - -#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/iomgr/socket_windows.h b/src/core/iomgr/socket_windows.h deleted file mode 100644 index 6fe3c6e080..0000000000 --- a/src/core/iomgr/socket_windows.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_SOCKET_WINDOWS_H -#define GRPC_CORE_IOMGR_SOCKET_WINDOWS_H - -#include -#include - -#include -#include - -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/iomgr/iomgr_internal.h" - -/* This holds the data for an outstanding read or write on a socket. - The mutex to protect the concurrent access to that data is the one - inside the winsocket wrapper. */ -typedef struct grpc_winsocket_callback_info { - /* This is supposed to be a WSAOVERLAPPED, but in order to get that - definition, we need to include ws2tcpip.h, which needs to be included - from the top, otherwise it'll clash with a previous inclusion of - windows.h that in turns includes winsock.h. If anyone knows a way - to do it properly, feel free to send a patch. */ - OVERLAPPED overlapped; - /* The callback information for the pending operation. May be empty if the - caller hasn't registered a callback yet. */ - grpc_closure *closure; - /* A boolean to describe if the IO Completion Port got a notification for - that operation. This will happen if the operation completed before the - called had time to register a callback. We could avoid that behavior - altogether by forcing the caller to always register its callback before - proceeding queue an operation, but it is frequent for an IO Completion - Port to trigger quickly. This way we avoid a context switch for calling - the callback. We also simplify the read / write operations to avoid having - to hold a mutex for a long amount of time. */ - int has_pending_iocp; - /* The results of the overlapped operation. */ - DWORD bytes_transfered; - int wsa_error; -} grpc_winsocket_callback_info; - -/* This is a wrapper to a Windows socket. A socket can have one outstanding - read, and one outstanding write. Doing an asynchronous accept means waiting - for a read operation. Doing an asynchronous connect means waiting for a - write operation. These are completely arbitrary ties between the operation - and the kind of event, because we can have one overlapped per pending - operation, whichever its nature is. So we could have more dedicated pending - operation callbacks for connect and listen. But given the scope of listen - and accept, we don't need to go to that extent and waste memory. Also, this - is closer to what happens in posix world. */ -typedef struct grpc_winsocket { - SOCKET socket; - - grpc_winsocket_callback_info write_info; - grpc_winsocket_callback_info read_info; - - gpr_mu state_mu; - - /* You can't add the same socket twice to the same IO Completion Port. - This prevents that. */ - int added_to_iocp; - - grpc_closure shutdown_closure; - - /* A label for iomgr to track outstanding objects */ - grpc_iomgr_object iomgr_object; -} grpc_winsocket; - -/* Create a wrapped windows handle. This takes ownership of it, meaning that - it will be responsible for closing it. */ -grpc_winsocket *grpc_winsocket_create(SOCKET socket, const char *name); - -/* Initiate an asynchronous shutdown of the socket. Will call off any pending - operation to cancel them. */ -void grpc_winsocket_shutdown(grpc_winsocket *socket); - -/* Destroy a socket. Should only be called if there's no pending operation. */ -void grpc_winsocket_destroy(grpc_winsocket *socket); - -#endif /* GRPC_CORE_IOMGR_SOCKET_WINDOWS_H */ diff --git a/src/core/iomgr/tcp_client.h b/src/core/iomgr/tcp_client.h deleted file mode 100644 index c36f8de713..0000000000 --- a/src/core/iomgr/tcp_client.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_TCP_CLIENT_H -#define GRPC_CORE_IOMGR_TCP_CLIENT_H - -#include -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/pollset_set.h" -#include "src/core/iomgr/sockaddr.h" - -/* Asynchronously connect to an address (specified as (addr, len)), and call - cb with arg and the completed connection when done (or call cb with arg and - NULL on failure). - interested_parties points to a set of pollsets that would be interested - in this connection being established (in order to continue their work) */ -void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_connect, - grpc_endpoint **endpoint, - grpc_pollset_set *interested_parties, - const struct sockaddr *addr, size_t addr_len, - gpr_timespec deadline); - -#endif /* GRPC_CORE_IOMGR_TCP_CLIENT_H */ diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c deleted file mode 100644 index 1d3f9b6555..0000000000 --- a/src/core/iomgr/tcp_client_posix.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_SOCKET - -#include "src/core/iomgr/tcp_client.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "src/core/iomgr/iomgr_posix.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/iomgr/pollset_set_posix.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/iomgr/tcp_posix.h" -#include "src/core/iomgr/timer.h" -#include "src/core/iomgr/unix_sockets_posix.h" -#include "src/core/support/string.h" - -extern int grpc_tcp_trace; - -typedef struct { - gpr_mu mu; - grpc_fd *fd; - gpr_timespec deadline; - grpc_timer alarm; - int refs; - grpc_closure write_closure; - grpc_pollset_set *interested_parties; - char *addr_str; - grpc_endpoint **ep; - grpc_closure *closure; -} async_connect; - -static int prepare_socket(const struct sockaddr *addr, int fd) { - if (fd < 0) { - goto error; - } - - if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || - (!grpc_is_unix_socket(addr) && !grpc_set_socket_low_latency(fd, 1)) || - !grpc_set_socket_no_sigpipe_if_possible(fd)) { - gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, - strerror(errno)); - goto error; - } - return 1; - -error: - if (fd >= 0) { - close(fd); - } - return 0; -} - -static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, bool success) { - int done; - async_connect *ac = acp; - if (grpc_tcp_trace) { - gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: success=%d", ac->addr_str, - success); - } - gpr_mu_lock(&ac->mu); - if (ac->fd != NULL) { - grpc_fd_shutdown(exec_ctx, ac->fd); - } - done = (--ac->refs == 0); - gpr_mu_unlock(&ac->mu); - if (done) { - gpr_mu_destroy(&ac->mu); - gpr_free(ac->addr_str); - gpr_free(ac); - } -} - -static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, bool success) { - async_connect *ac = acp; - int so_error = 0; - socklen_t so_error_size; - int err; - int done; - grpc_endpoint **ep = ac->ep; - grpc_closure *closure = ac->closure; - grpc_fd *fd; - - if (grpc_tcp_trace) { - gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_writable: success=%d", - ac->addr_str, success); - } - - gpr_mu_lock(&ac->mu); - GPR_ASSERT(ac->fd); - fd = ac->fd; - ac->fd = NULL; - gpr_mu_unlock(&ac->mu); - - grpc_timer_cancel(exec_ctx, &ac->alarm); - - gpr_mu_lock(&ac->mu); - if (success) { - do { - so_error_size = sizeof(so_error); - err = getsockopt(fd->fd, SOL_SOCKET, SO_ERROR, &so_error, &so_error_size); - } while (err < 0 && errno == EINTR); - if (err < 0) { - gpr_log(GPR_ERROR, "failed to connect to '%s': getsockopt(ERROR): %s", - ac->addr_str, strerror(errno)); - goto finish; - } else if (so_error != 0) { - if (so_error == ENOBUFS) { - /* We will get one of these errors if we have run out of - memory in the kernel for the data structures allocated - when you connect a socket. If this happens it is very - likely that if we wait a little bit then try again the - connection will work (since other programs or this - program will close their network connections and free up - memory). This does _not_ indicate that there is anything - wrong with the server we are connecting to, this is a - local problem. - - If you are looking at this code, then chances are that - your program or another program on the same computer - opened too many network connections. The "easy" fix: - don't do that! */ - gpr_log(GPR_ERROR, "kernel out of buffers"); - gpr_mu_unlock(&ac->mu); - grpc_fd_notify_on_write(exec_ctx, fd, &ac->write_closure); - return; - } else { - switch (so_error) { - case ECONNREFUSED: - gpr_log( - GPR_ERROR, - "failed to connect to '%s': socket error: connection refused", - ac->addr_str); - break; - default: - gpr_log(GPR_ERROR, "failed to connect to '%s': socket error: %d", - ac->addr_str, so_error); - break; - } - goto finish; - } - } else { - grpc_pollset_set_del_fd(exec_ctx, ac->interested_parties, fd); - *ep = grpc_tcp_create(fd, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, ac->addr_str); - fd = NULL; - goto finish; - } - } else { - gpr_log(GPR_ERROR, "failed to connect to '%s': timeout occurred", - ac->addr_str); - goto finish; - } - - GPR_UNREACHABLE_CODE(return ); - -finish: - if (fd != NULL) { - grpc_pollset_set_del_fd(exec_ctx, ac->interested_parties, fd); - grpc_fd_orphan(exec_ctx, fd, NULL, NULL, "tcp_client_orphan"); - fd = NULL; - } - done = (--ac->refs == 0); - gpr_mu_unlock(&ac->mu); - if (done) { - gpr_mu_destroy(&ac->mu); - gpr_free(ac->addr_str); - gpr_free(ac); - } - grpc_exec_ctx_enqueue(exec_ctx, closure, *ep != NULL, NULL); -} - -void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure, - grpc_endpoint **ep, - grpc_pollset_set *interested_parties, - const struct sockaddr *addr, size_t addr_len, - gpr_timespec deadline) { - int fd; - grpc_dualstack_mode dsmode; - int err; - async_connect *ac; - struct sockaddr_in6 addr6_v4mapped; - struct sockaddr_in addr4_copy; - grpc_fd *fdobj; - char *name; - char *addr_str; - - *ep = NULL; - - /* Use dualstack sockets where available. */ - if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { - addr = (const struct sockaddr *)&addr6_v4mapped; - addr_len = sizeof(addr6_v4mapped); - } - - fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode); - if (fd < 0) { - gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno)); - } - if (dsmode == GRPC_DSMODE_IPV4) { - /* If we got an AF_INET socket, map the address back to IPv4. */ - GPR_ASSERT(grpc_sockaddr_is_v4mapped(addr, &addr4_copy)); - addr = (struct sockaddr *)&addr4_copy; - addr_len = sizeof(addr4_copy); - } - if (!prepare_socket(addr, fd)) { - grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL); - return; - } - - do { - GPR_ASSERT(addr_len < ~(socklen_t)0); - err = connect(fd, addr, (socklen_t)addr_len); - } while (err < 0 && errno == EINTR); - - addr_str = grpc_sockaddr_to_uri(addr); - gpr_asprintf(&name, "tcp-client:%s", addr_str); - - fdobj = grpc_fd_create(fd, name); - - if (err >= 0) { - *ep = grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str); - grpc_exec_ctx_enqueue(exec_ctx, closure, true, NULL); - goto done; - } - - if (errno != EWOULDBLOCK && errno != EINPROGRESS) { - gpr_log(GPR_ERROR, "connect error to '%s': %s", addr_str, strerror(errno)); - grpc_fd_orphan(exec_ctx, fdobj, NULL, NULL, "tcp_client_connect_error"); - grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL); - goto done; - } - - grpc_pollset_set_add_fd(exec_ctx, interested_parties, fdobj); - - ac = gpr_malloc(sizeof(async_connect)); - ac->closure = closure; - ac->ep = ep; - ac->fd = fdobj; - ac->interested_parties = interested_parties; - ac->addr_str = addr_str; - addr_str = NULL; - gpr_mu_init(&ac->mu); - ac->refs = 2; - ac->write_closure.cb = on_writable; - ac->write_closure.cb_arg = ac; - - if (grpc_tcp_trace) { - gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: asynchronously connecting", - ac->addr_str); - } - - gpr_mu_lock(&ac->mu); - grpc_timer_init(exec_ctx, &ac->alarm, - gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC), - tc_on_alarm, ac, gpr_now(GPR_CLOCK_MONOTONIC)); - grpc_fd_notify_on_write(exec_ctx, ac->fd, &ac->write_closure); - gpr_mu_unlock(&ac->mu); - -done: - gpr_free(name); - gpr_free(addr_str); -} - -#endif diff --git a/src/core/iomgr/tcp_client_windows.c b/src/core/iomgr/tcp_client_windows.c deleted file mode 100644 index da83f7b79c..0000000000 --- a/src/core/iomgr/tcp_client_windows.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_WINSOCK_SOCKET - -#include "src/core/iomgr/sockaddr_win32.h" - -#include -#include -#include -#include -#include - -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/sockaddr.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/socket_windows.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/iomgr/tcp_windows.h" -#include "src/core/iomgr/timer.h" - -typedef struct { - grpc_closure *on_done; - gpr_mu mu; - grpc_winsocket *socket; - gpr_timespec deadline; - grpc_timer alarm; - char *addr_name; - int refs; - grpc_closure on_connect; - grpc_endpoint **endpoint; -} async_connect; - -static void async_connect_unlock_and_cleanup(async_connect *ac) { - int done = (--ac->refs == 0); - gpr_mu_unlock(&ac->mu); - if (done) { - if (ac->socket != NULL) grpc_winsocket_destroy(ac->socket); - gpr_mu_destroy(&ac->mu); - gpr_free(ac->addr_name); - gpr_free(ac); - } -} - -static void on_alarm(grpc_exec_ctx *exec_ctx, void *acp, bool occured) { - async_connect *ac = acp; - gpr_mu_lock(&ac->mu); - /* If the alarm didn't occur, it got cancelled. */ - if (ac->socket != NULL && occured) { - grpc_winsocket_shutdown(ac->socket); - } - async_connect_unlock_and_cleanup(ac); -} - -static void on_connect(grpc_exec_ctx *exec_ctx, void *acp, bool from_iocp) { - async_connect *ac = acp; - SOCKET sock = ac->socket->socket; - grpc_endpoint **ep = ac->endpoint; - grpc_winsocket_callback_info *info = &ac->socket->write_info; - grpc_closure *on_done = ac->on_done; - - grpc_timer_cancel(exec_ctx, &ac->alarm); - - gpr_mu_lock(&ac->mu); - - if (from_iocp) { - DWORD transfered_bytes = 0; - DWORD flags; - BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped, - &transfered_bytes, FALSE, &flags); - GPR_ASSERT(transfered_bytes == 0); - if (!wsa_success) { - char *utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message); - gpr_free(utf8_message); - } else { - *ep = grpc_tcp_create(ac->socket, ac->addr_name); - ac->socket = NULL; - } - } - - async_connect_unlock_and_cleanup(ac); - /* If the connection was aborted, the callback was already called when - the deadline was met. */ - on_done->cb(exec_ctx, on_done->cb_arg, *ep != NULL); -} - -/* Tries to issue one async connection, then schedules both an IOCP - notification request for the connection, and one timeout alert. */ -void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done, - grpc_endpoint **endpoint, - grpc_pollset_set *interested_parties, - const struct sockaddr *addr, size_t addr_len, - gpr_timespec deadline) { - SOCKET sock = INVALID_SOCKET; - BOOL success; - int status; - struct sockaddr_in6 addr6_v4mapped; - struct sockaddr_in6 local_address; - async_connect *ac; - grpc_winsocket *socket = NULL; - LPFN_CONNECTEX ConnectEx; - GUID guid = WSAID_CONNECTEX; - DWORD ioctl_num_bytes; - const char *message = NULL; - char *utf8_message; - grpc_winsocket_callback_info *info; - - *endpoint = NULL; - - /* Use dualstack sockets where available. */ - if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { - addr = (const struct sockaddr *)&addr6_v4mapped; - addr_len = sizeof(addr6_v4mapped); - } - - sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); - if (sock == INVALID_SOCKET) { - message = "Unable to create socket: %s"; - goto failure; - } - - if (!grpc_tcp_prepare_socket(sock)) { - message = "Unable to set socket options: %s"; - goto failure; - } - - /* Grab the function pointer for ConnectEx for that specific socket. - It may change depending on the interface. */ - status = - WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), - &ConnectEx, sizeof(ConnectEx), &ioctl_num_bytes, NULL, NULL); - - if (status != 0) { - message = "Unable to retrieve ConnectEx pointer: %s"; - goto failure; - } - - grpc_sockaddr_make_wildcard6(0, &local_address); - - status = bind(sock, (struct sockaddr *)&local_address, sizeof(local_address)); - if (status != 0) { - message = "Unable to bind socket: %s"; - goto failure; - } - - socket = grpc_winsocket_create(sock, "client"); - info = &socket->write_info; - success = - ConnectEx(sock, addr, (int)addr_len, NULL, 0, NULL, &info->overlapped); - - /* It wouldn't be unusual to get a success immediately. But we'll still get - an IOCP notification, so let's ignore it. */ - if (!success) { - int error = WSAGetLastError(); - if (error != ERROR_IO_PENDING) { - message = "ConnectEx failed: %s"; - goto failure; - } - } - - ac = gpr_malloc(sizeof(async_connect)); - ac->on_done = on_done; - ac->socket = socket; - gpr_mu_init(&ac->mu); - ac->refs = 2; - ac->addr_name = grpc_sockaddr_to_uri(addr); - ac->endpoint = endpoint; - grpc_closure_init(&ac->on_connect, on_connect, ac); - - grpc_timer_init(exec_ctx, &ac->alarm, deadline, on_alarm, ac, - gpr_now(GPR_CLOCK_MONOTONIC)); - grpc_socket_notify_on_write(exec_ctx, socket, &ac->on_connect); - return; - -failure: - utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, message, utf8_message); - gpr_free(utf8_message); - if (socket != NULL) { - grpc_winsocket_destroy(socket); - } else if (sock != INVALID_SOCKET) { - closesocket(sock); - } - grpc_exec_ctx_enqueue(exec_ctx, on_done, false, NULL); -} - -#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/iomgr/tcp_posix.c b/src/core/iomgr/tcp_posix.c deleted file mode 100644 index e8f73811ce..0000000000 --- a/src/core/iomgr/tcp_posix.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_SOCKET - -#include "src/core/iomgr/tcp_posix.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "src/core/debug/trace.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/iomgr/pollset_set_posix.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" - -#ifdef GPR_HAVE_MSG_NOSIGNAL -#define SENDMSG_FLAGS MSG_NOSIGNAL -#else -#define SENDMSG_FLAGS 0 -#endif - -#ifdef GPR_MSG_IOVLEN_TYPE -typedef GPR_MSG_IOVLEN_TYPE msg_iovlen_type; -#else -typedef size_t msg_iovlen_type; -#endif - -int grpc_tcp_trace = 0; - -typedef struct { - grpc_endpoint base; - grpc_fd *em_fd; - int fd; - int finished_edge; - msg_iovlen_type iov_size; /* Number of slices to allocate per read attempt */ - size_t slice_size; - gpr_refcount refcount; - - /* garbage after the last read */ - gpr_slice_buffer last_read_buffer; - - gpr_slice_buffer *incoming_buffer; - gpr_slice_buffer *outgoing_buffer; - /** slice within outgoing_buffer to write next */ - size_t outgoing_slice_idx; - /** byte within outgoing_buffer->slices[outgoing_slice_idx] to write next */ - size_t outgoing_byte_idx; - - grpc_closure *read_cb; - grpc_closure *write_cb; - grpc_closure *release_fd_cb; - int *release_fd; - - grpc_closure read_closure; - grpc_closure write_closure; - - char *peer_string; -} grpc_tcp; - -static void tcp_handle_read(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */, - bool success); -static void tcp_handle_write(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */, - bool success); - -static void tcp_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) { - grpc_tcp *tcp = (grpc_tcp *)ep; - grpc_fd_shutdown(exec_ctx, tcp->em_fd); -} - -static void tcp_free(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) { - grpc_fd_orphan(exec_ctx, tcp->em_fd, tcp->release_fd_cb, tcp->release_fd, - "tcp_unref_orphan"); - gpr_slice_buffer_destroy(&tcp->last_read_buffer); - gpr_free(tcp->peer_string); - gpr_free(tcp); -} - -/*#define GRPC_TCP_REFCOUNT_DEBUG*/ -#ifdef GRPC_TCP_REFCOUNT_DEBUG -#define TCP_UNREF(cl, tcp, reason) \ - tcp_unref((cl), (tcp), (reason), __FILE__, __LINE__) -#define TCP_REF(tcp, reason) tcp_ref((tcp), (reason), __FILE__, __LINE__) -static void tcp_unref(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp, - const char *reason, const char *file, int line) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "TCP unref %p : %s %d -> %d", tcp, - reason, tcp->refcount.count, tcp->refcount.count - 1); - if (gpr_unref(&tcp->refcount)) { - tcp_free(exec_ctx, tcp); - } -} - -static void tcp_ref(grpc_tcp *tcp, const char *reason, const char *file, - int line) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "TCP ref %p : %s %d -> %d", tcp, - reason, tcp->refcount.count, tcp->refcount.count + 1); - gpr_ref(&tcp->refcount); -} -#else -#define TCP_UNREF(cl, tcp, reason) tcp_unref((cl), (tcp)) -#define TCP_REF(tcp, reason) tcp_ref((tcp)) -static void tcp_unref(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) { - if (gpr_unref(&tcp->refcount)) { - tcp_free(exec_ctx, tcp); - } -} - -static void tcp_ref(grpc_tcp *tcp) { gpr_ref(&tcp->refcount); } -#endif - -static void tcp_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) { - grpc_tcp *tcp = (grpc_tcp *)ep; - TCP_UNREF(exec_ctx, tcp, "destroy"); -} - -static void call_read_cb(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp, int success) { - grpc_closure *cb = tcp->read_cb; - - if (grpc_tcp_trace) { - size_t i; - gpr_log(GPR_DEBUG, "read: success=%d", success); - for (i = 0; i < tcp->incoming_buffer->count; i++) { - char *dump = gpr_dump_slice(tcp->incoming_buffer->slices[i], - GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_DEBUG, "READ %p: %s", tcp, dump); - gpr_free(dump); - } - } - - tcp->read_cb = NULL; - tcp->incoming_buffer = NULL; - cb->cb(exec_ctx, cb->cb_arg, success); -} - -#define MAX_READ_IOVEC 4 -static void tcp_continue_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) { - struct msghdr msg; - struct iovec iov[MAX_READ_IOVEC]; - ssize_t read_bytes; - size_t i; - - GPR_ASSERT(!tcp->finished_edge); - GPR_ASSERT(tcp->iov_size <= MAX_READ_IOVEC); - GPR_ASSERT(tcp->incoming_buffer->count <= MAX_READ_IOVEC); - GPR_TIMER_BEGIN("tcp_continue_read", 0); - - while (tcp->incoming_buffer->count < (size_t)tcp->iov_size) { - gpr_slice_buffer_add_indexed(tcp->incoming_buffer, - gpr_slice_malloc(tcp->slice_size)); - } - for (i = 0; i < tcp->incoming_buffer->count; i++) { - iov[i].iov_base = GPR_SLICE_START_PTR(tcp->incoming_buffer->slices[i]); - iov[i].iov_len = GPR_SLICE_LENGTH(tcp->incoming_buffer->slices[i]); - } - - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = iov; - msg.msg_iovlen = tcp->iov_size; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - GPR_TIMER_BEGIN("recvmsg", 1); - do { - read_bytes = recvmsg(tcp->fd, &msg, 0); - } while (read_bytes < 0 && errno == EINTR); - GPR_TIMER_END("recvmsg", 0); - - if (read_bytes < 0) { - /* NB: After calling call_read_cb a parallel call of the read handler may - * be running. */ - if (errno == EAGAIN) { - if (tcp->iov_size > 1) { - tcp->iov_size /= 2; - } - /* We've consumed the edge, request a new one */ - grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure); - } else { - /* TODO(klempner): Log interesting errors */ - gpr_slice_buffer_reset_and_unref(tcp->incoming_buffer); - call_read_cb(exec_ctx, tcp, 0); - TCP_UNREF(exec_ctx, tcp, "read"); - } - } else if (read_bytes == 0) { - /* 0 read size ==> end of stream */ - gpr_slice_buffer_reset_and_unref(tcp->incoming_buffer); - call_read_cb(exec_ctx, tcp, 0); - TCP_UNREF(exec_ctx, tcp, "read"); - } else { - GPR_ASSERT((size_t)read_bytes <= tcp->incoming_buffer->length); - if ((size_t)read_bytes < tcp->incoming_buffer->length) { - gpr_slice_buffer_trim_end( - tcp->incoming_buffer, - tcp->incoming_buffer->length - (size_t)read_bytes, - &tcp->last_read_buffer); - } else if (tcp->iov_size < MAX_READ_IOVEC) { - ++tcp->iov_size; - } - GPR_ASSERT((size_t)read_bytes == tcp->incoming_buffer->length); - call_read_cb(exec_ctx, tcp, 1); - TCP_UNREF(exec_ctx, tcp, "read"); - } - - GPR_TIMER_END("tcp_continue_read", 0); -} - -static void tcp_handle_read(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */, - bool success) { - grpc_tcp *tcp = (grpc_tcp *)arg; - GPR_ASSERT(!tcp->finished_edge); - - if (!success) { - gpr_slice_buffer_reset_and_unref(tcp->incoming_buffer); - call_read_cb(exec_ctx, tcp, 0); - TCP_UNREF(exec_ctx, tcp, "read"); - } else { - tcp_continue_read(exec_ctx, tcp); - } -} - -static void tcp_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - gpr_slice_buffer *incoming_buffer, grpc_closure *cb) { - grpc_tcp *tcp = (grpc_tcp *)ep; - GPR_ASSERT(tcp->read_cb == NULL); - tcp->read_cb = cb; - tcp->incoming_buffer = incoming_buffer; - gpr_slice_buffer_reset_and_unref(incoming_buffer); - gpr_slice_buffer_swap(incoming_buffer, &tcp->last_read_buffer); - TCP_REF(tcp, "read"); - if (tcp->finished_edge) { - tcp->finished_edge = 0; - grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure); - } else { - grpc_exec_ctx_enqueue(exec_ctx, &tcp->read_closure, true, NULL); - } -} - -typedef enum { FLUSH_DONE, FLUSH_PENDING, FLUSH_ERROR } flush_result; - -#define MAX_WRITE_IOVEC 16 -static flush_result tcp_flush(grpc_tcp *tcp) { - struct msghdr msg; - struct iovec iov[MAX_WRITE_IOVEC]; - msg_iovlen_type iov_size; - ssize_t sent_length; - size_t sending_length; - size_t trailing; - size_t unwind_slice_idx; - size_t unwind_byte_idx; - - for (;;) { - sending_length = 0; - unwind_slice_idx = tcp->outgoing_slice_idx; - unwind_byte_idx = tcp->outgoing_byte_idx; - for (iov_size = 0; tcp->outgoing_slice_idx != tcp->outgoing_buffer->count && - iov_size != MAX_WRITE_IOVEC; - iov_size++) { - iov[iov_size].iov_base = - GPR_SLICE_START_PTR( - tcp->outgoing_buffer->slices[tcp->outgoing_slice_idx]) + - tcp->outgoing_byte_idx; - iov[iov_size].iov_len = - GPR_SLICE_LENGTH( - tcp->outgoing_buffer->slices[tcp->outgoing_slice_idx]) - - tcp->outgoing_byte_idx; - sending_length += iov[iov_size].iov_len; - tcp->outgoing_slice_idx++; - tcp->outgoing_byte_idx = 0; - } - GPR_ASSERT(iov_size > 0); - - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = iov; - msg.msg_iovlen = iov_size; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - GPR_TIMER_BEGIN("sendmsg", 1); - do { - /* TODO(klempner): Cork if this is a partial write */ - sent_length = sendmsg(tcp->fd, &msg, SENDMSG_FLAGS); - } while (sent_length < 0 && errno == EINTR); - GPR_TIMER_END("sendmsg", 0); - - if (sent_length < 0) { - if (errno == EAGAIN) { - tcp->outgoing_slice_idx = unwind_slice_idx; - tcp->outgoing_byte_idx = unwind_byte_idx; - return FLUSH_PENDING; - } else { - /* TODO(klempner): Log some of these */ - return FLUSH_ERROR; - } - } - - GPR_ASSERT(tcp->outgoing_byte_idx == 0); - trailing = sending_length - (size_t)sent_length; - while (trailing > 0) { - size_t slice_length; - - tcp->outgoing_slice_idx--; - slice_length = GPR_SLICE_LENGTH( - tcp->outgoing_buffer->slices[tcp->outgoing_slice_idx]); - if (slice_length > trailing) { - tcp->outgoing_byte_idx = slice_length - trailing; - break; - } else { - trailing -= slice_length; - } - } - - if (tcp->outgoing_slice_idx == tcp->outgoing_buffer->count) { - return FLUSH_DONE; - } - }; -} - -static void tcp_handle_write(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */, - bool success) { - grpc_tcp *tcp = (grpc_tcp *)arg; - flush_result status; - grpc_closure *cb; - - if (!success) { - cb = tcp->write_cb; - tcp->write_cb = NULL; - cb->cb(exec_ctx, cb->cb_arg, 0); - TCP_UNREF(exec_ctx, tcp, "write"); - return; - } - - status = tcp_flush(tcp); - if (status == FLUSH_PENDING) { - grpc_fd_notify_on_write(exec_ctx, tcp->em_fd, &tcp->write_closure); - } else { - cb = tcp->write_cb; - tcp->write_cb = NULL; - GPR_TIMER_BEGIN("tcp_handle_write.cb", 0); - cb->cb(exec_ctx, cb->cb_arg, status == FLUSH_DONE); - GPR_TIMER_END("tcp_handle_write.cb", 0); - TCP_UNREF(exec_ctx, tcp, "write"); - } -} - -static void tcp_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - gpr_slice_buffer *buf, grpc_closure *cb) { - grpc_tcp *tcp = (grpc_tcp *)ep; - flush_result status; - - if (grpc_tcp_trace) { - size_t i; - - for (i = 0; i < buf->count; i++) { - char *data = - gpr_dump_slice(buf->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_DEBUG, "WRITE %p: %s", tcp, data); - gpr_free(data); - } - } - - GPR_TIMER_BEGIN("tcp_write", 0); - GPR_ASSERT(tcp->write_cb == NULL); - - if (buf->length == 0) { - GPR_TIMER_END("tcp_write", 0); - grpc_exec_ctx_enqueue(exec_ctx, cb, true, NULL); - return; - } - tcp->outgoing_buffer = buf; - tcp->outgoing_slice_idx = 0; - tcp->outgoing_byte_idx = 0; - - status = tcp_flush(tcp); - if (status == FLUSH_PENDING) { - TCP_REF(tcp, "write"); - tcp->write_cb = cb; - grpc_fd_notify_on_write(exec_ctx, tcp->em_fd, &tcp->write_closure); - } else { - grpc_exec_ctx_enqueue(exec_ctx, cb, status == FLUSH_DONE, NULL); - } - - GPR_TIMER_END("tcp_write", 0); -} - -static void tcp_add_to_pollset(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - grpc_pollset *pollset) { - grpc_tcp *tcp = (grpc_tcp *)ep; - grpc_pollset_add_fd(exec_ctx, pollset, tcp->em_fd); -} - -static void tcp_add_to_pollset_set(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - grpc_pollset_set *pollset_set) { - grpc_tcp *tcp = (grpc_tcp *)ep; - grpc_pollset_set_add_fd(exec_ctx, pollset_set, tcp->em_fd); -} - -static char *tcp_get_peer(grpc_endpoint *ep) { - grpc_tcp *tcp = (grpc_tcp *)ep; - return gpr_strdup(tcp->peer_string); -} - -static const grpc_endpoint_vtable vtable = { - tcp_read, tcp_write, tcp_add_to_pollset, tcp_add_to_pollset_set, - tcp_shutdown, tcp_destroy, tcp_get_peer}; - -grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size, - const char *peer_string) { - grpc_tcp *tcp = (grpc_tcp *)gpr_malloc(sizeof(grpc_tcp)); - tcp->base.vtable = &vtable; - tcp->peer_string = gpr_strdup(peer_string); - tcp->fd = em_fd->fd; - tcp->read_cb = NULL; - tcp->write_cb = NULL; - tcp->release_fd_cb = NULL; - tcp->release_fd = NULL; - tcp->incoming_buffer = NULL; - tcp->slice_size = slice_size; - tcp->iov_size = 1; - tcp->finished_edge = 1; - /* paired with unref in grpc_tcp_destroy */ - gpr_ref_init(&tcp->refcount, 1); - tcp->em_fd = em_fd; - tcp->read_closure.cb = tcp_handle_read; - tcp->read_closure.cb_arg = tcp; - tcp->write_closure.cb = tcp_handle_write; - tcp->write_closure.cb_arg = tcp; - gpr_slice_buffer_init(&tcp->last_read_buffer); - - return &tcp->base; -} - -int grpc_tcp_fd(grpc_endpoint *ep) { - grpc_tcp *tcp = (grpc_tcp *)ep; - GPR_ASSERT(ep->vtable == &vtable); - return grpc_fd_wrapped_fd(tcp->em_fd); -} - -void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - int *fd, grpc_closure *done) { - grpc_tcp *tcp = (grpc_tcp *)ep; - GPR_ASSERT(ep->vtable == &vtable); - tcp->release_fd = fd; - tcp->release_fd_cb = done; - TCP_UNREF(exec_ctx, tcp, "destroy"); -} - -#endif diff --git a/src/core/iomgr/tcp_posix.h b/src/core/iomgr/tcp_posix.h deleted file mode 100644 index d846ec570f..0000000000 --- a/src/core/iomgr/tcp_posix.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_TCP_POSIX_H -#define GRPC_CORE_IOMGR_TCP_POSIX_H -/* - Low level TCP "bottom half" implementation, for use by transports built on - top of a TCP connection. - - Note that this file does not (yet) include APIs for creating the socket in - the first place. - - All calls passing slice transfer ownership of a slice refcount unless - otherwise specified. -*/ - -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/fd_posix.h" - -#define GRPC_TCP_DEFAULT_READ_SLICE_SIZE 8192 - -extern int grpc_tcp_trace; - -/* Create a tcp endpoint given a file desciptor and a read slice size. - Takes ownership of fd. */ -grpc_endpoint *grpc_tcp_create(grpc_fd *fd, size_t read_slice_size, - const char *peer_string); - -/* Return the tcp endpoint's fd, or -1 if this is not available. Does not - release the fd. - Requires: ep must be a tcp endpoint. - */ -int grpc_tcp_fd(grpc_endpoint *ep); - -/* Destroy the tcp endpoint without closing its fd. *fd will be set and done - * will be called when the endpoint is destroyed. - * Requires: ep must be a tcp endpoint and fd must not be NULL. */ -void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - int *fd, grpc_closure *done); - -#endif /* GRPC_CORE_IOMGR_TCP_POSIX_H */ diff --git a/src/core/iomgr/tcp_server.h b/src/core/iomgr/tcp_server.h deleted file mode 100644 index 93247e9e4e..0000000000 --- a/src/core/iomgr/tcp_server.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_TCP_SERVER_H -#define GRPC_CORE_IOMGR_TCP_SERVER_H - -#include "src/core/iomgr/closure.h" -#include "src/core/iomgr/endpoint.h" - -/* Forward decl of grpc_tcp_server */ -typedef struct grpc_tcp_server grpc_tcp_server; - -typedef struct grpc_tcp_server_acceptor { - /* grpc_tcp_server_cb functions share a ref on from_server that is valid - until the function returns. */ - grpc_tcp_server *from_server; - /* Indices that may be passed to grpc_tcp_server_port_fd(). */ - unsigned port_index; - unsigned fd_index; -} grpc_tcp_server_acceptor; - -/* Called for newly connected TCP connections. */ -typedef void (*grpc_tcp_server_cb)(grpc_exec_ctx *exec_ctx, void *arg, - grpc_endpoint *ep, - grpc_tcp_server_acceptor *acceptor); - -/* Create a server, initially not bound to any ports. The caller owns one ref. - If shutdown_complete is not NULL, it will be used by - grpc_tcp_server_unref() when the ref count reaches zero. */ -grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete); - -/* Start listening to bound ports */ -void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *server, - grpc_pollset **pollsets, size_t pollset_count, - grpc_tcp_server_cb on_accept_cb, void *cb_arg); - -/* Add a port to the server, returning the newly allocated port on success, or - -1 on failure. - - The :: and 0.0.0.0 wildcard addresses are treated identically, accepting - both IPv4 and IPv6 connections, but :: is the preferred style. This usually - creates one socket, but possibly two on systems which support IPv6, - but not dualstack sockets. */ -/* TODO(ctiller): deprecate this, and make grpc_tcp_server_add_ports to handle - all of the multiple socket port matching logic in one place */ -int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, - size_t addr_len); - -/* Number of fds at the given port_index, or 0 if port_index is out of - bounds. */ -unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s, unsigned port_index); - -/* Returns the file descriptor of the Mth (fd_index) listening socket of the Nth - (port_index) call to add_port() on this server, or -1 if the indices are out - of bounds. The file descriptor remains owned by the server, and will be - cleaned up when the ref count reaches zero. */ -int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index, - unsigned fd_index); - -/* Ref s and return s. */ -grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s); - -/* shutdown_starting is called when ref count has reached zero and the server is - about to be destroyed. The server will be deleted after it returns. Calling - grpc_tcp_server_ref() from it has no effect. */ -void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s, - grpc_closure *shutdown_starting); - -/* If the refcount drops to zero, delete s, and call (exec_ctx==NULL) or enqueue - a call (exec_ctx!=NULL) to shutdown_complete. */ -void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s); - -#endif /* GRPC_CORE_IOMGR_TCP_SERVER_H */ diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c deleted file mode 100644 index 74ee68a6f1..0000000000 --- a/src/core/iomgr/tcp_server_posix.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* FIXME: "posix" files shouldn't be depending on _GNU_SOURCE */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include - -#ifdef GPR_POSIX_SOCKET - -#include "src/core/iomgr/tcp_server.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/iomgr/tcp_posix.h" -#include "src/core/iomgr/unix_sockets_posix.h" -#include "src/core/support/string.h" - -#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100 - -static gpr_once s_init_max_accept_queue_size; -static int s_max_accept_queue_size; - -/* one listening port */ -typedef struct grpc_tcp_listener grpc_tcp_listener; -struct grpc_tcp_listener { - int fd; - grpc_fd *emfd; - grpc_tcp_server *server; - union { - uint8_t untyped[GRPC_MAX_SOCKADDR_SIZE]; - struct sockaddr sockaddr; - } addr; - size_t addr_len; - int port; - unsigned port_index; - unsigned fd_index; - grpc_closure read_closure; - grpc_closure destroyed_closure; - struct grpc_tcp_listener *next; - /* When we add a listener, more than one can be created, mainly because of - IPv6. A sibling will still be in the normal list, but will be flagged - as such. Any action, such as ref or unref, will affect all of the - siblings in the list. */ - struct grpc_tcp_listener *sibling; - int is_sibling; -}; - -/* the overall server */ -struct grpc_tcp_server { - gpr_refcount refs; - /* Called whenever accept() succeeds on a server port. */ - grpc_tcp_server_cb on_accept_cb; - void *on_accept_cb_arg; - - gpr_mu mu; - - /* active port count: how many ports are actually still listening */ - size_t active_ports; - /* destroyed port count: how many ports are completely destroyed */ - size_t destroyed_ports; - - /* is this server shutting down? (boolean) */ - int shutdown; - - /* linked list of server ports */ - grpc_tcp_listener *head; - grpc_tcp_listener *tail; - unsigned nports; - - /* List of closures passed to shutdown_starting_add(). */ - grpc_closure_list shutdown_starting; - - /* shutdown callback */ - grpc_closure *shutdown_complete; - - /* all pollsets interested in new connections */ - grpc_pollset **pollsets; - /* number of pollsets in the pollsets array */ - size_t pollset_count; -}; - -grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) { - grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server)); - gpr_ref_init(&s->refs, 1); - gpr_mu_init(&s->mu); - s->active_ports = 0; - s->destroyed_ports = 0; - s->shutdown = 0; - s->shutdown_starting.head = NULL; - s->shutdown_starting.tail = NULL; - s->shutdown_complete = shutdown_complete; - s->on_accept_cb = NULL; - s->on_accept_cb_arg = NULL; - s->head = NULL; - s->tail = NULL; - s->nports = 0; - return s; -} - -static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { - if (s->shutdown_complete != NULL) { - grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, true, NULL); - } - - gpr_mu_destroy(&s->mu); - - while (s->head) { - grpc_tcp_listener *sp = s->head; - s->head = sp->next; - gpr_free(sp); - } - - gpr_free(s); -} - -static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server, - bool success) { - grpc_tcp_server *s = server; - gpr_mu_lock(&s->mu); - s->destroyed_ports++; - if (s->destroyed_ports == s->nports) { - gpr_mu_unlock(&s->mu); - finish_shutdown(exec_ctx, s); - } else { - GPR_ASSERT(s->destroyed_ports < s->nports); - gpr_mu_unlock(&s->mu); - } -} - -/* called when all listening endpoints have been shutdown, so no further - events will be received on them - at this point it's safe to destroy - things */ -static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { - /* delete ALL the things */ - gpr_mu_lock(&s->mu); - - if (!s->shutdown) { - gpr_mu_unlock(&s->mu); - return; - } - - if (s->head) { - grpc_tcp_listener *sp; - for (sp = s->head; sp; sp = sp->next) { - grpc_unlink_if_unix_domain_socket(&sp->addr.sockaddr); - sp->destroyed_closure.cb = destroyed_port; - sp->destroyed_closure.cb_arg = s; - grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, - "tcp_listener_shutdown"); - } - gpr_mu_unlock(&s->mu); - } else { - gpr_mu_unlock(&s->mu); - finish_shutdown(exec_ctx, s); - } -} - -static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { - gpr_mu_lock(&s->mu); - - GPR_ASSERT(!s->shutdown); - s->shutdown = 1; - - /* shutdown all fd's */ - if (s->active_ports) { - grpc_tcp_listener *sp; - for (sp = s->head; sp; sp = sp->next) { - grpc_fd_shutdown(exec_ctx, sp->emfd); - } - gpr_mu_unlock(&s->mu); - } else { - gpr_mu_unlock(&s->mu); - deactivated_all_ports(exec_ctx, s); - } -} - -/* get max listen queue size on linux */ -static void init_max_accept_queue_size(void) { - int n = SOMAXCONN; - char buf[64]; - FILE *fp = fopen("/proc/sys/net/core/somaxconn", "r"); - if (fp == NULL) { - /* 2.4 kernel. */ - s_max_accept_queue_size = SOMAXCONN; - return; - } - if (fgets(buf, sizeof buf, fp)) { - char *end; - long i = strtol(buf, &end, 10); - if (i > 0 && i <= INT_MAX && end && *end == 0) { - n = (int)i; - } - } - fclose(fp); - s_max_accept_queue_size = n; - - if (s_max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) { - gpr_log(GPR_INFO, - "Suspiciously small accept queue (%d) will probably lead to " - "connection drops", - s_max_accept_queue_size); - } -} - -static int get_max_accept_queue_size(void) { - gpr_once_init(&s_init_max_accept_queue_size, init_max_accept_queue_size); - return s_max_accept_queue_size; -} - -/* Prepare a recently-created socket for listening. */ -static int prepare_socket(int fd, const struct sockaddr *addr, - size_t addr_len) { - struct sockaddr_storage sockname_temp; - socklen_t sockname_len; - - if (fd < 0) { - goto error; - } - - if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || - (!grpc_is_unix_socket(addr) && (!grpc_set_socket_low_latency(fd, 1) || - !grpc_set_socket_reuse_addr(fd, 1))) || - !grpc_set_socket_no_sigpipe_if_possible(fd)) { - gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, - strerror(errno)); - goto error; - } - - GPR_ASSERT(addr_len < ~(socklen_t)0); - if (bind(fd, addr, (socklen_t)addr_len) < 0) { - char *addr_str; - grpc_sockaddr_to_string(&addr_str, addr, 0); - gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno)); - gpr_free(addr_str); - goto error; - } - - if (listen(fd, get_max_accept_queue_size()) < 0) { - gpr_log(GPR_ERROR, "listen: %s", strerror(errno)); - goto error; - } - - sockname_len = sizeof(sockname_temp); - if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) { - goto error; - } - - return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); - -error: - if (fd >= 0) { - close(fd); - } - return -1; -} - -/* event manager callback when reads are ready */ -static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - grpc_tcp_listener *sp = arg; - grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index, - sp->fd_index}; - grpc_fd *fdobj; - size_t i; - - if (!success) { - goto error; - } - - /* loop until accept4 returns EAGAIN, and then re-arm notification */ - for (;;) { - struct sockaddr_storage addr; - socklen_t addrlen = sizeof(addr); - char *addr_str; - char *name; - /* Note: If we ever decide to return this address to the user, remember to - strip off the ::ffff:0.0.0.0/96 prefix first. */ - int fd = grpc_accept4(sp->fd, (struct sockaddr *)&addr, &addrlen, 1, 1); - if (fd < 0) { - switch (errno) { - case EINTR: - continue; - case EAGAIN: - grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure); - return; - default: - gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno)); - goto error; - } - } - - grpc_set_socket_no_sigpipe_if_possible(fd); - - addr_str = grpc_sockaddr_to_uri((struct sockaddr *)&addr); - gpr_asprintf(&name, "tcp-server-connection:%s", addr_str); - - if (grpc_tcp_trace) { - gpr_log(GPR_DEBUG, "SERVER_CONNECT: incoming connection: %s", addr_str); - } - - fdobj = grpc_fd_create(fd, name); - /* TODO(ctiller): revise this when we have server-side sharding - of channels -- we certainly should not be automatically adding every - incoming channel to every pollset owned by the server */ - for (i = 0; i < sp->server->pollset_count; i++) { - grpc_pollset_add_fd(exec_ctx, sp->server->pollsets[i], fdobj); - } - sp->server->on_accept_cb( - exec_ctx, sp->server->on_accept_cb_arg, - grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str), - &acceptor); - - gpr_free(name); - gpr_free(addr_str); - } - - GPR_UNREACHABLE_CODE(return ); - -error: - gpr_mu_lock(&sp->server->mu); - if (0 == --sp->server->active_ports) { - gpr_mu_unlock(&sp->server->mu); - deactivated_all_ports(exec_ctx, sp->server); - } else { - gpr_mu_unlock(&sp->server->mu); - } -} - -static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd, - const struct sockaddr *addr, - size_t addr_len, - unsigned port_index, - unsigned fd_index) { - grpc_tcp_listener *sp = NULL; - int port; - char *addr_str; - char *name; - - port = prepare_socket(fd, addr, addr_len); - if (port >= 0) { - grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1); - gpr_asprintf(&name, "tcp-server-listener:%s", addr_str); - gpr_mu_lock(&s->mu); - s->nports++; - GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server"); - sp = gpr_malloc(sizeof(grpc_tcp_listener)); - sp->next = NULL; - if (s->head == NULL) { - s->head = sp; - } else { - s->tail->next = sp; - } - s->tail = sp; - sp->server = s; - sp->fd = fd; - sp->emfd = grpc_fd_create(fd, name); - memcpy(sp->addr.untyped, addr, addr_len); - sp->addr_len = addr_len; - sp->port = port; - sp->port_index = port_index; - sp->fd_index = fd_index; - sp->is_sibling = 0; - sp->sibling = NULL; - GPR_ASSERT(sp->emfd); - gpr_mu_unlock(&s->mu); - gpr_free(addr_str); - gpr_free(name); - } - - return sp; -} - -int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, - size_t addr_len) { - grpc_tcp_listener *sp; - grpc_tcp_listener *sp2 = NULL; - int fd; - grpc_dualstack_mode dsmode; - struct sockaddr_in6 addr6_v4mapped; - struct sockaddr_in wild4; - struct sockaddr_in6 wild6; - struct sockaddr_in addr4_copy; - struct sockaddr *allocated_addr = NULL; - struct sockaddr_storage sockname_temp; - socklen_t sockname_len; - int port; - unsigned port_index = 0; - unsigned fd_index = 0; - if (s->tail != NULL) { - port_index = s->tail->port_index + 1; - } - grpc_unlink_if_unix_domain_socket((struct sockaddr *)addr); - - /* Check if this is a wildcard port, and if so, try to keep the port the same - as some previously created listener. */ - if (grpc_sockaddr_get_port(addr) == 0) { - for (sp = s->head; sp; sp = sp->next) { - sockname_len = sizeof(sockname_temp); - if (0 == getsockname(sp->fd, (struct sockaddr *)&sockname_temp, - &sockname_len)) { - port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); - if (port > 0) { - allocated_addr = malloc(addr_len); - memcpy(allocated_addr, addr, addr_len); - grpc_sockaddr_set_port(allocated_addr, port); - addr = allocated_addr; - break; - } - } - } - } - - sp = NULL; - - if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { - addr = (const struct sockaddr *)&addr6_v4mapped; - addr_len = sizeof(addr6_v4mapped); - } - - /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */ - if (grpc_sockaddr_is_wildcard(addr, &port)) { - grpc_sockaddr_make_wildcards(port, &wild4, &wild6); - - /* Try listening on IPv6 first. */ - addr = (struct sockaddr *)&wild6; - addr_len = sizeof(wild6); - fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode); - sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index); - if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) { - goto done; - } - if (sp != NULL) { - ++fd_index; - } - /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */ - if (port == 0 && sp != NULL) { - grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port); - } - addr = (struct sockaddr *)&wild4; - addr_len = sizeof(wild4); - } - - fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode); - if (fd < 0) { - gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno)); - } else { - if (dsmode == GRPC_DSMODE_IPV4 && - grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) { - addr = (struct sockaddr *)&addr4_copy; - addr_len = sizeof(addr4_copy); - } - sp2 = sp; - sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index); - if (sp2 != NULL && sp != NULL) { - sp2->sibling = sp; - sp->is_sibling = 1; - } - } - -done: - gpr_free(allocated_addr); - if (sp != NULL) { - return sp->port; - } else { - return -1; - } -} - -unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s, - unsigned port_index) { - unsigned num_fds = 0; - grpc_tcp_listener *sp; - for (sp = s->head; sp && port_index != 0; sp = sp->next) { - if (!sp->is_sibling) { - --port_index; - } - } - for (; sp; sp = sp->sibling, ++num_fds) - ; - return num_fds; -} - -int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index, - unsigned fd_index) { - grpc_tcp_listener *sp; - for (sp = s->head; sp && port_index != 0; sp = sp->next) { - if (!sp->is_sibling) { - --port_index; - } - } - for (; sp && fd_index != 0; sp = sp->sibling, --fd_index) - ; - if (sp) { - return sp->fd; - } else { - return -1; - } -} - -void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, - grpc_pollset **pollsets, size_t pollset_count, - grpc_tcp_server_cb on_accept_cb, - void *on_accept_cb_arg) { - size_t i; - grpc_tcp_listener *sp; - GPR_ASSERT(on_accept_cb); - gpr_mu_lock(&s->mu); - GPR_ASSERT(!s->on_accept_cb); - GPR_ASSERT(s->active_ports == 0); - s->on_accept_cb = on_accept_cb; - s->on_accept_cb_arg = on_accept_cb_arg; - s->pollsets = pollsets; - s->pollset_count = pollset_count; - for (sp = s->head; sp; sp = sp->next) { - for (i = 0; i < pollset_count; i++) { - grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd); - } - sp->read_closure.cb = on_read; - sp->read_closure.cb_arg = sp; - grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure); - s->active_ports++; - } - gpr_mu_unlock(&s->mu); -} - -grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) { - gpr_ref(&s->refs); - return s; -} - -void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s, - grpc_closure *shutdown_starting) { - gpr_mu_lock(&s->mu); - grpc_closure_list_add(&s->shutdown_starting, shutdown_starting, 1); - gpr_mu_unlock(&s->mu); -} - -void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { - if (gpr_unref(&s->refs)) { - /* Complete shutdown_starting work before destroying. */ - grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT; - gpr_mu_lock(&s->mu); - grpc_exec_ctx_enqueue_list(&local_exec_ctx, &s->shutdown_starting, NULL); - gpr_mu_unlock(&s->mu); - if (exec_ctx == NULL) { - grpc_exec_ctx_flush(&local_exec_ctx); - tcp_server_destroy(&local_exec_ctx, s); - grpc_exec_ctx_finish(&local_exec_ctx); - } else { - grpc_exec_ctx_finish(&local_exec_ctx); - tcp_server_destroy(exec_ctx, s); - } - } -} - -#endif diff --git a/src/core/iomgr/tcp_server_windows.c b/src/core/iomgr/tcp_server_windows.c deleted file mode 100644 index a4abc5b974..0000000000 --- a/src/core/iomgr/tcp_server_windows.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_WINSOCK_SOCKET - -#include - -#include "src/core/iomgr/sockaddr_utils.h" - -#include -#include -#include -#include -#include -#include - -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/pollset_windows.h" -#include "src/core/iomgr/socket_windows.h" -#include "src/core/iomgr/tcp_server.h" -#include "src/core/iomgr/tcp_windows.h" - -#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100 - -/* one listening port */ -typedef struct grpc_tcp_listener grpc_tcp_listener; -struct grpc_tcp_listener { - /* This seemingly magic number comes from AcceptEx's documentation. each - address buffer needs to have at least 16 more bytes at their end. */ - uint8_t addresses[(sizeof(struct sockaddr_in6) + 16) * 2]; - /* This will hold the socket for the next accept. */ - SOCKET new_socket; - /* The listener winsocket. */ - grpc_winsocket *socket; - /* The actual TCP port number. */ - int port; - unsigned port_index; - grpc_tcp_server *server; - /* The cached AcceptEx for that port. */ - LPFN_ACCEPTEX AcceptEx; - int shutting_down; - /* closure for socket notification of accept being ready */ - grpc_closure on_accept; - /* linked list */ - struct grpc_tcp_listener *next; -}; - -/* the overall server */ -struct grpc_tcp_server { - gpr_refcount refs; - /* Called whenever accept() succeeds on a server port. */ - grpc_tcp_server_cb on_accept_cb; - void *on_accept_cb_arg; - - gpr_mu mu; - - /* active port count: how many ports are actually still listening */ - int active_ports; - - /* linked list of server ports */ - grpc_tcp_listener *head; - grpc_tcp_listener *tail; - - /* List of closures passed to shutdown_starting_add(). */ - grpc_closure_list shutdown_starting; - - /* shutdown callback */ - grpc_closure *shutdown_complete; -}; - -/* Public function. Allocates the proper data structures to hold a - grpc_tcp_server. */ -grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) { - grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server)); - gpr_ref_init(&s->refs, 1); - gpr_mu_init(&s->mu); - s->active_ports = 0; - s->on_accept_cb = NULL; - s->on_accept_cb_arg = NULL; - s->head = NULL; - s->tail = NULL; - s->shutdown_starting.head = NULL; - s->shutdown_starting.tail = NULL; - s->shutdown_complete = shutdown_complete; - return s; -} - -static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { - if (s->shutdown_complete != NULL) { - grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, true, NULL); - } - - /* Now that the accepts have been aborted, we can destroy the sockets. - The IOCP won't get notified on these, so we can flag them as already - closed by the system. */ - while (s->head) { - grpc_tcp_listener *sp = s->head; - s->head = sp->next; - sp->next = NULL; - grpc_winsocket_destroy(sp->socket); - gpr_free(sp); - } - gpr_free(s); -} - -grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) { - gpr_ref(&s->refs); - return s; -} - -void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s, - grpc_closure *shutdown_starting) { - gpr_mu_lock(&s->mu); - grpc_closure_list_add(&s->shutdown_starting, shutdown_starting, 1); - gpr_mu_unlock(&s->mu); -} - -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); - - /* First, shutdown all fd's. This will queue abortion calls for all - of the pending accepts due to the normal operation mechanism. */ - if (s->active_ports == 0) { - immediately_done = 1; - } - for (sp = s->head; sp; sp = sp->next) { - sp->shutting_down = 1; - grpc_winsocket_shutdown(sp->socket); - } - gpr_mu_unlock(&s->mu); - - if (immediately_done) { - finish_shutdown(exec_ctx, s); - } -} - -void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { - if (gpr_unref(&s->refs)) { - /* Complete shutdown_starting work before destroying. */ - grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT; - gpr_mu_lock(&s->mu); - grpc_exec_ctx_enqueue_list(&local_exec_ctx, &s->shutdown_starting, NULL); - gpr_mu_unlock(&s->mu); - if (exec_ctx == NULL) { - grpc_exec_ctx_flush(&local_exec_ctx); - tcp_server_destroy(&local_exec_ctx, s); - grpc_exec_ctx_finish(&local_exec_ctx); - } else { - grpc_exec_ctx_finish(&local_exec_ctx); - tcp_server_destroy(exec_ctx, s); - } - } -} - -/* Prepare (bind) a recently-created socket for listening. */ -static int prepare_socket(SOCKET sock, const struct sockaddr *addr, - size_t addr_len) { - struct sockaddr_storage sockname_temp; - socklen_t sockname_len; - - if (sock == INVALID_SOCKET) goto error; - - if (!grpc_tcp_prepare_socket(sock)) { - char *utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, "Unable to prepare socket: %s", utf8_message); - gpr_free(utf8_message); - goto error; - } - - if (bind(sock, addr, (int)addr_len) == SOCKET_ERROR) { - char *addr_str; - char *utf8_message = gpr_format_message(WSAGetLastError()); - grpc_sockaddr_to_string(&addr_str, addr, 0); - gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, utf8_message); - gpr_free(utf8_message); - gpr_free(addr_str); - goto error; - } - - if (listen(sock, SOMAXCONN) == SOCKET_ERROR) { - char *utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, "listen: %s", utf8_message); - gpr_free(utf8_message); - goto error; - } - - sockname_len = sizeof(sockname_temp); - if (getsockname(sock, (struct sockaddr *)&sockname_temp, &sockname_len) == - SOCKET_ERROR) { - char *utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, "getsockname: %s", utf8_message); - gpr_free(utf8_message); - goto error; - } - - return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); - -error: - if (sock != INVALID_SOCKET) closesocket(sock); - return -1; -} - -static void decrement_active_ports_and_notify(grpc_exec_ctx *exec_ctx, - grpc_tcp_listener *sp) { - int notify = 0; - sp->shutting_down = 0; - gpr_mu_lock(&sp->server->mu); - GPR_ASSERT(sp->server->active_ports > 0); - if (0 == --sp->server->active_ports) { - notify = 1; - } - gpr_mu_unlock(&sp->server->mu); - if (notify) { - finish_shutdown(exec_ctx, sp->server); - } -} - -/* In order to do an async accept, we need to create a socket first which - will be the one assigned to the new incoming connection. */ -static void start_accept(grpc_exec_ctx *exec_ctx, grpc_tcp_listener *port) { - SOCKET sock = INVALID_SOCKET; - char *message; - char *utf8_message; - BOOL success; - DWORD addrlen = sizeof(struct sockaddr_in6) + 16; - DWORD bytes_received = 0; - - sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); - - if (sock == INVALID_SOCKET) { - message = "Unable to create socket: %s"; - goto failure; - } - - if (!grpc_tcp_prepare_socket(sock)) { - message = "Unable to prepare socket: %s"; - goto failure; - } - - /* Start the "accept" asynchronously. */ - success = port->AcceptEx(port->socket->socket, sock, port->addresses, 0, - addrlen, addrlen, &bytes_received, - &port->socket->read_info.overlapped); - - /* It is possible to get an accept immediately without delay. However, we - will still get an IOCP notification for it. So let's just ignore it. */ - if (!success) { - int error = WSAGetLastError(); - if (error != ERROR_IO_PENDING) { - message = "AcceptEx failed: %s"; - goto failure; - } - } - - /* We're ready to do the accept. Calling grpc_socket_notify_on_read may - immediately process an accept that happened in the meantime. */ - port->new_socket = sock; - grpc_socket_notify_on_read(exec_ctx, port->socket, &port->on_accept); - return; - -failure: - if (port->shutting_down) { - /* We are abandoning the listener port, take that into account to prevent - occasional hangs on shutdown. The hang happens when sp->shutting_down - change is not seen by on_accept and we proceed to trying new accept, - but we fail there because the listening port has been closed in the - meantime. */ - decrement_active_ports_and_notify(exec_ctx, port); - return; - } - utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, message, utf8_message); - gpr_free(utf8_message); - if (sock != INVALID_SOCKET) closesocket(sock); -} - -/* Event manager callback when reads are ready. */ -static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, bool from_iocp) { - grpc_tcp_listener *sp = arg; - grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index, 0}; - SOCKET sock = sp->new_socket; - grpc_winsocket_callback_info *info = &sp->socket->read_info; - grpc_endpoint *ep = NULL; - struct sockaddr_storage peer_name; - char *peer_name_string; - char *fd_name; - int peer_name_len = sizeof(peer_name); - DWORD transfered_bytes; - DWORD flags; - BOOL wsa_success; - int err; - - /* The general mechanism for shutting down is to queue abortion calls. While - this is necessary in the read/write case, it's useless for the accept - case. We only need to adjust the pending callback count */ - if (!from_iocp) { - return; - } - - /* The IOCP notified us of a completed operation. Let's grab the results, - and act accordingly. */ - transfered_bytes = 0; - wsa_success = WSAGetOverlappedResult(sock, &info->overlapped, - &transfered_bytes, FALSE, &flags); - if (!wsa_success) { - if (sp->shutting_down) { - /* During the shutdown case, we ARE expecting an error. So that's well, - and we can wake up the shutdown thread. */ - decrement_active_ports_and_notify(exec_ctx, sp); - return; - } else { - char *utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, "on_accept error: %s", utf8_message); - gpr_free(utf8_message); - closesocket(sock); - } - } else { - if (!sp->shutting_down) { - peer_name_string = NULL; - err = setsockopt(sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, - (char *)&sp->socket->socket, sizeof(sp->socket->socket)); - if (err) { - char *utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, "setsockopt error: %s", utf8_message); - gpr_free(utf8_message); - } - err = getpeername(sock, (struct sockaddr *)&peer_name, &peer_name_len); - if (!err) { - peer_name_string = grpc_sockaddr_to_uri((struct sockaddr *)&peer_name); - } else { - char *utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, "getpeername error: %s", utf8_message); - gpr_free(utf8_message); - } - gpr_asprintf(&fd_name, "tcp_server:%s", peer_name_string); - ep = grpc_tcp_create(grpc_winsocket_create(sock, fd_name), - peer_name_string); - gpr_free(fd_name); - gpr_free(peer_name_string); - } else { - closesocket(sock); - } - } - - /* The only time we should call our callback, is where we successfully - managed to accept a connection, and created an endpoint. */ - if (ep) - sp->server->on_accept_cb(exec_ctx, sp->server->on_accept_cb_arg, ep, - &acceptor); - /* As we were notified from the IOCP of one and exactly one accept, - the former socked we created has now either been destroy or assigned - to the new connection. We need to create a new one for the next - connection. */ - start_accept(exec_ctx, sp); -} - -static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, SOCKET sock, - const struct sockaddr *addr, - size_t addr_len, - unsigned port_index) { - grpc_tcp_listener *sp = NULL; - int port; - int status; - GUID guid = WSAID_ACCEPTEX; - DWORD ioctl_num_bytes; - LPFN_ACCEPTEX AcceptEx; - - if (sock == INVALID_SOCKET) return NULL; - - /* We need to grab the AcceptEx pointer for that port, as it may be - interface-dependent. We'll cache it to avoid doing that again. */ - status = - WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), - &AcceptEx, sizeof(AcceptEx), &ioctl_num_bytes, NULL, NULL); - - if (status != 0) { - char *utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message); - gpr_free(utf8_message); - closesocket(sock); - return NULL; - } - - port = prepare_socket(sock, addr, addr_len); - if (port >= 0) { - gpr_mu_lock(&s->mu); - GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server"); - sp = gpr_malloc(sizeof(grpc_tcp_listener)); - sp->next = NULL; - if (s->head == NULL) { - s->head = sp; - } else { - s->tail->next = sp; - } - s->tail = sp; - sp->server = s; - sp->socket = grpc_winsocket_create(sock, "listener"); - sp->shutting_down = 0; - sp->AcceptEx = AcceptEx; - sp->new_socket = INVALID_SOCKET; - sp->port = port; - sp->port_index = port_index; - grpc_closure_init(&sp->on_accept, on_accept, sp); - GPR_ASSERT(sp->socket); - gpr_mu_unlock(&s->mu); - } - - return sp; -} - -int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, - size_t addr_len) { - grpc_tcp_listener *sp; - SOCKET sock; - struct sockaddr_in6 addr6_v4mapped; - struct sockaddr_in6 wildcard; - struct sockaddr *allocated_addr = NULL; - struct sockaddr_storage sockname_temp; - socklen_t sockname_len; - int port; - unsigned port_index = 0; - if (s->tail != NULL) { - port_index = s->tail->port_index + 1; - } - - /* Check if this is a wildcard port, and if so, try to keep the port the same - as some previously created listener. */ - if (grpc_sockaddr_get_port(addr) == 0) { - for (sp = s->head; sp; sp = sp->next) { - sockname_len = sizeof(sockname_temp); - if (0 == getsockname(sp->socket->socket, - (struct sockaddr *)&sockname_temp, &sockname_len)) { - port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); - if (port > 0) { - allocated_addr = malloc(addr_len); - memcpy(allocated_addr, addr, addr_len); - grpc_sockaddr_set_port(allocated_addr, port); - addr = allocated_addr; - break; - } - } - } - } - - if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { - addr = (const struct sockaddr *)&addr6_v4mapped; - addr_len = sizeof(addr6_v4mapped); - } - - /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */ - if (grpc_sockaddr_is_wildcard(addr, &port)) { - grpc_sockaddr_make_wildcard6(port, &wildcard); - - addr = (struct sockaddr *)&wildcard; - addr_len = sizeof(wildcard); - } - - sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); - if (sock == INVALID_SOCKET) { - char *utf8_message = gpr_format_message(WSAGetLastError()); - gpr_log(GPR_ERROR, "unable to create socket: %s", utf8_message); - gpr_free(utf8_message); - } - - sp = add_socket_to_server(s, sock, addr, addr_len, port_index); - gpr_free(allocated_addr); - - if (sp) { - return sp->port; - } else { - return -1; - } -} - -unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s, - unsigned port_index) { - grpc_tcp_listener *sp; - for (sp = s->head; sp && port_index != 0; sp = sp->next, --port_index) - ; - if (sp) { - return 1; - } else { - return 0; - } -} - -int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index, - unsigned fd_index) { - grpc_tcp_listener *sp; - if (fd_index != 0) { - /* Windows implementation has only one fd per port_index. */ - return -1; - } - for (sp = s->head; sp && port_index != 0; sp = sp->next, --port_index) - ; - if (sp) { - return _open_osfhandle((intptr_t)sp->socket->socket, 0); - } else { - return -1; - } -} - -void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, - grpc_pollset **pollset, size_t pollset_count, - grpc_tcp_server_cb on_accept_cb, - void *on_accept_cb_arg) { - grpc_tcp_listener *sp; - GPR_ASSERT(on_accept_cb); - gpr_mu_lock(&s->mu); - GPR_ASSERT(!s->on_accept_cb); - GPR_ASSERT(s->active_ports == 0); - s->on_accept_cb = on_accept_cb; - s->on_accept_cb_arg = on_accept_cb_arg; - for (sp = s->head; sp; sp = sp->next) { - start_accept(exec_ctx, sp); - s->active_ports++; - } - gpr_mu_unlock(&s->mu); -} - -#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/iomgr/tcp_windows.c b/src/core/iomgr/tcp_windows.c deleted file mode 100644 index 9b1db5fa7e..0000000000 --- a/src/core/iomgr/tcp_windows.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_WINSOCK_SOCKET - -#include "src/core/iomgr/sockaddr_win32.h" - -#include -#include -#include -#include -#include -#include - -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/sockaddr.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/socket_windows.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/iomgr/timer.h" - -static int set_non_block(SOCKET sock) { - int status; - unsigned long param = 1; - DWORD ret; - status = - WSAIoctl(sock, FIONBIO, ¶m, sizeof(param), NULL, 0, &ret, NULL, NULL); - return status == 0; -} - -static int set_dualstack(SOCKET sock) { - int status; - unsigned long param = 0; - status = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)¶m, - sizeof(param)); - return status == 0; -} - -int grpc_tcp_prepare_socket(SOCKET sock) { - if (!set_non_block(sock)) return 0; - if (!set_dualstack(sock)) return 0; - return 1; -} - -typedef struct grpc_tcp { - /* This is our C++ class derivation emulation. */ - grpc_endpoint base; - /* The one socket this endpoint is using. */ - grpc_winsocket *socket; - /* Refcounting how many operations are in progress. */ - gpr_refcount refcount; - - grpc_closure on_read; - grpc_closure on_write; - - grpc_closure *read_cb; - grpc_closure *write_cb; - gpr_slice read_slice; - gpr_slice_buffer *write_slices; - gpr_slice_buffer *read_slices; - - /* The IO Completion Port runs from another thread. We need some mechanism - to protect ourselves when requesting a shutdown. */ - gpr_mu mu; - int shutting_down; - - char *peer_string; -} grpc_tcp; - -static void tcp_free(grpc_tcp *tcp) { - grpc_winsocket_destroy(tcp->socket); - gpr_mu_destroy(&tcp->mu); - gpr_free(tcp->peer_string); - gpr_free(tcp); -} - -/*#define GRPC_TCP_REFCOUNT_DEBUG*/ -#ifdef GRPC_TCP_REFCOUNT_DEBUG -#define TCP_UNREF(tcp, reason) tcp_unref((tcp), (reason), __FILE__, __LINE__) -#define TCP_REF(tcp, reason) tcp_ref((tcp), (reason), __FILE__, __LINE__) -static void tcp_unref(grpc_tcp *tcp, const char *reason, const char *file, - int line) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "TCP unref %p : %s %d -> %d", tcp, - reason, tcp->refcount.count, tcp->refcount.count - 1); - if (gpr_unref(&tcp->refcount)) { - tcp_free(tcp); - } -} - -static void tcp_ref(grpc_tcp *tcp, const char *reason, const char *file, - int line) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "TCP ref %p : %s %d -> %d", tcp, - reason, tcp->refcount.count, tcp->refcount.count + 1); - gpr_ref(&tcp->refcount); -} -#else -#define TCP_UNREF(tcp, reason) tcp_unref((tcp)) -#define TCP_REF(tcp, reason) tcp_ref((tcp)) -static void tcp_unref(grpc_tcp *tcp) { - if (gpr_unref(&tcp->refcount)) { - tcp_free(tcp); - } -} - -static void tcp_ref(grpc_tcp *tcp) { gpr_ref(&tcp->refcount); } -#endif - -/* Asynchronous callback from the IOCP, or the background thread. */ -static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, bool success) { - grpc_tcp *tcp = tcpp; - grpc_closure *cb = tcp->read_cb; - grpc_winsocket *socket = tcp->socket; - gpr_slice sub; - grpc_winsocket_callback_info *info = &socket->read_info; - - if (success) { - if (info->wsa_error != 0 && !tcp->shutting_down) { - if (info->wsa_error != WSAECONNRESET) { - char *utf8_message = gpr_format_message(info->wsa_error); - gpr_log(GPR_ERROR, "ReadFile overlapped error: %s", utf8_message); - gpr_free(utf8_message); - } - success = 0; - gpr_slice_unref(tcp->read_slice); - } else { - if (info->bytes_transfered != 0 && !tcp->shutting_down) { - sub = gpr_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); - gpr_slice_buffer_add(tcp->read_slices, sub); - success = 1; - } else { - gpr_slice_unref(tcp->read_slice); - success = 0; - } - } - } - - tcp->read_cb = NULL; - TCP_UNREF(tcp, "read"); - if (cb) { - cb->cb(exec_ctx, cb->cb_arg, success); - } -} - -static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - gpr_slice_buffer *read_slices, grpc_closure *cb) { - grpc_tcp *tcp = (grpc_tcp *)ep; - grpc_winsocket *handle = tcp->socket; - grpc_winsocket_callback_info *info = &handle->read_info; - int status; - DWORD bytes_read = 0; - DWORD flags = 0; - WSABUF buffer; - - if (tcp->shutting_down) { - grpc_exec_ctx_enqueue(exec_ctx, cb, false, NULL); - return; - } - - tcp->read_cb = cb; - tcp->read_slices = read_slices; - gpr_slice_buffer_reset_and_unref(read_slices); - - tcp->read_slice = gpr_slice_malloc(8192); - - buffer.len = (ULONG)GPR_SLICE_LENGTH( - tcp->read_slice); // we know slice size fits in 32bit. - buffer.buf = (char *)GPR_SLICE_START_PTR(tcp->read_slice); - - TCP_REF(tcp, "read"); - - /* First let's try a synchronous, non-blocking read. */ - status = - WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, NULL, NULL); - info->wsa_error = status == 0 ? 0 : WSAGetLastError(); - - /* Did we get data immediately ? Yay. */ - if (info->wsa_error != WSAEWOULDBLOCK) { - info->bytes_transfered = bytes_read; - grpc_exec_ctx_enqueue(exec_ctx, &tcp->on_read, true, NULL); - return; - } - - /* Otherwise, let's retry, by queuing a read. */ - memset(&tcp->socket->read_info.overlapped, 0, sizeof(OVERLAPPED)); - status = WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, - &info->overlapped, NULL); - - if (status != 0) { - int wsa_error = WSAGetLastError(); - if (wsa_error != WSA_IO_PENDING) { - info->wsa_error = wsa_error; - grpc_exec_ctx_enqueue(exec_ctx, &tcp->on_read, false, NULL); - return; - } - } - - grpc_socket_notify_on_read(exec_ctx, tcp->socket, &tcp->on_read); -} - -/* Asynchronous callback from the IOCP, or the background thread. */ -static void on_write(grpc_exec_ctx *exec_ctx, void *tcpp, bool success) { - grpc_tcp *tcp = (grpc_tcp *)tcpp; - grpc_winsocket *handle = tcp->socket; - grpc_winsocket_callback_info *info = &handle->write_info; - grpc_closure *cb; - - gpr_mu_lock(&tcp->mu); - cb = tcp->write_cb; - tcp->write_cb = NULL; - gpr_mu_unlock(&tcp->mu); - - if (success) { - if (info->wsa_error != 0) { - if (info->wsa_error != WSAECONNRESET) { - char *utf8_message = gpr_format_message(info->wsa_error); - gpr_log(GPR_ERROR, "WSASend overlapped error: %s", utf8_message); - gpr_free(utf8_message); - } - success = 0; - } else { - GPR_ASSERT(info->bytes_transfered == tcp->write_slices->length); - } - } - - TCP_UNREF(tcp, "write"); - cb->cb(exec_ctx, cb->cb_arg, success); -} - -/* Initiates a write. */ -static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - gpr_slice_buffer *slices, grpc_closure *cb) { - grpc_tcp *tcp = (grpc_tcp *)ep; - grpc_winsocket *socket = tcp->socket; - grpc_winsocket_callback_info *info = &socket->write_info; - unsigned i; - DWORD bytes_sent; - int status; - WSABUF local_buffers[16]; - WSABUF *allocated = NULL; - WSABUF *buffers = local_buffers; - size_t len; - - if (tcp->shutting_down) { - grpc_exec_ctx_enqueue(exec_ctx, cb, false, NULL); - return; - } - - tcp->write_cb = cb; - tcp->write_slices = slices; - GPR_ASSERT(tcp->write_slices->count <= UINT_MAX); - if (tcp->write_slices->count > GPR_ARRAY_SIZE(local_buffers)) { - buffers = (WSABUF *)gpr_malloc(sizeof(WSABUF) * tcp->write_slices->count); - allocated = buffers; - } - - for (i = 0; i < tcp->write_slices->count; i++) { - len = GPR_SLICE_LENGTH(tcp->write_slices->slices[i]); - GPR_ASSERT(len <= ULONG_MAX); - buffers[i].len = (ULONG)len; - buffers[i].buf = (char *)GPR_SLICE_START_PTR(tcp->write_slices->slices[i]); - } - - /* First, let's try a synchronous, non-blocking write. */ - status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count, - &bytes_sent, 0, NULL, NULL); - info->wsa_error = status == 0 ? 0 : WSAGetLastError(); - - /* We would kind of expect to get a WSAEWOULDBLOCK here, especially on a busy - connection that has its send queue filled up. But if we don't, then we can - avoid doing an async write operation at all. */ - if (info->wsa_error != WSAEWOULDBLOCK) { - bool ok = false; - if (status == 0) { - ok = true; - GPR_ASSERT(bytes_sent == tcp->write_slices->length); - } else { - if (info->wsa_error != WSAECONNRESET) { - char *utf8_message = gpr_format_message(info->wsa_error); - gpr_log(GPR_ERROR, "WSASend error: %s", utf8_message); - gpr_free(utf8_message); - } - } - if (allocated) gpr_free(allocated); - grpc_exec_ctx_enqueue(exec_ctx, cb, ok, NULL); - return; - } - - TCP_REF(tcp, "write"); - - /* If we got a WSAEWOULDBLOCK earlier, then we need to re-do the same - operation, this time asynchronously. */ - memset(&socket->write_info.overlapped, 0, sizeof(OVERLAPPED)); - status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count, - &bytes_sent, 0, &socket->write_info.overlapped, NULL); - if (allocated) gpr_free(allocated); - - if (status != 0) { - int wsa_error = WSAGetLastError(); - if (wsa_error != WSA_IO_PENDING) { - TCP_UNREF(tcp, "write"); - grpc_exec_ctx_enqueue(exec_ctx, cb, false, NULL); - return; - } - } - - /* As all is now setup, we can now ask for the IOCP notification. It may - trigger the callback immediately however, but no matter. */ - grpc_socket_notify_on_write(exec_ctx, socket, &tcp->on_write); -} - -static void win_add_to_pollset(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - grpc_pollset *ps) { - grpc_tcp *tcp; - (void)ps; - tcp = (grpc_tcp *)ep; - grpc_iocp_add_socket(tcp->socket); -} - -static void win_add_to_pollset_set(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, - grpc_pollset_set *pss) { - grpc_tcp *tcp; - (void)pss; - tcp = (grpc_tcp *)ep; - grpc_iocp_add_socket(tcp->socket); -} - -/* Initiates a shutdown of the TCP endpoint. This will queue abort callbacks - for the potential read and write operations. It is up to the caller to - guarantee this isn't called in parallel to a read or write request, so - we're not going to protect against these. However the IO Completion Port - callback will happen from another thread, so we need to protect against - concurrent access of the data structure in that regard. */ -static void win_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) { - grpc_tcp *tcp = (grpc_tcp *)ep; - gpr_mu_lock(&tcp->mu); - /* At that point, what may happen is that we're already inside the IOCP - callback. See the comments in on_read and on_write. */ - tcp->shutting_down = 1; - grpc_winsocket_shutdown(tcp->socket); - gpr_mu_unlock(&tcp->mu); -} - -static void win_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) { - grpc_tcp *tcp = (grpc_tcp *)ep; - TCP_UNREF(tcp, "destroy"); -} - -static char *win_get_peer(grpc_endpoint *ep) { - grpc_tcp *tcp = (grpc_tcp *)ep; - return gpr_strdup(tcp->peer_string); -} - -static grpc_endpoint_vtable vtable = { - win_read, win_write, win_add_to_pollset, win_add_to_pollset_set, - win_shutdown, win_destroy, win_get_peer}; - -grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket, char *peer_string) { - grpc_tcp *tcp = (grpc_tcp *)gpr_malloc(sizeof(grpc_tcp)); - memset(tcp, 0, sizeof(grpc_tcp)); - tcp->base.vtable = &vtable; - tcp->socket = socket; - gpr_mu_init(&tcp->mu); - gpr_ref_init(&tcp->refcount, 1); - grpc_closure_init(&tcp->on_read, on_read, tcp); - grpc_closure_init(&tcp->on_write, on_write, tcp); - tcp->peer_string = gpr_strdup(peer_string); - return &tcp->base; -} - -#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/iomgr/tcp_windows.h b/src/core/iomgr/tcp_windows.h deleted file mode 100644 index 78bc13389a..0000000000 --- a/src/core/iomgr/tcp_windows.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_TCP_WINDOWS_H -#define GRPC_CORE_IOMGR_TCP_WINDOWS_H -/* - Low level TCP "bottom half" implementation, for use by transports built on - top of a TCP connection. - - Note that this file does not (yet) include APIs for creating the socket in - the first place. - - All calls passing slice transfer ownership of a slice refcount unless - otherwise specified. -*/ - -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/socket_windows.h" - -/* Create a tcp endpoint given a winsock handle. - * Takes ownership of the handle. - */ -grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket, char *peer_string); - -int grpc_tcp_prepare_socket(SOCKET sock); - -#endif /* GRPC_CORE_IOMGR_TCP_WINDOWS_H */ diff --git a/src/core/iomgr/time_averaged_stats.c b/src/core/iomgr/time_averaged_stats.c deleted file mode 100644 index e075db4373..0000000000 --- a/src/core/iomgr/time_averaged_stats.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * - * Copyright 2015, 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/iomgr/time_averaged_stats.h" - -void grpc_time_averaged_stats_init(grpc_time_averaged_stats* stats, - double init_avg, double regress_weight, - double persistence_factor) { - stats->init_avg = init_avg; - stats->regress_weight = regress_weight; - stats->persistence_factor = persistence_factor; - stats->batch_total_value = 0; - stats->batch_num_samples = 0; - stats->aggregate_total_weight = 0; - stats->aggregate_weighted_avg = init_avg; -} - -void grpc_time_averaged_stats_add_sample(grpc_time_averaged_stats* stats, - double value) { - stats->batch_total_value += value; - ++stats->batch_num_samples; -} - -double grpc_time_averaged_stats_update_average( - grpc_time_averaged_stats* stats) { - /* Start with the current batch: */ - double weighted_sum = stats->batch_total_value; - double total_weight = stats->batch_num_samples; - if (stats->regress_weight > 0) { - /* Add in the regression towards init_avg_: */ - weighted_sum += stats->regress_weight * stats->init_avg; - total_weight += stats->regress_weight; - } - if (stats->persistence_factor > 0) { - /* Add in the persistence: */ - const double prev_sample_weight = - stats->persistence_factor * stats->aggregate_total_weight; - weighted_sum += prev_sample_weight * stats->aggregate_weighted_avg; - total_weight += prev_sample_weight; - } - stats->aggregate_weighted_avg = - (total_weight > 0) ? (weighted_sum / total_weight) : stats->init_avg; - stats->aggregate_total_weight = total_weight; - stats->batch_num_samples = 0; - stats->batch_total_value = 0; - return stats->aggregate_weighted_avg; -} diff --git a/src/core/iomgr/time_averaged_stats.h b/src/core/iomgr/time_averaged_stats.h deleted file mode 100644 index 048e244bcc..0000000000 --- a/src/core/iomgr/time_averaged_stats.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_TIME_AVERAGED_STATS_H -#define GRPC_CORE_IOMGR_TIME_AVERAGED_STATS_H - -/* This tracks a time-decaying weighted average. It works by collecting - batches of samples and then mixing their average into a time-decaying - weighted mean. It is designed for batch operations where we do many adds - before updating the average. */ - -typedef struct { - /* The initial average value. This is the reported average until the first - grpc_time_averaged_stats_update_average call. If a positive regress_weight - is used, we also regress towards this value on each update. */ - double init_avg; - /* The sample weight of "init_avg" that is mixed in with each call to - grpc_time_averaged_stats_update_average. If the calls to - grpc_time_averaged_stats_add_sample stop, this will cause the average to - regress back to the mean. This should be non-negative. Set it to 0 to - disable the bias. A value of 1 has the effect of adding in 1 bonus sample - with value init_avg to each sample period. */ - double regress_weight; - /* This determines the rate of decay of the time-averaging from one period - to the next by scaling the aggregate_total_weight of samples from prior - periods when combining with the latest period. It should be in the range - [0,1]. A higher value adapts more slowly. With a value of 0.5, if the - batches each have k samples, the samples_in_avg_ will grow to 2 k, so the - weighting of the time average will eventually be 1/3 new batch and 2/3 - old average. */ - double persistence_factor; - - /* The total value of samples since the last UpdateAverage(). */ - double batch_total_value; - /* The number of samples since the last UpdateAverage(). */ - double batch_num_samples; - /* The time-decayed sum of batch_num_samples_ over previous batches. This is - the "weight" of the old aggregate_weighted_avg_ when updating the - average. */ - double aggregate_total_weight; - /* A time-decayed average of the (batch_total_value_ / batch_num_samples_), - computed by decaying the samples_in_avg_ weight in the weighted average. */ - double aggregate_weighted_avg; -} grpc_time_averaged_stats; - -/* See the comments on the members above for an explanation of init_avg, - regress_weight, and persistence_factor. */ -void grpc_time_averaged_stats_init(grpc_time_averaged_stats* stats, - double init_avg, double regress_weight, - double persistence_factor); -/* Add a sample to the current batch. */ -void grpc_time_averaged_stats_add_sample(grpc_time_averaged_stats* stats, - double value); -/* Complete a batch and compute the new estimate of the average sample - value. */ -double grpc_time_averaged_stats_update_average(grpc_time_averaged_stats* stats); - -#endif /* GRPC_CORE_IOMGR_TIME_AVERAGED_STATS_H */ diff --git a/src/core/iomgr/timer.c b/src/core/iomgr/timer.c deleted file mode 100644 index f444643428..0000000000 --- a/src/core/iomgr/timer.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - * - * Copyright 2015-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/iomgr/timer.h" - -#include -#include -#include -#include "src/core/iomgr/time_averaged_stats.h" -#include "src/core/iomgr/timer_heap.h" - -#define INVALID_HEAP_INDEX 0xffffffffu - -#define LOG2_NUM_SHARDS 5 -#define NUM_SHARDS (1 << LOG2_NUM_SHARDS) -#define ADD_DEADLINE_SCALE 0.33 -#define MIN_QUEUE_WINDOW_DURATION 0.01 -#define MAX_QUEUE_WINDOW_DURATION 1 - -typedef struct { - gpr_mu mu; - grpc_time_averaged_stats stats; - /* All and only timers with deadlines <= this will be in the heap. */ - gpr_timespec queue_deadline_cap; - gpr_timespec min_deadline; - /* Index in the g_shard_queue */ - uint32_t shard_queue_index; - /* This holds all timers with deadlines < queue_deadline_cap. Timers in this - list have the top bit of their deadline set to 0. */ - grpc_timer_heap heap; - /* This holds timers whose deadline is >= queue_deadline_cap. */ - grpc_timer list; -} shard_type; - -/* Protects g_shard_queue */ -static gpr_mu g_mu; -/* Allow only one run_some_expired_timers at once */ -static gpr_mu g_checker_mu; -static gpr_clock_type g_clock_type; -static shard_type g_shards[NUM_SHARDS]; -/* Protected by g_mu */ -static shard_type *g_shard_queue[NUM_SHARDS]; - -static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now, - gpr_timespec *next, int success); - -static gpr_timespec compute_min_deadline(shard_type *shard) { - return grpc_timer_heap_is_empty(&shard->heap) - ? shard->queue_deadline_cap - : grpc_timer_heap_top(&shard->heap)->deadline; -} - -void grpc_timer_list_init(gpr_timespec now) { - uint32_t i; - - gpr_mu_init(&g_mu); - gpr_mu_init(&g_checker_mu); - g_clock_type = now.clock_type; - - for (i = 0; i < NUM_SHARDS; i++) { - shard_type *shard = &g_shards[i]; - gpr_mu_init(&shard->mu); - grpc_time_averaged_stats_init(&shard->stats, 1.0 / ADD_DEADLINE_SCALE, 0.1, - 0.5); - shard->queue_deadline_cap = now; - shard->shard_queue_index = i; - grpc_timer_heap_init(&shard->heap); - shard->list.next = shard->list.prev = &shard->list; - shard->min_deadline = compute_min_deadline(shard); - g_shard_queue[i] = shard; - } -} - -void grpc_timer_list_shutdown(grpc_exec_ctx *exec_ctx) { - int i; - run_some_expired_timers(exec_ctx, gpr_inf_future(g_clock_type), NULL, 0); - for (i = 0; i < NUM_SHARDS; i++) { - shard_type *shard = &g_shards[i]; - gpr_mu_destroy(&shard->mu); - grpc_timer_heap_destroy(&shard->heap); - } - gpr_mu_destroy(&g_mu); - gpr_mu_destroy(&g_checker_mu); -} - -/* This is a cheap, but good enough, pointer hash for sharding the tasks: */ -static size_t shard_idx(const grpc_timer *info) { - size_t x = (size_t)info; - return ((x >> 4) ^ (x >> 9) ^ (x >> 14)) & (NUM_SHARDS - 1); -} - -static double ts_to_dbl(gpr_timespec ts) { - return (double)ts.tv_sec + 1e-9 * ts.tv_nsec; -} - -static gpr_timespec dbl_to_ts(double d) { - gpr_timespec ts; - ts.tv_sec = (int64_t)d; - ts.tv_nsec = (int32_t)(1e9 * (d - (double)ts.tv_sec)); - ts.clock_type = GPR_TIMESPAN; - return ts; -} - -static void list_join(grpc_timer *head, grpc_timer *timer) { - timer->next = head; - timer->prev = head->prev; - timer->next->prev = timer->prev->next = timer; -} - -static void list_remove(grpc_timer *timer) { - timer->next->prev = timer->prev; - timer->prev->next = timer->next; -} - -static void swap_adjacent_shards_in_queue(uint32_t first_shard_queue_index) { - shard_type *temp; - temp = g_shard_queue[first_shard_queue_index]; - g_shard_queue[first_shard_queue_index] = - g_shard_queue[first_shard_queue_index + 1]; - g_shard_queue[first_shard_queue_index + 1] = temp; - g_shard_queue[first_shard_queue_index]->shard_queue_index = - first_shard_queue_index; - g_shard_queue[first_shard_queue_index + 1]->shard_queue_index = - first_shard_queue_index + 1; -} - -static void note_deadline_change(shard_type *shard) { - while (shard->shard_queue_index > 0 && - gpr_time_cmp( - shard->min_deadline, - g_shard_queue[shard->shard_queue_index - 1]->min_deadline) < 0) { - swap_adjacent_shards_in_queue(shard->shard_queue_index - 1); - } - while (shard->shard_queue_index < NUM_SHARDS - 1 && - gpr_time_cmp( - shard->min_deadline, - g_shard_queue[shard->shard_queue_index + 1]->min_deadline) > 0) { - swap_adjacent_shards_in_queue(shard->shard_queue_index); - } -} - -void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer, - gpr_timespec deadline, grpc_iomgr_cb_func timer_cb, - void *timer_cb_arg, gpr_timespec now) { - int is_first_timer = 0; - shard_type *shard = &g_shards[shard_idx(timer)]; - GPR_ASSERT(deadline.clock_type == g_clock_type); - GPR_ASSERT(now.clock_type == g_clock_type); - grpc_closure_init(&timer->closure, timer_cb, timer_cb_arg); - timer->deadline = deadline; - timer->triggered = 0; - - /* TODO(ctiller): check deadline expired */ - - gpr_mu_lock(&shard->mu); - grpc_time_averaged_stats_add_sample(&shard->stats, - ts_to_dbl(gpr_time_sub(deadline, now))); - if (gpr_time_cmp(deadline, shard->queue_deadline_cap) < 0) { - is_first_timer = grpc_timer_heap_add(&shard->heap, timer); - } else { - timer->heap_index = INVALID_HEAP_INDEX; - list_join(&shard->list, timer); - } - gpr_mu_unlock(&shard->mu); - - /* Deadline may have decreased, we need to adjust the master queue. Note - that there is a potential racy unlocked region here. There could be a - reordering of multiple grpc_timer_init calls, at this point, but the < test - below should ensure that we err on the side of caution. There could - also be a race with grpc_timer_check, which might beat us to the lock. In - that case, it is possible that the timer that we added will have already - run by the time we hold the lock, but that too is a safe error. - Finally, it's possible that the grpc_timer_check that intervened failed to - trigger the new timer because the min_deadline hadn't yet been reduced. - In that case, the timer will simply have to wait for the next - grpc_timer_check. */ - if (is_first_timer) { - gpr_mu_lock(&g_mu); - if (gpr_time_cmp(deadline, shard->min_deadline) < 0) { - gpr_timespec old_min_deadline = g_shard_queue[0]->min_deadline; - shard->min_deadline = deadline; - note_deadline_change(shard); - if (shard->shard_queue_index == 0 && - gpr_time_cmp(deadline, old_min_deadline) < 0) { - grpc_kick_poller(); - } - } - gpr_mu_unlock(&g_mu); - } -} - -void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) { - shard_type *shard = &g_shards[shard_idx(timer)]; - gpr_mu_lock(&shard->mu); - if (!timer->triggered) { - grpc_exec_ctx_enqueue(exec_ctx, &timer->closure, false, NULL); - timer->triggered = 1; - if (timer->heap_index == INVALID_HEAP_INDEX) { - list_remove(timer); - } else { - grpc_timer_heap_remove(&shard->heap, timer); - } - } - gpr_mu_unlock(&shard->mu); -} - -/* This is called when the queue is empty and "now" has reached the - queue_deadline_cap. We compute a new queue deadline and then scan the map - for timers that fall at or under it. Returns true if the queue is no - longer empty. - REQUIRES: shard->mu locked */ -static int refill_queue(shard_type *shard, gpr_timespec now) { - /* Compute the new queue window width and bound by the limits: */ - double computed_deadline_delta = - grpc_time_averaged_stats_update_average(&shard->stats) * - ADD_DEADLINE_SCALE; - double deadline_delta = - GPR_CLAMP(computed_deadline_delta, MIN_QUEUE_WINDOW_DURATION, - MAX_QUEUE_WINDOW_DURATION); - grpc_timer *timer, *next; - - /* Compute the new cap and put all timers under it into the queue: */ - shard->queue_deadline_cap = gpr_time_add( - gpr_time_max(now, shard->queue_deadline_cap), dbl_to_ts(deadline_delta)); - for (timer = shard->list.next; timer != &shard->list; timer = next) { - next = timer->next; - - if (gpr_time_cmp(timer->deadline, shard->queue_deadline_cap) < 0) { - list_remove(timer); - grpc_timer_heap_add(&shard->heap, timer); - } - } - return !grpc_timer_heap_is_empty(&shard->heap); -} - -/* This pops the next non-cancelled timer with deadline <= now from the queue, - or returns NULL if there isn't one. - REQUIRES: shard->mu locked */ -static grpc_timer *pop_one(shard_type *shard, gpr_timespec now) { - grpc_timer *timer; - for (;;) { - if (grpc_timer_heap_is_empty(&shard->heap)) { - if (gpr_time_cmp(now, shard->queue_deadline_cap) < 0) return NULL; - if (!refill_queue(shard, now)) return NULL; - } - timer = grpc_timer_heap_top(&shard->heap); - if (gpr_time_cmp(timer->deadline, now) > 0) return NULL; - timer->triggered = 1; - grpc_timer_heap_pop(&shard->heap); - return timer; - } -} - -/* REQUIRES: shard->mu unlocked */ -static size_t pop_timers(grpc_exec_ctx *exec_ctx, shard_type *shard, - gpr_timespec now, gpr_timespec *new_min_deadline, - int success) { - size_t n = 0; - grpc_timer *timer; - gpr_mu_lock(&shard->mu); - while ((timer = pop_one(shard, now))) { - grpc_exec_ctx_enqueue(exec_ctx, &timer->closure, success, NULL); - n++; - } - *new_min_deadline = compute_min_deadline(shard); - gpr_mu_unlock(&shard->mu); - return n; -} - -static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now, - gpr_timespec *next, int success) { - size_t n = 0; - - /* TODO(ctiller): verify that there are any timers (atomically) here */ - - if (gpr_mu_trylock(&g_checker_mu)) { - gpr_mu_lock(&g_mu); - - while (gpr_time_cmp(g_shard_queue[0]->min_deadline, now) < 0) { - gpr_timespec new_min_deadline; - - /* For efficiency, we pop as many available timers as we can from the - shard. This may violate perfect timer deadline ordering, but that - shouldn't be a big deal because we don't make ordering guarantees. */ - n += pop_timers(exec_ctx, g_shard_queue[0], now, &new_min_deadline, - success); - - /* An grpc_timer_init() on the shard could intervene here, adding a new - timer that is earlier than new_min_deadline. However, - grpc_timer_init() will block on the master_lock before it can call - set_min_deadline, so this one will complete first and then the Addtimer - will reduce the min_deadline (perhaps unnecessarily). */ - g_shard_queue[0]->min_deadline = new_min_deadline; - note_deadline_change(g_shard_queue[0]); - } - - if (next) { - *next = gpr_time_min(*next, g_shard_queue[0]->min_deadline); - } - - gpr_mu_unlock(&g_mu); - gpr_mu_unlock(&g_checker_mu); - } else if (next != NULL) { - /* TODO(ctiller): this forces calling code to do an short poll, and - then retry the timer check (because this time through the timer list was - contended). - - We could reduce the cost here dramatically by keeping a count of how many - currently active pollers got through the uncontended case above - successfully, and waking up other pollers IFF that count drops to zero. - - Once that count is in place, this entire else branch could disappear. */ - *next = gpr_time_min( - *next, gpr_time_add(now, gpr_time_from_millis(1, GPR_TIMESPAN))); - } - - return (int)n; -} - -bool grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now, - gpr_timespec *next) { - GPR_ASSERT(now.clock_type == g_clock_type); - return run_some_expired_timers( - exec_ctx, now, next, - gpr_time_cmp(now, gpr_inf_future(now.clock_type)) != 0); -} diff --git a/src/core/iomgr/timer.h b/src/core/iomgr/timer.h deleted file mode 100644 index 1e2d1cbfbd..0000000000 --- a/src/core/iomgr/timer.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_TIMER_H -#define GRPC_CORE_IOMGR_TIMER_H - -#include -#include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/iomgr/iomgr.h" - -typedef struct grpc_timer { - gpr_timespec deadline; - uint32_t heap_index; /* INVALID_HEAP_INDEX if not in heap */ - int triggered; - struct grpc_timer *next; - struct grpc_timer *prev; - grpc_closure closure; -} grpc_timer; - -/* Initialize *timer. When expired or canceled, timer_cb will be called with - *timer_cb_arg and status to indicate if it expired (SUCCESS) or was - canceled (CANCELLED). timer_cb is guaranteed to be called exactly once, - and application code should check the status to determine how it was - invoked. The application callback is also responsible for maintaining - information about when to free up any user-level state. */ -void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer, - gpr_timespec deadline, grpc_iomgr_cb_func timer_cb, - void *timer_cb_arg, gpr_timespec now); - -/* Note that there is no timer destroy function. This is because the - timer is a one-time occurrence with a guarantee that the callback will - be called exactly once, either at expiration or cancellation. Thus, all - the internal timer event management state is destroyed just before - that callback is invoked. If the user has additional state associated with - the timer, the user is responsible for determining when it is safe to - destroy that state. */ - -/* Cancel an *timer. - There are three cases: - 1. We normally cancel the timer - 2. The timer has already run - 3. We can't cancel the timer because it is "in flight". - - In all of these cases, the cancellation is still considered successful. - They are essentially distinguished in that the timer_cb will be run - exactly once from either the cancellation (with status CANCELLED) - or from the activation (with status SUCCESS) - - Note carefully that the callback function MAY occur in the same callstack - as grpc_timer_cancel. It's expected that most timers will be cancelled (their - primary use is to implement deadlines), and so this code is optimized such - that cancellation costs as little as possible. Making callbacks run inline - matches this aim. - - Requires: cancel() must happen after add() on a given timer */ -void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer); - -/* iomgr internal api for dealing with timers */ - -/* Check for timers to be run, and run them. - Return true if timer callbacks were executed. - Drops drop_mu if it is non-null before executing callbacks. - If next is non-null, TRY to update *next with the next running timer - IF that timer occurs before *next current value. - *next is never guaranteed to be updated on any given execution; however, - with high probability at least one thread in the system will see an update - at any time slice. */ -bool grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now, - gpr_timespec *next); -void grpc_timer_list_init(gpr_timespec now); -void grpc_timer_list_shutdown(grpc_exec_ctx *exec_ctx); - -/* the following must be implemented by each iomgr implementation */ - -void grpc_kick_poller(void); - -#endif /* GRPC_CORE_IOMGR_TIMER_H */ diff --git a/src/core/iomgr/timer_heap.c b/src/core/iomgr/timer_heap.c deleted file mode 100644 index b5df566c45..0000000000 --- a/src/core/iomgr/timer_heap.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * - * Copyright 2015-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/iomgr/timer_heap.h" - -#include - -#include -#include - -/* Adjusts a heap so as to move a hole at position i closer to the root, - until a suitable position is found for element t. Then, copies t into that - position. This functor is called each time immediately after modifying a - value in the underlying container, with the offset of the modified element as - its argument. */ -static void adjust_upwards(grpc_timer **first, uint32_t i, grpc_timer *t) { - while (i > 0) { - uint32_t parent = (uint32_t)(((int)i - 1) / 2); - if (gpr_time_cmp(first[parent]->deadline, t->deadline) <= 0) break; - first[i] = first[parent]; - first[i]->heap_index = i; - i = parent; - } - first[i] = t; - t->heap_index = i; -} - -/* Adjusts a heap so as to move a hole at position i farther away from the root, - until a suitable position is found for element t. Then, copies t into that - position. */ -static void adjust_downwards(grpc_timer **first, uint32_t i, uint32_t length, - grpc_timer *t) { - for (;;) { - uint32_t left_child = 1u + 2u * i; - if (left_child >= length) break; - uint32_t right_child = left_child + 1; - uint32_t next_i = right_child < length && - gpr_time_cmp(first[left_child]->deadline, - first[right_child]->deadline) > 0 - ? right_child - : left_child; - if (gpr_time_cmp(t->deadline, first[next_i]->deadline) <= 0) break; - first[i] = first[next_i]; - first[i]->heap_index = i; - i = next_i; - } - first[i] = t; - t->heap_index = i; -} - -#define SHRINK_MIN_ELEMS 8 -#define SHRINK_FULLNESS_FACTOR 2 - -static void maybe_shrink(grpc_timer_heap *heap) { - if (heap->timer_count >= 8 && - heap->timer_count <= heap->timer_capacity / SHRINK_FULLNESS_FACTOR / 2) { - heap->timer_capacity = heap->timer_count * SHRINK_FULLNESS_FACTOR; - heap->timers = - gpr_realloc(heap->timers, heap->timer_capacity * sizeof(grpc_timer *)); - } -} - -static void note_changed_priority(grpc_timer_heap *heap, grpc_timer *timer) { - uint32_t i = timer->heap_index; - uint32_t parent = (uint32_t)(((int)i - 1) / 2); - if (gpr_time_cmp(heap->timers[parent]->deadline, timer->deadline) > 0) { - adjust_upwards(heap->timers, i, timer); - } else { - adjust_downwards(heap->timers, i, heap->timer_count, timer); - } -} - -void grpc_timer_heap_init(grpc_timer_heap *heap) { - memset(heap, 0, sizeof(*heap)); -} - -void grpc_timer_heap_destroy(grpc_timer_heap *heap) { gpr_free(heap->timers); } - -int grpc_timer_heap_add(grpc_timer_heap *heap, grpc_timer *timer) { - if (heap->timer_count == heap->timer_capacity) { - heap->timer_capacity = - GPR_MAX(heap->timer_capacity + 1, heap->timer_capacity * 3 / 2); - heap->timers = - gpr_realloc(heap->timers, heap->timer_capacity * sizeof(grpc_timer *)); - } - timer->heap_index = heap->timer_count; - adjust_upwards(heap->timers, heap->timer_count, timer); - heap->timer_count++; - return timer->heap_index == 0; -} - -void grpc_timer_heap_remove(grpc_timer_heap *heap, grpc_timer *timer) { - uint32_t i = timer->heap_index; - if (i == heap->timer_count - 1) { - heap->timer_count--; - maybe_shrink(heap); - return; - } - heap->timers[i] = heap->timers[heap->timer_count - 1]; - heap->timers[i]->heap_index = i; - heap->timer_count--; - maybe_shrink(heap); - note_changed_priority(heap, heap->timers[i]); -} - -int grpc_timer_heap_is_empty(grpc_timer_heap *heap) { - return heap->timer_count == 0; -} - -grpc_timer *grpc_timer_heap_top(grpc_timer_heap *heap) { - return heap->timers[0]; -} - -void grpc_timer_heap_pop(grpc_timer_heap *heap) { - grpc_timer_heap_remove(heap, grpc_timer_heap_top(heap)); -} diff --git a/src/core/iomgr/timer_heap.h b/src/core/iomgr/timer_heap.h deleted file mode 100644 index c2912ef45d..0000000000 --- a/src/core/iomgr/timer_heap.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_TIMER_HEAP_H -#define GRPC_CORE_IOMGR_TIMER_HEAP_H - -#include "src/core/iomgr/timer.h" - -typedef struct { - grpc_timer **timers; - uint32_t timer_count; - uint32_t timer_capacity; -} grpc_timer_heap; - -/* return 1 if the new timer is the first timer in the heap */ -int grpc_timer_heap_add(grpc_timer_heap *heap, grpc_timer *timer); - -void grpc_timer_heap_init(grpc_timer_heap *heap); -void grpc_timer_heap_destroy(grpc_timer_heap *heap); - -void grpc_timer_heap_remove(grpc_timer_heap *heap, grpc_timer *timer); -grpc_timer *grpc_timer_heap_top(grpc_timer_heap *heap); -void grpc_timer_heap_pop(grpc_timer_heap *heap); - -int grpc_timer_heap_is_empty(grpc_timer_heap *heap); - -#endif /* GRPC_CORE_IOMGR_TIMER_HEAP_H */ diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c deleted file mode 100644 index 174159170f..0000000000 --- a/src/core/iomgr/udp_server.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* FIXME: "posix" files shouldn't be depending on _GNU_SOURCE */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include - -#ifdef GRPC_NEED_UDP -#ifdef GPR_POSIX_SOCKET - -#include "src/core/iomgr/udp_server.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/iomgr/unix_sockets_posix.h" -#include "src/core/support/string.h" - -#define INIT_PORT_CAP 2 - -/* one listening port */ -typedef struct { - int fd; - grpc_fd *emfd; - grpc_udp_server *server; - union { - uint8_t untyped[GRPC_MAX_SOCKADDR_SIZE]; - struct sockaddr sockaddr; - } addr; - size_t addr_len; - grpc_closure read_closure; - grpc_closure destroyed_closure; - grpc_udp_server_read_cb read_cb; -} server_port; - -/* the overall server */ -struct grpc_udp_server { - gpr_mu mu; - gpr_cv cv; - - /* active port count: how many ports are actually still listening */ - size_t active_ports; - /* destroyed port count: how many ports are completely destroyed */ - size_t destroyed_ports; - - /* is this server shutting down? (boolean) */ - int shutdown; - - /* all listening ports */ - server_port *ports; - size_t nports; - size_t port_capacity; - - /* shutdown callback */ - grpc_closure *shutdown_complete; - - /* all pollsets interested in new connections */ - grpc_pollset **pollsets; - /* number of pollsets in the pollsets array */ - size_t pollset_count; - /* The parent grpc server */ - grpc_server *grpc_server; -}; - -grpc_udp_server *grpc_udp_server_create(void) { - grpc_udp_server *s = gpr_malloc(sizeof(grpc_udp_server)); - gpr_mu_init(&s->mu); - gpr_cv_init(&s->cv); - s->active_ports = 0; - s->destroyed_ports = 0; - s->shutdown = 0; - s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP); - s->nports = 0; - s->port_capacity = INIT_PORT_CAP; - - return s; -} - -static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { - grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1, NULL); - - gpr_mu_destroy(&s->mu); - gpr_cv_destroy(&s->cv); - - gpr_free(s->ports); - gpr_free(s); -} - -static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server, - bool success) { - grpc_udp_server *s = server; - gpr_mu_lock(&s->mu); - s->destroyed_ports++; - if (s->destroyed_ports == s->nports) { - gpr_mu_unlock(&s->mu); - finish_shutdown(exec_ctx, s); - } else { - gpr_mu_unlock(&s->mu); - } -} - -/* called when all listening endpoints have been shutdown, so no further - events will be received on them - at this point it's safe to destroy - things */ -static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { - size_t i; - - /* delete ALL the things */ - gpr_mu_lock(&s->mu); - - if (!s->shutdown) { - gpr_mu_unlock(&s->mu); - return; - } - - if (s->nports) { - for (i = 0; i < s->nports; i++) { - server_port *sp = &s->ports[i]; - grpc_unlink_if_unix_domain_socket(&sp->addr.sockaddr); - sp->destroyed_closure.cb = destroyed_port; - sp->destroyed_closure.cb_arg = s; - grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, - "udp_listener_shutdown"); - } - gpr_mu_unlock(&s->mu); - } else { - gpr_mu_unlock(&s->mu); - finish_shutdown(exec_ctx, s); - } -} - -void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *s, - grpc_closure *on_done) { - size_t i; - gpr_mu_lock(&s->mu); - - GPR_ASSERT(!s->shutdown); - s->shutdown = 1; - - s->shutdown_complete = on_done; - - /* shutdown all fd's */ - if (s->active_ports) { - for (i = 0; i < s->nports; i++) { - grpc_fd_shutdown(exec_ctx, s->ports[i].emfd); - } - gpr_mu_unlock(&s->mu); - } else { - gpr_mu_unlock(&s->mu); - deactivated_all_ports(exec_ctx, s); - } -} - -/* Prepare a recently-created socket for listening. */ -static int prepare_socket(int fd, const struct sockaddr *addr, - size_t addr_len) { - struct sockaddr_storage sockname_temp; - socklen_t sockname_len; - int get_local_ip; - int rc; - - if (fd < 0) { - goto error; - } - - if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1)) { - gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, - strerror(errno)); - } - - get_local_ip = 1; - rc = setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_local_ip, - sizeof(get_local_ip)); - if (rc == 0 && addr->sa_family == AF_INET6) { -#if !defined(__APPLE__) - rc = setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &get_local_ip, - sizeof(get_local_ip)); -#endif - } - - GPR_ASSERT(addr_len < ~(socklen_t)0); - if (bind(fd, addr, (socklen_t)addr_len) < 0) { - char *addr_str; - grpc_sockaddr_to_string(&addr_str, addr, 0); - gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno)); - gpr_free(addr_str); - goto error; - } - - sockname_len = sizeof(sockname_temp); - if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) { - goto error; - } - - return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); - -error: - if (fd >= 0) { - close(fd); - } - return -1; -} - -/* event manager callback when reads are ready */ -static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - server_port *sp = arg; - - if (!success) { - gpr_mu_lock(&sp->server->mu); - if (0 == --sp->server->active_ports) { - gpr_mu_unlock(&sp->server->mu); - deactivated_all_ports(exec_ctx, sp->server); - } else { - gpr_mu_unlock(&sp->server->mu); - } - return; - } - - /* Tell the registered callback that data is available to read. */ - GPR_ASSERT(sp->read_cb); - sp->read_cb(exec_ctx, sp->emfd, sp->server->grpc_server); - - /* Re-arm the notification event so we get another chance to read. */ - grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure); -} - -static int add_socket_to_server(grpc_udp_server *s, int fd, - const struct sockaddr *addr, size_t addr_len, - grpc_udp_server_read_cb read_cb) { - server_port *sp; - int port; - char *addr_str; - char *name; - - port = prepare_socket(fd, addr, addr_len); - if (port >= 0) { - grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1); - gpr_asprintf(&name, "udp-server-listener:%s", addr_str); - gpr_free(addr_str); - gpr_mu_lock(&s->mu); - /* append it to the list under a lock */ - if (s->nports == s->port_capacity) { - s->port_capacity *= 2; - s->ports = gpr_realloc(s->ports, sizeof(server_port) * s->port_capacity); - } - sp = &s->ports[s->nports++]; - sp->server = s; - sp->fd = fd; - sp->emfd = grpc_fd_create(fd, name); - memcpy(sp->addr.untyped, addr, addr_len); - sp->addr_len = addr_len; - sp->read_cb = read_cb; - GPR_ASSERT(sp->emfd); - gpr_mu_unlock(&s->mu); - gpr_free(name); - } - - return port; -} - -int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, - size_t addr_len, grpc_udp_server_read_cb read_cb) { - int allocated_port1 = -1; - int allocated_port2 = -1; - unsigned i; - int fd; - grpc_dualstack_mode dsmode; - struct sockaddr_in6 addr6_v4mapped; - struct sockaddr_in wild4; - struct sockaddr_in6 wild6; - struct sockaddr_in addr4_copy; - struct sockaddr *allocated_addr = NULL; - struct sockaddr_storage sockname_temp; - socklen_t sockname_len; - int port; - - grpc_unlink_if_unix_domain_socket((struct sockaddr *)addr); - - /* Check if this is a wildcard port, and if so, try to keep the port the same - as some previously created listener. */ - if (grpc_sockaddr_get_port(addr) == 0) { - for (i = 0; i < s->nports; i++) { - sockname_len = sizeof(sockname_temp); - if (0 == getsockname(s->ports[i].fd, (struct sockaddr *)&sockname_temp, - &sockname_len)) { - port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); - if (port > 0) { - allocated_addr = malloc(addr_len); - memcpy(allocated_addr, addr, addr_len); - grpc_sockaddr_set_port(allocated_addr, port); - addr = allocated_addr; - break; - } - } - } - } - - if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { - addr = (const struct sockaddr *)&addr6_v4mapped; - addr_len = sizeof(addr6_v4mapped); - } - - /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */ - if (grpc_sockaddr_is_wildcard(addr, &port)) { - grpc_sockaddr_make_wildcards(port, &wild4, &wild6); - - /* Try listening on IPv6 first. */ - addr = (struct sockaddr *)&wild6; - addr_len = sizeof(wild6); - fd = grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode); - allocated_port1 = add_socket_to_server(s, fd, addr, addr_len, read_cb); - if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) { - goto done; - } - - /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */ - if (port == 0 && allocated_port1 > 0) { - grpc_sockaddr_set_port((struct sockaddr *)&wild4, allocated_port1); - } - addr = (struct sockaddr *)&wild4; - addr_len = sizeof(wild4); - } - - fd = grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode); - if (fd < 0) { - gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno)); - } - if (dsmode == GRPC_DSMODE_IPV4 && - grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) { - addr = (struct sockaddr *)&addr4_copy; - addr_len = sizeof(addr4_copy); - } - allocated_port2 = add_socket_to_server(s, fd, addr, addr_len, read_cb); - -done: - gpr_free(allocated_addr); - return allocated_port1 >= 0 ? allocated_port1 : allocated_port2; -} - -int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned port_index) { - return (port_index < s->nports) ? s->ports[port_index].fd : -1; -} - -void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s, - grpc_pollset **pollsets, size_t pollset_count, - grpc_server *server) { - size_t i, j; - gpr_mu_lock(&s->mu); - GPR_ASSERT(s->active_ports == 0); - s->pollsets = pollsets; - s->grpc_server = server; - for (i = 0; i < s->nports; i++) { - for (j = 0; j < pollset_count; j++) { - grpc_pollset_add_fd(exec_ctx, pollsets[j], s->ports[i].emfd); - } - s->ports[i].read_closure.cb = on_read; - s->ports[i].read_closure.cb_arg = &s->ports[i]; - grpc_fd_notify_on_read(exec_ctx, s->ports[i].emfd, - &s->ports[i].read_closure); - s->active_ports++; - } - gpr_mu_unlock(&s->mu); -} - -#endif -#endif diff --git a/src/core/iomgr/udp_server.h b/src/core/iomgr/udp_server.h deleted file mode 100644 index 148c04fa9b..0000000000 --- a/src/core/iomgr/udp_server.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_UDP_SERVER_H -#define GRPC_CORE_IOMGR_UDP_SERVER_H - -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/fd_posix.h" - -/* Forward decl of struct grpc_server */ -/* This is not typedef'ed to avoid a typedef-redefinition error */ -struct grpc_server; - -/* Forward decl of grpc_udp_server */ -typedef struct grpc_udp_server grpc_udp_server; - -/* Called when data is available to read from the socket. */ -typedef void (*grpc_udp_server_read_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, - struct grpc_server *server); - -/* Create a server, initially not bound to any ports */ -grpc_udp_server *grpc_udp_server_create(void); - -/* Start listening to bound ports */ -void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *udp_server, - grpc_pollset **pollsets, size_t pollset_count, - struct grpc_server *server); - -int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned index); - -/* Add a port to the server, returning port number on success, or negative - on failure. - - The :: and 0.0.0.0 wildcard addresses are treated identically, accepting - both IPv4 and IPv6 connections, but :: is the preferred style. This usually - creates one socket, but possibly two on systems which support IPv6, - but not dualstack sockets. */ - -/* TODO(ctiller): deprecate this, and make grpc_udp_server_add_ports to handle - all of the multiple socket port matching logic in one place */ -int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, - size_t addr_len, grpc_udp_server_read_cb read_cb); - -void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *server, - grpc_closure *on_done); - -#endif /* GRPC_CORE_IOMGR_UDP_SERVER_H */ diff --git a/src/core/iomgr/unix_sockets_posix.c b/src/core/iomgr/unix_sockets_posix.c deleted file mode 100644 index 174a7e7abf..0000000000 --- a/src/core/iomgr/unix_sockets_posix.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * - * 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/iomgr/unix_sockets_posix.h" - -#ifdef GPR_HAVE_UNIX_SOCKET - -#include -#include -#include -#include - -#include - -void grpc_create_socketpair_if_unix(int sv[2]) { - GPR_ASSERT(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); -} - -grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char *name) { - struct sockaddr_un *un; - - grpc_resolved_addresses *addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); - addrs->naddrs = 1; - addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address)); - un = (struct sockaddr_un *)addrs->addrs->addr; - un->sun_family = AF_UNIX; - strcpy(un->sun_path, name); - addrs->addrs->len = strlen(un->sun_path) + sizeof(un->sun_family) + 1; - return addrs; -} - -int grpc_is_unix_socket(const struct sockaddr *addr) { - return addr->sa_family == AF_UNIX; -} - -void grpc_unlink_if_unix_domain_socket(const struct sockaddr *addr) { - if (addr->sa_family != AF_UNIX) { - return; - } - struct sockaddr_un *un = (struct sockaddr_un *)addr; - struct stat st; - - if (stat(un->sun_path, &st) == 0 && (st.st_mode & S_IFMT) == S_IFSOCK) { - unlink(un->sun_path); - } -} - -int grpc_parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { - struct sockaddr_un *un = (struct sockaddr_un *)addr; - - un->sun_family = AF_UNIX; - strcpy(un->sun_path, uri->path); - *len = strlen(un->sun_path) + sizeof(un->sun_family) + 1; - - return 1; -} - -char *grpc_unix_get_default_authority(grpc_resolver_factory *factory, - grpc_uri *uri) { - return gpr_strdup("localhost"); -} - -char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr) { - if (addr->sa_family != AF_UNIX) { - return NULL; - } - - char *result; - gpr_asprintf(&result, "unix:%s", ((struct sockaddr_un *)addr)->sun_path); - return result; -} - -#endif diff --git a/src/core/iomgr/unix_sockets_posix.h b/src/core/iomgr/unix_sockets_posix.h deleted file mode 100644 index e842ba3770..0000000000 --- a/src/core/iomgr/unix_sockets_posix.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * 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_IOMGR_UNIX_SOCKETS_POSIX_H -#define GRPC_CORE_IOMGR_UNIX_SOCKETS_POSIX_H - -#include - -#include - -#include "src/core/client_config/resolver_factory.h" -#include "src/core/client_config/uri_parser.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/sockaddr.h" - -void grpc_create_socketpair_if_unix(int sv[2]); - -grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char *name); - -int grpc_is_unix_socket(const struct sockaddr *addr); - -void grpc_unlink_if_unix_domain_socket(const struct sockaddr *addr); - -int grpc_parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len); - -char *grpc_unix_get_default_authority(grpc_resolver_factory *factory, - grpc_uri *uri); - -char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr); - -#endif /* GRPC_CORE_IOMGR_UNIX_SOCKETS_POSIX_H */ diff --git a/src/core/iomgr/unix_sockets_posix_noop.c b/src/core/iomgr/unix_sockets_posix_noop.c deleted file mode 100644 index 045467bea4..0000000000 --- a/src/core/iomgr/unix_sockets_posix_noop.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * 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/iomgr/unix_sockets_posix.h" - -#ifndef GPR_HAVE_UNIX_SOCKET - -void grpc_create_socketpair_if_unix(int sv[2]) {} - -grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char *name) { - return NULL; -} - -int grpc_is_unix_socket(const struct sockaddr *addr) { return false; } - -void grpc_unlink_if_unix_domain_socket(const struct sockaddr *addr) {} - -int grpc_parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { - return 0; -} - -char *grpc_unix_get_default_authority(grpc_resolver_factory *factory, - grpc_uri *uri) { - return NULL; -} - -char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr) { - return NULL; -} - -#endif diff --git a/src/core/iomgr/wakeup_fd_eventfd.c b/src/core/iomgr/wakeup_fd_eventfd.c deleted file mode 100644 index f67379e4fc..0000000000 --- a/src/core/iomgr/wakeup_fd_eventfd.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * Copyright 2015, 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 - -#ifdef GPR_LINUX_EVENTFD - -#include -#include -#include - -#include - -#include "src/core/iomgr/wakeup_fd_posix.h" -#include "src/core/profiling/timers.h" - -static void eventfd_create(grpc_wakeup_fd* fd_info) { - int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); - /* TODO(klempner): Handle failure more gracefully */ - GPR_ASSERT(efd >= 0); - fd_info->read_fd = efd; - fd_info->write_fd = -1; -} - -static void eventfd_consume(grpc_wakeup_fd* fd_info) { - eventfd_t value; - int err; - do { - err = eventfd_read(fd_info->read_fd, &value); - } while (err < 0 && errno == EINTR); -} - -static void eventfd_wakeup(grpc_wakeup_fd* fd_info) { - int err; - GPR_TIMER_BEGIN("eventfd_wakeup", 0); - do { - err = eventfd_write(fd_info->read_fd, 1); - } while (err < 0 && errno == EINTR); - GPR_TIMER_END("eventfd_wakeup", 0); -} - -static void eventfd_destroy(grpc_wakeup_fd* fd_info) { - if (fd_info->read_fd != 0) close(fd_info->read_fd); -} - -static int eventfd_check_availability(void) { - /* TODO(klempner): Actually check if eventfd is available */ - return 1; -} - -const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable = { - eventfd_create, eventfd_consume, eventfd_wakeup, eventfd_destroy, - eventfd_check_availability}; - -#endif /* GPR_LINUX_EVENTFD */ diff --git a/src/core/iomgr/wakeup_fd_nospecial.c b/src/core/iomgr/wakeup_fd_nospecial.c deleted file mode 100644 index 7b2be9ed52..0000000000 --- a/src/core/iomgr/wakeup_fd_nospecial.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* - * This is a dummy file to provide an invalid specialized_wakeup_fd_vtable on - * systems without anything better than pipe. - */ - -#include - -#ifdef GPR_POSIX_NO_SPECIAL_WAKEUP_FD - -#include -#include "src/core/iomgr/wakeup_fd_posix.h" - -static int check_availability_invalid(void) { return 0; } - -const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable = { - NULL, NULL, NULL, NULL, check_availability_invalid}; - -#endif /* GPR_POSIX_NO_SPECIAL_WAKEUP_FD */ diff --git a/src/core/iomgr/wakeup_fd_pipe.c b/src/core/iomgr/wakeup_fd_pipe.c deleted file mode 100644 index dd2fd1f057..0000000000 --- a/src/core/iomgr/wakeup_fd_pipe.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_WAKEUP_FD - -#include "src/core/iomgr/wakeup_fd_posix.h" - -#include -#include -#include - -#include - -#include "src/core/iomgr/socket_utils_posix.h" - -static void pipe_init(grpc_wakeup_fd* fd_info) { - int pipefd[2]; - /* TODO(klempner): Make this nonfatal */ - int r = pipe(pipefd); - if (0 != r) { - gpr_log(GPR_ERROR, "pipe creation failed (%d): %s", errno, strerror(errno)); - abort(); - } - GPR_ASSERT(grpc_set_socket_nonblocking(pipefd[0], 1)); - GPR_ASSERT(grpc_set_socket_nonblocking(pipefd[1], 1)); - fd_info->read_fd = pipefd[0]; - fd_info->write_fd = pipefd[1]; -} - -static void pipe_consume(grpc_wakeup_fd* fd_info) { - char buf[128]; - ssize_t r; - - for (;;) { - r = read(fd_info->read_fd, buf, sizeof(buf)); - if (r > 0) continue; - if (r == 0) return; - switch (errno) { - case EAGAIN: - return; - case EINTR: - continue; - default: - gpr_log(GPR_ERROR, "error reading pipe: %s", strerror(errno)); - return; - } - } -} - -static void pipe_wakeup(grpc_wakeup_fd* fd_info) { - char c = 0; - while (write(fd_info->write_fd, &c, 1) != 1 && errno == EINTR) - ; -} - -static void pipe_destroy(grpc_wakeup_fd* fd_info) { - if (fd_info->read_fd != 0) close(fd_info->read_fd); - if (fd_info->write_fd != 0) close(fd_info->write_fd); -} - -static int pipe_check_availability(void) { - /* Assume that pipes are always available. */ - return 1; -} - -const grpc_wakeup_fd_vtable grpc_pipe_wakeup_fd_vtable = { - pipe_init, pipe_consume, pipe_wakeup, pipe_destroy, - pipe_check_availability}; - -#endif /* GPR_POSIX_WAKUP_FD */ diff --git a/src/core/iomgr/wakeup_fd_pipe.h b/src/core/iomgr/wakeup_fd_pipe.h deleted file mode 100644 index eb3e02b482..0000000000 --- a/src/core/iomgr/wakeup_fd_pipe.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_WAKEUP_FD_PIPE_H -#define GRPC_CORE_IOMGR_WAKEUP_FD_PIPE_H - -#include "src/core/iomgr/wakeup_fd_posix.h" - -extern grpc_wakeup_fd_vtable grpc_pipe_wakeup_fd_vtable; - -#endif /* GRPC_CORE_IOMGR_WAKEUP_FD_PIPE_H */ diff --git a/src/core/iomgr/wakeup_fd_posix.c b/src/core/iomgr/wakeup_fd_posix.c deleted file mode 100644 index 07778c408e..0000000000 --- a/src/core/iomgr/wakeup_fd_posix.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_WAKEUP_FD - -#include -#include "src/core/iomgr/wakeup_fd_pipe.h" -#include "src/core/iomgr/wakeup_fd_posix.h" - -static const grpc_wakeup_fd_vtable *wakeup_fd_vtable = NULL; -int grpc_allow_specialized_wakeup_fd = 1; - -void grpc_wakeup_fd_global_init(void) { - if (grpc_allow_specialized_wakeup_fd && - grpc_specialized_wakeup_fd_vtable.check_availability()) { - wakeup_fd_vtable = &grpc_specialized_wakeup_fd_vtable; - } else { - wakeup_fd_vtable = &grpc_pipe_wakeup_fd_vtable; - } -} - -void grpc_wakeup_fd_global_destroy(void) { wakeup_fd_vtable = NULL; } - -void grpc_wakeup_fd_init(grpc_wakeup_fd *fd_info) { - wakeup_fd_vtable->init(fd_info); -} - -void grpc_wakeup_fd_consume_wakeup(grpc_wakeup_fd *fd_info) { - wakeup_fd_vtable->consume(fd_info); -} - -void grpc_wakeup_fd_wakeup(grpc_wakeup_fd *fd_info) { - wakeup_fd_vtable->wakeup(fd_info); -} - -void grpc_wakeup_fd_destroy(grpc_wakeup_fd *fd_info) { - wakeup_fd_vtable->destroy(fd_info); -} - -#endif /* GPR_POSIX_WAKEUP_FD */ diff --git a/src/core/iomgr/wakeup_fd_posix.h b/src/core/iomgr/wakeup_fd_posix.h deleted file mode 100644 index d7e3cf4673..0000000000 --- a/src/core/iomgr/wakeup_fd_posix.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* - * wakeup_fd abstracts the concept of a file descriptor for the purpose of - * waking up a thread in select()/poll()/epoll_wait()/etc. - - * The poll() family of system calls provide a way for a thread to block until - * there is activity on one (or more) of a set of file descriptors. An - * application may wish to wake up this thread to do non file related work. The - * typical way to do this is to add a pipe to the set of file descriptors, then - * write to the pipe to wake up the thread in poll(). - * - * Linux has a lighter weight eventfd specifically designed for this purpose. - * wakeup_fd abstracts the difference between the two. - * - * Setup: - * 1. Before calling anything, call global_init() at least once. - * 1. Call grpc_wakeup_fd_create() to get a wakeup_fd. - * 2. Add the result of GRPC_WAKEUP_FD_FD to the set of monitored file - * descriptors for the poll() style API you are using. Monitor the file - * descriptor for readability. - * 3. To tear down, call grpc_wakeup_fd_destroy(). This closes the underlying - * file descriptor. - * - * Usage: - * 1. To wake up a polling thread, call grpc_wakeup_fd_wakeup() on a wakeup_fd - * it is monitoring. - * 2. If the polling thread was awakened by a wakeup_fd event, call - * grpc_wakeup_fd_consume_wakeup() on it. - */ -#ifndef GRPC_CORE_IOMGR_WAKEUP_FD_POSIX_H -#define GRPC_CORE_IOMGR_WAKEUP_FD_POSIX_H - -void grpc_wakeup_fd_global_init(void); -void grpc_wakeup_fd_global_destroy(void); - -/* Force using the fallback implementation. This is intended for testing - * purposes only.*/ -void grpc_wakeup_fd_global_init_force_fallback(void); - -typedef struct grpc_wakeup_fd grpc_wakeup_fd; - -typedef struct grpc_wakeup_fd_vtable { - void (*init)(grpc_wakeup_fd* fd_info); - void (*consume)(grpc_wakeup_fd* fd_info); - void (*wakeup)(grpc_wakeup_fd* fd_info); - void (*destroy)(grpc_wakeup_fd* fd_info); - /* Must be called before calling any other functions */ - int (*check_availability)(void); -} grpc_wakeup_fd_vtable; - -struct grpc_wakeup_fd { - int read_fd; - int write_fd; -}; - -extern int grpc_allow_specialized_wakeup_fd; - -#define GRPC_WAKEUP_FD_GET_READ_FD(fd_info) ((fd_info)->read_fd) - -void grpc_wakeup_fd_init(grpc_wakeup_fd* fd_info); -void grpc_wakeup_fd_consume_wakeup(grpc_wakeup_fd* fd_info); -void grpc_wakeup_fd_wakeup(grpc_wakeup_fd* fd_info); -void grpc_wakeup_fd_destroy(grpc_wakeup_fd* fd_info); - -/* Defined in some specialized implementation's .c file, or by - * wakeup_fd_nospecial.c if no such implementation exists. */ -extern const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable; - -#endif /* GRPC_CORE_IOMGR_WAKEUP_FD_POSIX_H */ diff --git a/src/core/iomgr/workqueue.h b/src/core/iomgr/workqueue.h deleted file mode 100644 index 2b923ba152..0000000000 --- a/src/core/iomgr/workqueue.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_WORKQUEUE_H -#define GRPC_CORE_IOMGR_WORKQUEUE_H - -#include "src/core/iomgr/closure.h" -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/iomgr/pollset.h" - -#ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/workqueue_posix.h" -#endif - -#ifdef GPR_WIN32 -#include "src/core/iomgr/workqueue_windows.h" -#endif - -/* grpc_workqueue is forward declared in exec_ctx.h */ - -/** Create a work queue */ -grpc_workqueue *grpc_workqueue_create(grpc_exec_ctx *exec_ctx); - -void grpc_workqueue_flush(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue); - -#define GRPC_WORKQUEUE_REFCOUNT_DEBUG -#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG -#define GRPC_WORKQUEUE_REF(p, r) \ - grpc_workqueue_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_WORKQUEUE_UNREF(cl, p, r) \ - grpc_workqueue_unref((cl), (p), __FILE__, __LINE__, (r)) -void grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, int line, - const char *reason); -void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, - const char *file, int line, const char *reason); -#else -#define GRPC_WORKQUEUE_REF(p, r) grpc_workqueue_ref((p)) -#define GRPC_WORKQUEUE_UNREF(cl, p, r) grpc_workqueue_unref((cl), (p)) -void grpc_workqueue_ref(grpc_workqueue *workqueue); -void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue); -#endif - -/** Bind this workqueue to a pollset */ -void grpc_workqueue_add_to_pollset(grpc_exec_ctx *exec_ctx, - grpc_workqueue *workqueue, - grpc_pollset *pollset); - -/** Add a work item to a workqueue */ -void grpc_workqueue_push(grpc_workqueue *workqueue, grpc_closure *closure, - int success); - -#endif /* GRPC_CORE_IOMGR_WORKQUEUE_H */ diff --git a/src/core/iomgr/workqueue_posix.c b/src/core/iomgr/workqueue_posix.c deleted file mode 100644 index 2b42e6d4fb..0000000000 --- a/src/core/iomgr/workqueue_posix.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_SOCKET - -#include "src/core/iomgr/workqueue.h" - -#include - -#include -#include -#include - -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/pollset_posix.h" - -static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, bool success); - -grpc_workqueue *grpc_workqueue_create(grpc_exec_ctx *exec_ctx) { - char name[32]; - grpc_workqueue *workqueue = gpr_malloc(sizeof(grpc_workqueue)); - gpr_ref_init(&workqueue->refs, 1); - gpr_mu_init(&workqueue->mu); - workqueue->closure_list.head = workqueue->closure_list.tail = NULL; - grpc_wakeup_fd_init(&workqueue->wakeup_fd); - sprintf(name, "workqueue:%p", (void *)workqueue); - workqueue->wakeup_read_fd = - grpc_fd_create(GRPC_WAKEUP_FD_GET_READ_FD(&workqueue->wakeup_fd), name); - grpc_closure_init(&workqueue->read_closure, on_readable, workqueue); - grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, - &workqueue->read_closure); - return workqueue; -} - -static void workqueue_destroy(grpc_exec_ctx *exec_ctx, - grpc_workqueue *workqueue) { - GPR_ASSERT(grpc_closure_list_empty(workqueue->closure_list)); - grpc_fd_shutdown(exec_ctx, workqueue->wakeup_read_fd); -} - -#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG -void grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, int line, - const char *reason) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "WORKQUEUE:%p ref %d -> %d %s", - workqueue, (int)workqueue->refs.count, (int)workqueue->refs.count + 1, - reason); -#else -void grpc_workqueue_ref(grpc_workqueue *workqueue) { -#endif - gpr_ref(&workqueue->refs); -} - -#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG -void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, - const char *file, int line, const char *reason) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "WORKQUEUE:%p unref %d -> %d %s", - workqueue, (int)workqueue->refs.count, (int)workqueue->refs.count - 1, - reason); -#else -void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) { -#endif - if (gpr_unref(&workqueue->refs)) { - workqueue_destroy(exec_ctx, workqueue); - } -} - -void grpc_workqueue_add_to_pollset(grpc_exec_ctx *exec_ctx, - grpc_workqueue *workqueue, - grpc_pollset *pollset) { - grpc_pollset_add_fd(exec_ctx, pollset, workqueue->wakeup_read_fd); -} - -void grpc_workqueue_flush(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) { - gpr_mu_lock(&workqueue->mu); - if (grpc_closure_list_empty(workqueue->closure_list)) { - grpc_wakeup_fd_wakeup(&workqueue->wakeup_fd); - } - grpc_exec_ctx_enqueue_list(exec_ctx, &workqueue->closure_list, NULL); - gpr_mu_unlock(&workqueue->mu); -} - -static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - grpc_workqueue *workqueue = arg; - - if (!success) { - gpr_mu_destroy(&workqueue->mu); - /* HACK: let wakeup_fd code know that we stole the fd */ - workqueue->wakeup_fd.read_fd = 0; - grpc_wakeup_fd_destroy(&workqueue->wakeup_fd); - grpc_fd_orphan(exec_ctx, workqueue->wakeup_read_fd, NULL, NULL, "destroy"); - gpr_free(workqueue); - } else { - gpr_mu_lock(&workqueue->mu); - grpc_exec_ctx_enqueue_list(exec_ctx, &workqueue->closure_list, NULL); - grpc_wakeup_fd_consume_wakeup(&workqueue->wakeup_fd); - gpr_mu_unlock(&workqueue->mu); - grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, - &workqueue->read_closure); - } -} - -void grpc_workqueue_push(grpc_workqueue *workqueue, grpc_closure *closure, - int success) { - gpr_mu_lock(&workqueue->mu); - if (grpc_closure_list_empty(workqueue->closure_list)) { - grpc_wakeup_fd_wakeup(&workqueue->wakeup_fd); - } - grpc_closure_list_add(&workqueue->closure_list, closure, success); - gpr_mu_unlock(&workqueue->mu); -} - -#endif /* GPR_POSIX_SOCKET */ diff --git a/src/core/iomgr/workqueue_posix.h b/src/core/iomgr/workqueue_posix.h deleted file mode 100644 index 89937b1ea8..0000000000 --- a/src/core/iomgr/workqueue_posix.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_WORKQUEUE_POSIX_H -#define GRPC_CORE_IOMGR_WORKQUEUE_POSIX_H - -#include "src/core/iomgr/wakeup_fd_posix.h" - -struct grpc_fd; - -struct grpc_workqueue { - gpr_refcount refs; - - gpr_mu mu; - grpc_closure_list closure_list; - - grpc_wakeup_fd wakeup_fd; - struct grpc_fd *wakeup_read_fd; - - grpc_closure read_closure; -}; - -#endif /* GRPC_CORE_IOMGR_WORKQUEUE_POSIX_H */ diff --git a/src/core/iomgr/workqueue_windows.c b/src/core/iomgr/workqueue_windows.c deleted file mode 100644 index f9ca57557b..0000000000 --- a/src/core/iomgr/workqueue_windows.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * Copyright 2015, 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 - -#ifdef GPR_WIN32 - -#include "src/core/iomgr/workqueue.h" - -#endif /* GPR_WIN32 */ diff --git a/src/core/iomgr/workqueue_windows.h b/src/core/iomgr/workqueue_windows.h deleted file mode 100644 index 7e8186921e..0000000000 --- a/src/core/iomgr/workqueue_windows.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * Copyright 2015-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_IOMGR_WORKQUEUE_WINDOWS_H -#define GRPC_CORE_IOMGR_WORKQUEUE_WINDOWS_H - -#endif /* GRPC_CORE_IOMGR_WORKQUEUE_WINDOWS_H */ diff --git a/src/core/json/json.c b/src/core/json/json.c deleted file mode 100644 index 96e11eebb1..0000000000 --- a/src/core/json/json.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * Copyright 2015, 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 - -#include - -#include "src/core/json/json.h" - -grpc_json *grpc_json_create(grpc_json_type type) { - grpc_json *json = gpr_malloc(sizeof(*json)); - memset(json, 0, sizeof(*json)); - json->type = type; - - return json; -} - -void grpc_json_destroy(grpc_json *json) { - while (json->child) { - grpc_json_destroy(json->child); - } - - if (json->next) { - json->next->prev = json->prev; - } - - if (json->prev) { - json->prev->next = json->next; - } else if (json->parent) { - json->parent->child = json->next; - } - - gpr_free(json); -} diff --git a/src/core/json/json.h b/src/core/json/json.h deleted file mode 100644 index aea9d5dadb..0000000000 --- a/src/core/json/json.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * - * Copyright 2015-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_JSON_JSON_H -#define GRPC_CORE_JSON_JSON_H - -#include - -#include "src/core/json/json_common.h" - -/* A tree-like structure to hold json values. The key and value pointers - * are not owned by it. - */ -typedef struct grpc_json { - struct grpc_json *next; - struct grpc_json *prev; - struct grpc_json *child; - struct grpc_json *parent; - - grpc_json_type type; - const char *key; - const char *value; -} grpc_json; - -/* The next two functions are going to parse the input string, and - * modify it in the process, in order to use its space to store - * all of the keys and values for the returned object tree. - * - * They assume UTF-8 input stream, and will output UTF-8 encoded - * strings in the tree. The input stream's UTF-8 isn't validated, - * as in, what you input is what you get as an output. - * - * All the keys and values in the grpc_json objects will be strings - * pointing at your input buffer. - * - * Delete the allocated tree afterward using grpc_json_destroy(). - */ -grpc_json *grpc_json_parse_string_with_len(char *input, size_t size); -grpc_json *grpc_json_parse_string(char *input); - -/* This function will create a new string using gpr_realloc, and will - * deserialize the grpc_json tree into it. It'll be zero-terminated, - * but will be allocated in chunks of 256 bytes. - * - * The indent parameter controls the way the output is formatted. - * If indent is 0, then newlines will be suppressed as well, and the - * output will be condensed at its maximum. - */ -char *grpc_json_dump_to_string(grpc_json *json, int indent); - -/* Use these to create or delete a grpc_json object. - * Deletion is recursive. We will not attempt to free any of the strings - * in any of the objects of that tree. - */ -grpc_json *grpc_json_create(grpc_json_type type); -void grpc_json_destroy(grpc_json *json); - -#endif /* GRPC_CORE_JSON_JSON_H */ diff --git a/src/core/json/json_common.h b/src/core/json/json_common.h deleted file mode 100644 index 7205a94685..0000000000 --- a/src/core/json/json_common.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright 2015-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_JSON_JSON_COMMON_H -#define GRPC_CORE_JSON_JSON_COMMON_H - -/* The various json types. */ -typedef enum { - GRPC_JSON_OBJECT, - GRPC_JSON_ARRAY, - GRPC_JSON_STRING, - GRPC_JSON_NUMBER, - GRPC_JSON_TRUE, - GRPC_JSON_FALSE, - GRPC_JSON_NULL, - GRPC_JSON_TOP_LEVEL -} grpc_json_type; - -#endif /* GRPC_CORE_JSON_JSON_COMMON_H */ diff --git a/src/core/json/json_reader.c b/src/core/json/json_reader.c deleted file mode 100644 index 30da6f28f3..0000000000 --- a/src/core/json/json_reader.c +++ /dev/null @@ -1,659 +0,0 @@ -/* - * - * Copyright 2015, 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 - -#include - -#include - -#include "src/core/json/json_reader.h" - -static void json_reader_string_clear(grpc_json_reader *reader) { - reader->vtable->string_clear(reader->userdata); -} - -static void json_reader_string_add_char(grpc_json_reader *reader, uint32_t c) { - reader->vtable->string_add_char(reader->userdata, c); -} - -static void json_reader_string_add_utf32(grpc_json_reader *reader, - uint32_t utf32) { - reader->vtable->string_add_utf32(reader->userdata, utf32); -} - -static uint32_t grpc_json_reader_read_char(grpc_json_reader *reader) { - return reader->vtable->read_char(reader->userdata); -} - -static void json_reader_container_begins(grpc_json_reader *reader, - grpc_json_type type) { - reader->vtable->container_begins(reader->userdata, type); -} - -static grpc_json_type grpc_json_reader_container_ends( - grpc_json_reader *reader) { - return reader->vtable->container_ends(reader->userdata); -} - -static void json_reader_set_key(grpc_json_reader *reader) { - reader->vtable->set_key(reader->userdata); -} - -static void json_reader_set_string(grpc_json_reader *reader) { - reader->vtable->set_string(reader->userdata); -} - -static int json_reader_set_number(grpc_json_reader *reader) { - return reader->vtable->set_number(reader->userdata); -} - -static void json_reader_set_true(grpc_json_reader *reader) { - reader->vtable->set_true(reader->userdata); -} - -static void json_reader_set_false(grpc_json_reader *reader) { - reader->vtable->set_false(reader->userdata); -} - -static void json_reader_set_null(grpc_json_reader *reader) { - reader->vtable->set_null(reader->userdata); -} - -/* Call this function to initialize the reader structure. */ -void grpc_json_reader_init(grpc_json_reader *reader, - grpc_json_reader_vtable *vtable, void *userdata) { - memset(reader, 0, sizeof(*reader)); - reader->vtable = vtable; - reader->userdata = userdata; - json_reader_string_clear(reader); - reader->state = GRPC_JSON_STATE_VALUE_BEGIN; -} - -int grpc_json_reader_is_complete(grpc_json_reader *reader) { - return ((reader->depth == 0) && - ((reader->state == GRPC_JSON_STATE_END) || - (reader->state == GRPC_JSON_STATE_VALUE_END))); -} - -grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) { - uint32_t c, success; - - /* This state-machine is a strict implementation of ECMA-404 */ - for (;;) { - c = grpc_json_reader_read_char(reader); - switch (c) { - /* Let's process the error cases first. */ - case GRPC_JSON_READ_CHAR_ERROR: - return GRPC_JSON_READ_ERROR; - - case GRPC_JSON_READ_CHAR_EAGAIN: - return GRPC_JSON_EAGAIN; - - case GRPC_JSON_READ_CHAR_EOF: - if (grpc_json_reader_is_complete(reader)) { - return GRPC_JSON_DONE; - } else { - return GRPC_JSON_PARSE_ERROR; - } - break; - - /* Processing whitespaces. */ - case ' ': - case '\t': - case '\n': - case '\r': - switch (reader->state) { - case GRPC_JSON_STATE_OBJECT_KEY_BEGIN: - case GRPC_JSON_STATE_OBJECT_KEY_END: - case GRPC_JSON_STATE_VALUE_BEGIN: - case GRPC_JSON_STATE_VALUE_END: - case GRPC_JSON_STATE_END: - break; - - case GRPC_JSON_STATE_OBJECT_KEY_STRING: - case GRPC_JSON_STATE_VALUE_STRING: - if (c != ' ') return GRPC_JSON_PARSE_ERROR; - if (reader->unicode_high_surrogate != 0) - return GRPC_JSON_PARSE_ERROR; - json_reader_string_add_char(reader, c); - break; - - case GRPC_JSON_STATE_VALUE_NUMBER: - case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL: - case GRPC_JSON_STATE_VALUE_NUMBER_ZERO: - case GRPC_JSON_STATE_VALUE_NUMBER_EPM: - success = (uint32_t)json_reader_set_number(reader); - if (!success) return GRPC_JSON_PARSE_ERROR; - json_reader_string_clear(reader); - reader->state = GRPC_JSON_STATE_VALUE_END; - break; - - default: - return GRPC_JSON_PARSE_ERROR; - } - break; - - /* Value, object or array terminations. */ - case ',': - case '}': - case ']': - switch (reader->state) { - case GRPC_JSON_STATE_OBJECT_KEY_STRING: - case GRPC_JSON_STATE_VALUE_STRING: - if (reader->unicode_high_surrogate != 0) - return GRPC_JSON_PARSE_ERROR; - json_reader_string_add_char(reader, c); - break; - - case GRPC_JSON_STATE_VALUE_NUMBER: - case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL: - case GRPC_JSON_STATE_VALUE_NUMBER_ZERO: - case GRPC_JSON_STATE_VALUE_NUMBER_EPM: - success = (uint32_t)json_reader_set_number(reader); - if (!success) return GRPC_JSON_PARSE_ERROR; - json_reader_string_clear(reader); - reader->state = GRPC_JSON_STATE_VALUE_END; - /* The missing break here is intentional. */ - - case GRPC_JSON_STATE_VALUE_END: - case GRPC_JSON_STATE_OBJECT_KEY_BEGIN: - case GRPC_JSON_STATE_VALUE_BEGIN: - if (c == ',') { - if (reader->state != GRPC_JSON_STATE_VALUE_END) { - return GRPC_JSON_PARSE_ERROR; - } - if (reader->in_object) { - reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN; - } else { - reader->state = GRPC_JSON_STATE_VALUE_BEGIN; - } - } else { - if (reader->depth-- == 0) return GRPC_JSON_PARSE_ERROR; - if ((c == '}') && !reader->in_object) { - return GRPC_JSON_PARSE_ERROR; - } - if ((c == '}') && - (reader->state == GRPC_JSON_STATE_OBJECT_KEY_BEGIN) && - !reader->container_just_begun) { - return GRPC_JSON_PARSE_ERROR; - } - if ((c == ']') && !reader->in_array) return GRPC_JSON_PARSE_ERROR; - if ((c == ']') && - (reader->state == GRPC_JSON_STATE_VALUE_BEGIN) && - !reader->container_just_begun) { - return GRPC_JSON_PARSE_ERROR; - } - reader->state = GRPC_JSON_STATE_VALUE_END; - switch (grpc_json_reader_container_ends(reader)) { - case GRPC_JSON_OBJECT: - reader->in_object = 1; - reader->in_array = 0; - break; - case GRPC_JSON_ARRAY: - reader->in_object = 0; - reader->in_array = 1; - break; - case GRPC_JSON_TOP_LEVEL: - GPR_ASSERT(reader->depth == 0); - reader->in_object = 0; - reader->in_array = 0; - reader->state = GRPC_JSON_STATE_END; - break; - default: - GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR); - } - } - break; - - default: - return GRPC_JSON_PARSE_ERROR; - } - break; - - /* In-string escaping. */ - case '\\': - switch (reader->state) { - case GRPC_JSON_STATE_OBJECT_KEY_STRING: - reader->escaped_string_was_key = 1; - reader->state = GRPC_JSON_STATE_STRING_ESCAPE; - break; - - case GRPC_JSON_STATE_VALUE_STRING: - reader->escaped_string_was_key = 0; - reader->state = GRPC_JSON_STATE_STRING_ESCAPE; - break; - - /* This is the \\ case. */ - case GRPC_JSON_STATE_STRING_ESCAPE: - if (reader->unicode_high_surrogate != 0) - return GRPC_JSON_PARSE_ERROR; - json_reader_string_add_char(reader, '\\'); - if (reader->escaped_string_was_key) { - reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; - } else { - reader->state = GRPC_JSON_STATE_VALUE_STRING; - } - break; - - default: - return GRPC_JSON_PARSE_ERROR; - } - break; - - default: - reader->container_just_begun = 0; - switch (reader->state) { - case GRPC_JSON_STATE_OBJECT_KEY_BEGIN: - if (c != '"') return GRPC_JSON_PARSE_ERROR; - reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; - break; - - case GRPC_JSON_STATE_OBJECT_KEY_STRING: - GPR_ASSERT(reader->unicode_high_surrogate == 0); - if (c == '"') { - reader->state = GRPC_JSON_STATE_OBJECT_KEY_END; - json_reader_set_key(reader); - json_reader_string_clear(reader); - } else { - if (c <= 0x001f) return GRPC_JSON_PARSE_ERROR; - json_reader_string_add_char(reader, c); - } - break; - - case GRPC_JSON_STATE_VALUE_STRING: - if (reader->unicode_high_surrogate != 0) - return GRPC_JSON_PARSE_ERROR; - if (c == '"') { - reader->state = GRPC_JSON_STATE_VALUE_END; - json_reader_set_string(reader); - json_reader_string_clear(reader); - } else { - if (c < 32) return GRPC_JSON_PARSE_ERROR; - json_reader_string_add_char(reader, c); - } - break; - - case GRPC_JSON_STATE_OBJECT_KEY_END: - if (c != ':') return GRPC_JSON_PARSE_ERROR; - reader->state = GRPC_JSON_STATE_VALUE_BEGIN; - break; - - case GRPC_JSON_STATE_VALUE_BEGIN: - switch (c) { - case 't': - reader->state = GRPC_JSON_STATE_VALUE_TRUE_R; - break; - - case 'f': - reader->state = GRPC_JSON_STATE_VALUE_FALSE_A; - break; - - case 'n': - reader->state = GRPC_JSON_STATE_VALUE_NULL_U; - break; - - case '"': - reader->state = GRPC_JSON_STATE_VALUE_STRING; - break; - - case '0': - json_reader_string_add_char(reader, c); - reader->state = GRPC_JSON_STATE_VALUE_NUMBER_ZERO; - break; - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - json_reader_string_add_char(reader, c); - reader->state = GRPC_JSON_STATE_VALUE_NUMBER; - break; - - case '{': - reader->container_just_begun = 1; - json_reader_container_begins(reader, GRPC_JSON_OBJECT); - reader->depth++; - reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN; - reader->in_object = 1; - reader->in_array = 0; - break; - - case '[': - reader->container_just_begun = 1; - json_reader_container_begins(reader, GRPC_JSON_ARRAY); - reader->depth++; - reader->in_object = 0; - reader->in_array = 1; - break; - } - break; - - case GRPC_JSON_STATE_STRING_ESCAPE: - if (reader->escaped_string_was_key) { - reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; - } else { - reader->state = GRPC_JSON_STATE_VALUE_STRING; - } - if (reader->unicode_high_surrogate && c != 'u') - return GRPC_JSON_PARSE_ERROR; - switch (c) { - case '"': - case '/': - json_reader_string_add_char(reader, c); - break; - case 'b': - json_reader_string_add_char(reader, '\b'); - break; - case 'f': - json_reader_string_add_char(reader, '\f'); - break; - case 'n': - json_reader_string_add_char(reader, '\n'); - break; - case 'r': - json_reader_string_add_char(reader, '\r'); - break; - case 't': - json_reader_string_add_char(reader, '\t'); - break; - case 'u': - reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U1; - reader->unicode_char = 0; - break; - default: - return GRPC_JSON_PARSE_ERROR; - } - break; - - case GRPC_JSON_STATE_STRING_ESCAPE_U1: - case GRPC_JSON_STATE_STRING_ESCAPE_U2: - case GRPC_JSON_STATE_STRING_ESCAPE_U3: - case GRPC_JSON_STATE_STRING_ESCAPE_U4: - if ((c >= '0') && (c <= '9')) { - c -= '0'; - } else if ((c >= 'A') && (c <= 'F')) { - c -= 'A' - 10; - } else if ((c >= 'a') && (c <= 'f')) { - c -= 'a' - 10; - } else { - return GRPC_JSON_PARSE_ERROR; - } - reader->unicode_char = (uint16_t)(reader->unicode_char << 4); - reader->unicode_char = (uint16_t)(reader->unicode_char | c); - - switch (reader->state) { - case GRPC_JSON_STATE_STRING_ESCAPE_U1: - reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U2; - break; - case GRPC_JSON_STATE_STRING_ESCAPE_U2: - reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U3; - break; - case GRPC_JSON_STATE_STRING_ESCAPE_U3: - reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U4; - break; - case GRPC_JSON_STATE_STRING_ESCAPE_U4: - /* See grpc_json_writer_escape_string to have a description - * of what's going on here. - */ - if ((reader->unicode_char & 0xfc00) == 0xd800) { - /* high surrogate utf-16 */ - if (reader->unicode_high_surrogate != 0) - return GRPC_JSON_PARSE_ERROR; - reader->unicode_high_surrogate = reader->unicode_char; - } else if ((reader->unicode_char & 0xfc00) == 0xdc00) { - /* low surrogate utf-16 */ - uint32_t utf32; - if (reader->unicode_high_surrogate == 0) - return GRPC_JSON_PARSE_ERROR; - utf32 = 0x10000; - utf32 += (uint32_t)( - (reader->unicode_high_surrogate - 0xd800) * 0x400); - utf32 += (uint32_t)(reader->unicode_char - 0xdc00); - json_reader_string_add_utf32(reader, utf32); - reader->unicode_high_surrogate = 0; - } else { - /* anything else */ - if (reader->unicode_high_surrogate != 0) - return GRPC_JSON_PARSE_ERROR; - json_reader_string_add_utf32(reader, reader->unicode_char); - } - if (reader->escaped_string_was_key) { - reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; - } else { - reader->state = GRPC_JSON_STATE_VALUE_STRING; - } - break; - default: - GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR); - } - break; - - case GRPC_JSON_STATE_VALUE_NUMBER: - json_reader_string_add_char(reader, c); - switch (c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - break; - case 'e': - case 'E': - reader->state = GRPC_JSON_STATE_VALUE_NUMBER_E; - break; - case '.': - reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT; - break; - default: - return GRPC_JSON_PARSE_ERROR; - } - break; - - case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL: - json_reader_string_add_char(reader, c); - switch (c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - break; - case 'e': - case 'E': - reader->state = GRPC_JSON_STATE_VALUE_NUMBER_E; - break; - default: - return GRPC_JSON_PARSE_ERROR; - } - break; - - case GRPC_JSON_STATE_VALUE_NUMBER_ZERO: - if (c != '.') return GRPC_JSON_PARSE_ERROR; - json_reader_string_add_char(reader, c); - reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT; - break; - - case GRPC_JSON_STATE_VALUE_NUMBER_DOT: - json_reader_string_add_char(reader, c); - switch (c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - reader->state = GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL; - break; - default: - return GRPC_JSON_PARSE_ERROR; - } - break; - - case GRPC_JSON_STATE_VALUE_NUMBER_E: - json_reader_string_add_char(reader, c); - switch (c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '+': - case '-': - reader->state = GRPC_JSON_STATE_VALUE_NUMBER_EPM; - break; - default: - return GRPC_JSON_PARSE_ERROR; - } - break; - - case GRPC_JSON_STATE_VALUE_NUMBER_EPM: - json_reader_string_add_char(reader, c); - switch (c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - break; - default: - return GRPC_JSON_PARSE_ERROR; - } - break; - - case GRPC_JSON_STATE_VALUE_TRUE_R: - if (c != 'r') return GRPC_JSON_PARSE_ERROR; - reader->state = GRPC_JSON_STATE_VALUE_TRUE_U; - break; - - case GRPC_JSON_STATE_VALUE_TRUE_U: - if (c != 'u') return GRPC_JSON_PARSE_ERROR; - reader->state = GRPC_JSON_STATE_VALUE_TRUE_E; - break; - - case GRPC_JSON_STATE_VALUE_TRUE_E: - if (c != 'e') return GRPC_JSON_PARSE_ERROR; - json_reader_set_true(reader); - reader->state = GRPC_JSON_STATE_VALUE_END; - break; - - case GRPC_JSON_STATE_VALUE_FALSE_A: - if (c != 'a') return GRPC_JSON_PARSE_ERROR; - reader->state = GRPC_JSON_STATE_VALUE_FALSE_L; - break; - - case GRPC_JSON_STATE_VALUE_FALSE_L: - if (c != 'l') return GRPC_JSON_PARSE_ERROR; - reader->state = GRPC_JSON_STATE_VALUE_FALSE_S; - break; - - case GRPC_JSON_STATE_VALUE_FALSE_S: - if (c != 's') return GRPC_JSON_PARSE_ERROR; - reader->state = GRPC_JSON_STATE_VALUE_FALSE_E; - break; - - case GRPC_JSON_STATE_VALUE_FALSE_E: - if (c != 'e') return GRPC_JSON_PARSE_ERROR; - json_reader_set_false(reader); - reader->state = GRPC_JSON_STATE_VALUE_END; - break; - - case GRPC_JSON_STATE_VALUE_NULL_U: - if (c != 'u') return GRPC_JSON_PARSE_ERROR; - reader->state = GRPC_JSON_STATE_VALUE_NULL_L1; - break; - - case GRPC_JSON_STATE_VALUE_NULL_L1: - if (c != 'l') return GRPC_JSON_PARSE_ERROR; - reader->state = GRPC_JSON_STATE_VALUE_NULL_L2; - break; - - case GRPC_JSON_STATE_VALUE_NULL_L2: - if (c != 'l') return GRPC_JSON_PARSE_ERROR; - json_reader_set_null(reader); - reader->state = GRPC_JSON_STATE_VALUE_END; - break; - - /* All of the VALUE_END cases are handled in the specialized case - * above. */ - case GRPC_JSON_STATE_VALUE_END: - switch (c) { - case ',': - case '}': - case ']': - GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR); - break; - - default: - return GRPC_JSON_PARSE_ERROR; - } - break; - - case GRPC_JSON_STATE_END: - return GRPC_JSON_PARSE_ERROR; - } - } - } - - GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR); -} diff --git a/src/core/json/json_reader.h b/src/core/json/json_reader.h deleted file mode 100644 index f25f44b2ef..0000000000 --- a/src/core/json/json_reader.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * - * Copyright 2015-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_JSON_JSON_READER_H -#define GRPC_CORE_JSON_JSON_READER_H - -#include -#include "src/core/json/json_common.h" - -typedef enum { - GRPC_JSON_STATE_OBJECT_KEY_BEGIN, - GRPC_JSON_STATE_OBJECT_KEY_STRING, - GRPC_JSON_STATE_OBJECT_KEY_END, - GRPC_JSON_STATE_VALUE_BEGIN, - GRPC_JSON_STATE_VALUE_STRING, - GRPC_JSON_STATE_STRING_ESCAPE, - GRPC_JSON_STATE_STRING_ESCAPE_U1, - GRPC_JSON_STATE_STRING_ESCAPE_U2, - GRPC_JSON_STATE_STRING_ESCAPE_U3, - GRPC_JSON_STATE_STRING_ESCAPE_U4, - GRPC_JSON_STATE_VALUE_NUMBER, - GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL, - GRPC_JSON_STATE_VALUE_NUMBER_ZERO, - GRPC_JSON_STATE_VALUE_NUMBER_DOT, - GRPC_JSON_STATE_VALUE_NUMBER_E, - GRPC_JSON_STATE_VALUE_NUMBER_EPM, - GRPC_JSON_STATE_VALUE_TRUE_R, - GRPC_JSON_STATE_VALUE_TRUE_U, - GRPC_JSON_STATE_VALUE_TRUE_E, - GRPC_JSON_STATE_VALUE_FALSE_A, - GRPC_JSON_STATE_VALUE_FALSE_L, - GRPC_JSON_STATE_VALUE_FALSE_S, - GRPC_JSON_STATE_VALUE_FALSE_E, - GRPC_JSON_STATE_VALUE_NULL_U, - GRPC_JSON_STATE_VALUE_NULL_L1, - GRPC_JSON_STATE_VALUE_NULL_L2, - GRPC_JSON_STATE_VALUE_END, - GRPC_JSON_STATE_END -} grpc_json_reader_state; - -enum { - /* The first non-unicode value is 0x110000. But let's pick - * a value high enough to start our error codes from. These - * values are safe to return from the read_char function. - */ - GRPC_JSON_READ_CHAR_EOF = 0x7ffffff0, - GRPC_JSON_READ_CHAR_EAGAIN, - GRPC_JSON_READ_CHAR_ERROR -}; - -struct grpc_json_reader; - -typedef struct grpc_json_reader_vtable { - /* Clears your internal string scratchpad. */ - void (*string_clear)(void *userdata); - /* Adds a char to the string scratchpad. */ - void (*string_add_char)(void *userdata, uint32_t c); - /* Adds a utf32 char to the string scratchpad. */ - void (*string_add_utf32)(void *userdata, uint32_t c); - /* Reads a character from your input. May be utf-8, 16 or 32. */ - uint32_t (*read_char)(void *userdata); - /* Starts a container of type GRPC_JSON_ARRAY or GRPC_JSON_OBJECT. */ - void (*container_begins)(void *userdata, grpc_json_type type); - /* Ends the current container. Must return the type of its parent. */ - grpc_json_type (*container_ends)(void *userdata); - /* Your internal string scratchpad is an object's key. */ - void (*set_key)(void *userdata); - /* Your internal string scratchpad is a string value. */ - void (*set_string)(void *userdata); - /* Your internal string scratchpad is a numerical value. Return 1 if valid. */ - int (*set_number)(void *userdata); - /* Sets the values true, false or null. */ - void (*set_true)(void *userdata); - void (*set_false)(void *userdata); - void (*set_null)(void *userdata); -} grpc_json_reader_vtable; - -typedef struct grpc_json_reader { - /* That structure is fully private, and initialized by grpc_json_reader_init. - * The definition is public so you can put it on your stack. - */ - - void *userdata; - grpc_json_reader_vtable *vtable; - int depth; - int in_object; - int in_array; - int escaped_string_was_key; - int container_just_begun; - uint16_t unicode_char, unicode_high_surrogate; - grpc_json_reader_state state; -} grpc_json_reader; - -/* The return type of the parser. */ -typedef enum { - GRPC_JSON_DONE, /* The parser finished successfully. */ - GRPC_JSON_EAGAIN, /* The parser yields to get more data. */ - GRPC_JSON_READ_ERROR, /* The parser passes through a read error. */ - GRPC_JSON_PARSE_ERROR, /* The parser found an error in the json stream. */ - GRPC_JSON_INTERNAL_ERROR /* The parser got an internal error. */ -} grpc_json_reader_status; - -/* Call this function to start parsing the input. It will return the following: - * . GRPC_JSON_DONE if the input got eof, and the parsing finished - * successfully. - * . GRPC_JSON_EAGAIN if the read_char function returned again. Call the - * parser again as needed. It is okay to call the parser in polling mode, - * although a bit dull. - * . GRPC_JSON_READ_ERROR if the read_char function returned an error. The - * state isn't broken however, and the function can be called again if the - * error has been corrected. But please use the EAGAIN feature instead for - * consistency. - * . GRPC_JSON_PARSE_ERROR if the input was somehow invalid. - * . GRPC_JSON_INTERNAL_ERROR if the parser somehow ended into an invalid - * internal state. - */ -grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader); - -/* Call this function to initialize the reader structure. */ -void grpc_json_reader_init(grpc_json_reader *reader, - grpc_json_reader_vtable *vtable, void *userdata); - -/* You may call this from the read_char callback if you don't know where is the - * end of your input stream, and you'd like the json reader to hint you that it - * has completed reading its input, so you can return an EOF to it. Note that - * there might still be trailing whitespaces after that point. - */ -int grpc_json_reader_is_complete(grpc_json_reader *reader); - -#endif /* GRPC_CORE_JSON_JSON_READER_H */ diff --git a/src/core/json/json_string.c b/src/core/json/json_string.c deleted file mode 100644 index d4ebce18e1..0000000000 --- a/src/core/json/json_string.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * - * Copyright 2015-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 -#include - -#include -#include - -#include "src/core/json/json.h" -#include "src/core/json/json_reader.h" -#include "src/core/json/json_writer.h" - -/* The json reader will construct a bunch of grpc_json objects and - * link them all up together in a tree-like structure that will represent - * the json data in memory. - * - * It also uses its own input as a scratchpad to store all of the decoded, - * unescaped strings. So we need to keep track of all these pointers in - * that opaque structure the reader will carry for us. - * - * Note that this works because the act of parsing json always reduces its - * input size, and never expands it. - */ -typedef struct { - grpc_json *top; - grpc_json *current_container; - grpc_json *current_value; - uint8_t *input; - uint8_t *key; - uint8_t *string; - uint8_t *string_ptr; - size_t remaining_input; -} json_reader_userdata; - -/* This json writer will put everything in a big string. - * The point is that we allocate that string in chunks of 256 bytes. - */ -typedef struct { - char *output; - size_t free_space; - size_t string_len; - size_t allocated; -} json_writer_userdata; - -/* This function checks if there's enough space left in the output buffer, - * and will enlarge it if necessary. We're only allocating chunks of 256 - * bytes at a time (or multiples thereof). - */ -static void json_writer_output_check(void *userdata, size_t needed) { - json_writer_userdata *state = userdata; - if (state->free_space >= needed) return; - needed -= state->free_space; - /* Round up by 256 bytes. */ - needed = (needed + 0xff) & ~0xffU; - state->output = gpr_realloc(state->output, state->allocated + needed); - state->free_space += needed; - state->allocated += needed; -} - -/* These are needed by the writer's implementation. */ -static void json_writer_output_char(void *userdata, char c) { - json_writer_userdata *state = userdata; - json_writer_output_check(userdata, 1); - state->output[state->string_len++] = c; - state->free_space--; -} - -static void json_writer_output_string_with_len(void *userdata, const char *str, - size_t len) { - json_writer_userdata *state = userdata; - json_writer_output_check(userdata, len); - memcpy(state->output + state->string_len, str, len); - state->string_len += len; - state->free_space -= len; -} - -static void json_writer_output_string(void *userdata, const char *str) { - size_t len = strlen(str); - json_writer_output_string_with_len(userdata, str, len); -} - -/* The reader asks us to clear our scratchpad. In our case, we'll simply mark - * the end of the current string, and advance our output pointer. - */ -static void json_reader_string_clear(void *userdata) { - json_reader_userdata *state = userdata; - if (state->string) { - GPR_ASSERT(state->string_ptr < state->input); - *state->string_ptr++ = 0; - } - state->string = state->string_ptr; -} - -static void json_reader_string_add_char(void *userdata, uint32_t c) { - json_reader_userdata *state = userdata; - GPR_ASSERT(state->string_ptr < state->input); - GPR_ASSERT(c <= 0xff); - *state->string_ptr++ = (uint8_t)c; -} - -/* We are converting a UTF-32 character into UTF-8 here, - * as described by RFC3629. - */ -static void json_reader_string_add_utf32(void *userdata, uint32_t c) { - if (c <= 0x7f) { - json_reader_string_add_char(userdata, c); - } else if (c <= 0x7ff) { - uint32_t b1 = 0xc0 | ((c >> 6) & 0x1f); - uint32_t b2 = 0x80 | (c & 0x3f); - json_reader_string_add_char(userdata, b1); - json_reader_string_add_char(userdata, b2); - } else if (c <= 0xffff) { - uint32_t b1 = 0xe0 | ((c >> 12) & 0x0f); - uint32_t b2 = 0x80 | ((c >> 6) & 0x3f); - uint32_t b3 = 0x80 | (c & 0x3f); - json_reader_string_add_char(userdata, b1); - json_reader_string_add_char(userdata, b2); - json_reader_string_add_char(userdata, b3); - } else if (c <= 0x1fffff) { - uint32_t b1 = 0xf0 | ((c >> 18) & 0x07); - uint32_t b2 = 0x80 | ((c >> 12) & 0x3f); - uint32_t b3 = 0x80 | ((c >> 6) & 0x3f); - uint32_t b4 = 0x80 | (c & 0x3f); - json_reader_string_add_char(userdata, b1); - json_reader_string_add_char(userdata, b2); - json_reader_string_add_char(userdata, b3); - json_reader_string_add_char(userdata, b4); - } -} - -/* We consider that the input may be a zero-terminated string. So we - * can end up hitting eof before the end of the alleged string length. - */ -static uint32_t json_reader_read_char(void *userdata) { - uint32_t r; - json_reader_userdata *state = userdata; - - if (state->remaining_input == 0) return GRPC_JSON_READ_CHAR_EOF; - - r = *state->input++; - state->remaining_input--; - - if (r == 0) { - state->remaining_input = 0; - return GRPC_JSON_READ_CHAR_EOF; - } - - return r; -} - -/* Helper function to create a new grpc_json object and link it into - * our tree-in-progress inside our opaque structure. - */ -static grpc_json *json_create_and_link(void *userdata, grpc_json_type type) { - json_reader_userdata *state = userdata; - grpc_json *json = grpc_json_create(type); - - json->parent = state->current_container; - json->prev = state->current_value; - state->current_value = json; - - if (json->prev) { - json->prev->next = json; - } - if (json->parent) { - if (!json->parent->child) { - json->parent->child = json; - } - if (json->parent->type == GRPC_JSON_OBJECT) { - json->key = (char *)state->key; - } - } - if (!state->top) { - state->top = json; - } - - return json; -} - -static void json_reader_container_begins(void *userdata, grpc_json_type type) { - json_reader_userdata *state = userdata; - grpc_json *container; - - GPR_ASSERT(type == GRPC_JSON_ARRAY || type == GRPC_JSON_OBJECT); - - container = json_create_and_link(userdata, type); - state->current_container = container; - state->current_value = NULL; -} - -/* It's important to remember that the reader is mostly stateless, so it - * isn't trying to remember what the container was prior the one that just - * ends. Since we're keeping track of these for our own purpose, we are - * able to return that information back, which is useful for it to validate - * the input json stream. - * - * Also note that if we're at the top of the tree, and the last container - * ends, we have to return GRPC_JSON_TOP_LEVEL. - */ -static grpc_json_type json_reader_container_ends(void *userdata) { - grpc_json_type container_type = GRPC_JSON_TOP_LEVEL; - json_reader_userdata *state = userdata; - - GPR_ASSERT(state->current_container); - - state->current_value = state->current_container; - state->current_container = state->current_container->parent; - - if (state->current_container) { - container_type = state->current_container->type; - } - - return container_type; -} - -/* The next 3 functions basically are the reader asking us to use our string - * scratchpad for one of these 3 purposes. - * - * Note that in the set_number case, we're not going to try interpreting it. - * We'll keep it as a string, and leave it to the caller to evaluate it. - */ -static void json_reader_set_key(void *userdata) { - json_reader_userdata *state = userdata; - state->key = state->string; -} - -static void json_reader_set_string(void *userdata) { - json_reader_userdata *state = userdata; - grpc_json *json = json_create_and_link(userdata, GRPC_JSON_STRING); - json->value = (char *)state->string; -} - -static int json_reader_set_number(void *userdata) { - json_reader_userdata *state = userdata; - grpc_json *json = json_create_and_link(userdata, GRPC_JSON_NUMBER); - json->value = (char *)state->string; - return 1; -} - -/* The object types true, false and null are self-sufficient, and don't need - * any more information beside their type. - */ -static void json_reader_set_true(void *userdata) { - json_create_and_link(userdata, GRPC_JSON_TRUE); -} - -static void json_reader_set_false(void *userdata) { - json_create_and_link(userdata, GRPC_JSON_FALSE); -} - -static void json_reader_set_null(void *userdata) { - json_create_and_link(userdata, GRPC_JSON_NULL); -} - -static grpc_json_reader_vtable reader_vtable = { - json_reader_string_clear, json_reader_string_add_char, - json_reader_string_add_utf32, json_reader_read_char, - json_reader_container_begins, json_reader_container_ends, - json_reader_set_key, json_reader_set_string, - json_reader_set_number, json_reader_set_true, - json_reader_set_false, json_reader_set_null}; - -/* And finally, let's define our public API. */ -grpc_json *grpc_json_parse_string_with_len(char *input, size_t size) { - grpc_json_reader reader; - json_reader_userdata state; - grpc_json *json = NULL; - grpc_json_reader_status status; - - if (!input) return NULL; - - state.top = state.current_container = state.current_value = NULL; - state.string = state.key = NULL; - state.string_ptr = state.input = (uint8_t *)input; - state.remaining_input = size; - grpc_json_reader_init(&reader, &reader_vtable, &state); - - status = grpc_json_reader_run(&reader); - json = state.top; - - if ((status != GRPC_JSON_DONE) && json) { - grpc_json_destroy(json); - json = NULL; - } - - return json; -} - -#define UNBOUND_JSON_STRING_LENGTH 0x7fffffff - -grpc_json *grpc_json_parse_string(char *input) { - return grpc_json_parse_string_with_len(input, UNBOUND_JSON_STRING_LENGTH); -} - -static void json_dump_recursive(grpc_json_writer *writer, grpc_json *json, - int in_object) { - while (json) { - if (in_object) grpc_json_writer_object_key(writer, json->key); - - switch (json->type) { - case GRPC_JSON_OBJECT: - case GRPC_JSON_ARRAY: - grpc_json_writer_container_begins(writer, json->type); - if (json->child) - json_dump_recursive(writer, json->child, - json->type == GRPC_JSON_OBJECT); - grpc_json_writer_container_ends(writer, json->type); - break; - case GRPC_JSON_STRING: - grpc_json_writer_value_string(writer, json->value); - break; - case GRPC_JSON_NUMBER: - grpc_json_writer_value_raw(writer, json->value); - break; - case GRPC_JSON_TRUE: - grpc_json_writer_value_raw_with_len(writer, "true", 4); - break; - case GRPC_JSON_FALSE: - grpc_json_writer_value_raw_with_len(writer, "false", 5); - break; - case GRPC_JSON_NULL: - grpc_json_writer_value_raw_with_len(writer, "null", 4); - break; - default: - GPR_UNREACHABLE_CODE(abort()); - } - json = json->next; - } -} - -static grpc_json_writer_vtable writer_vtable = { - json_writer_output_char, json_writer_output_string, - json_writer_output_string_with_len}; - -char *grpc_json_dump_to_string(grpc_json *json, int indent) { - grpc_json_writer writer; - json_writer_userdata state; - - state.output = NULL; - state.free_space = state.string_len = state.allocated = 0; - grpc_json_writer_init(&writer, indent, &writer_vtable, &state); - - json_dump_recursive(&writer, json, 0); - - json_writer_output_char(&state, 0); - - return state.output; -} diff --git a/src/core/json/json_writer.c b/src/core/json/json_writer.c deleted file mode 100644 index 326ec2d431..0000000000 --- a/src/core/json/json_writer.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * - * Copyright 2015, 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 - -#include - -#include "src/core/json/json_writer.h" - -static void json_writer_output_char(grpc_json_writer *writer, char c) { - writer->vtable->output_char(writer->userdata, c); -} - -static void json_writer_output_string(grpc_json_writer *writer, - const char *str) { - writer->vtable->output_string(writer->userdata, str); -} - -static void json_writer_output_string_with_len(grpc_json_writer *writer, - const char *str, size_t len) { - writer->vtable->output_string_with_len(writer->userdata, str, len); -} - -void grpc_json_writer_init(grpc_json_writer *writer, int indent, - grpc_json_writer_vtable *vtable, void *userdata) { - memset(writer, 0, sizeof(*writer)); - writer->container_empty = 1; - writer->indent = indent; - writer->vtable = vtable; - writer->userdata = userdata; -} - -static void json_writer_output_indent(grpc_json_writer *writer) { - static const char spacesstr[] = - " " - " " - " " - " "; - - unsigned spaces = (unsigned)(writer->depth * writer->indent); - - if (writer->indent == 0) return; - - if (writer->got_key) { - json_writer_output_char(writer, ' '); - return; - } - - while (spaces >= (sizeof(spacesstr) - 1)) { - json_writer_output_string_with_len(writer, spacesstr, - sizeof(spacesstr) - 1); - spaces -= (unsigned)(sizeof(spacesstr) - 1); - } - - if (spaces == 0) return; - - json_writer_output_string_with_len( - writer, spacesstr + sizeof(spacesstr) - 1 - spaces, spaces); -} - -static void json_writer_value_end(grpc_json_writer *writer) { - if (writer->container_empty) { - writer->container_empty = 0; - if ((writer->indent == 0) || (writer->depth == 0)) return; - json_writer_output_char(writer, '\n'); - } else { - json_writer_output_char(writer, ','); - if (writer->indent == 0) return; - json_writer_output_char(writer, '\n'); - } -} - -static void json_writer_escape_utf16(grpc_json_writer *writer, uint16_t utf16) { - static const char hex[] = "0123456789abcdef"; - - json_writer_output_string_with_len(writer, "\\u", 2); - json_writer_output_char(writer, hex[(utf16 >> 12) & 0x0f]); - json_writer_output_char(writer, hex[(utf16 >> 8) & 0x0f]); - json_writer_output_char(writer, hex[(utf16 >> 4) & 0x0f]); - json_writer_output_char(writer, hex[(utf16)&0x0f]); -} - -static void json_writer_escape_string(grpc_json_writer *writer, - const char *string) { - json_writer_output_char(writer, '"'); - - for (;;) { - uint8_t c = (uint8_t)*string++; - if (c == 0) { - break; - } else if ((c >= 32) && (c <= 126)) { - if ((c == '\\') || (c == '"')) json_writer_output_char(writer, '\\'); - json_writer_output_char(writer, (char)c); - } else if ((c < 32) || (c == 127)) { - switch (c) { - case '\b': - json_writer_output_string_with_len(writer, "\\b", 2); - break; - case '\f': - json_writer_output_string_with_len(writer, "\\f", 2); - break; - case '\n': - json_writer_output_string_with_len(writer, "\\n", 2); - break; - case '\r': - json_writer_output_string_with_len(writer, "\\r", 2); - break; - case '\t': - json_writer_output_string_with_len(writer, "\\t", 2); - break; - default: - json_writer_escape_utf16(writer, c); - break; - } - } else { - uint32_t utf32 = 0; - int extra = 0; - int i; - int valid = 1; - if ((c & 0xe0) == 0xc0) { - utf32 = c & 0x1f; - extra = 1; - } else if ((c & 0xf0) == 0xe0) { - utf32 = c & 0x0f; - extra = 2; - } else if ((c & 0xf8) == 0xf0) { - utf32 = c & 0x07; - extra = 3; - } else { - break; - } - for (i = 0; i < extra; i++) { - utf32 <<= 6; - c = (uint8_t)(*string++); - /* Breaks out and bail on any invalid UTF-8 sequence, including \0. */ - if ((c & 0xc0) != 0x80) { - valid = 0; - break; - } - utf32 |= c & 0x3f; - } - if (!valid) break; - /* The range 0xd800 - 0xdfff is reserved by the surrogates ad vitam. - * Any other range is technically reserved for future usage, so if we - * don't want the software to break in the future, we have to allow - * anything else. The first non-unicode character is 0x110000. */ - if (((utf32 >= 0xd800) && (utf32 <= 0xdfff)) || (utf32 >= 0x110000)) - break; - if (utf32 >= 0x10000) { - /* If utf32 contains a character that is above 0xffff, it needs to be - * broken down into a utf-16 surrogate pair. A surrogate pair is first - * a high surrogate, followed by a low surrogate. Each surrogate holds - * 10 bits of usable data, thus allowing a total of 20 bits of data. - * The high surrogate marker is 0xd800, while the low surrogate marker - * is 0xdc00. The low 10 bits of each will be the usable data. - * - * After re-combining the 20 bits of data, one has to add 0x10000 to - * the resulting value, in order to obtain the original character. - * This is obviously because the range 0x0000 - 0xffff can be written - * without any special trick. - * - * Since 0x10ffff is the highest allowed character, we're working in - * the range 0x00000 - 0xfffff after we decrement it by 0x10000. - * That range is exactly 20 bits. - */ - utf32 -= 0x10000; - json_writer_escape_utf16(writer, (uint16_t)(0xd800 | (utf32 >> 10))); - json_writer_escape_utf16(writer, (uint16_t)(0xdc00 | (utf32 & 0x3ff))); - } else { - json_writer_escape_utf16(writer, (uint16_t)utf32); - } - } - } - - json_writer_output_char(writer, '"'); -} - -void grpc_json_writer_container_begins(grpc_json_writer *writer, - grpc_json_type type) { - if (!writer->got_key) json_writer_value_end(writer); - json_writer_output_indent(writer); - json_writer_output_char(writer, type == GRPC_JSON_OBJECT ? '{' : '['); - writer->container_empty = 1; - writer->got_key = 0; - writer->depth++; -} - -void grpc_json_writer_container_ends(grpc_json_writer *writer, - grpc_json_type type) { - if (writer->indent && !writer->container_empty) - json_writer_output_char(writer, '\n'); - writer->depth--; - if (!writer->container_empty) json_writer_output_indent(writer); - json_writer_output_char(writer, type == GRPC_JSON_OBJECT ? '}' : ']'); - writer->container_empty = 0; - writer->got_key = 0; -} - -void grpc_json_writer_object_key(grpc_json_writer *writer, const char *string) { - json_writer_value_end(writer); - json_writer_output_indent(writer); - json_writer_escape_string(writer, string); - json_writer_output_char(writer, ':'); - writer->got_key = 1; -} - -void grpc_json_writer_value_raw(grpc_json_writer *writer, const char *string) { - if (!writer->got_key) json_writer_value_end(writer); - json_writer_output_indent(writer); - json_writer_output_string(writer, string); - writer->got_key = 0; -} - -void grpc_json_writer_value_raw_with_len(grpc_json_writer *writer, - const char *string, size_t len) { - if (!writer->got_key) json_writer_value_end(writer); - json_writer_output_indent(writer); - json_writer_output_string_with_len(writer, string, len); - writer->got_key = 0; -} - -void grpc_json_writer_value_string(grpc_json_writer *writer, - const char *string) { - if (!writer->got_key) json_writer_value_end(writer); - json_writer_output_indent(writer); - json_writer_escape_string(writer, string); - writer->got_key = 0; -} diff --git a/src/core/json/json_writer.h b/src/core/json/json_writer.h deleted file mode 100644 index c392126950..0000000000 --- a/src/core/json/json_writer.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* The idea of the writer is basically symmetrical of the reader. While the - * reader emits various calls to your code, the writer takes basically the - * same calls and emit json out of it. It doesn't try to make any check on - * the order of the calls you do on it. Meaning you can theorically force - * it to generate invalid json. - * - * Also, unlike the reader, the writer expects UTF-8 encoded input strings. - * These strings will be UTF-8 validated, and any invalid character will - * cut the conversion short, before any invalid UTF-8 sequence, thus forming - * a valid UTF-8 string overall. - */ - -#ifndef GRPC_CORE_JSON_JSON_WRITER_H -#define GRPC_CORE_JSON_JSON_WRITER_H - -#include - -#include "src/core/json/json_common.h" - -typedef struct grpc_json_writer_vtable { - /* Adds a character to the output stream. */ - void (*output_char)(void *userdata, char); - /* Adds a zero-terminated string to the output stream. */ - void (*output_string)(void *userdata, const char *str); - /* Adds a fixed-length string to the output stream. */ - void (*output_string_with_len)(void *userdata, const char *str, size_t len); - -} grpc_json_writer_vtable; - -typedef struct grpc_json_writer { - void *userdata; - grpc_json_writer_vtable *vtable; - int indent; - int depth; - int container_empty; - int got_key; -} grpc_json_writer; - -/* Call this to initialize your writer structure. The indent parameter is - * specifying the number of spaces to use for indenting the output. If you - * use indent=0, then the output will not have any newlines either, thus - * emitting a condensed json output. - */ -void grpc_json_writer_init(grpc_json_writer *writer, int indent, - grpc_json_writer_vtable *vtable, void *userdata); - -/* Signals the beginning of a container. */ -void grpc_json_writer_container_begins(grpc_json_writer *writer, - grpc_json_type type); -/* Signals the end of a container. */ -void grpc_json_writer_container_ends(grpc_json_writer *writer, - grpc_json_type type); -/* Writes down an object key for the next value. */ -void grpc_json_writer_object_key(grpc_json_writer *writer, const char *string); -/* Sets a raw value. Useful for numbers. */ -void grpc_json_writer_value_raw(grpc_json_writer *writer, const char *string); -/* Sets a raw value with its length. Useful for values like true or false. */ -void grpc_json_writer_value_raw_with_len(grpc_json_writer *writer, - const char *string, size_t len); -/* Sets a string value. It'll be escaped, and utf-8 validated. */ -void grpc_json_writer_value_string(grpc_json_writer *writer, - const char *string); - -#endif /* GRPC_CORE_JSON_JSON_WRITER_H */ diff --git a/src/core/lib/census/README.md b/src/core/lib/census/README.md new file mode 100644 index 0000000000..fb615a2194 --- /dev/null +++ b/src/core/lib/census/README.md @@ -0,0 +1,76 @@ + + +# Census - a resource measurement and tracing system + +This directory contains code for Census, which will ultimately provide the +following features for any gRPC-using system: +* A [dapper](http://research.google.com/pubs/pub36356.html)-like tracing + system, enabling tracing across a distributed infrastructure. +* RPC statistics and measurements for key metrics, such as latency, bytes + transferred, number of errors etc. +* Resource measurement framework which can be used for measuring custom + metrics. Through the use of [tags](#Tags), these can be broken down across + the entire distributed stack. +* Easy integration of the above with + [Google Cloud Trace](https://cloud.google.com/tools/cloud-trace) and + [Google Cloud Monitoring](https://cloud.google.com/monitoring/). + +## Concepts + +### Context + +### Operations + +### Tags + +### Metrics + +## API + +### Internal/RPC API + +### External/Client API + +### RPC API + +## Files in this directory + +Note that files and functions in this directory can be split into two +categories: +* Files that define core census library functions. Functions etc. in these + files are named census\_\*, and constitute the core census library + functionality. At some time in the future, these will become a standalone + library. +* Files that define functions etc. that provide a convenient interface between + grpc and the core census functionality. These files are all named + grpc\_\*.{c,h}, and define function names beginning with grpc\_census\_\*. + diff --git a/src/core/lib/census/aggregation.h b/src/core/lib/census/aggregation.h new file mode 100644 index 0000000000..e0ef9630c9 --- /dev/null +++ b/src/core/lib/census/aggregation.h @@ -0,0 +1,66 @@ +/* + * + * Copyright 2015-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 + +#ifndef GRPC_CORE_CENSUS_AGGREGATION_H +#define GRPC_CORE_CENSUS_AGGREGATION_H + +/** Structure used to describe an aggregation type. */ +struct census_aggregation_ops { + /* Create a new aggregation. The pointer returned can be used in future calls + to clone(), free(), record(), data() and reset(). */ + void *(*create)(const void *create_arg); + /* Make a copy of an aggregation created by create() */ + void *(*clone)(const void *aggregation); + /* Destroy an aggregation created by create() */ + void (*free)(void *aggregation); + /* Record a new value against aggregation. */ + void (*record)(void *aggregation, double value); + /* Return current aggregation data. The caller must cast this object into + the correct type for the aggregation result. The object returned can be + freed by using free_data(). */ + void *(*data)(const void *aggregation); + /* free data returned by data() */ + void (*free_data)(void *data); + /* Reset an aggregation to default (zero) values. */ + void (*reset)(void *aggregation); + /* Merge 'from' aggregation into 'to'. Both aggregations must be compatible */ + void (*merge)(void *to, const void *from); + /* Fill buffer with printable string version of aggregation contents. For + debugging only. Returns the number of bytes added to buffer (a value == n + implies the buffer was of insufficient size). */ + size_t (*print)(const void *aggregation, char *buffer, size_t n); +}; + +#endif /* GRPC_CORE_CENSUS_AGGREGATION_H */ diff --git a/src/core/lib/census/context.c b/src/core/lib/census/context.c new file mode 100644 index 0000000000..89b8ee0b39 --- /dev/null +++ b/src/core/lib/census/context.c @@ -0,0 +1,509 @@ +/* + * + * Copyright 2015-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 +#include +#include +#include +#include +#include +#include +#include "src/core/support/string.h" + +// Functions in this file support the public context API, including +// encoding/decoding as part of context propagation across RPC's. The overall +// requirements (in approximate priority order) for the +// context representation: +// 1. Efficient conversion to/from wire format +// 2. Minimal bytes used on-wire +// 3. Efficient context creation +// 4. Efficient lookup of tag value for a key +// 5. Efficient iteration over tags +// 6. Minimal memory footprint +// +// Notes on tradeoffs/decisions: +// * tag includes 1 byte length of key, as well as nil-terminating byte. These +// are to aid in efficient parsing and the ability to directly return key +// strings. This is more important than saving a single byte/tag on the wire. +// * The wire encoding uses only single byte values. This eliminates the need +// to handle endian-ness conversions. It also means there is a hard upper +// limit of 255 for both CENSUS_MAX_TAG_KV_LEN and CENSUS_MAX_PROPAGATED_TAGS. +// * Keep all tag information (keys/values/flags) in a single memory buffer, +// that can be directly copied to the wire. + +// min and max valid chars in tag keys and values. All printable ASCII is OK. +#define MIN_VALID_TAG_CHAR 32 // ' ' +#define MAX_VALID_TAG_CHAR 126 // '~' + +// Structure representing a set of tags. Essentially a count of number of tags +// present, and pointer to a chunk of memory that contains the per-tag details. +struct tag_set { + int ntags; // number of tags. + int ntags_alloc; // ntags + number of deleted tags (total number of tags + // in all of kvm). This will always be == ntags, except during the process + // of building a new tag set. + size_t kvm_size; // number of bytes allocated for key/value storage. + size_t kvm_used; // number of bytes of used key/value memory + char *kvm; // key/value memory. Consists of repeated entries of: + // Offset Size Description + // 0 1 Key length, including trailing 0. (K) + // 1 1 Value length, including trailing 0 (V) + // 2 1 Flags + // 3 K Key bytes + // 3 + K V Value bytes + // + // We refer to the first 3 entries as the 'tag header'. If extra values are + // introduced in the header, you will need to modify the TAG_HEADER_SIZE + // constant, the raw_tag structure (and everything that uses it) and the + // encode/decode functions appropriately. +}; + +// Number of bytes in tag header. +#define TAG_HEADER_SIZE 3 // key length (1) + value length (1) + flags (1) +// Offsets to tag header entries. +#define KEY_LEN_OFFSET 0 +#define VALUE_LEN_OFFSET 1 +#define FLAG_OFFSET 2 + +// raw_tag represents the raw-storage form of a tag in the kvm of a tag_set. +struct raw_tag { + uint8_t key_len; + uint8_t value_len; + uint8_t flags; + char *key; + char *value; +}; + +// Use a reserved flag bit for indication of deleted tag. +#define CENSUS_TAG_DELETED CENSUS_TAG_RESERVED +#define CENSUS_TAG_IS_DELETED(flags) (flags & CENSUS_TAG_DELETED) + +// Primary representation of a context. Composed of 2 underlying tag_set +// structs, one each for propagated and local (non-propagated) tags. This is +// to efficiently support tag encoding/decoding. +// TODO(aveitch): need to add tracing id's/structure. +struct census_context { + struct tag_set tags[2]; + census_context_status status; +}; + +// Indices into the tags member of census_context +#define PROPAGATED_TAGS 0 +#define LOCAL_TAGS 1 + +// Validate (check all characters are in range and size is less than limit) a +// key or value string. Returns 0 if the string is invalid, or the length +// (including terminator) if valid. +static size_t validate_tag(const char *kv) { + size_t len = 1; + char ch; + while ((ch = *kv++) != 0) { + if (ch < MIN_VALID_TAG_CHAR || ch > MAX_VALID_TAG_CHAR) { + return 0; + } + len++; + } + if (len > CENSUS_MAX_TAG_KV_LEN) { + return 0; + } + return len; +} + +// Extract a raw tag given a pointer (raw) to the tag header. Allow for some +// extra bytes in the tag header (see encode/decode functions for usage: this +// allows for future expansion of the tag header). +static char *decode_tag(struct raw_tag *tag, char *header, int offset) { + tag->key_len = (uint8_t)(*header++); + tag->value_len = (uint8_t)(*header++); + tag->flags = (uint8_t)(*header++); + header += offset; + tag->key = header; + header += tag->key_len; + tag->value = header; + return header + tag->value_len; +} + +// Make a copy (in 'to') of an existing tag_set. +static void tag_set_copy(struct tag_set *to, const struct tag_set *from) { + memcpy(to, from, sizeof(struct tag_set)); + to->kvm = gpr_malloc(to->kvm_size); + memcpy(to->kvm, from->kvm, from->kvm_used); +} + +// Delete a tag from a tag_set, if it exists (returns true if it did). +static bool tag_set_delete_tag(struct tag_set *tags, const char *key, + size_t key_len) { + char *kvp = tags->kvm; + for (int i = 0; i < tags->ntags_alloc; i++) { + uint8_t *flags = (uint8_t *)(kvp + FLAG_OFFSET); + struct raw_tag tag; + kvp = decode_tag(&tag, kvp, 0); + if (CENSUS_TAG_IS_DELETED(tag.flags)) continue; + if ((key_len == tag.key_len) && (memcmp(key, tag.key, key_len) == 0)) { + *flags |= CENSUS_TAG_DELETED; + tags->ntags--; + return true; + } + } + return false; +} + +// Delete a tag from a context, return true if it existed. +static bool context_delete_tag(census_context *context, const census_tag *tag, + size_t key_len) { + return ( + tag_set_delete_tag(&context->tags[LOCAL_TAGS], tag->key, key_len) || + tag_set_delete_tag(&context->tags[PROPAGATED_TAGS], tag->key, key_len)); +} + +// Add a tag to a tag_set. Return true on success, false if the tag could +// not be added because of constraints on tag set size. This function should +// not be called if the tag may already exist (in a non-deleted state) in +// the tag_set, as that would result in two tags with the same key. +static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag, + size_t key_len, size_t value_len) { + if (tags->ntags == CENSUS_MAX_PROPAGATED_TAGS) { + return false; + } + const size_t tag_size = key_len + value_len + TAG_HEADER_SIZE; + if (tags->kvm_used + tag_size > tags->kvm_size) { + // allocate new memory if needed + tags->kvm_size += 2 * CENSUS_MAX_TAG_KV_LEN + TAG_HEADER_SIZE; + char *new_kvm = gpr_malloc(tags->kvm_size); + memcpy(new_kvm, tags->kvm, tags->kvm_used); + gpr_free(tags->kvm); + tags->kvm = new_kvm; + } + char *kvp = tags->kvm + tags->kvm_used; + *kvp++ = (char)key_len; + *kvp++ = (char)value_len; + // ensure reserved flags are not used. + *kvp++ = (char)(tag->flags & (CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS)); + memcpy(kvp, tag->key, key_len); + kvp += key_len; + memcpy(kvp, tag->value, value_len); + tags->kvm_used += tag_size; + tags->ntags++; + tags->ntags_alloc++; + return true; +} + +// Add/modify/delete a tag to/in a context. Caller must validate that tag key +// etc. are valid. +static void context_modify_tag(census_context *context, const census_tag *tag, + size_t key_len, size_t value_len) { + // First delete the tag if it is already present. + bool deleted = context_delete_tag(context, tag, key_len); + bool added = false; + if (CENSUS_TAG_IS_PROPAGATED(tag->flags)) { + added = tag_set_add_tag(&context->tags[PROPAGATED_TAGS], tag, key_len, + value_len); + } else { + added = + tag_set_add_tag(&context->tags[LOCAL_TAGS], tag, key_len, value_len); + } + + if (deleted) { + context->status.n_modified_tags++; + } else { + if (added) { + context->status.n_added_tags++; + } else { + context->status.n_ignored_tags++; + } + } +} + +// Remove memory used for deleted tags from a tag set. Basic algorithm: +// 1) Walk through tag set to find first deleted tag. Record where it is. +// 2) Find the next not-deleted tag. Copy all of kvm from there to the end +// "over" the deleted tags +// 3) repeat #1 and #2 until we have seen all tags +// 4) if we are still looking for a not-deleted tag, then all the end portion +// of the kvm is deleted. Just reduce the used amount of memory by the +// appropriate amount. +static void tag_set_flatten(struct tag_set *tags) { + if (tags->ntags == tags->ntags_alloc) return; + bool found_deleted = false; // found a deleted tag. + char *kvp = tags->kvm; + char *dbase = NULL; // record location of deleted tag + for (int i = 0; i < tags->ntags_alloc; i++) { + struct raw_tag tag; + char *next_kvp = decode_tag(&tag, kvp, 0); + if (found_deleted) { + if (!CENSUS_TAG_IS_DELETED(tag.flags)) { + ptrdiff_t reduce = kvp - dbase; // #bytes in deleted tags + GPR_ASSERT(reduce > 0); + ptrdiff_t copy_size = tags->kvm + tags->kvm_used - kvp; + GPR_ASSERT(copy_size > 0); + memmove(dbase, kvp, (size_t)copy_size); + tags->kvm_used -= (size_t)reduce; + next_kvp -= reduce; + found_deleted = false; + } + } else { + if (CENSUS_TAG_IS_DELETED(tag.flags)) { + dbase = kvp; + found_deleted = true; + } + } + kvp = next_kvp; + } + if (found_deleted) { + GPR_ASSERT(dbase > tags->kvm); + tags->kvm_used = (size_t)(dbase - tags->kvm); + } + tags->ntags_alloc = tags->ntags; +} + +census_context *census_context_create(const census_context *base, + const census_tag *tags, int ntags, + census_context_status const **status) { + census_context *context = gpr_malloc(sizeof(census_context)); + // If we are given a base, copy it into our new tag set. Otherwise set it + // to zero/NULL everything. + if (base == NULL) { + memset(context, 0, sizeof(census_context)); + } else { + tag_set_copy(&context->tags[PROPAGATED_TAGS], &base->tags[PROPAGATED_TAGS]); + tag_set_copy(&context->tags[LOCAL_TAGS], &base->tags[LOCAL_TAGS]); + memset(&context->status, 0, sizeof(context->status)); + } + // Walk over the additional tags and, for those that aren't invalid, modify + // the context to add/replace/delete as required. + for (int i = 0; i < ntags; i++) { + const census_tag *tag = &tags[i]; + size_t key_len = validate_tag(tag->key); + // ignore the tag if it is invalid or too short. + if (key_len <= 1) { + context->status.n_invalid_tags++; + } else { + if (tag->value != NULL) { + size_t value_len = validate_tag(tag->value); + if (value_len != 0) { + context_modify_tag(context, tag, key_len, value_len); + } else { + context->status.n_invalid_tags++; + } + } else { + if (context_delete_tag(context, tag, key_len)) { + context->status.n_deleted_tags++; + } + } + } + } + // Remove any deleted tags, update status if needed, and return. + tag_set_flatten(&context->tags[PROPAGATED_TAGS]); + tag_set_flatten(&context->tags[LOCAL_TAGS]); + context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags; + context->status.n_local_tags = context->tags[LOCAL_TAGS].ntags; + if (status) { + *status = &context->status; + } + return context; +} + +const census_context_status *census_context_get_status( + const census_context *context) { + return &context->status; +} + +void census_context_destroy(census_context *context) { + gpr_free(context->tags[PROPAGATED_TAGS].kvm); + gpr_free(context->tags[LOCAL_TAGS].kvm); + gpr_free(context); +} + +void census_context_initialize_iterator(const census_context *context, + census_context_iterator *iterator) { + iterator->context = context; + iterator->index = 0; + if (context->tags[PROPAGATED_TAGS].ntags != 0) { + iterator->base = PROPAGATED_TAGS; + iterator->kvm = context->tags[PROPAGATED_TAGS].kvm; + } else if (context->tags[LOCAL_TAGS].ntags != 0) { + iterator->base = LOCAL_TAGS; + iterator->kvm = context->tags[LOCAL_TAGS].kvm; + } else { + iterator->base = -1; + } +} + +int census_context_next_tag(census_context_iterator *iterator, + census_tag *tag) { + if (iterator->base < 0) { + return 0; + } + struct raw_tag raw; + iterator->kvm = decode_tag(&raw, iterator->kvm, 0); + tag->key = raw.key; + tag->value = raw.value; + tag->flags = raw.flags; + if (++iterator->index == iterator->context->tags[iterator->base].ntags) { + do { + if (iterator->base == LOCAL_TAGS) { + iterator->base = -1; + return 1; + } + } while (iterator->context->tags[++iterator->base].ntags == 0); + iterator->index = 0; + iterator->kvm = iterator->context->tags[iterator->base].kvm; + } + return 1; +} + +// Find a tag in a tag_set by key. Return true if found, false otherwise. +static bool tag_set_get_tag(const struct tag_set *tags, const char *key, + size_t key_len, census_tag *tag) { + char *kvp = tags->kvm; + for (int i = 0; i < tags->ntags; i++) { + struct raw_tag raw; + kvp = decode_tag(&raw, kvp, 0); + if (key_len == raw.key_len && memcmp(raw.key, key, key_len) == 0) { + tag->key = raw.key; + tag->value = raw.value; + tag->flags = raw.flags; + return true; + } + } + return false; +} + +int census_context_get_tag(const census_context *context, const char *key, + census_tag *tag) { + size_t key_len = strlen(key) + 1; + if (key_len == 1) { + return 0; + } + if (tag_set_get_tag(&context->tags[PROPAGATED_TAGS], key, key_len, tag) || + tag_set_get_tag(&context->tags[LOCAL_TAGS], key, key_len, tag)) { + return 1; + } + return 0; +} + +// Context encoding and decoding functions. +// +// Wire format for tag_set's on the wire: +// +// First, a tag set header: +// +// offset bytes description +// 0 1 version number +// 1 1 number of bytes in this header. This allows for future +// expansion. +// 2 1 number of bytes in each tag header. +// 3 1 ntags value from tag set. +// +// This is followed by the key/value memory from struct tag_set. + +#define ENCODED_VERSION 0 // Version number +#define ENCODED_HEADER_SIZE 4 // size of tag set header + +// Encode a tag set. Returns 0 if buffer is too small. +static size_t tag_set_encode(const struct tag_set *tags, char *buffer, + size_t buf_size) { + if (buf_size < ENCODED_HEADER_SIZE + tags->kvm_used) { + return 0; + } + buf_size -= ENCODED_HEADER_SIZE; + *buffer++ = (char)ENCODED_VERSION; + *buffer++ = (char)ENCODED_HEADER_SIZE; + *buffer++ = (char)TAG_HEADER_SIZE; + *buffer++ = (char)tags->ntags; + if (tags->ntags == 0) { + return ENCODED_HEADER_SIZE; + } + memcpy(buffer, tags->kvm, tags->kvm_used); + return ENCODED_HEADER_SIZE + tags->kvm_used; +} + +size_t census_context_encode(const census_context *context, char *buffer, + size_t buf_size) { + return tag_set_encode(&context->tags[PROPAGATED_TAGS], buffer, buf_size); +} + +// Decode a tag set. +static void tag_set_decode(struct tag_set *tags, const char *buffer, + size_t size) { + uint8_t version = (uint8_t)(*buffer++); + uint8_t header_size = (uint8_t)(*buffer++); + uint8_t tag_header_size = (uint8_t)(*buffer++); + tags->ntags = tags->ntags_alloc = (int)(*buffer++); + if (tags->ntags == 0) { + tags->ntags_alloc = 0; + tags->kvm_size = 0; + tags->kvm_used = 0; + tags->kvm = NULL; + return; + } + if (header_size != ENCODED_HEADER_SIZE) { + GPR_ASSERT(version != ENCODED_VERSION); + GPR_ASSERT(ENCODED_HEADER_SIZE < header_size); + buffer += (header_size - ENCODED_HEADER_SIZE); + } + tags->kvm_used = size - header_size; + tags->kvm_size = tags->kvm_used + CENSUS_MAX_TAG_KV_LEN; + tags->kvm = gpr_malloc(tags->kvm_size); + if (tag_header_size != TAG_HEADER_SIZE) { + // something new in the tag information. I don't understand it, so + // don't copy it over. + GPR_ASSERT(version != ENCODED_VERSION); + GPR_ASSERT(tag_header_size > TAG_HEADER_SIZE); + char *kvp = tags->kvm; + for (int i = 0; i < tags->ntags; i++) { + memcpy(kvp, buffer, TAG_HEADER_SIZE); + kvp += header_size; + struct raw_tag raw; + buffer = + decode_tag(&raw, (char *)buffer, tag_header_size - TAG_HEADER_SIZE); + memcpy(kvp, raw.key, (size_t)raw.key_len + raw.value_len); + kvp += raw.key_len + raw.value_len; + } + } else { + memcpy(tags->kvm, buffer, tags->kvm_used); + } +} + +census_context *census_context_decode(const char *buffer, size_t size) { + census_context *context = gpr_malloc(sizeof(census_context)); + memset(&context->tags[LOCAL_TAGS], 0, sizeof(struct tag_set)); + if (buffer == NULL) { + memset(&context->tags[PROPAGATED_TAGS], 0, sizeof(struct tag_set)); + } else { + tag_set_decode(&context->tags[PROPAGATED_TAGS], buffer, size); + } + memset(&context->status, 0, sizeof(context->status)); + context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags; + return context; +} diff --git a/src/core/lib/census/grpc_context.c b/src/core/lib/census/grpc_context.c new file mode 100644 index 0000000000..4b61382a2c --- /dev/null +++ b/src/core/lib/census/grpc_context.c @@ -0,0 +1,53 @@ +/* + * + * Copyright 2015, 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 +#include +#include "src/core/surface/api_trace.h" +#include "src/core/surface/call.h" + +void grpc_census_call_set_context(grpc_call *call, census_context *context) { + GRPC_API_TRACE("grpc_census_call_set_context(call=%p, census_context=%p)", 2, + (call, context)); + if (census_enabled() == CENSUS_FEATURE_NONE) { + return; + } + if (context != NULL) { + grpc_call_context_set(call, GRPC_CONTEXT_TRACING, context, NULL); + } +} + +census_context *grpc_census_call_get_context(grpc_call *call) { + GRPC_API_TRACE("grpc_census_call_get_context(call=%p)", 1, (call)); + return (census_context *)grpc_call_context_get(call, GRPC_CONTEXT_TRACING); +} diff --git a/src/core/lib/census/grpc_filter.c b/src/core/lib/census/grpc_filter.c new file mode 100644 index 0000000000..11120a28d1 --- /dev/null +++ b/src/core/lib/census/grpc_filter.c @@ -0,0 +1,198 @@ +/* + * + * Copyright 2015-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/census/grpc_filter.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "src/core/channel/channel_stack.h" +#include "src/core/statistics/census_interface.h" +#include "src/core/statistics/census_rpc_stats.h" +#include "src/core/transport/static_metadata.h" + +typedef struct call_data { + census_op_id op_id; + census_context *ctxt; + gpr_timespec start_ts; + int error; + + /* recv callback */ + grpc_metadata_batch *recv_initial_metadata; + grpc_closure *on_done_recv; + grpc_closure finish_recv; +} call_data; + +typedef struct channel_data { uint8_t unused; } channel_data; + +static void extract_and_annotate_method_tag(grpc_metadata_batch *md, + call_data *calld, + channel_data *chand) { + grpc_linked_mdelem *m; + for (m = md->list.head; m != NULL; m = m->next) { + if (m->md->key == GRPC_MDSTR_PATH) { + gpr_log(GPR_DEBUG, "%s", + (const char *)GPR_SLICE_START_PTR(m->md->value->slice)); + /* Add method tag here */ + } + } +} + +static void client_mutate_op(grpc_call_element *elem, + grpc_transport_stream_op *op) { + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + if (op->send_initial_metadata) { + extract_and_annotate_method_tag(op->send_initial_metadata, calld, chand); + } +} + +static void client_start_transport_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + client_mutate_op(elem, op); + grpc_call_next_op(exec_ctx, elem, op); +} + +static void server_on_done_recv(grpc_exec_ctx *exec_ctx, void *ptr, + bool success) { + grpc_call_element *elem = ptr; + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + if (success) { + extract_and_annotate_method_tag(calld->recv_initial_metadata, calld, chand); + } + calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, success); +} + +static void server_mutate_op(grpc_call_element *elem, + grpc_transport_stream_op *op) { + call_data *calld = elem->call_data; + if (op->recv_initial_metadata) { + /* substitute our callback for the op callback */ + calld->recv_initial_metadata = op->recv_initial_metadata; + calld->on_done_recv = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = &calld->finish_recv; + } +} + +static void server_start_transport_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + /* TODO(ctiller): this code fails. I don't know why. I expect it's + incomplete, and someone should look at it soon. + + call_data *calld = elem->call_data; + GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0)); */ + server_mutate_op(elem, op); + grpc_call_next_op(exec_ctx, elem, op); +} + +static void client_init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { + call_data *d = elem->call_data; + GPR_ASSERT(d != NULL); + memset(d, 0, sizeof(*d)); + d->start_ts = gpr_now(GPR_CLOCK_REALTIME); +} + +static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + call_data *d = elem->call_data; + GPR_ASSERT(d != NULL); + /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */ +} + +static void server_init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { + call_data *d = elem->call_data; + GPR_ASSERT(d != NULL); + memset(d, 0, sizeof(*d)); + d->start_ts = gpr_now(GPR_CLOCK_REALTIME); + /* TODO(hongyu): call census_tracing_start_op here. */ + grpc_closure_init(&d->finish_recv, server_on_done_recv, elem); +} + +static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + call_data *d = elem->call_data; + GPR_ASSERT(d != NULL); + /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */ +} + +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + channel_data *chand = elem->channel_data; + GPR_ASSERT(chand != NULL); +} + +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) { + channel_data *chand = elem->channel_data; + GPR_ASSERT(chand != NULL); +} + +const grpc_channel_filter grpc_client_census_filter = { + client_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + client_init_call_elem, + grpc_call_stack_ignore_set_pollset, + client_destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "census-client"}; + +const grpc_channel_filter grpc_server_census_filter = { + server_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + server_init_call_elem, + grpc_call_stack_ignore_set_pollset, + server_destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "census-server"}; diff --git a/src/core/lib/census/grpc_filter.h b/src/core/lib/census/grpc_filter.h new file mode 100644 index 0000000000..4699e4d692 --- /dev/null +++ b/src/core/lib/census/grpc_filter.h @@ -0,0 +1,44 @@ +/* + * + * Copyright 2015-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_CENSUS_GRPC_FILTER_H +#define GRPC_CORE_CENSUS_GRPC_FILTER_H + +#include "src/core/channel/channel_stack.h" + +/* Census filters: provides tracing and stats collection functionalities. It + needs to reside right below the surface filter in the channel stack. */ +extern const grpc_channel_filter grpc_client_census_filter; +extern const grpc_channel_filter grpc_server_census_filter; + +#endif /* GRPC_CORE_CENSUS_GRPC_FILTER_H */ diff --git a/src/core/lib/census/grpc_plugin.c b/src/core/lib/census/grpc_plugin.c new file mode 100644 index 0000000000..3ca9400f7e --- /dev/null +++ b/src/core/lib/census/grpc_plugin.c @@ -0,0 +1,70 @@ +/* + * + * Copyright 2015-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/census/grpc_plugin.h" + +#include + +#include + +#include "src/core/census/grpc_filter.h" +#include "src/core/channel/channel_stack_builder.h" +#include "src/core/surface/channel_init.h" + +static bool maybe_add_census_filter(grpc_channel_stack_builder *builder, + void *arg_must_be_null) { + const grpc_channel_args *args = + grpc_channel_stack_builder_get_channel_arguments(builder); + if (grpc_channel_args_is_census_enabled(args)) { + return grpc_channel_stack_builder_prepend_filter( + builder, &grpc_client_census_filter, NULL, NULL); + } + return true; +} + +void census_grpc_plugin_init(void) { + /* Only initialize census if no one else has and some features are + * available. */ + if (census_enabled() == CENSUS_FEATURE_NONE && + census_supported() != CENSUS_FEATURE_NONE) { + if (census_initialize(census_supported())) { /* enable all features. */ + gpr_log(GPR_ERROR, "Could not initialize census."); + } + } + grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, + maybe_add_census_filter, NULL); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, + maybe_add_census_filter, NULL); +} + +void census_grpc_plugin_destroy(void) { census_shutdown(); } diff --git a/src/core/lib/census/grpc_plugin.h b/src/core/lib/census/grpc_plugin.h new file mode 100644 index 0000000000..9321c2c30f --- /dev/null +++ b/src/core/lib/census/grpc_plugin.h @@ -0,0 +1,40 @@ +/* + * + * Copyright 2015-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_CENSUS_GRPC_PLUGIN_H +#define GRPC_CORE_CENSUS_GRPC_PLUGIN_H + +void census_grpc_plugin_init(void); +void census_grpc_plugin_destroy(void); + +#endif /* GRPC_CORE_CENSUS_GRPC_PLUGIN_H */ diff --git a/src/core/lib/census/initialize.c b/src/core/lib/census/initialize.c new file mode 100644 index 0000000000..ce7ec09b89 --- /dev/null +++ b/src/core/lib/census/initialize.c @@ -0,0 +1,54 @@ +/* + * + * Copyright 2015-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 + +static int features_enabled = CENSUS_FEATURE_NONE; + +int census_initialize(int features) { + if (features_enabled != CENSUS_FEATURE_NONE) { + // Must have been a previous call to census_initialize; return error + return 1; + } + features_enabled = features; + return 0; +} + +void census_shutdown(void) { features_enabled = CENSUS_FEATURE_NONE; } + +int census_supported(void) { + /* TODO(aveitch): improve this as we implement features... */ + return CENSUS_FEATURE_NONE; +} + +int census_enabled(void) { return features_enabled; } diff --git a/src/core/lib/census/mlog.c b/src/core/lib/census/mlog.c new file mode 100644 index 0000000000..a2cc46d3f2 --- /dev/null +++ b/src/core/lib/census/mlog.c @@ -0,0 +1,600 @@ +/* + * + * Copyright 2015-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. + * + */ + +// Implements an efficient in-memory log, optimized for multiple writers and +// a single reader. Available log space is divided up in blocks of +// CENSUS_LOG_2_MAX_RECORD_SIZE bytes. A block can be in one of the following +// three data structures: +// - Free blocks (free_block_list) +// - Blocks with unread data (dirty_block_list) +// - Blocks currently attached to cores (core_local_blocks[]) +// +// census_log_start_write() moves a block from core_local_blocks[] to the end of +// dirty_block_list when block: +// - is out-of-space OR +// - has an incomplete record (an incomplete record occurs when a thread calls +// census_log_start_write() and is context-switched before calling +// census_log_end_write() +// So, blocks in dirty_block_list are ordered, from oldest to newest, by the +// time when block is detached from the core. +// +// census_log_read_next() first iterates over dirty_block_list and then +// core_local_blocks[]. It moves completely read blocks from dirty_block_list +// to free_block_list. Blocks in core_local_blocks[] are not freed, even when +// completely read. +// +// If the log is configured to discard old records and free_block_list is empty, +// census_log_start_write() iterates over dirty_block_list to allocate a +// new block. It moves the oldest available block (no pending read/write) to +// core_local_blocks[]. +// +// core_local_block_struct is used to implement a map from core id to the block +// associated with that core. This mapping is advisory. It is possible that the +// block returned by this mapping is no longer associated with that core. This +// mapping is updated, lazily, by census_log_start_write(). +// +// Locking in block struct: +// +// Exclusive g_log.lock must be held before calling any functions operating on +// block structs except census_log_start_write() and census_log_end_write(). +// +// Writes to a block are serialized via writer_lock. census_log_start_write() +// acquires this lock and census_log_end_write() releases it. On failure to +// acquire the lock, writer allocates a new block for the current core and +// updates core_local_block accordingly. +// +// Simultaneous read and write access is allowed. Readers can safely read up to +// committed bytes (bytes_committed). +// +// reader_lock protects the block, currently being read, from getting recycled. +// start_read() acquires reader_lock and end_read() releases the lock. +// +// Read/write access to a block is disabled via try_disable_access(). It returns +// with both writer_lock and reader_lock held. These locks are subsequently +// released by enable_access() to enable access to the block. +// +// A note on naming: Most function/struct names are prepended by cl_ +// (shorthand for census_log). Further, functions that manipulate structures +// include the name of the structure, which will be passed as the first +// argument. E.g. cl_block_initialize() will initialize a cl_block. + +#include "src/core/census/mlog.h" +#include +#include +#include +#include +#include +#include +#include +#include + +// End of platform specific code + +typedef struct census_log_block_list_struct { + struct census_log_block_list_struct* next; + struct census_log_block_list_struct* prev; + struct census_log_block* block; +} cl_block_list_struct; + +typedef struct census_log_block { + // Pointer to underlying buffer. + char* buffer; + gpr_atm writer_lock; + gpr_atm reader_lock; + // Keeps completely written bytes. Declared atomic because accessed + // simultaneously by reader and writer. + gpr_atm bytes_committed; + // Bytes already read. + size_t bytes_read; + // Links for list. + cl_block_list_struct link; +// We want this structure to be cacheline aligned. We assume the following +// sizes for the various parts on 32/64bit systems: +// type 32b size 64b size +// char* 4 8 +// 3x gpr_atm 12 24 +// size_t 4 8 +// cl_block_list_struct 12 24 +// TOTAL 32 64 +// +// Depending on the size of our cacheline and the architecture, we +// selectively add char buffering to this structure. The size is checked +// via assert in census_log_initialize(). +#if defined(GPR_ARCH_64) +#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 64) +#else +#if defined(GPR_ARCH_32) +#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 32) +#else +#error "Unknown architecture" +#endif +#endif +#if CL_BLOCK_PAD_SIZE > 0 + char padding[CL_BLOCK_PAD_SIZE]; +#endif +} cl_block; + +// A list of cl_blocks, doubly-linked through cl_block::link. +typedef struct census_log_block_list { + int32_t count; // Number of items in list. + cl_block_list_struct ht; // head/tail of linked list. +} cl_block_list; + +// Cacheline aligned block pointers to avoid false sharing. Block pointer must +// be initialized via set_block(), before calling other functions +typedef struct census_log_core_local_block { + gpr_atm block; +// Ensure cachline alignment: we assume sizeof(gpr_atm) == 4 or 8 +#if defined(GPR_ARCH_64) +#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 8) +#else +#if defined(GPR_ARCH_32) +#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 4) +#else +#error "Unknown architecture" +#endif +#endif +#if CL_CORE_LOCAL_BLOCK_PAD_SIZE > 0 + char padding[CL_CORE_LOCAL_BLOCK_PAD_SIZE]; +#endif +} cl_core_local_block; + +struct census_log { + int discard_old_records; + // Number of cores (aka hardware-contexts) + unsigned num_cores; + // number of CENSUS_LOG_2_MAX_RECORD_SIZE blocks in log + uint32_t num_blocks; + cl_block* blocks; // Block metadata. + cl_core_local_block* core_local_blocks; // Keeps core to block mappings. + gpr_mu lock; + int initialized; // has log been initialized? + // Keeps the state of the reader iterator. A value of 0 indicates that + // iterator has reached the end. census_log_init_reader() resets the value + // to num_core to restart iteration. + uint32_t read_iterator_state; + // Points to the block being read. If non-NULL, the block is locked for + // reading(block_being_read_->reader_lock is held). + cl_block* block_being_read; + char* buffer; + cl_block_list free_block_list; + cl_block_list dirty_block_list; + gpr_atm out_of_space_count; +}; + +// Single internal log. +static struct census_log g_log; + +// Functions that operate on an atomic memory location used as a lock. + +// Returns non-zero if lock is acquired. +static int cl_try_lock(gpr_atm* lock) { return gpr_atm_acq_cas(lock, 0, 1); } + +static void cl_unlock(gpr_atm* lock) { gpr_atm_rel_store(lock, 0); } + +// Functions that operate on cl_core_local_block's. + +static void cl_core_local_block_set_block(cl_core_local_block* clb, + cl_block* block) { + gpr_atm_rel_store(&clb->block, (gpr_atm)block); +} + +static cl_block* cl_core_local_block_get_block(cl_core_local_block* clb) { + return (cl_block*)gpr_atm_acq_load(&clb->block); +} + +// Functions that operate on cl_block_list_struct's. + +static void cl_block_list_struct_initialize(cl_block_list_struct* bls, + cl_block* block) { + bls->next = bls->prev = bls; + bls->block = block; +} + +// Functions that operate on cl_block_list's. + +static void cl_block_list_initialize(cl_block_list* list) { + list->count = 0; + cl_block_list_struct_initialize(&list->ht, NULL); +} + +// Returns head of *this, or NULL if empty. +static cl_block* cl_block_list_head(cl_block_list* list) { + return list->ht.next->block; +} + +// Insert element *e after *pos. +static void cl_block_list_insert(cl_block_list* list, cl_block_list_struct* pos, + cl_block_list_struct* e) { + list->count++; + e->next = pos->next; + e->prev = pos; + e->next->prev = e; + e->prev->next = e; +} + +// Insert block at the head of the list +static void cl_block_list_insert_at_head(cl_block_list* list, cl_block* block) { + cl_block_list_insert(list, &list->ht, &block->link); +} + +// Insert block at the tail of the list. +static void cl_block_list_insert_at_tail(cl_block_list* list, cl_block* block) { + cl_block_list_insert(list, list->ht.prev, &block->link); +} + +// Removes block *b. Requires *b be in the list. +static void cl_block_list_remove(cl_block_list* list, cl_block* b) { + list->count--; + b->link.next->prev = b->link.prev; + b->link.prev->next = b->link.next; +} + +// Functions that operate on cl_block's + +static void cl_block_initialize(cl_block* block, char* buffer) { + block->buffer = buffer; + gpr_atm_rel_store(&block->writer_lock, 0); + gpr_atm_rel_store(&block->reader_lock, 0); + gpr_atm_rel_store(&block->bytes_committed, 0); + block->bytes_read = 0; + cl_block_list_struct_initialize(&block->link, block); +} + +// Guards against exposing partially written buffer to the reader. +static void cl_block_set_bytes_committed(cl_block* block, + size_t bytes_committed) { + gpr_atm_rel_store(&block->bytes_committed, (gpr_atm)bytes_committed); +} + +static size_t cl_block_get_bytes_committed(cl_block* block) { + return (size_t)gpr_atm_acq_load(&block->bytes_committed); +} + +// Tries to disable future read/write access to this block. Succeeds if: +// - no in-progress write AND +// - no in-progress read AND +// - 'discard_data' set to true OR no unread data +// On success, clears the block state and returns with writer_lock_ and +// reader_lock_ held. These locks are released by a subsequent +// cl_block_access_enable() call. +static bool cl_block_try_disable_access(cl_block* block, int discard_data) { + if (!cl_try_lock(&block->writer_lock)) { + return false; + } + if (!cl_try_lock(&block->reader_lock)) { + cl_unlock(&block->writer_lock); + return false; + } + if (!discard_data && + (block->bytes_read != cl_block_get_bytes_committed(block))) { + cl_unlock(&block->reader_lock); + cl_unlock(&block->writer_lock); + return false; + } + cl_block_set_bytes_committed(block, 0); + block->bytes_read = 0; + return true; +} + +static void cl_block_enable_access(cl_block* block) { + cl_unlock(&block->reader_lock); + cl_unlock(&block->writer_lock); +} + +// Returns with writer_lock held. +static void* cl_block_start_write(cl_block* block, size_t size) { + if (!cl_try_lock(&block->writer_lock)) { + return NULL; + } + size_t bytes_committed = cl_block_get_bytes_committed(block); + if (bytes_committed + size > CENSUS_LOG_MAX_RECORD_SIZE) { + cl_unlock(&block->writer_lock); + return NULL; + } + return block->buffer + bytes_committed; +} + +// Releases writer_lock and increments committed bytes by 'bytes_written'. +// 'bytes_written' must be <= 'size' specified in the corresponding +// StartWrite() call. This function is thread-safe. +static void cl_block_end_write(cl_block* block, size_t bytes_written) { + cl_block_set_bytes_committed( + block, cl_block_get_bytes_committed(block) + bytes_written); + cl_unlock(&block->writer_lock); +} + +// Returns a pointer to the first unread byte in buffer. The number of bytes +// available are returned in 'bytes_available'. Acquires reader lock that is +// released by a subsequent cl_block_end_read() call. Returns NULL if: +// - read in progress +// - no data available +static void* cl_block_start_read(cl_block* block, size_t* bytes_available) { + if (!cl_try_lock(&block->reader_lock)) { + return NULL; + } + // bytes_committed may change from under us. Use bytes_available to update + // bytes_read below. + size_t bytes_committed = cl_block_get_bytes_committed(block); + GPR_ASSERT(bytes_committed >= block->bytes_read); + *bytes_available = bytes_committed - block->bytes_read; + if (*bytes_available == 0) { + cl_unlock(&block->reader_lock); + return NULL; + } + void* record = block->buffer + block->bytes_read; + block->bytes_read += *bytes_available; + return record; +} + +static void cl_block_end_read(cl_block* block) { + cl_unlock(&block->reader_lock); +} + +// Internal functions operating on g_log + +// Allocates a new free block (or recycles an available dirty block if log is +// configured to discard old records). Returns NULL if out-of-space. +static cl_block* cl_allocate_block(void) { + cl_block* block = cl_block_list_head(&g_log.free_block_list); + if (block != NULL) { + cl_block_list_remove(&g_log.free_block_list, block); + return block; + } + if (!g_log.discard_old_records) { + // No free block and log is configured to keep old records. + return NULL; + } + // Recycle dirty block. Start from the oldest. + for (block = cl_block_list_head(&g_log.dirty_block_list); block != NULL; + block = block->link.next->block) { + if (cl_block_try_disable_access(block, 1 /* discard data */)) { + cl_block_list_remove(&g_log.dirty_block_list, block); + return block; + } + } + return NULL; +} + +// Allocates a new block and updates core id => block mapping. 'old_block' +// points to the block that the caller thinks is attached to +// 'core_id'. 'old_block' may be NULL. Returns true if: +// - allocated a new block OR +// - 'core_id' => 'old_block' mapping changed (another thread allocated a +// block before lock was acquired). +static bool cl_allocate_core_local_block(uint32_t core_id, + cl_block* old_block) { + // Now that we have the lock, check if core-local mapping has changed. + cl_core_local_block* core_local_block = &g_log.core_local_blocks[core_id]; + cl_block* block = cl_core_local_block_get_block(core_local_block); + if ((block != NULL) && (block != old_block)) { + return true; + } + if (block != NULL) { + cl_core_local_block_set_block(core_local_block, NULL); + cl_block_list_insert_at_tail(&g_log.dirty_block_list, block); + } + block = cl_allocate_block(); + if (block == NULL) { + return false; + } + cl_core_local_block_set_block(core_local_block, block); + cl_block_enable_access(block); + return true; +} + +static cl_block* cl_get_block(void* record) { + uintptr_t p = (uintptr_t)((char*)record - g_log.buffer); + uintptr_t index = p >> CENSUS_LOG_2_MAX_RECORD_SIZE; + return &g_log.blocks[index]; +} + +// Gets the next block to read and tries to free 'prev' block (if not NULL). +// Returns NULL if reached the end. +static cl_block* cl_next_block_to_read(cl_block* prev) { + cl_block* block = NULL; + if (g_log.read_iterator_state == g_log.num_cores) { + // We are traversing dirty list; find the next dirty block. + if (prev != NULL) { + // Try to free the previous block if there is no unread data. This + // block + // may have unread data if previously incomplete record completed + // between + // read_next() calls. + block = prev->link.next->block; + if (cl_block_try_disable_access(prev, 0 /* do not discard data */)) { + cl_block_list_remove(&g_log.dirty_block_list, prev); + cl_block_list_insert_at_head(&g_log.free_block_list, prev); + } + } else { + block = cl_block_list_head(&g_log.dirty_block_list); + } + if (block != NULL) { + return block; + } + // We are done with the dirty list; moving on to core-local blocks. + } + while (g_log.read_iterator_state > 0) { + g_log.read_iterator_state--; + block = cl_core_local_block_get_block( + &g_log.core_local_blocks[g_log.read_iterator_state]); + if (block != NULL) { + return block; + } + } + return NULL; +} + +#define CL_LOG_2_MB 20 // 2^20 = 1MB + +// External functions: primary stats_log interface +void census_log_initialize(size_t size_in_mb, int discard_old_records) { + // Check cacheline alignment. + GPR_ASSERT(sizeof(cl_block) % GPR_CACHELINE_SIZE == 0); + GPR_ASSERT(sizeof(cl_core_local_block) % GPR_CACHELINE_SIZE == 0); + GPR_ASSERT(!g_log.initialized); + g_log.discard_old_records = discard_old_records; + g_log.num_cores = gpr_cpu_num_cores(); + // Ensure that we will not get any overflow in calaculating num_blocks + GPR_ASSERT(CL_LOG_2_MB >= CENSUS_LOG_2_MAX_RECORD_SIZE); + GPR_ASSERT(size_in_mb < 1000); + // Ensure at least 2x as many blocks as there are cores. + g_log.num_blocks = + (uint32_t)GPR_MAX(2 * g_log.num_cores, (size_in_mb << CL_LOG_2_MB) >> + CENSUS_LOG_2_MAX_RECORD_SIZE); + gpr_mu_init(&g_log.lock); + g_log.read_iterator_state = 0; + g_log.block_being_read = NULL; + g_log.core_local_blocks = (cl_core_local_block*)gpr_malloc_aligned( + g_log.num_cores * sizeof(cl_core_local_block), GPR_CACHELINE_SIZE_LOG); + memset(g_log.core_local_blocks, 0, + g_log.num_cores * sizeof(cl_core_local_block)); + g_log.blocks = (cl_block*)gpr_malloc_aligned( + g_log.num_blocks * sizeof(cl_block), GPR_CACHELINE_SIZE_LOG); + memset(g_log.blocks, 0, g_log.num_blocks * sizeof(cl_block)); + g_log.buffer = gpr_malloc(g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE); + memset(g_log.buffer, 0, g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE); + cl_block_list_initialize(&g_log.free_block_list); + cl_block_list_initialize(&g_log.dirty_block_list); + for (uint32_t i = 0; i < g_log.num_blocks; ++i) { + cl_block* block = g_log.blocks + i; + cl_block_initialize(block, g_log.buffer + (CENSUS_LOG_MAX_RECORD_SIZE * i)); + cl_block_try_disable_access(block, 1 /* discard data */); + cl_block_list_insert_at_tail(&g_log.free_block_list, block); + } + gpr_atm_rel_store(&g_log.out_of_space_count, 0); + g_log.initialized = 1; +} + +void census_log_shutdown(void) { + GPR_ASSERT(g_log.initialized); + gpr_mu_destroy(&g_log.lock); + gpr_free_aligned(g_log.core_local_blocks); + g_log.core_local_blocks = NULL; + gpr_free_aligned(g_log.blocks); + g_log.blocks = NULL; + gpr_free(g_log.buffer); + g_log.buffer = NULL; + g_log.initialized = 0; +} + +void* census_log_start_write(size_t size) { + // Used to bound number of times block allocation is attempted. + GPR_ASSERT(size > 0); + GPR_ASSERT(g_log.initialized); + if (size > CENSUS_LOG_MAX_RECORD_SIZE) { + return NULL; + } + uint32_t attempts_remaining = g_log.num_blocks; + uint32_t core_id = gpr_cpu_current_cpu(); + do { + void* record = NULL; + cl_block* block = + cl_core_local_block_get_block(&g_log.core_local_blocks[core_id]); + if (block && (record = cl_block_start_write(block, size))) { + return record; + } + // Need to allocate a new block. We are here if: + // - No block associated with the core OR + // - Write in-progress on the block OR + // - block is out of space + gpr_mu_lock(&g_log.lock); + bool allocated = cl_allocate_core_local_block(core_id, block); + gpr_mu_unlock(&g_log.lock); + if (!allocated) { + gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1); + return NULL; + } + } while (attempts_remaining--); + // Give up. + gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1); + return NULL; +} + +void census_log_end_write(void* record, size_t bytes_written) { + GPR_ASSERT(g_log.initialized); + cl_block_end_write(cl_get_block(record), bytes_written); +} + +void census_log_init_reader(void) { + GPR_ASSERT(g_log.initialized); + gpr_mu_lock(&g_log.lock); + // If a block is locked for reading unlock it. + if (g_log.block_being_read != NULL) { + cl_block_end_read(g_log.block_being_read); + g_log.block_being_read = NULL; + } + g_log.read_iterator_state = g_log.num_cores; + gpr_mu_unlock(&g_log.lock); +} + +const void* census_log_read_next(size_t* bytes_available) { + GPR_ASSERT(g_log.initialized); + gpr_mu_lock(&g_log.lock); + if (g_log.block_being_read != NULL) { + cl_block_end_read(g_log.block_being_read); + } + do { + g_log.block_being_read = cl_next_block_to_read(g_log.block_being_read); + if (g_log.block_being_read != NULL) { + void* record = + cl_block_start_read(g_log.block_being_read, bytes_available); + if (record != NULL) { + gpr_mu_unlock(&g_log.lock); + return record; + } + } + } while (g_log.block_being_read != NULL); + gpr_mu_unlock(&g_log.lock); + return NULL; +} + +size_t census_log_remaining_space(void) { + GPR_ASSERT(g_log.initialized); + size_t space = 0; + gpr_mu_lock(&g_log.lock); + if (g_log.discard_old_records) { + // Remaining space is not meaningful; just return the entire log space. + space = g_log.num_blocks << CENSUS_LOG_2_MAX_RECORD_SIZE; + } else { + GPR_ASSERT(g_log.free_block_list.count >= 0); + space = (size_t)g_log.free_block_list.count * CENSUS_LOG_MAX_RECORD_SIZE; + } + gpr_mu_unlock(&g_log.lock); + return space; +} + +int64_t census_log_out_of_space_count(void) { + GPR_ASSERT(g_log.initialized); + return gpr_atm_acq_load(&g_log.out_of_space_count); +} diff --git a/src/core/lib/census/mlog.h b/src/core/lib/census/mlog.h new file mode 100644 index 0000000000..bc6eaeaf28 --- /dev/null +++ b/src/core/lib/census/mlog.h @@ -0,0 +1,95 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* A very fast in-memory log, optimized for multiple writers. */ + +#ifndef GRPC_CORE_CENSUS_MLOG_H +#define GRPC_CORE_CENSUS_MLOG_H + +#include +#include + +/* Maximum record size, in bytes. */ +#define CENSUS_LOG_2_MAX_RECORD_SIZE 14 /* 2^14 = 16KB */ +#define CENSUS_LOG_MAX_RECORD_SIZE (1 << CENSUS_LOG_2_MAX_RECORD_SIZE) + +/* Initialize the statistics logging subsystem with the given log size. A log + size of 0 will result in the smallest possible log for the platform + (approximately CENSUS_LOG_MAX_RECORD_SIZE * gpr_cpu_num_cores()). If + discard_old_records is non-zero, then new records will displace older ones + when the log is full. This function must be called before any other + census_log functions. +*/ +void census_log_initialize(size_t size_in_mb, int discard_old_records); + +/* Shutdown the logging subsystem. Caller must ensure that: + - no in progress or future call to any census_log functions + - no incomplete records +*/ +void census_log_shutdown(void); + +/* Allocates and returns a 'size' bytes record and marks it in use. A + subsequent census_log_end_write() marks the record complete. The + 'bytes_written' census_log_end_write() argument must be <= + 'size'. Returns NULL if out-of-space AND: + - log is configured to keep old records OR + - all blocks are pinned by incomplete records. +*/ +void* census_log_start_write(size_t size); + +void census_log_end_write(void* record, size_t bytes_written); + +void census_log_init_reader(void); + +/* census_log_read_next() iterates over blocks with data and for each block + returns a pointer to the first unread byte. The number of bytes that can be + read are returned in 'bytes_available'. Reader is expected to read all + available data. Reading the data consumes it i.e. it cannot be read again. + census_log_read_next() returns NULL if the end is reached i.e last block + is read. census_log_init_reader() starts the iteration or aborts the + current iteration. +*/ +const void* census_log_read_next(size_t* bytes_available); + +/* Returns estimated remaining space across all blocks, in bytes. If log is + configured to discard old records, returns total log space. Otherwise, + returns space available in empty blocks (partially filled blocks are + treated as full). +*/ +size_t census_log_remaining_space(void); + +/* Returns the number of times gprc_stats_log_start_write() failed due to + out-of-space. */ +int64_t census_log_out_of_space_count(void); + +#endif /* GRPC_CORE_CENSUS_MLOG_H */ diff --git a/src/core/lib/census/operation.c b/src/core/lib/census/operation.c new file mode 100644 index 0000000000..5c58704372 --- /dev/null +++ b/src/core/lib/census/operation.c @@ -0,0 +1,63 @@ +/* + * Copyright 2015, 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 + +/* TODO(aveitch): These are all placeholder implementations. */ + +census_timestamp census_start_rpc_op_timestamp(void) { + census_timestamp ct; + /* TODO(aveitch): assumes gpr_timespec implementation of census_timestamp. */ + ct.ts = gpr_now(GPR_CLOCK_MONOTONIC); + return ct; +} + +census_context *census_start_client_rpc_op( + const census_context *context, int64_t rpc_name_id, + const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, + const census_timestamp *start_time) { + return NULL; +} + +census_context *census_start_server_rpc_op( + const char *buffer, int64_t rpc_name_id, + const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, + census_timestamp *start_time) { + return NULL; +} + +census_context *census_start_op(census_context *context, const char *family, + const char *name, int trace_mask) { + return NULL; +} + +void census_end_op(census_context *context, int status) {} diff --git a/src/core/lib/census/placeholders.c b/src/core/lib/census/placeholders.c new file mode 100644 index 0000000000..fe23d13971 --- /dev/null +++ b/src/core/lib/census/placeholders.c @@ -0,0 +1,109 @@ +/* + * + * 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 + +#include + +/* Placeholders for the pending APIs */ + +int census_get_trace_record(census_trace_record *trace_record) { + (void)trace_record; + abort(); +} + +void census_record_values(census_context *context, census_value *values, + size_t nvalues) { + (void)context; + (void)values; + (void)nvalues; + abort(); +} + +void census_set_rpc_client_peer(census_context *context, const char *peer) { + (void)context; + (void)peer; + abort(); +} + +void census_trace_scan_end() { abort(); } + +int census_trace_scan_start(int consume) { + (void)consume; + abort(); +} + +const census_aggregation *census_view_aggregrations(const census_view *view) { + (void)view; + abort(); +} + +census_view *census_view_create(uint32_t metric_id, const census_context *tags, + const census_aggregation *aggregations, + size_t naggregations) { + (void)metric_id; + (void)tags; + (void)aggregations; + (void)naggregations; + abort(); +} + +const census_context *census_view_tags(const census_view *view) { + (void)view; + abort(); +} + +void census_view_delete(census_view *view) { + (void)view; + abort(); +} + +const census_view_data *census_view_get_data(const census_view *view) { + (void)view; + abort(); +} + +size_t census_view_metric(const census_view *view) { + (void)view; + abort(); +} + +size_t census_view_naggregations(const census_view *view) { + (void)view; + abort(); +} + +void census_view_reset(census_view *view) { + (void)view; + abort(); +} diff --git a/src/core/lib/census/rpc_metric_id.h b/src/core/lib/census/rpc_metric_id.h new file mode 100644 index 0000000000..f8d8dad0bf --- /dev/null +++ b/src/core/lib/census/rpc_metric_id.h @@ -0,0 +1,51 @@ +/* + * + * Copyright 2015-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_CENSUS_RPC_METRIC_ID_H +#define GRPC_CORE_CENSUS_RPC_METRIC_ID_H + +/* Metric ID's used for RPC measurements. */ +/* Count of client requests sent. */ +#define CENSUS_METRIC_RPC_CLIENT_REQUESTS ((uint32_t)0) +/* Count of server requests sent. */ +#define CENSUS_METRIC_RPC_SERVER_REQUESTS ((uint32_t)1) +/* Client error counts. */ +#define CENSUS_METRIC_RPC_CLIENT_ERRORS ((uint32_t)2) +/* Server error counts. */ +#define CENSUS_METRIC_RPC_SERVER_ERRORS ((uint32_t)3) +/* Client side request latency. */ +#define CENSUS_METRIC_RPC_CLIENT_LATENCY ((uint32_t)4) +/* Server side request latency. */ +#define CENSUS_METRIC_RPC_SERVER_LATENCY ((uint32_t)5) + +#endif /* GRPC_CORE_CENSUS_RPC_METRIC_ID_H */ diff --git a/src/core/lib/census/tracing.c b/src/core/lib/census/tracing.c new file mode 100644 index 0000000000..3b5d6dab2b --- /dev/null +++ b/src/core/lib/census/tracing.c @@ -0,0 +1,45 @@ +/* + * + * Copyright 2015, 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 + +/* 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) {} + +void census_trace_print(census_context *context, uint32_t type, + const char *buffer, size_t n) {} diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c new file mode 100644 index 0000000000..e0382fa0d9 --- /dev/null +++ b/src/core/lib/channel/channel_args.c @@ -0,0 +1,271 @@ +/* + * + * Copyright 2015-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/channel/channel_args.h" +#include +#include "src/core/support/string.h" + +#include +#include +#include +#include +#include + +#include + +static grpc_arg copy_arg(const grpc_arg *src) { + grpc_arg dst; + dst.type = src->type; + dst.key = gpr_strdup(src->key); + switch (dst.type) { + case GRPC_ARG_STRING: + dst.value.string = gpr_strdup(src->value.string); + break; + case GRPC_ARG_INTEGER: + dst.value.integer = src->value.integer; + break; + case GRPC_ARG_POINTER: + dst.value.pointer = src->value.pointer; + dst.value.pointer.p = + src->value.pointer.vtable->copy(src->value.pointer.p); + break; + } + return dst; +} + +grpc_channel_args *grpc_channel_args_copy_and_add(const grpc_channel_args *src, + const grpc_arg *to_add, + size_t num_to_add) { + grpc_channel_args *dst = gpr_malloc(sizeof(grpc_channel_args)); + size_t i; + size_t src_num_args = (src == NULL) ? 0 : src->num_args; + if (!src && !to_add) { + dst->num_args = 0; + dst->args = NULL; + return dst; + } + dst->num_args = src_num_args + num_to_add; + dst->args = gpr_malloc(sizeof(grpc_arg) * dst->num_args); + for (i = 0; i < src_num_args; i++) { + dst->args[i] = copy_arg(&src->args[i]); + } + for (i = 0; i < num_to_add; i++) { + dst->args[i + src_num_args] = copy_arg(&to_add[i]); + } + return dst; +} + +grpc_channel_args *grpc_channel_args_copy(const grpc_channel_args *src) { + return grpc_channel_args_copy_and_add(src, NULL, 0); +} + +grpc_channel_args *grpc_channel_args_merge(const grpc_channel_args *a, + const grpc_channel_args *b) { + return grpc_channel_args_copy_and_add(a, b->args, b->num_args); +} + +static int cmp_arg(const grpc_arg *a, const grpc_arg *b) { + int c = GPR_ICMP(a->type, b->type); + if (c != 0) return c; + c = strcmp(a->key, b->key); + if (c != 0) return c; + switch (a->type) { + case GRPC_ARG_STRING: + return strcmp(a->value.string, b->value.string); + case GRPC_ARG_INTEGER: + return GPR_ICMP(a->value.integer, b->value.integer); + case GRPC_ARG_POINTER: + c = GPR_ICMP(a->value.pointer.p, b->value.pointer.p); + if (c != 0) { + c = GPR_ICMP(a->value.pointer.vtable, b->value.pointer.vtable); + if (c == 0) { + c = a->value.pointer.vtable->cmp(a->value.pointer.p, + b->value.pointer.p); + } + } + return c; + } + GPR_UNREACHABLE_CODE(return 0); +} + +/* stabilizing comparison function: since channel_args ordering matters for + * keys with the same name, we need to preserve that ordering */ +static int cmp_key_stable(const void *ap, const void *bp) { + const grpc_arg *const *a = ap; + const grpc_arg *const *b = bp; + int c = strcmp((*a)->key, (*b)->key); + if (c == 0) c = GPR_ICMP(*a, *b); + return c; +} + +grpc_channel_args *grpc_channel_args_normalize(const grpc_channel_args *a) { + grpc_arg **args = gpr_malloc(sizeof(grpc_arg *) * a->num_args); + for (size_t i = 0; i < a->num_args; i++) { + args[i] = &a->args[i]; + } + qsort(args, a->num_args, sizeof(grpc_arg *), cmp_key_stable); + + grpc_channel_args *b = gpr_malloc(sizeof(grpc_channel_args)); + b->num_args = a->num_args; + b->args = gpr_malloc(sizeof(grpc_arg) * b->num_args); + for (size_t i = 0; i < a->num_args; i++) { + b->args[i] = copy_arg(args[i]); + } + + gpr_free(args); + return b; +} + +void grpc_channel_args_destroy(grpc_channel_args *a) { + size_t i; + for (i = 0; i < a->num_args; i++) { + switch (a->args[i].type) { + case GRPC_ARG_STRING: + gpr_free(a->args[i].value.string); + break; + case GRPC_ARG_INTEGER: + break; + case GRPC_ARG_POINTER: + a->args[i].value.pointer.vtable->destroy(a->args[i].value.pointer.p); + break; + } + gpr_free(a->args[i].key); + } + gpr_free(a->args); + gpr_free(a); +} + +int grpc_channel_args_is_census_enabled(const grpc_channel_args *a) { + size_t i; + if (a == NULL) return 0; + for (i = 0; i < a->num_args; i++) { + if (0 == strcmp(a->args[i].key, GRPC_ARG_ENABLE_CENSUS)) { + return a->args[i].value.integer != 0 && census_enabled(); + } + } + return census_enabled(); +} + +grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( + const grpc_channel_args *a) { + size_t i; + if (a == NULL) return 0; + for (i = 0; i < a->num_args; ++i) { + if (a->args[i].type == GRPC_ARG_INTEGER && + !strcmp(GRPC_COMPRESSION_ALGORITHM_ARG, a->args[i].key)) { + return (grpc_compression_algorithm)a->args[i].value.integer; + break; + } + } + return GRPC_COMPRESS_NONE; +} + +grpc_channel_args *grpc_channel_args_set_compression_algorithm( + grpc_channel_args *a, grpc_compression_algorithm algorithm) { + grpc_arg tmp; + tmp.type = GRPC_ARG_INTEGER; + tmp.key = GRPC_COMPRESSION_ALGORITHM_ARG; + tmp.value.integer = algorithm; + return grpc_channel_args_copy_and_add(a, &tmp, 1); +} + +/** Returns 1 if the argument for compression algorithm's enabled states bitset + * was found in \a a, returning the arg's value in \a states. Otherwise, returns + * 0. */ +static int find_compression_algorithm_states_bitset(const grpc_channel_args *a, + int **states_arg) { + if (a != NULL) { + size_t i; + for (i = 0; i < a->num_args; ++i) { + if (a->args[i].type == GRPC_ARG_INTEGER && + !strcmp(GRPC_COMPRESSION_ALGORITHM_STATE_ARG, a->args[i].key)) { + *states_arg = &a->args[i].value.integer; + return 1; /* GPR_TRUE */ + } + } + } + return 0; /* GPR_FALSE */ +} + +grpc_channel_args *grpc_channel_args_compression_algorithm_set_state( + grpc_channel_args **a, grpc_compression_algorithm algorithm, int state) { + int *states_arg; + grpc_channel_args *result = *a; + const int states_arg_found = + find_compression_algorithm_states_bitset(*a, &states_arg); + + if (states_arg_found) { + if (state != 0) { + GPR_BITSET((unsigned *)states_arg, algorithm); + } else { + GPR_BITCLEAR((unsigned *)states_arg, algorithm); + } + } else { + /* create a new arg */ + grpc_arg tmp; + tmp.type = GRPC_ARG_INTEGER; + tmp.key = GRPC_COMPRESSION_ALGORITHM_STATE_ARG; + /* all enabled by default */ + tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; + if (state != 0) { + GPR_BITSET((unsigned *)&tmp.value.integer, algorithm); + } else { + GPR_BITCLEAR((unsigned *)&tmp.value.integer, algorithm); + } + result = grpc_channel_args_copy_and_add(*a, &tmp, 1); + grpc_channel_args_destroy(*a); + *a = result; + } + return result; +} + +int grpc_channel_args_compression_algorithm_get_states( + const grpc_channel_args *a) { + int *states_arg; + if (find_compression_algorithm_states_bitset(a, &states_arg)) { + return *states_arg; + } else { + return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */ + } +} + +int grpc_channel_args_compare(const grpc_channel_args *a, + const grpc_channel_args *b) { + int c = GPR_ICMP(a->num_args, b->num_args); + if (c != 0) return c; + for (size_t i = 0; i < a->num_args; i++) { + c = cmp_arg(&a->args[i], &b->args[i]); + if (c != 0) return c; + } + return 0; +} diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h new file mode 100644 index 0000000000..e19440f76f --- /dev/null +++ b/src/core/lib/channel/channel_args.h @@ -0,0 +1,94 @@ +/* + * + * Copyright 2015-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_CHANNEL_CHANNEL_ARGS_H +#define GRPC_CORE_CHANNEL_CHANNEL_ARGS_H + +#include +#include + +/* Copy some arguments */ +grpc_channel_args *grpc_channel_args_copy(const grpc_channel_args *src); + +/* Copy some arguments, stably sorting keys */ +grpc_channel_args *grpc_channel_args_normalize(const grpc_channel_args *a); + +/** Copy some arguments and add the to_add parameter in the end. + If to_add is NULL, it is equivalent to call grpc_channel_args_copy. */ +grpc_channel_args *grpc_channel_args_copy_and_add(const grpc_channel_args *src, + const grpc_arg *to_add, + size_t num_to_add); + +/** Copy args from a then args from b into a new channel args */ +grpc_channel_args *grpc_channel_args_merge(const grpc_channel_args *a, + const grpc_channel_args *b); + +/** Destroy arguments created by grpc_channel_args_copy */ +void grpc_channel_args_destroy(grpc_channel_args *a); + +/** Reads census_enabled settings from channel args. Returns 1 if census_enabled + * is specified in channel args, otherwise returns 0. */ +int grpc_channel_args_is_census_enabled(const grpc_channel_args *a); + +/** Returns the compression algorithm set in \a a. */ +grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( + const grpc_channel_args *a); + +/** Returns a channel arg instance with compression enabled. If \a a is + * non-NULL, its args are copied. N.B. GRPC_COMPRESS_NONE disables compression + * for the channel. */ +grpc_channel_args *grpc_channel_args_set_compression_algorithm( + grpc_channel_args *a, grpc_compression_algorithm algorithm); + +/** Sets the support for the given compression algorithm. By default, all + * compression algorithms are enabled. It's an error to disable an algorithm set + * by grpc_channel_args_set_compression_algorithm. + * + * Returns an instance with the updated algorithm states. The \a a pointer is + * modified to point to the returned instance (which may be different from the + * input value of \a a). */ +grpc_channel_args *grpc_channel_args_compression_algorithm_set_state( + grpc_channel_args **a, grpc_compression_algorithm algorithm, int enabled); + +/** Returns the bitset representing the support state (true for enabled, false + * for disabled) for compression algorithms. + * + * The i-th bit of the returned bitset corresponds to the i-th entry in the + * grpc_compression_algorithm enum. */ +int grpc_channel_args_compression_algorithm_get_states( + const grpc_channel_args *a); + +int grpc_channel_args_compare(const grpc_channel_args *a, + const grpc_channel_args *b); + +#endif /* GRPC_CORE_CHANNEL_CHANNEL_ARGS_H */ diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c new file mode 100644 index 0000000000..3e61688364 --- /dev/null +++ b/src/core/lib/channel/channel_stack.c @@ -0,0 +1,262 @@ +/* + * + * Copyright 2015, 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/channel/channel_stack.h" +#include + +#include +#include + +int grpc_trace_channel = 0; + +/* Memory layouts. + + Channel stack is laid out as: { + grpc_channel_stack stk; + padding to GPR_MAX_ALIGNMENT + grpc_channel_element[stk.count]; + per-filter memory, aligned to GPR_MAX_ALIGNMENT + } + + Call stack is laid out as: { + grpc_call_stack stk; + padding to GPR_MAX_ALIGNMENT + grpc_call_element[stk.count]; + per-filter memory, aligned to GPR_MAX_ALIGNMENT + } */ + +/* Given a size, round up to the next multiple of sizeof(void*) */ +#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \ + (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u)) + +size_t grpc_channel_stack_size(const grpc_channel_filter **filters, + size_t filter_count) { + /* always need the header, and size for the channel elements */ + size_t size = + ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)) + + ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element)); + size_t i; + + GPR_ASSERT((GPR_MAX_ALIGNMENT & (GPR_MAX_ALIGNMENT - 1)) == 0 && + "GPR_MAX_ALIGNMENT must be a power of two"); + + /* add the size for each filter */ + for (i = 0; i < filter_count; i++) { + size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); + } + + return size; +} + +#define CHANNEL_ELEMS_FROM_STACK(stk) \ + ((grpc_channel_element *)((char *)(stk) + ROUND_UP_TO_ALIGNMENT_SIZE( \ + sizeof(grpc_channel_stack)))) + +#define CALL_ELEMS_FROM_STACK(stk) \ + ((grpc_call_element *)((char *)(stk) + \ + ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)))) + +grpc_channel_element *grpc_channel_stack_element( + grpc_channel_stack *channel_stack, size_t index) { + return CHANNEL_ELEMS_FROM_STACK(channel_stack) + index; +} + +grpc_channel_element *grpc_channel_stack_last_element( + grpc_channel_stack *channel_stack) { + return grpc_channel_stack_element(channel_stack, channel_stack->count - 1); +} + +grpc_call_element *grpc_call_stack_element(grpc_call_stack *call_stack, + size_t index) { + return CALL_ELEMS_FROM_STACK(call_stack) + index; +} + +void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs, + grpc_iomgr_cb_func destroy, void *destroy_arg, + const grpc_channel_filter **filters, + size_t filter_count, + const grpc_channel_args *channel_args, + const char *name, grpc_channel_stack *stack) { + size_t call_size = + ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) + + ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element)); + grpc_channel_element *elems; + grpc_channel_element_args args; + char *user_data; + size_t i; + + stack->count = filter_count; + GRPC_STREAM_REF_INIT(&stack->refcount, initial_refs, destroy, destroy_arg, + name); + elems = CHANNEL_ELEMS_FROM_STACK(stack); + user_data = + ((char *)elems) + + ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element)); + + /* init per-filter data */ + for (i = 0; i < filter_count; i++) { + args.channel_stack = stack; + args.channel_args = channel_args; + args.is_first = i == 0; + args.is_last = i == (filter_count - 1); + elems[i].filter = filters[i]; + elems[i].channel_data = user_data; + elems[i].filter->init_channel_elem(exec_ctx, &elems[i], &args); + user_data += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); + call_size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data); + } + + GPR_ASSERT(user_data > (char *)stack); + GPR_ASSERT((uintptr_t)(user_data - (char *)stack) == + grpc_channel_stack_size(filters, filter_count)); + + stack->call_stack_size = call_size; +} + +void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx, + grpc_channel_stack *stack) { + grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(stack); + size_t count = stack->count; + size_t i; + + /* destroy per-filter data */ + for (i = 0; i < count; i++) { + channel_elems[i].filter->destroy_channel_elem(exec_ctx, &channel_elems[i]); + } +} + +void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, + grpc_channel_stack *channel_stack, int initial_refs, + grpc_iomgr_cb_func destroy, void *destroy_arg, + grpc_call_context_element *context, + const void *transport_server_data, + grpc_call_stack *call_stack) { + grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(channel_stack); + grpc_call_element_args args; + size_t count = channel_stack->count; + grpc_call_element *call_elems; + char *user_data; + size_t i; + + call_stack->count = count; + GRPC_STREAM_REF_INIT(&call_stack->refcount, initial_refs, destroy, + destroy_arg, "CALL_STACK"); + call_elems = CALL_ELEMS_FROM_STACK(call_stack); + user_data = ((char *)call_elems) + + ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element)); + + /* init per-filter data */ + for (i = 0; i < count; i++) { + args.call_stack = call_stack; + args.server_transport_data = transport_server_data; + args.context = context; + call_elems[i].filter = channel_elems[i].filter; + call_elems[i].channel_data = channel_elems[i].channel_data; + call_elems[i].call_data = user_data; + call_elems[i].filter->init_call_elem(exec_ctx, &call_elems[i], &args); + user_data += + ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data); + } +} + +void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx, + grpc_call_stack *call_stack, + grpc_pollset *pollset) { + size_t count = call_stack->count; + grpc_call_element *call_elems; + char *user_data; + size_t i; + + call_elems = CALL_ELEMS_FROM_STACK(call_stack); + user_data = ((char *)call_elems) + + ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element)); + + /* init per-filter data */ + for (i = 0; i < count; i++) { + call_elems[i].filter->set_pollset(exec_ctx, &call_elems[i], pollset); + user_data += + ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data); + } +} + +void grpc_call_stack_ignore_set_pollset(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_pollset *pollset) {} + +void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack) { + grpc_call_element *elems = CALL_ELEMS_FROM_STACK(stack); + size_t count = stack->count; + size_t i; + + /* destroy per-filter data */ + for (i = 0; i < count; i++) { + elems[i].filter->destroy_call_elem(exec_ctx, &elems[i]); + } +} + +void grpc_call_next_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_transport_stream_op *op) { + grpc_call_element *next_elem = elem + 1; + next_elem->filter->start_transport_stream_op(exec_ctx, next_elem, op); +} + +char *grpc_call_next_get_peer(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + grpc_call_element *next_elem = elem + 1; + return next_elem->filter->get_peer(exec_ctx, next_elem); +} + +void grpc_channel_next_op(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, + grpc_transport_op *op) { + grpc_channel_element *next_elem = elem + 1; + next_elem->filter->start_transport_op(exec_ctx, next_elem, op); +} + +grpc_channel_stack *grpc_channel_stack_from_top_element( + grpc_channel_element *elem) { + return (grpc_channel_stack *)((char *)(elem)-ROUND_UP_TO_ALIGNMENT_SIZE( + sizeof(grpc_channel_stack))); +} + +grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem) { + return (grpc_call_stack *)((char *)(elem)-ROUND_UP_TO_ALIGNMENT_SIZE( + sizeof(grpc_call_stack))); +} + +void grpc_call_element_send_cancel(grpc_exec_ctx *exec_ctx, + grpc_call_element *cur_elem) { + grpc_transport_stream_op op; + memset(&op, 0, sizeof(op)); + op.cancel_with_status = GRPC_STATUS_CANCELLED; + grpc_call_next_op(exec_ctx, cur_elem, &op); +} diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h new file mode 100644 index 0000000000..52362f0b20 --- /dev/null +++ b/src/core/lib/channel/channel_stack.h @@ -0,0 +1,260 @@ +/* + * + * Copyright 2015-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_CHANNEL_CHANNEL_STACK_H +#define GRPC_CORE_CHANNEL_CHANNEL_STACK_H + +/* A channel filter defines how operations on a channel are implemented. + Channel filters are chained together to create full channels, and if those + chains are linear, then channel stacks provide a mechanism to minimize + allocations for that chain. + Call stacks are created by channel stacks and represent the per-call data + for that stack. */ + +#include + +#include +#include +#include "src/core/debug/trace.h" +#include "src/core/transport/transport.h" + +typedef struct grpc_channel_element grpc_channel_element; +typedef struct grpc_call_element grpc_call_element; + +typedef struct grpc_channel_stack grpc_channel_stack; +typedef struct grpc_call_stack grpc_call_stack; + +typedef struct { + grpc_channel_stack *channel_stack; + const grpc_channel_args *channel_args; + int is_first; + int is_last; +} grpc_channel_element_args; + +typedef struct { + grpc_call_stack *call_stack; + const void *server_transport_data; + grpc_call_context_element *context; +} grpc_call_element_args; + +/* Channel filters specify: + 1. the amount of memory needed in the channel & call (via the sizeof_XXX + members) + 2. functions to initialize and destroy channel & call data + (init_XXX, destroy_XXX) + 3. functions to implement call operations and channel operations (call_op, + channel_op) + 4. a name, which is useful when debugging + + Members are laid out in approximate frequency of use order. */ +typedef struct { + /* Called to eg. send/receive data on a call. + See grpc_call_next_op on how to call the next element in the stack */ + void (*start_transport_stream_op)(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op); + /* Called to handle channel level operations - e.g. new calls, or transport + closure. + See grpc_channel_next_op on how to call the next element in the stack */ + void (*start_transport_op)(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, grpc_transport_op *op); + + /* sizeof(per call data) */ + size_t sizeof_call_data; + /* Initialize per call data. + elem is initialized at the start of the call, and elem->call_data is what + needs initializing. + The filter does not need to do any chaining. + server_transport_data is an opaque pointer. If it is NULL, this call is + on a client; if it is non-NULL, then it points to memory owned by the + transport and is on the server. Most filters want to ignore this + argument. */ + void (*init_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args); + void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_pollset *pollset); + /* Destroy per call data. + The filter does not need to do any chaining */ + void (*destroy_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); + + /* sizeof(per channel data) */ + size_t sizeof_channel_data; + /* Initialize per-channel data. + elem is initialized at the start of the call, and elem->channel_data is + what needs initializing. + is_first, is_last designate this elements position in the stack, and are + useful for asserting correct configuration by upper layer code. + The filter does not need to do any chaining */ + void (*init_channel_elem)(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, + grpc_channel_element_args *args); + /* Destroy per channel data. + The filter does not need to do any chaining */ + void (*destroy_channel_elem)(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem); + + /* Implement grpc_call_get_peer() */ + char *(*get_peer)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); + + /* The name of this filter */ + const char *name; +} grpc_channel_filter; + +/* A channel_element tracks its filter and the filter requested memory within + a channel allocation */ +struct grpc_channel_element { + const grpc_channel_filter *filter; + void *channel_data; +}; + +/* A call_element tracks its filter, the filter requested memory within + a channel allocation, and the filter requested memory within a call + allocation */ +struct grpc_call_element { + const grpc_channel_filter *filter; + void *channel_data; + void *call_data; +}; + +/* A channel stack tracks a set of related filters for one channel, and + guarantees they live within a single malloc() allocation */ +struct grpc_channel_stack { + grpc_stream_refcount refcount; + size_t count; + /* Memory required for a call stack (computed at channel stack + initialization) */ + size_t call_stack_size; +}; + +/* A call stack tracks a set of related filters for one call, and guarantees + they live within a single malloc() allocation */ +struct grpc_call_stack { + /* shared refcount for this channel stack. + MUST be the first element: the underlying code calls destroy + with the address of the refcount, but higher layers prefer to think + about the address of the call stack itself. */ + grpc_stream_refcount refcount; + size_t count; +}; + +/* Get a channel element given a channel stack and its index */ +grpc_channel_element *grpc_channel_stack_element(grpc_channel_stack *stack, + size_t i); +/* Get the last channel element in a channel stack */ +grpc_channel_element *grpc_channel_stack_last_element( + grpc_channel_stack *stack); +/* Get a call stack element given a call stack and an index */ +grpc_call_element *grpc_call_stack_element(grpc_call_stack *stack, size_t i); + +/* Determine memory required for a channel stack containing a set of filters */ +size_t grpc_channel_stack_size(const grpc_channel_filter **filters, + size_t filter_count); +/* Initialize a channel stack given some filters */ +void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs, + grpc_iomgr_cb_func destroy, void *destroy_arg, + const grpc_channel_filter **filters, + size_t filter_count, const grpc_channel_args *args, + const char *name, grpc_channel_stack *stack); +/* Destroy a channel stack */ +void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx, + grpc_channel_stack *stack); + +/* Initialize a call stack given a channel stack. transport_server_data is + expected to be NULL on a client, or an opaque transport owned pointer on the + server. */ +void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, + grpc_channel_stack *channel_stack, int initial_refs, + grpc_iomgr_cb_func destroy, void *destroy_arg, + grpc_call_context_element *context, + const void *transport_server_data, + grpc_call_stack *call_stack); +/* Set a pollset for a call stack: must occur before the first op is started */ +void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx, + grpc_call_stack *call_stack, + grpc_pollset *pollset); + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +#define GRPC_CALL_STACK_REF(call_stack, reason) \ + grpc_stream_ref(&(call_stack)->refcount, reason) +#define GRPC_CALL_STACK_UNREF(exec_ctx, call_stack, reason) \ + grpc_stream_unref(exec_ctx, &(call_stack)->refcount, reason) +#define GRPC_CHANNEL_STACK_REF(channel_stack, reason) \ + grpc_stream_ref(&(channel_stack)->refcount, reason) +#define GRPC_CHANNEL_STACK_UNREF(exec_ctx, channel_stack, reason) \ + grpc_stream_unref(exec_ctx, &(channel_stack)->refcount, reason) +#else +#define GRPC_CALL_STACK_REF(call_stack, reason) \ + grpc_stream_ref(&(call_stack)->refcount) +#define GRPC_CALL_STACK_UNREF(exec_ctx, call_stack, reason) \ + grpc_stream_unref(exec_ctx, &(call_stack)->refcount) +#define GRPC_CHANNEL_STACK_REF(channel_stack, reason) \ + grpc_stream_ref(&(channel_stack)->refcount) +#define GRPC_CHANNEL_STACK_UNREF(exec_ctx, channel_stack, reason) \ + grpc_stream_unref(exec_ctx, &(channel_stack)->refcount) +#endif + +/* Destroy a call stack */ +void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack); + +/* Ignore set pollset - used by filters to implement the set_pollset method + if they don't care about pollsets at all. Does nothing. */ +void grpc_call_stack_ignore_set_pollset(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_pollset *pollset); +/* Call the next operation in a call stack */ +void grpc_call_next_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_transport_stream_op *op); +/* Call the next operation (depending on call directionality) in a channel + stack */ +void grpc_channel_next_op(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, + grpc_transport_op *op); +/* Pass through a request to get_peer to the next child element */ +char *grpc_call_next_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); + +/* Given the top element of a channel stack, get the channel stack itself */ +grpc_channel_stack *grpc_channel_stack_from_top_element( + grpc_channel_element *elem); +/* Given the top element of a call stack, get the call stack itself */ +grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem); + +void grpc_call_log_op(char *file, int line, gpr_log_severity severity, + grpc_call_element *elem, grpc_transport_stream_op *op); + +void grpc_call_element_send_cancel(grpc_exec_ctx *exec_ctx, + grpc_call_element *cur_elem); + +extern int grpc_trace_channel; + +#define GRPC_CALL_LOG_OP(sev, elem, op) \ + if (grpc_trace_channel) grpc_call_log_op(sev, elem, op) + +#endif /* GRPC_CORE_CHANNEL_CHANNEL_STACK_H */ diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c new file mode 100644 index 0000000000..1b1004e5f9 --- /dev/null +++ b/src/core/lib/channel/channel_stack_builder.c @@ -0,0 +1,258 @@ +/* + * + * 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/channel/channel_stack_builder.h" + +#include + +#include + +int grpc_trace_channel_stack_builder = 0; + +typedef struct filter_node { + struct filter_node *next; + struct filter_node *prev; + const grpc_channel_filter *filter; + grpc_post_filter_create_init_func init; + void *init_arg; +} filter_node; + +struct grpc_channel_stack_builder { + // sentinel nodes for filters that have been added + filter_node begin; + filter_node end; + // various set/get-able parameters + const grpc_channel_args *args; + grpc_transport *transport; + const char *name; +}; + +struct grpc_channel_stack_builder_iterator { + grpc_channel_stack_builder *builder; + filter_node *node; +}; + +grpc_channel_stack_builder *grpc_channel_stack_builder_create(void) { + grpc_channel_stack_builder *b = gpr_malloc(sizeof(*b)); + memset(b, 0, sizeof(*b)); + + b->begin.filter = NULL; + b->end.filter = NULL; + b->begin.next = &b->end; + b->begin.prev = &b->end; + b->end.next = &b->begin; + b->end.prev = &b->begin; + + return b; +} + +static grpc_channel_stack_builder_iterator *create_iterator_at_filter_node( + grpc_channel_stack_builder *builder, filter_node *node) { + grpc_channel_stack_builder_iterator *it = gpr_malloc(sizeof(*it)); + it->builder = builder; + it->node = node; + return it; +} + +void grpc_channel_stack_builder_iterator_destroy( + grpc_channel_stack_builder_iterator *it) { + gpr_free(it); +} + +grpc_channel_stack_builder_iterator * +grpc_channel_stack_builder_create_iterator_at_first( + grpc_channel_stack_builder *builder) { + return create_iterator_at_filter_node(builder, &builder->begin); +} + +grpc_channel_stack_builder_iterator * +grpc_channel_stack_builder_create_iterator_at_last( + grpc_channel_stack_builder *builder) { + return create_iterator_at_filter_node(builder, &builder->end); +} + +bool grpc_channel_stack_builder_move_next( + grpc_channel_stack_builder_iterator *iterator) { + if (iterator->node == &iterator->builder->end) return false; + iterator->node = iterator->node->next; + return true; +} + +bool grpc_channel_stack_builder_move_prev( + grpc_channel_stack_builder_iterator *iterator) { + if (iterator->node == &iterator->builder->begin) return false; + iterator->node = iterator->node->prev; + return true; +} + +bool grpc_channel_stack_builder_move_prev( + grpc_channel_stack_builder_iterator *iterator); + +void grpc_channel_stack_builder_set_name(grpc_channel_stack_builder *builder, + const char *name) { + GPR_ASSERT(builder->name == NULL); + builder->name = name; +} + +void grpc_channel_stack_builder_set_channel_arguments( + grpc_channel_stack_builder *builder, const grpc_channel_args *args) { + GPR_ASSERT(builder->args == NULL); + builder->args = args; +} + +void grpc_channel_stack_builder_set_transport( + grpc_channel_stack_builder *builder, grpc_transport *transport) { + GPR_ASSERT(builder->transport == NULL); + builder->transport = transport; +} + +grpc_transport *grpc_channel_stack_builder_get_transport( + grpc_channel_stack_builder *builder) { + return builder->transport; +} + +const grpc_channel_args *grpc_channel_stack_builder_get_channel_arguments( + grpc_channel_stack_builder *builder) { + return builder->args; +} + +bool grpc_channel_stack_builder_append_filter( + grpc_channel_stack_builder *builder, const grpc_channel_filter *filter, + grpc_post_filter_create_init_func post_init_func, void *user_data) { + grpc_channel_stack_builder_iterator *it = + grpc_channel_stack_builder_create_iterator_at_last(builder); + bool ok = grpc_channel_stack_builder_add_filter_before( + it, filter, post_init_func, user_data); + grpc_channel_stack_builder_iterator_destroy(it); + return ok; +} + +bool grpc_channel_stack_builder_prepend_filter( + grpc_channel_stack_builder *builder, const grpc_channel_filter *filter, + grpc_post_filter_create_init_func post_init_func, void *user_data) { + grpc_channel_stack_builder_iterator *it = + grpc_channel_stack_builder_create_iterator_at_first(builder); + bool ok = grpc_channel_stack_builder_add_filter_after( + it, filter, post_init_func, user_data); + grpc_channel_stack_builder_iterator_destroy(it); + return ok; +} + +static void add_after(filter_node *before, const grpc_channel_filter *filter, + grpc_post_filter_create_init_func post_init_func, + void *user_data) { + filter_node *new = gpr_malloc(sizeof(*new)); + new->next = before->next; + new->prev = before; + new->next->prev = new->prev->next = new; + new->filter = filter; + new->init = post_init_func; + new->init_arg = user_data; +} + +bool grpc_channel_stack_builder_add_filter_before( + grpc_channel_stack_builder_iterator *iterator, + const grpc_channel_filter *filter, + grpc_post_filter_create_init_func post_init_func, void *user_data) { + if (iterator->node == &iterator->builder->begin) return false; + add_after(iterator->node->prev, filter, post_init_func, user_data); + return true; +} + +bool grpc_channel_stack_builder_add_filter_after( + grpc_channel_stack_builder_iterator *iterator, + const grpc_channel_filter *filter, + grpc_post_filter_create_init_func post_init_func, void *user_data) { + if (iterator->node == &iterator->builder->end) return false; + add_after(iterator->node, filter, post_init_func, user_data); + return true; +} + +void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder) { + filter_node *p = builder->begin.next; + while (p != &builder->end) { + filter_node *next = p->next; + gpr_free(p); + p = next; + } + gpr_free(builder); +} + +void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx, + grpc_channel_stack_builder *builder, + size_t prefix_bytes, int initial_refs, + grpc_iomgr_cb_func destroy, + void *destroy_arg) { + // count the number of filters + size_t num_filters = 0; + for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) { + num_filters++; + } + + // create an array of filters + const grpc_channel_filter **filters = + gpr_malloc(sizeof(*filters) * num_filters); + size_t i = 0; + for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) { + filters[i++] = p->filter; + } + + // calculate the size of the channel stack + size_t channel_stack_size = grpc_channel_stack_size(filters, num_filters); + + // allocate memory, with prefix_bytes followed by channel_stack_size + char *result = gpr_malloc(prefix_bytes + channel_stack_size); + // fetch a pointer to the channel stack + grpc_channel_stack *channel_stack = + (grpc_channel_stack *)(result + prefix_bytes); + // and initialize it + grpc_channel_stack_init(exec_ctx, initial_refs, destroy, + destroy_arg == NULL ? result : destroy_arg, filters, + num_filters, builder->args, builder->name, + channel_stack); + + // run post-initialization functions + i = 0; + for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) { + if (p->init != NULL) { + p->init(channel_stack, grpc_channel_stack_element(channel_stack, i), + p->init_arg); + } + i++; + } + + grpc_channel_stack_builder_destroy(builder); + gpr_free((grpc_channel_filter **)filters); + + return result; +} diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h new file mode 100644 index 0000000000..15f395e8b8 --- /dev/null +++ b/src/core/lib/channel/channel_stack_builder.h @@ -0,0 +1,155 @@ +/* + * + * 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_CHANNEL_CHANNEL_STACK_BUILDER_H +#define GRPC_CORE_CHANNEL_CHANNEL_STACK_BUILDER_H + +#include + +#include "src/core/channel/channel_args.h" +#include "src/core/channel/channel_stack.h" + +/// grpc_channel_stack_builder offers a programmatic interface to selected +/// and order channel filters +typedef struct grpc_channel_stack_builder grpc_channel_stack_builder; +typedef struct grpc_channel_stack_builder_iterator + grpc_channel_stack_builder_iterator; + +/// Create a new channel stack builder +grpc_channel_stack_builder *grpc_channel_stack_builder_create(void); + +/// Assign a name to the channel stack: \a name must be statically allocated +void grpc_channel_stack_builder_set_name(grpc_channel_stack_builder *builder, + const char *name); + +/// Attach \a transport to the builder (does not take ownership) +void grpc_channel_stack_builder_set_transport( + grpc_channel_stack_builder *builder, grpc_transport *transport); + +/// Fetch attached transport +grpc_transport *grpc_channel_stack_builder_get_transport( + grpc_channel_stack_builder *builder); + +/// Set channel arguments: \a args must continue to exist until after +/// grpc_channel_stack_builder_finish returns +void grpc_channel_stack_builder_set_channel_arguments( + grpc_channel_stack_builder *builder, const grpc_channel_args *args); + +/// Return a borrowed pointer to the channel arguments +const grpc_channel_args *grpc_channel_stack_builder_get_channel_arguments( + grpc_channel_stack_builder *builder); + +/// Begin iterating over already defined filters in the builder at the beginning +grpc_channel_stack_builder_iterator * +grpc_channel_stack_builder_create_iterator_at_first( + grpc_channel_stack_builder *builder); + +/// Begin iterating over already defined filters in the builder at the end +grpc_channel_stack_builder_iterator * +grpc_channel_stack_builder_create_iterator_at_last( + grpc_channel_stack_builder *builder); + +/// Is an iterator at the first element? +bool grpc_channel_stack_builder_iterator_is_first( + grpc_channel_stack_builder_iterator *iterator); + +/// Is an iterator at the end? +bool grpc_channel_stack_builder_iterator_is_end( + grpc_channel_stack_builder_iterator *iterator); + +/// Move an iterator to the next item +bool grpc_channel_stack_builder_move_next( + grpc_channel_stack_builder_iterator *iterator); + +/// Move an iterator to the previous item +bool grpc_channel_stack_builder_move_prev( + grpc_channel_stack_builder_iterator *iterator); + +typedef void (*grpc_post_filter_create_init_func)( + grpc_channel_stack *channel_stack, grpc_channel_element *elem, void *arg); + +/// Add \a filter to the stack, after \a iterator. +/// Call \a post_init_func(..., \a user_data) once the channel stack is +/// created. +bool grpc_channel_stack_builder_add_filter_after( + grpc_channel_stack_builder_iterator *iterator, + const grpc_channel_filter *filter, + grpc_post_filter_create_init_func post_init_func, + void *user_data) GRPC_MUST_USE_RESULT; + +/// Add \a filter to the stack, before \a iterator. +/// Call \a post_init_func(..., \a user_data) once the channel stack is +/// created. +bool grpc_channel_stack_builder_add_filter_before( + grpc_channel_stack_builder_iterator *iterator, + const grpc_channel_filter *filter, + grpc_post_filter_create_init_func post_init_func, + void *user_data) GRPC_MUST_USE_RESULT; + +/// Add \a filter to the beginning of the filter list. +/// Call \a post_init_func(..., \a user_data) once the channel stack is +/// created. +bool grpc_channel_stack_builder_prepend_filter( + grpc_channel_stack_builder *builder, const grpc_channel_filter *filter, + grpc_post_filter_create_init_func post_init_func, + void *user_data) GRPC_MUST_USE_RESULT; + +/// Add \a filter to the end of the filter list. +/// Call \a post_init_func(..., \a user_data) once the channel stack is +/// created. +bool grpc_channel_stack_builder_append_filter( + grpc_channel_stack_builder *builder, const grpc_channel_filter *filter, + grpc_post_filter_create_init_func post_init_func, + void *user_data) GRPC_MUST_USE_RESULT; + +/// Terminate iteration and destroy \a iterator +void grpc_channel_stack_builder_iterator_destroy( + grpc_channel_stack_builder_iterator *iterator); + +/// Destroy the builder, return the freshly minted channel stack +/// Allocates \a prefix_bytes bytes before the channel stack +/// Returns the base pointer of the allocated block +/// \a initial_refs, \a destroy, \a destroy_arg are as per +/// grpc_channel_stack_init +void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx, + grpc_channel_stack_builder *builder, + size_t prefix_bytes, int initial_refs, + grpc_iomgr_cb_func destroy, + void *destroy_arg); + +/// Destroy the builder without creating a channel stack +void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder); + +extern int grpc_trace_channel_stack_builder; + +#endif /* GRPC_CORE_CHANNEL_CHANNEL_STACK_BUILDER_H */ diff --git a/src/core/lib/channel/client_channel.c b/src/core/lib/channel/client_channel.c new file mode 100644 index 0000000000..ad1ded9ab7 --- /dev/null +++ b/src/core/lib/channel/client_channel.c @@ -0,0 +1,526 @@ +/* + * + * Copyright 2015-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/channel/client_channel.h" + +#include +#include + +#include +#include +#include +#include + +#include "src/core/channel/channel_args.h" +#include "src/core/channel/connected_channel.h" +#include "src/core/channel/subchannel_call_holder.h" +#include "src/core/iomgr/iomgr.h" +#include "src/core/profiling/timers.h" +#include "src/core/support/string.h" +#include "src/core/surface/channel.h" +#include "src/core/transport/connectivity_state.h" + +/* Client channel implementation */ + +typedef grpc_subchannel_call_holder call_data; + +typedef struct client_channel_channel_data { + /** resolver for this channel */ + grpc_resolver *resolver; + /** have we started resolving this channel */ + int started_resolving; + + /** mutex protecting client configuration, including all + variables below in this data structure */ + gpr_mu mu_config; + /** currently active load balancer - guarded by mu_config */ + grpc_lb_policy *lb_policy; + /** incoming configuration - set by resolver.next + guarded by mu_config */ + grpc_client_config *incoming_configuration; + /** a list of closures that are all waiting for config to come in */ + grpc_closure_list waiting_for_config_closures; + /** resolver callback */ + grpc_closure on_config_changed; + /** connectivity state being tracked */ + grpc_connectivity_state_tracker state_tracker; + /** when an lb_policy arrives, should we try to exit idle */ + int exit_idle_when_lb_policy_arrives; + /** owning stack */ + grpc_channel_stack *owning_stack; + /** interested parties (owned) */ + grpc_pollset_set *interested_parties; +} channel_data; + +/** We create one watcher for each new lb_policy that is returned from a + resolver, + to watch for state changes from the lb_policy. When a state change is seen, + we + update the channel, and create a new watcher */ +typedef struct { + channel_data *chand; + grpc_closure on_changed; + grpc_connectivity_state state; + grpc_lb_policy *lb_policy; +} lb_policy_connectivity_watcher; + +typedef struct { + grpc_closure closure; + grpc_call_element *elem; +} waiting_call; + +static char *cc_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { + return grpc_subchannel_call_holder_get_peer(exec_ctx, elem->call_data); +} + +static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + GRPC_CALL_LOG_OP(GPR_INFO, elem, op); + grpc_subchannel_call_holder_perform_op(exec_ctx, elem->call_data, op); +} + +static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand, + grpc_lb_policy *lb_policy, + grpc_connectivity_state current_state); + +static void on_lb_policy_state_changed_locked( + grpc_exec_ctx *exec_ctx, lb_policy_connectivity_watcher *w) { + grpc_connectivity_state publish_state = w->state; + /* check if the notification is for a stale policy */ + if (w->lb_policy != w->chand->lb_policy) return; + + if (publish_state == GRPC_CHANNEL_FATAL_FAILURE && + w->chand->resolver != NULL) { + publish_state = GRPC_CHANNEL_TRANSIENT_FAILURE; + grpc_resolver_channel_saw_error(exec_ctx, w->chand->resolver); + GRPC_LB_POLICY_UNREF(exec_ctx, w->chand->lb_policy, "channel"); + w->chand->lb_policy = NULL; + } + grpc_connectivity_state_set(exec_ctx, &w->chand->state_tracker, publish_state, + "lb_changed"); + if (w->state != GRPC_CHANNEL_FATAL_FAILURE) { + watch_lb_policy(exec_ctx, w->chand, w->lb_policy, w->state); + } +} + +static void on_lb_policy_state_changed(grpc_exec_ctx *exec_ctx, void *arg, + bool iomgr_success) { + lb_policy_connectivity_watcher *w = arg; + + gpr_mu_lock(&w->chand->mu_config); + on_lb_policy_state_changed_locked(exec_ctx, w); + gpr_mu_unlock(&w->chand->mu_config); + + GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack, "watch_lb_policy"); + gpr_free(w); +} + +static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand, + grpc_lb_policy *lb_policy, + grpc_connectivity_state current_state) { + lb_policy_connectivity_watcher *w = gpr_malloc(sizeof(*w)); + GRPC_CHANNEL_STACK_REF(chand->owning_stack, "watch_lb_policy"); + + w->chand = chand; + grpc_closure_init(&w->on_changed, on_lb_policy_state_changed, w); + w->state = current_state; + w->lb_policy = lb_policy; + grpc_lb_policy_notify_on_state_change(exec_ctx, lb_policy, &w->state, + &w->on_changed); +} + +static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg, + bool iomgr_success) { + channel_data *chand = arg; + grpc_lb_policy *lb_policy = NULL; + grpc_lb_policy *old_lb_policy; + grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE; + int exit_idle = 0; + + if (chand->incoming_configuration != NULL) { + lb_policy = grpc_client_config_get_lb_policy(chand->incoming_configuration); + if (lb_policy != NULL) { + GRPC_LB_POLICY_REF(lb_policy, "channel"); + GRPC_LB_POLICY_REF(lb_policy, "config_change"); + state = grpc_lb_policy_check_connectivity(exec_ctx, lb_policy); + } + + grpc_client_config_unref(exec_ctx, chand->incoming_configuration); + } + + chand->incoming_configuration = NULL; + + if (lb_policy != NULL) { + grpc_pollset_set_add_pollset_set(exec_ctx, lb_policy->interested_parties, + chand->interested_parties); + } + + gpr_mu_lock(&chand->mu_config); + old_lb_policy = chand->lb_policy; + chand->lb_policy = lb_policy; + if (lb_policy != NULL || chand->resolver == NULL /* disconnected */) { + grpc_exec_ctx_enqueue_list(exec_ctx, &chand->waiting_for_config_closures, + NULL); + } + if (lb_policy != NULL && chand->exit_idle_when_lb_policy_arrives) { + GRPC_LB_POLICY_REF(lb_policy, "exit_idle"); + exit_idle = 1; + chand->exit_idle_when_lb_policy_arrives = 0; + } + + if (iomgr_success && chand->resolver) { + grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, state, + "new_lb+resolver"); + if (lb_policy != NULL) { + watch_lb_policy(exec_ctx, chand, lb_policy, state); + } + GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); + grpc_resolver_next(exec_ctx, chand->resolver, + &chand->incoming_configuration, + &chand->on_config_changed); + gpr_mu_unlock(&chand->mu_config); + } else { + if (chand->resolver != NULL) { + grpc_resolver_shutdown(exec_ctx, chand->resolver); + GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel"); + chand->resolver = NULL; + } + grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, + GRPC_CHANNEL_FATAL_FAILURE, "resolver_gone"); + gpr_mu_unlock(&chand->mu_config); + } + + if (exit_idle) { + grpc_lb_policy_exit_idle(exec_ctx, lb_policy); + GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "exit_idle"); + } + + if (old_lb_policy != NULL) { + grpc_pollset_set_del_pollset_set( + exec_ctx, old_lb_policy->interested_parties, chand->interested_parties); + GRPC_LB_POLICY_UNREF(exec_ctx, old_lb_policy, "channel"); + } + + if (lb_policy != NULL) { + GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "config_change"); + } + + GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->owning_stack, "resolver"); +} + +static void cc_start_transport_op(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_transport_op *op) { + channel_data *chand = elem->channel_data; + + grpc_exec_ctx_enqueue(exec_ctx, op->on_consumed, true, NULL); + + GPR_ASSERT(op->set_accept_stream == false); + if (op->bind_pollset != NULL) { + grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, + op->bind_pollset); + } + + gpr_mu_lock(&chand->mu_config); + if (op->on_connectivity_state_change != NULL) { + grpc_connectivity_state_notify_on_state_change( + exec_ctx, &chand->state_tracker, op->connectivity_state, + op->on_connectivity_state_change); + op->on_connectivity_state_change = NULL; + op->connectivity_state = NULL; + } + + if (op->send_ping != NULL) { + if (chand->lb_policy == NULL) { + grpc_exec_ctx_enqueue(exec_ctx, op->send_ping, false, NULL); + } else { + grpc_lb_policy_ping_one(exec_ctx, chand->lb_policy, op->send_ping); + op->bind_pollset = NULL; + } + op->send_ping = NULL; + } + + if (op->disconnect && chand->resolver != NULL) { + grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, + GRPC_CHANNEL_FATAL_FAILURE, "disconnect"); + grpc_resolver_shutdown(exec_ctx, chand->resolver); + GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel"); + chand->resolver = NULL; + if (chand->lb_policy != NULL) { + grpc_pollset_set_del_pollset_set(exec_ctx, + chand->lb_policy->interested_parties, + chand->interested_parties); + GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel"); + chand->lb_policy = NULL; + } + } + gpr_mu_unlock(&chand->mu_config); +} + +typedef struct { + grpc_metadata_batch *initial_metadata; + grpc_connected_subchannel **connected_subchannel; + grpc_closure *on_ready; + grpc_call_element *elem; + grpc_closure closure; +} continue_picking_args; + +static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *arg, + grpc_metadata_batch *initial_metadata, + grpc_connected_subchannel **connected_subchannel, + grpc_closure *on_ready); + +static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + continue_picking_args *cpa = arg; + if (!success) { + grpc_exec_ctx_enqueue(exec_ctx, cpa->on_ready, false, NULL); + } else if (cpa->connected_subchannel == NULL) { + /* cancelled, do nothing */ + } else if (cc_pick_subchannel(exec_ctx, cpa->elem, cpa->initial_metadata, + cpa->connected_subchannel, cpa->on_ready)) { + grpc_exec_ctx_enqueue(exec_ctx, cpa->on_ready, true, NULL); + } + gpr_free(cpa); +} + +static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp, + grpc_metadata_batch *initial_metadata, + grpc_connected_subchannel **connected_subchannel, + grpc_closure *on_ready) { + grpc_call_element *elem = elemp; + channel_data *chand = elem->channel_data; + call_data *calld = elem->call_data; + continue_picking_args *cpa; + grpc_closure *closure; + + GPR_ASSERT(connected_subchannel); + + gpr_mu_lock(&chand->mu_config); + if (initial_metadata == NULL) { + if (chand->lb_policy != NULL) { + grpc_lb_policy_cancel_pick(exec_ctx, chand->lb_policy, + connected_subchannel); + } + for (closure = chand->waiting_for_config_closures.head; closure != NULL; + closure = grpc_closure_next(closure)) { + cpa = closure->cb_arg; + if (cpa->connected_subchannel == connected_subchannel) { + cpa->connected_subchannel = NULL; + grpc_exec_ctx_enqueue(exec_ctx, cpa->on_ready, false, NULL); + } + } + gpr_mu_unlock(&chand->mu_config); + return 1; + } + if (chand->lb_policy != NULL) { + grpc_lb_policy *lb_policy = chand->lb_policy; + int r; + GRPC_LB_POLICY_REF(lb_policy, "cc_pick_subchannel"); + gpr_mu_unlock(&chand->mu_config); + r = grpc_lb_policy_pick(exec_ctx, lb_policy, calld->pollset, + initial_metadata, connected_subchannel, on_ready); + GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "cc_pick_subchannel"); + return r; + } + if (chand->resolver != NULL && !chand->started_resolving) { + chand->started_resolving = 1; + GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); + grpc_resolver_next(exec_ctx, chand->resolver, + &chand->incoming_configuration, + &chand->on_config_changed); + } + cpa = gpr_malloc(sizeof(*cpa)); + cpa->initial_metadata = initial_metadata; + cpa->connected_subchannel = connected_subchannel; + cpa->on_ready = on_ready; + cpa->elem = elem; + grpc_closure_init(&cpa->closure, continue_picking, cpa); + grpc_closure_list_add(&chand->waiting_for_config_closures, &cpa->closure, 1); + gpr_mu_unlock(&chand->mu_config); + return 0; +} + +/* Constructor for call_data */ +static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args) { + grpc_subchannel_call_holder_init(elem->call_data, cc_pick_subchannel, elem, + args->call_stack); +} + +/* Destructor for call_data */ +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + grpc_subchannel_call_holder_destroy(exec_ctx, elem->call_data); +} + +/* Constructor for channel_data */ +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + channel_data *chand = elem->channel_data; + + memset(chand, 0, sizeof(*chand)); + + GPR_ASSERT(args->is_last); + GPR_ASSERT(elem->filter == &grpc_client_channel_filter); + + gpr_mu_init(&chand->mu_config); + grpc_closure_init(&chand->on_config_changed, cc_on_config_changed, chand); + chand->owning_stack = args->channel_stack; + + grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, + "client_channel"); + chand->interested_parties = grpc_pollset_set_create(); +} + +/* Destructor for channel_data */ +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) { + channel_data *chand = elem->channel_data; + + if (chand->resolver != NULL) { + grpc_resolver_shutdown(exec_ctx, chand->resolver); + GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel"); + } + if (chand->lb_policy != NULL) { + grpc_pollset_set_del_pollset_set(exec_ctx, + chand->lb_policy->interested_parties, + chand->interested_parties); + GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel"); + } + grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker); + grpc_pollset_set_destroy(chand->interested_parties); + gpr_mu_destroy(&chand->mu_config); +} + +static void cc_set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_pollset *pollset) { + call_data *calld = elem->call_data; + calld->pollset = pollset; +} + +const grpc_channel_filter grpc_client_channel_filter = { + cc_start_transport_stream_op, + cc_start_transport_op, + sizeof(call_data), + init_call_elem, + cc_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + cc_get_peer, + "client-channel", +}; + +void grpc_client_channel_set_resolver(grpc_exec_ctx *exec_ctx, + grpc_channel_stack *channel_stack, + grpc_resolver *resolver) { + /* post construction initialization: set the transport setup pointer */ + grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack); + channel_data *chand = elem->channel_data; + gpr_mu_lock(&chand->mu_config); + GPR_ASSERT(!chand->resolver); + chand->resolver = resolver; + GRPC_RESOLVER_REF(resolver, "channel"); + if (!grpc_closure_list_empty(chand->waiting_for_config_closures) || + chand->exit_idle_when_lb_policy_arrives) { + chand->started_resolving = 1; + GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); + grpc_resolver_next(exec_ctx, resolver, &chand->incoming_configuration, + &chand->on_config_changed); + } + gpr_mu_unlock(&chand->mu_config); +} + +grpc_connectivity_state grpc_client_channel_check_connectivity_state( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect) { + channel_data *chand = elem->channel_data; + grpc_connectivity_state out; + gpr_mu_lock(&chand->mu_config); + out = grpc_connectivity_state_check(&chand->state_tracker); + if (out == GRPC_CHANNEL_IDLE && try_to_connect) { + if (chand->lb_policy != NULL) { + grpc_lb_policy_exit_idle(exec_ctx, chand->lb_policy); + } else { + chand->exit_idle_when_lb_policy_arrives = 1; + if (!chand->started_resolving && chand->resolver != NULL) { + GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); + chand->started_resolving = 1; + grpc_resolver_next(exec_ctx, chand->resolver, + &chand->incoming_configuration, + &chand->on_config_changed); + } + } + } + gpr_mu_unlock(&chand->mu_config); + return out; +} + +typedef struct { + channel_data *chand; + grpc_pollset *pollset; + grpc_closure *on_complete; + grpc_closure my_closure; +} external_connectivity_watcher; + +static void on_external_watch_complete(grpc_exec_ctx *exec_ctx, void *arg, + bool iomgr_success) { + external_connectivity_watcher *w = arg; + grpc_closure *follow_up = w->on_complete; + grpc_pollset_set_del_pollset(exec_ctx, w->chand->interested_parties, + w->pollset); + GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack, + "external_connectivity_watcher"); + gpr_free(w); + follow_up->cb(exec_ctx, follow_up->cb_arg, iomgr_success); +} + +void grpc_client_channel_watch_connectivity_state( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset, + grpc_connectivity_state *state, grpc_closure *on_complete) { + channel_data *chand = elem->channel_data; + external_connectivity_watcher *w = gpr_malloc(sizeof(*w)); + w->chand = chand; + w->pollset = pollset; + w->on_complete = on_complete; + grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, pollset); + grpc_closure_init(&w->my_closure, on_external_watch_complete, w); + GRPC_CHANNEL_STACK_REF(w->chand->owning_stack, + "external_connectivity_watcher"); + gpr_mu_lock(&chand->mu_config); + grpc_connectivity_state_notify_on_state_change( + exec_ctx, &chand->state_tracker, state, &w->my_closure); + gpr_mu_unlock(&chand->mu_config); +} diff --git a/src/core/lib/channel/client_channel.h b/src/core/lib/channel/client_channel.h new file mode 100644 index 0000000000..422f7f8374 --- /dev/null +++ b/src/core/lib/channel/client_channel.h @@ -0,0 +1,63 @@ +/* + * + * Copyright 2015-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_CHANNEL_CLIENT_CHANNEL_H +#define GRPC_CORE_CHANNEL_CLIENT_CHANNEL_H + +#include "src/core/channel/channel_stack.h" +#include "src/core/client_config/resolver.h" + +/* A client channel is a channel that begins disconnected, and can connect + to some endpoint on demand. If that endpoint disconnects, it will be + connected to again later. + + Calls on a disconnected client channel are queued until a connection is + established. */ + +extern const grpc_channel_filter grpc_client_channel_filter; + +/* post-construction initializer to let the client channel know which + transport setup it should cancel upon destruction, or initiate when it needs + a connection */ +void grpc_client_channel_set_resolver(grpc_exec_ctx *exec_ctx, + grpc_channel_stack *channel_stack, + grpc_resolver *resolver); + +grpc_connectivity_state grpc_client_channel_check_connectivity_state( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect); + +void grpc_client_channel_watch_connectivity_state( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset, + grpc_connectivity_state *state, grpc_closure *on_complete); + +#endif /* GRPC_CORE_CHANNEL_CLIENT_CHANNEL_H */ diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c new file mode 100644 index 0000000000..6f5a9740ad --- /dev/null +++ b/src/core/lib/channel/compress_filter.c @@ -0,0 +1,304 @@ +/* + * + * Copyright 2015-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 +#include + +#include +#include +#include +#include + +#include "src/core/channel/channel_args.h" +#include "src/core/channel/compress_filter.h" +#include "src/core/compression/algorithm_metadata.h" +#include "src/core/compression/message_compress.h" +#include "src/core/profiling/timers.h" +#include "src/core/support/string.h" +#include "src/core/transport/static_metadata.h" + +typedef struct call_data { + gpr_slice_buffer slices; /**< Buffers up input slices to be compressed */ + grpc_linked_mdelem compression_algorithm_storage; + grpc_linked_mdelem accept_encoding_storage; + uint32_t remaining_slice_bytes; + /** Compression algorithm we'll try to use. It may be given by incoming + * metadata, or by the channel's default compression settings. */ + grpc_compression_algorithm compression_algorithm; + /** If true, contents of \a compression_algorithm are authoritative */ + int has_compression_algorithm; + + grpc_transport_stream_op send_op; + uint32_t send_length; + uint32_t send_flags; + gpr_slice incoming_slice; + grpc_slice_buffer_stream replacement_stream; + grpc_closure *post_send; + grpc_closure send_done; + grpc_closure got_slice; +} call_data; + +typedef struct channel_data { + /** The default, channel-level, compression algorithm */ + grpc_compression_algorithm default_compression_algorithm; + /** Compression options for the channel */ + grpc_compression_options compression_options; + /** Supported compression algorithms */ + uint32_t supported_compression_algorithms; +} channel_data; + +/** For each \a md element from the incoming metadata, filter out the entry for + * "grpc-encoding", using its value to populate the call data's + * compression_algorithm field. */ +static grpc_mdelem *compression_md_filter(void *user_data, grpc_mdelem *md) { + grpc_call_element *elem = user_data; + call_data *calld = elem->call_data; + channel_data *channeld = elem->channel_data; + + if (md->key == GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST) { + const char *md_c_str = grpc_mdstr_as_c_string(md->value); + if (!grpc_compression_algorithm_parse(md_c_str, strlen(md_c_str), + &calld->compression_algorithm)) { + gpr_log(GPR_ERROR, + "Invalid compression algorithm: '%s' (unknown). Ignoring.", + md_c_str); + calld->compression_algorithm = GRPC_COMPRESS_NONE; + } + if (grpc_compression_options_is_algorithm_enabled( + &channeld->compression_options, calld->compression_algorithm) == + 0) { + gpr_log(GPR_ERROR, + "Invalid compression algorithm: '%s' (previously disabled). " + "Ignoring.", + md_c_str); + calld->compression_algorithm = GRPC_COMPRESS_NONE; + } + calld->has_compression_algorithm = 1; + return NULL; + } + + return md; +} + +static int skip_compression(grpc_call_element *elem) { + call_data *calld = elem->call_data; + channel_data *channeld = elem->channel_data; + if (calld->has_compression_algorithm) { + if (calld->compression_algorithm == GRPC_COMPRESS_NONE) { + return 1; + } + return 0; /* we have an actual call-specific algorithm */ + } + /* no per-call compression override */ + return channeld->default_compression_algorithm == GRPC_COMPRESS_NONE; +} + +/** Filter initial metadata */ +static void process_send_initial_metadata( + grpc_call_element *elem, grpc_metadata_batch *initial_metadata) { + call_data *calld = elem->call_data; + channel_data *channeld = elem->channel_data; + /* Parse incoming request for compression. If any, it'll be available + * at calld->compression_algorithm */ + grpc_metadata_batch_filter(initial_metadata, compression_md_filter, elem); + if (!calld->has_compression_algorithm) { + /* If no algorithm was found in the metadata and we aren't + * exceptionally skipping compression, fall back to the channel + * default */ + calld->compression_algorithm = channeld->default_compression_algorithm; + calld->has_compression_algorithm = 1; /* GPR_TRUE */ + } + /* hint compression algorithm */ + grpc_metadata_batch_add_tail( + initial_metadata, &calld->compression_algorithm_storage, + grpc_compression_encoding_mdelem(calld->compression_algorithm)); + + /* convey supported compression algorithms */ + grpc_metadata_batch_add_tail(initial_metadata, + &calld->accept_encoding_storage, + GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS( + channeld->supported_compression_algorithms)); +} + +static void continue_send_message(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem); + +static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, bool success) { + grpc_call_element *elem = elemp; + call_data *calld = elem->call_data; + gpr_slice_buffer_reset_and_unref(&calld->slices); + calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, success); +} + +static void finish_send_message(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + call_data *calld = elem->call_data; + int did_compress; + gpr_slice_buffer tmp; + gpr_slice_buffer_init(&tmp); + did_compress = + grpc_msg_compress(calld->compression_algorithm, &calld->slices, &tmp); + if (did_compress) { + gpr_slice_buffer_swap(&calld->slices, &tmp); + calld->send_flags |= GRPC_WRITE_INTERNAL_COMPRESS; + } + gpr_slice_buffer_destroy(&tmp); + + grpc_slice_buffer_stream_init(&calld->replacement_stream, &calld->slices, + calld->send_flags); + calld->send_op.send_message = &calld->replacement_stream.base; + calld->post_send = calld->send_op.on_complete; + calld->send_op.on_complete = &calld->send_done; + + grpc_call_next_op(exec_ctx, elem, &calld->send_op); +} + +static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, bool success) { + grpc_call_element *elem = elemp; + call_data *calld = elem->call_data; + gpr_slice_buffer_add(&calld->slices, calld->incoming_slice); + if (calld->send_length == calld->slices.length) { + finish_send_message(exec_ctx, elem); + } else { + continue_send_message(exec_ctx, elem); + } +} + +static void continue_send_message(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + call_data *calld = elem->call_data; + while (grpc_byte_stream_next(exec_ctx, calld->send_op.send_message, + &calld->incoming_slice, ~(size_t)0, + &calld->got_slice)) { + gpr_slice_buffer_add(&calld->slices, calld->incoming_slice); + if (calld->send_length == calld->slices.length) { + finish_send_message(exec_ctx, elem); + break; + } + } +} + +static void compress_start_transport_stream_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + call_data *calld = elem->call_data; + + GPR_TIMER_BEGIN("compress_start_transport_stream_op", 0); + + if (op->send_initial_metadata) { + process_send_initial_metadata(elem, op->send_initial_metadata); + } + if (op->send_message != NULL && !skip_compression(elem) && + 0 == (op->send_message->flags & GRPC_WRITE_NO_COMPRESS)) { + calld->send_op = *op; + calld->send_length = op->send_message->length; + calld->send_flags = op->send_message->flags; + continue_send_message(exec_ctx, elem); + } else { + /* pass control down the stack */ + grpc_call_next_op(exec_ctx, elem, op); + } + + GPR_TIMER_END("compress_start_transport_stream_op", 0); +} + +/* Constructor for call_data */ +static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args) { + /* grab pointers to our data from the call element */ + call_data *calld = elem->call_data; + + /* initialize members */ + gpr_slice_buffer_init(&calld->slices); + calld->has_compression_algorithm = 0; + grpc_closure_init(&calld->got_slice, got_slice, elem); + grpc_closure_init(&calld->send_done, send_done, elem); +} + +/* Destructor for call_data */ +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + /* grab pointers to our data from the call element */ + call_data *calld = elem->call_data; + gpr_slice_buffer_destroy(&calld->slices); +} + +/* Constructor for channel_data */ +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + channel_data *channeld = elem->channel_data; + grpc_compression_algorithm algo_idx; + + grpc_compression_options_init(&channeld->compression_options); + channeld->compression_options.enabled_algorithms_bitset = + (uint32_t)grpc_channel_args_compression_algorithm_get_states( + args->channel_args); + + channeld->default_compression_algorithm = + grpc_channel_args_get_compression_algorithm(args->channel_args); + /* Make sure the default isn't disabled. */ + GPR_ASSERT(grpc_compression_options_is_algorithm_enabled( + &channeld->compression_options, channeld->default_compression_algorithm)); + channeld->compression_options.default_compression_algorithm = + channeld->default_compression_algorithm; + + channeld->supported_compression_algorithms = 0; + for (algo_idx = 0; algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) { + /* skip disabled algorithms */ + if (grpc_compression_options_is_algorithm_enabled( + &channeld->compression_options, algo_idx) == 0) { + continue; + } + channeld->supported_compression_algorithms |= 1u << algo_idx; + } + + GPR_ASSERT(!args->is_last); +} + +/* Destructor for channel data */ +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) {} + +const grpc_channel_filter grpc_compress_filter = { + compress_start_transport_stream_op, + grpc_channel_next_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "compress"}; diff --git a/src/core/lib/channel/compress_filter.h b/src/core/lib/channel/compress_filter.h new file mode 100644 index 0000000000..8c208ac799 --- /dev/null +++ b/src/core/lib/channel/compress_filter.h @@ -0,0 +1,65 @@ +/* + * + * Copyright 2015-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_CHANNEL_COMPRESS_FILTER_H +#define GRPC_CORE_CHANNEL_COMPRESS_FILTER_H + +#include "src/core/channel/channel_stack.h" + +#define GRPC_COMPRESS_REQUEST_ALGORITHM_KEY "grpc-internal-encoding-request" + +/** Compression filter for outgoing data. + * + * See for the available compression settings. + * + * Compression settings may come from: + * - Channel configuration, as established at channel creation time. + * - The metadata accompanying the outgoing data to be compressed. This is + * taken as a request only. We may choose not to honor it. The metadata key + * is given by \a GRPC_COMPRESS_REQUEST_ALGORITHM_KEY. + * + * Compression can be disabled for concrete messages (for instance in order to + * prevent CRIME/BEAST type attacks) by having the GRPC_WRITE_NO_COMPRESS set in + * the BEGIN_MESSAGE flags. + * + * The attempted compression mechanism is added to the resulting initial + * metadata under the'grpc-encoding' key. + * + * If compression is actually performed, BEGIN_MESSAGE's flag is modified to + * incorporate GRPC_WRITE_INTERNAL_COMPRESS. Otherwise, and regardless of the + * aforementioned 'grpc-encoding' metadata value, data will pass through + * uncompressed. */ + +extern const grpc_channel_filter grpc_compress_filter; + +#endif /* GRPC_CORE_CHANNEL_COMPRESS_FILTER_H */ diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c new file mode 100644 index 0000000000..df11d54297 --- /dev/null +++ b/src/core/lib/channel/connected_channel.c @@ -0,0 +1,176 @@ +/* + * + * Copyright 2015-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/channel/connected_channel.h" + +#include +#include +#include + +#include +#include +#include +#include +#include "src/core/profiling/timers.h" +#include "src/core/support/string.h" +#include "src/core/transport/transport.h" + +#define MAX_BUFFER_LENGTH 8192 + +typedef struct connected_channel_channel_data { + grpc_transport *transport; +} channel_data; + +typedef struct connected_channel_call_data { void *unused; } call_data; + +/* We perform a small hack to locate transport data alongside the connected + channel data in call allocations, to allow everything to be pulled in minimal + cache line requests */ +#define TRANSPORT_STREAM_FROM_CALL_DATA(calld) ((grpc_stream *)((calld) + 1)) +#define CALL_DATA_FROM_TRANSPORT_STREAM(transport_stream) \ + (((call_data *)(transport_stream)) - 1) + +/* Intercept a call operation and either push it directly up or translate it + into transport stream operations */ +static void con_start_transport_stream_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + GRPC_CALL_LOG_OP(GPR_INFO, elem, op); + + grpc_transport_perform_stream_op(exec_ctx, chand->transport, + TRANSPORT_STREAM_FROM_CALL_DATA(calld), op); +} + +static void con_start_transport_op(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_transport_op *op) { + channel_data *chand = elem->channel_data; + grpc_transport_perform_op(exec_ctx, chand->transport, op); +} + +/* Constructor for call_data */ +static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args) { + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + int r; + + r = grpc_transport_init_stream( + exec_ctx, chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld), + &args->call_stack->refcount, args->server_transport_data); + GPR_ASSERT(r == 0); +} + +static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_pollset *pollset) { + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + grpc_transport_set_pollset(exec_ctx, chand->transport, + TRANSPORT_STREAM_FROM_CALL_DATA(calld), pollset); +} + +/* Destructor for call_data */ +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + grpc_transport_destroy_stream(exec_ctx, chand->transport, + TRANSPORT_STREAM_FROM_CALL_DATA(calld)); +} + +/* Constructor for channel_data */ +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + channel_data *cd = (channel_data *)elem->channel_data; + GPR_ASSERT(args->is_last); + cd->transport = NULL; +} + +/* Destructor for channel_data */ +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) { + channel_data *cd = (channel_data *)elem->channel_data; + grpc_transport_destroy(exec_ctx, cd->transport); +} + +static char *con_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { + channel_data *chand = elem->channel_data; + return grpc_transport_get_peer(exec_ctx, chand->transport); +} + +static const grpc_channel_filter connected_channel_filter = { + con_start_transport_stream_op, + con_start_transport_op, + sizeof(call_data), + init_call_elem, + set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + con_get_peer, + "connected", +}; + +static void bind_transport(grpc_channel_stack *channel_stack, + grpc_channel_element *elem, void *t) { + channel_data *cd = (channel_data *)elem->channel_data; + GPR_ASSERT(elem->filter == &connected_channel_filter); + GPR_ASSERT(cd->transport == NULL); + cd->transport = t; + + /* HACK(ctiller): increase call stack size for the channel to make space + for channel data. We need a cleaner (but performant) way to do this, + and I'm not sure what that is yet. + This is only "safe" because call stacks place no additional data after + the last call element, and the last call element MUST be the connected + channel. */ + channel_stack->call_stack_size += grpc_transport_stream_size(t); +} + +bool grpc_add_connected_filter(grpc_channel_stack_builder *builder, + void *arg_must_be_null) { + GPR_ASSERT(arg_must_be_null == NULL); + grpc_transport *t = grpc_channel_stack_builder_get_transport(builder); + GPR_ASSERT(t != NULL); + return grpc_channel_stack_builder_append_filter( + builder, &connected_channel_filter, bind_transport, t); +} + +grpc_stream *grpc_connected_channel_get_stream(grpc_call_element *elem) { + call_data *calld = elem->call_data; + return TRANSPORT_STREAM_FROM_CALL_DATA(calld); +} diff --git a/src/core/lib/channel/connected_channel.h b/src/core/lib/channel/connected_channel.h new file mode 100644 index 0000000000..7c0c8359a4 --- /dev/null +++ b/src/core/lib/channel/connected_channel.h @@ -0,0 +1,42 @@ +/* + * + * Copyright 2015-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_CHANNEL_CONNECTED_CHANNEL_H +#define GRPC_CORE_CHANNEL_CONNECTED_CHANNEL_H + +#include "src/core/channel/channel_stack_builder.h" + +bool grpc_add_connected_filter(grpc_channel_stack_builder *builder, + void *arg_must_be_null); + +#endif /* GRPC_CORE_CHANNEL_CONNECTED_CHANNEL_H */ diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h new file mode 100644 index 0000000000..db217dc133 --- /dev/null +++ b/src/core/lib/channel/context.h @@ -0,0 +1,49 @@ +/* + * + * Copyright 2015-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_CHANNEL_CONTEXT_H +#define GRPC_CORE_CHANNEL_CONTEXT_H + +/* Call object context pointers */ +typedef enum { + GRPC_CONTEXT_SECURITY = 0, + GRPC_CONTEXT_TRACING, + GRPC_CONTEXT_COUNT +} grpc_context_index; + +typedef struct { + void *value; + void (*destroy)(void *); +} grpc_call_context_element; + +#endif /* GRPC_CORE_CHANNEL_CONTEXT_H */ diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c new file mode 100644 index 0000000000..582427daf9 --- /dev/null +++ b/src/core/lib/channel/http_client_filter.c @@ -0,0 +1,255 @@ +/* + * Copyright 2015-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/channel/http_client_filter.h" +#include +#include +#include +#include +#include "src/core/profiling/timers.h" +#include "src/core/support/string.h" +#include "src/core/transport/static_metadata.h" + +typedef struct call_data { + grpc_linked_mdelem method; + grpc_linked_mdelem scheme; + grpc_linked_mdelem authority; + grpc_linked_mdelem te_trailers; + grpc_linked_mdelem content_type; + grpc_linked_mdelem user_agent; + + grpc_metadata_batch *recv_initial_metadata; + + /** Closure to call when finished with the hc_on_recv hook */ + grpc_closure *on_done_recv; + /** Receive closures are chained: we inject this closure as the on_done_recv + up-call on transport_op, and remember to call our on_done_recv member + after handling it. */ + grpc_closure hc_on_recv; +} call_data; + +typedef struct channel_data { + grpc_mdelem *static_scheme; + grpc_mdelem *user_agent; +} channel_data; + +typedef struct { + grpc_call_element *elem; + grpc_exec_ctx *exec_ctx; +} client_recv_filter_args; + +static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) { + client_recv_filter_args *a = user_data; + if (md == GRPC_MDELEM_STATUS_200) { + return NULL; + } else if (md->key == GRPC_MDSTR_STATUS) { + grpc_call_element_send_cancel(a->exec_ctx, a->elem); + return NULL; + } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) { + return NULL; + } + return md; +} + +static void hc_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, bool success) { + grpc_call_element *elem = user_data; + call_data *calld = elem->call_data; + client_recv_filter_args a; + a.elem = elem; + a.exec_ctx = exec_ctx; + grpc_metadata_batch_filter(calld->recv_initial_metadata, client_recv_filter, + &a); + calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, success); +} + +static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) { + /* eat the things we'd like to set ourselves */ + if (md->key == GRPC_MDSTR_METHOD) return NULL; + if (md->key == GRPC_MDSTR_SCHEME) return NULL; + if (md->key == GRPC_MDSTR_TE) return NULL; + if (md->key == GRPC_MDSTR_CONTENT_TYPE) return NULL; + if (md->key == GRPC_MDSTR_USER_AGENT) return NULL; + return md; +} + +static void hc_mutate_op(grpc_call_element *elem, + grpc_transport_stream_op *op) { + /* grab pointers to our data from the call element */ + call_data *calld = elem->call_data; + channel_data *channeld = elem->channel_data; + if (op->send_initial_metadata != NULL) { + grpc_metadata_batch_filter(op->send_initial_metadata, client_strip_filter, + elem); + /* Send : prefixed headers, which have to be before any application + layer headers. */ + grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method, + GRPC_MDELEM_METHOD_POST); + grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme, + channeld->static_scheme); + grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->te_trailers, + GRPC_MDELEM_TE_TRAILERS); + grpc_metadata_batch_add_tail( + op->send_initial_metadata, &calld->content_type, + GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC); + grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->user_agent, + GRPC_MDELEM_REF(channeld->user_agent)); + } + + if (op->recv_initial_metadata != NULL) { + /* substitute our callback for the higher callback */ + calld->recv_initial_metadata = op->recv_initial_metadata; + calld->on_done_recv = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = &calld->hc_on_recv; + } +} + +static void hc_start_transport_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + GPR_TIMER_BEGIN("hc_start_transport_op", 0); + GRPC_CALL_LOG_OP(GPR_INFO, elem, op); + hc_mutate_op(elem, op); + GPR_TIMER_END("hc_start_transport_op", 0); + grpc_call_next_op(exec_ctx, elem, op); +} + +/* Constructor for call_data */ +static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args) { + call_data *calld = elem->call_data; + calld->on_done_recv = NULL; + grpc_closure_init(&calld->hc_on_recv, hc_on_recv, elem); +} + +/* Destructor for call_data */ +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) {} + +static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) { + unsigned i; + size_t j; + grpc_mdelem *valid_schemes[] = {GRPC_MDELEM_SCHEME_HTTP, + GRPC_MDELEM_SCHEME_HTTPS}; + if (args != NULL) { + for (i = 0; i < args->num_args; ++i) { + if (args->args[i].type == GRPC_ARG_STRING && + strcmp(args->args[i].key, GRPC_ARG_HTTP2_SCHEME) == 0) { + for (j = 0; j < GPR_ARRAY_SIZE(valid_schemes); j++) { + if (0 == strcmp(grpc_mdstr_as_c_string(valid_schemes[j]->value), + args->args[i].value.string)) { + return valid_schemes[j]; + } + } + } + } + } + return GRPC_MDELEM_SCHEME_HTTP; +} + +static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args) { + gpr_strvec v; + size_t i; + int is_first = 1; + char *tmp; + grpc_mdstr *result; + + gpr_strvec_init(&v); + + for (i = 0; args && i < args->num_args; i++) { + if (0 == strcmp(args->args[i].key, GRPC_ARG_PRIMARY_USER_AGENT_STRING)) { + if (args->args[i].type != GRPC_ARG_STRING) { + gpr_log(GPR_ERROR, "Channel argument '%s' should be a string", + GRPC_ARG_PRIMARY_USER_AGENT_STRING); + } else { + if (!is_first) gpr_strvec_add(&v, gpr_strdup(" ")); + is_first = 0; + gpr_strvec_add(&v, gpr_strdup(args->args[i].value.string)); + } + } + } + + gpr_asprintf(&tmp, "%sgrpc-c/%s (%s)", is_first ? "" : " ", + grpc_version_string(), GPR_PLATFORM_STRING); + is_first = 0; + gpr_strvec_add(&v, tmp); + + for (i = 0; args && i < args->num_args; i++) { + if (0 == strcmp(args->args[i].key, GRPC_ARG_SECONDARY_USER_AGENT_STRING)) { + if (args->args[i].type != GRPC_ARG_STRING) { + gpr_log(GPR_ERROR, "Channel argument '%s' should be a string", + GRPC_ARG_SECONDARY_USER_AGENT_STRING); + } else { + if (!is_first) gpr_strvec_add(&v, gpr_strdup(" ")); + is_first = 0; + gpr_strvec_add(&v, gpr_strdup(args->args[i].value.string)); + } + } + } + + tmp = gpr_strvec_flatten(&v, NULL); + gpr_strvec_destroy(&v); + result = grpc_mdstr_from_string(tmp); + gpr_free(tmp); + + return result; +} + +/* Constructor for channel_data */ +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + channel_data *chand = elem->channel_data; + GPR_ASSERT(!args->is_last); + chand->static_scheme = scheme_from_args(args->channel_args); + chand->user_agent = grpc_mdelem_from_metadata_strings( + GRPC_MDSTR_USER_AGENT, user_agent_from_args(args->channel_args)); +} + +/* Destructor for channel data */ +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) { + channel_data *chand = elem->channel_data; + GRPC_MDELEM_UNREF(chand->user_agent); +} + +const grpc_channel_filter grpc_http_client_filter = { + hc_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "http-client"}; diff --git a/src/core/lib/channel/http_client_filter.h b/src/core/lib/channel/http_client_filter.h new file mode 100644 index 0000000000..6f619bbf00 --- /dev/null +++ b/src/core/lib/channel/http_client_filter.h @@ -0,0 +1,44 @@ +/* + * + * Copyright 2015-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_CHANNEL_HTTP_CLIENT_FILTER_H +#define GRPC_CORE_CHANNEL_HTTP_CLIENT_FILTER_H + +#include "src/core/channel/channel_stack.h" + +/* Processes metadata on the client side for HTTP2 transports */ +extern const grpc_channel_filter grpc_http_client_filter; + +#define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme" + +#endif /* GRPC_CORE_CHANNEL_HTTP_CLIENT_FILTER_H */ diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c new file mode 100644 index 0000000000..1a2e0c5db3 --- /dev/null +++ b/src/core/lib/channel/http_server_filter.c @@ -0,0 +1,240 @@ +/* + * + * Copyright 2015-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/channel/http_server_filter.h" + +#include +#include +#include +#include "src/core/profiling/timers.h" +#include "src/core/transport/static_metadata.h" + +typedef struct call_data { + uint8_t seen_path; + uint8_t seen_post; + uint8_t sent_status; + uint8_t seen_scheme; + uint8_t seen_te_trailers; + uint8_t seen_authority; + grpc_linked_mdelem status; + grpc_linked_mdelem content_type; + + grpc_metadata_batch *recv_initial_metadata; + /** Closure to call when finished with the hs_on_recv hook */ + grpc_closure *on_done_recv; + /** Receive closures are chained: we inject this closure as the on_done_recv + up-call on transport_op, and remember to call our on_done_recv member + after handling it. */ + grpc_closure hs_on_recv; +} call_data; + +typedef struct channel_data { uint8_t unused; } channel_data; + +typedef struct { + grpc_call_element *elem; + grpc_exec_ctx *exec_ctx; +} server_filter_args; + +static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) { + server_filter_args *a = user_data; + grpc_call_element *elem = a->elem; + call_data *calld = elem->call_data; + + /* Check if it is one of the headers we care about. */ + if (md == GRPC_MDELEM_TE_TRAILERS || md == GRPC_MDELEM_METHOD_POST || + md == GRPC_MDELEM_SCHEME_HTTP || md == GRPC_MDELEM_SCHEME_HTTPS || + md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) { + /* swallow it */ + if (md == GRPC_MDELEM_METHOD_POST) { + calld->seen_post = 1; + } else if (md->key == GRPC_MDSTR_SCHEME) { + calld->seen_scheme = 1; + } else if (md == GRPC_MDELEM_TE_TRAILERS) { + calld->seen_te_trailers = 1; + } + /* TODO(klempner): Track that we've seen all the headers we should + require */ + return NULL; + } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) { + if (strncmp(grpc_mdstr_as_c_string(md->value), "application/grpc+", 17) == + 0) { + /* Although the C implementation doesn't (currently) generate them, + any custom +-suffix is explicitly valid. */ + /* TODO(klempner): We should consider preallocating common values such + as +proto or +json, or at least stashing them if we see them. */ + /* TODO(klempner): Should we be surfacing this to application code? */ + } else { + /* TODO(klempner): We're currently allowing this, but we shouldn't + see it without a proxy so log for now. */ + gpr_log(GPR_INFO, "Unexpected content-type %s", + grpc_mdstr_as_c_string(md->value)); + } + return NULL; + } else if (md->key == GRPC_MDSTR_TE || md->key == GRPC_MDSTR_METHOD || + md->key == GRPC_MDSTR_SCHEME) { + gpr_log(GPR_ERROR, "Invalid %s: header: '%s'", + grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value)); + /* swallow it and error everything out. */ + /* TODO(klempner): We ought to generate more descriptive error messages + on the wire here. */ + grpc_call_element_send_cancel(a->exec_ctx, elem); + return NULL; + } else if (md->key == GRPC_MDSTR_PATH) { + if (calld->seen_path) { + gpr_log(GPR_ERROR, "Received :path twice"); + return NULL; + } + calld->seen_path = 1; + return md; + } else if (md->key == GRPC_MDSTR_AUTHORITY) { + calld->seen_authority = 1; + return md; + } else if (md->key == GRPC_MDSTR_HOST) { + /* translate host to :authority since :authority may be + omitted */ + grpc_mdelem *authority = grpc_mdelem_from_metadata_strings( + GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value)); + calld->seen_authority = 1; + return authority; + } else { + return md; + } +} + +static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, bool success) { + grpc_call_element *elem = user_data; + call_data *calld = elem->call_data; + if (success) { + server_filter_args a; + a.elem = elem; + a.exec_ctx = exec_ctx; + grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, &a); + /* Have we seen the required http2 transport headers? + (:method, :scheme, content-type, with :path and :authority covered + at the channel level right now) */ + if (calld->seen_post && calld->seen_scheme && calld->seen_te_trailers && + calld->seen_path && calld->seen_authority) { + /* do nothing */ + } else { + if (!calld->seen_path) { + gpr_log(GPR_ERROR, "Missing :path header"); + } + if (!calld->seen_authority) { + gpr_log(GPR_ERROR, "Missing :authority header"); + } + if (!calld->seen_post) { + gpr_log(GPR_ERROR, "Missing :method header"); + } + if (!calld->seen_scheme) { + gpr_log(GPR_ERROR, "Missing :scheme header"); + } + if (!calld->seen_te_trailers) { + gpr_log(GPR_ERROR, "Missing te trailers header"); + } + /* Error this call out */ + success = 0; + grpc_call_element_send_cancel(exec_ctx, elem); + } + } + calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, success); +} + +static void hs_mutate_op(grpc_call_element *elem, + grpc_transport_stream_op *op) { + /* grab pointers to our data from the call element */ + call_data *calld = elem->call_data; + + if (op->send_initial_metadata != NULL && !calld->sent_status) { + calld->sent_status = 1; + grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->status, + GRPC_MDELEM_STATUS_200); + grpc_metadata_batch_add_tail( + op->send_initial_metadata, &calld->content_type, + GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC); + } + + if (op->recv_initial_metadata) { + /* substitute our callback for the higher callback */ + calld->recv_initial_metadata = op->recv_initial_metadata; + calld->on_done_recv = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = &calld->hs_on_recv; + } +} + +static void hs_start_transport_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + GRPC_CALL_LOG_OP(GPR_INFO, elem, op); + GPR_TIMER_BEGIN("hs_start_transport_op", 0); + hs_mutate_op(elem, op); + grpc_call_next_op(exec_ctx, elem, op); + GPR_TIMER_END("hs_start_transport_op", 0); +} + +/* Constructor for call_data */ +static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args) { + /* grab pointers to our data from the call element */ + call_data *calld = elem->call_data; + /* initialize members */ + memset(calld, 0, sizeof(*calld)); + grpc_closure_init(&calld->hs_on_recv, hs_on_recv, elem); +} + +/* Destructor for call_data */ +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) {} + +/* Constructor for channel_data */ +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + GPR_ASSERT(!args->is_last); +} + +/* Destructor for channel data */ +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) {} + +const grpc_channel_filter grpc_http_server_filter = { + hs_start_transport_op, + grpc_channel_next_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "http-server"}; diff --git a/src/core/lib/channel/http_server_filter.h b/src/core/lib/channel/http_server_filter.h new file mode 100644 index 0000000000..528c8648fd --- /dev/null +++ b/src/core/lib/channel/http_server_filter.h @@ -0,0 +1,42 @@ +/* + * + * Copyright 2015-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_CHANNEL_HTTP_SERVER_FILTER_H +#define GRPC_CORE_CHANNEL_HTTP_SERVER_FILTER_H + +#include "src/core/channel/channel_stack.h" + +/* Processes metadata on the client side for HTTP2 transports */ +extern const grpc_channel_filter grpc_http_server_filter; + +#endif /* GRPC_CORE_CHANNEL_HTTP_SERVER_FILTER_H */ diff --git a/src/core/lib/channel/subchannel_call_holder.c b/src/core/lib/channel/subchannel_call_holder.c new file mode 100644 index 0000000000..9c087dc2a1 --- /dev/null +++ b/src/core/lib/channel/subchannel_call_holder.c @@ -0,0 +1,259 @@ +/* + * + * Copyright 2015-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/channel/subchannel_call_holder.h" + +#include + +#include "src/core/profiling/timers.h" + +#define GET_CALL(holder) \ + ((grpc_subchannel_call *)(gpr_atm_acq_load(&(holder)->subchannel_call))) + +#define CANCELLED_CALL ((grpc_subchannel_call *)1) + +static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *holder, + bool success); +static void retry_ops(grpc_exec_ctx *exec_ctx, void *retry_ops_args, + bool success); + +static void add_waiting_locked(grpc_subchannel_call_holder *holder, + grpc_transport_stream_op *op); +static void fail_locked(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call_holder *holder); +static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call_holder *holder); + +void grpc_subchannel_call_holder_init( + grpc_subchannel_call_holder *holder, + grpc_subchannel_call_holder_pick_subchannel pick_subchannel, + void *pick_subchannel_arg, grpc_call_stack *owning_call) { + gpr_atm_rel_store(&holder->subchannel_call, 0); + holder->pick_subchannel = pick_subchannel; + holder->pick_subchannel_arg = pick_subchannel_arg; + gpr_mu_init(&holder->mu); + holder->connected_subchannel = NULL; + holder->waiting_ops = NULL; + holder->waiting_ops_count = 0; + holder->waiting_ops_capacity = 0; + holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; + holder->owning_call = owning_call; +} + +void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call_holder *holder) { + grpc_subchannel_call *call = GET_CALL(holder); + if (call != NULL && call != CANCELLED_CALL) { + GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "holder"); + } + GPR_ASSERT(holder->creation_phase == + GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING); + gpr_mu_destroy(&holder->mu); + GPR_ASSERT(holder->waiting_ops_count == 0); + gpr_free(holder->waiting_ops); +} + +void grpc_subchannel_call_holder_perform_op(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call_holder *holder, + grpc_transport_stream_op *op) { + /* try to (atomically) get the call */ + grpc_subchannel_call *call = GET_CALL(holder); + GPR_TIMER_BEGIN("grpc_subchannel_call_holder_perform_op", 0); + if (call == CANCELLED_CALL) { + grpc_transport_stream_op_finish_with_failure(exec_ctx, op); + GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); + return; + } + if (call != NULL) { + grpc_subchannel_call_process_op(exec_ctx, call, op); + GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); + return; + } + /* we failed; lock and figure out what to do */ + gpr_mu_lock(&holder->mu); +retry: + /* need to recheck that another thread hasn't set the call */ + call = GET_CALL(holder); + if (call == CANCELLED_CALL) { + gpr_mu_unlock(&holder->mu); + grpc_transport_stream_op_finish_with_failure(exec_ctx, op); + GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); + return; + } + if (call != NULL) { + gpr_mu_unlock(&holder->mu); + grpc_subchannel_call_process_op(exec_ctx, call, op); + GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); + return; + } + /* if this is a cancellation, then we can raise our cancelled flag */ + if (op->cancel_with_status != GRPC_STATUS_OK) { + if (!gpr_atm_rel_cas(&holder->subchannel_call, 0, 1)) { + goto retry; + } else { + switch (holder->creation_phase) { + case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING: + fail_locked(exec_ctx, holder); + break; + case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL: + holder->pick_subchannel(exec_ctx, holder->pick_subchannel_arg, NULL, + &holder->connected_subchannel, NULL); + break; + } + gpr_mu_unlock(&holder->mu); + grpc_transport_stream_op_finish_with_failure(exec_ctx, op); + GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); + return; + } + } + /* if we don't have a subchannel, try to get one */ + if (holder->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && + holder->connected_subchannel == NULL && + op->send_initial_metadata != NULL) { + holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL; + grpc_closure_init(&holder->next_step, subchannel_ready, holder); + GRPC_CALL_STACK_REF(holder->owning_call, "pick_subchannel"); + if (holder->pick_subchannel( + exec_ctx, holder->pick_subchannel_arg, op->send_initial_metadata, + &holder->connected_subchannel, &holder->next_step)) { + holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; + GRPC_CALL_STACK_UNREF(exec_ctx, holder->owning_call, "pick_subchannel"); + } + } + /* if we've got a subchannel, then let's ask it to create a call */ + if (holder->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && + holder->connected_subchannel != NULL) { + gpr_atm_rel_store( + &holder->subchannel_call, + (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call( + exec_ctx, holder->connected_subchannel, holder->pollset)); + retry_waiting_locked(exec_ctx, holder); + goto retry; + } + /* nothing to be done but wait */ + add_waiting_locked(holder, op); + gpr_mu_unlock(&holder->mu); + GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); +} + +static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + grpc_subchannel_call_holder *holder = arg; + gpr_mu_lock(&holder->mu); + GPR_ASSERT(holder->creation_phase == + GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL); + holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; + if (holder->connected_subchannel == NULL) { + fail_locked(exec_ctx, holder); + } else if (1 == gpr_atm_acq_load(&holder->subchannel_call)) { + /* already cancelled before subchannel became ready */ + fail_locked(exec_ctx, holder); + } else { + gpr_atm_rel_store( + &holder->subchannel_call, + (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call( + exec_ctx, holder->connected_subchannel, holder->pollset)); + retry_waiting_locked(exec_ctx, holder); + } + gpr_mu_unlock(&holder->mu); + GRPC_CALL_STACK_UNREF(exec_ctx, holder->owning_call, "pick_subchannel"); +} + +typedef struct { + grpc_transport_stream_op *ops; + size_t nops; + grpc_subchannel_call *call; +} retry_ops_args; + +static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call_holder *holder) { + retry_ops_args *a = gpr_malloc(sizeof(*a)); + a->ops = holder->waiting_ops; + a->nops = holder->waiting_ops_count; + a->call = GET_CALL(holder); + if (a->call == CANCELLED_CALL) { + gpr_free(a); + fail_locked(exec_ctx, holder); + return; + } + holder->waiting_ops = NULL; + holder->waiting_ops_count = 0; + holder->waiting_ops_capacity = 0; + GRPC_SUBCHANNEL_CALL_REF(a->call, "retry_ops"); + grpc_exec_ctx_enqueue(exec_ctx, grpc_closure_create(retry_ops, a), true, + NULL); +} + +static void retry_ops(grpc_exec_ctx *exec_ctx, void *args, bool success) { + retry_ops_args *a = args; + size_t i; + for (i = 0; i < a->nops; i++) { + grpc_subchannel_call_process_op(exec_ctx, a->call, &a->ops[i]); + } + GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, a->call, "retry_ops"); + gpr_free(a->ops); + gpr_free(a); +} + +static void add_waiting_locked(grpc_subchannel_call_holder *holder, + grpc_transport_stream_op *op) { + GPR_TIMER_BEGIN("add_waiting_locked", 0); + if (holder->waiting_ops_count == holder->waiting_ops_capacity) { + holder->waiting_ops_capacity = GPR_MAX(3, 2 * holder->waiting_ops_capacity); + holder->waiting_ops = + gpr_realloc(holder->waiting_ops, holder->waiting_ops_capacity * + sizeof(*holder->waiting_ops)); + } + holder->waiting_ops[holder->waiting_ops_count++] = *op; + GPR_TIMER_END("add_waiting_locked", 0); +} + +static void fail_locked(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call_holder *holder) { + size_t i; + for (i = 0; i < holder->waiting_ops_count; i++) { + grpc_transport_stream_op_finish_with_failure(exec_ctx, + &holder->waiting_ops[i]); + } + holder->waiting_ops_count = 0; +} + +char *grpc_subchannel_call_holder_get_peer( + grpc_exec_ctx *exec_ctx, grpc_subchannel_call_holder *holder) { + grpc_subchannel_call *subchannel_call = GET_CALL(holder); + + if (subchannel_call) { + return grpc_subchannel_call_get_peer(exec_ctx, subchannel_call); + } else { + return NULL; + } +} diff --git a/src/core/lib/channel/subchannel_call_holder.h b/src/core/lib/channel/subchannel_call_holder.h new file mode 100644 index 0000000000..84b4657db4 --- /dev/null +++ b/src/core/lib/channel/subchannel_call_holder.h @@ -0,0 +1,97 @@ +/* + * + * Copyright 2015-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_CHANNEL_SUBCHANNEL_CALL_HOLDER_H +#define GRPC_CORE_CHANNEL_SUBCHANNEL_CALL_HOLDER_H + +#include "src/core/client_config/subchannel.h" + +/** Pick a subchannel for grpc_subchannel_call_holder; + Return 1 if subchannel is available immediately (in which case on_ready + should not be called), or 0 otherwise (in which case on_ready should be + called when the subchannel is available) */ +typedef int (*grpc_subchannel_call_holder_pick_subchannel)( + grpc_exec_ctx *exec_ctx, void *arg, grpc_metadata_batch *initial_metadata, + grpc_connected_subchannel **connected_subchannel, grpc_closure *on_ready); + +typedef enum { + GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING, + GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL +} grpc_subchannel_call_holder_creation_phase; + +/** Wrapper for holding a pointer to grpc_subchannel_call, and the + associated machinery to create such a pointer. + Handles queueing of stream ops until a call object is ready, waiting + for initial metadata before trying to create a call object, + and handling cancellation gracefully. + + The channel filter uses this as their call_data. */ +typedef struct grpc_subchannel_call_holder { + /** either 0 for no call, 1 for cancelled, or a pointer to a + grpc_subchannel_call */ + gpr_atm subchannel_call; + /** Helper function to choose the subchannel on which to create + the call object. Channel filter delegates to the load + balancing policy (once it's ready). */ + grpc_subchannel_call_holder_pick_subchannel pick_subchannel; + void *pick_subchannel_arg; + + gpr_mu mu; + + grpc_subchannel_call_holder_creation_phase creation_phase; + grpc_connected_subchannel *connected_subchannel; + grpc_pollset *pollset; + + grpc_transport_stream_op *waiting_ops; + size_t waiting_ops_count; + size_t waiting_ops_capacity; + + grpc_closure next_step; + + grpc_call_stack *owning_call; +} grpc_subchannel_call_holder; + +void grpc_subchannel_call_holder_init( + grpc_subchannel_call_holder *holder, + grpc_subchannel_call_holder_pick_subchannel pick_subchannel, + void *pick_subchannel_arg, grpc_call_stack *owning_call); +void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call_holder *holder); + +void grpc_subchannel_call_holder_perform_op(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call_holder *holder, + grpc_transport_stream_op *op); +char *grpc_subchannel_call_holder_get_peer(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call_holder *holder); + +#endif /* GRPC_CORE_CHANNEL_SUBCHANNEL_CALL_HOLDER_H */ diff --git a/src/core/lib/client_config/README.md b/src/core/lib/client_config/README.md new file mode 100644 index 0000000000..fff7a5af5b --- /dev/null +++ b/src/core/lib/client_config/README.md @@ -0,0 +1,66 @@ +Client Configuration Support for GRPC +===================================== + +This library provides high level configuration machinery to construct client +channels and load balance between them. + +Each grpc_channel is created with a grpc_resolver. It is the resolver's duty +to resolve a name into configuration data for the channel. Such configuration +data might include: + +- a list of (ip, port) addresses to connect to +- a load balancing policy to decide which server to send a request to +- a set of filters to mutate outgoing requests (say, by adding metadata) + +The resolver provides this data as a stream of grpc_client_config objects to +the channel. We represent configuration as a stream so that it can be changed +by the resolver during execution, by reacting to external events (such as a +new configuration file being pushed to some store). + + +Load Balancing +-------------- + +Load balancing configuration is provided by a grpc_lb_policy object, stored as +part of grpc_client_config. + +The primary job of the load balancing policies is to pick a target server given only the +initial metadata for a request. It does this by providing a grpc_subchannel +object to the owning channel. + + +Sub-Channels +------------ + +A sub-channel provides a connection to a server for a client channel. It has a +connectivity state like a regular channel, and so can be connected or +disconnected. This connectivity state can be used to inform load balancing +decisions (for example, by avoiding disconnected backends). + +Configured sub-channels are fully setup to participate in the grpc data plane. +Their behavior is specified by a set of grpc channel filters defined at their +construction. To customize this behavior, resolvers build +grpc_subchannel_factory objects, which use the decorator pattern to customize +construction arguments for concrete grpc_subchannel instances. + + +Naming for GRPC +=============== + +Names in GRPC are represented by a URI (as defined in +[RFC 3986](https://tools.ietf.org/html/rfc3986)). + +The following schemes are currently supported: + +dns:///host:port - dns schemes are currently supported so long as authority is + empty (authority based dns resolution is expected in a future + release) + +unix:path - the unix scheme is used to create and connect to unix domain + sockets - the authority must be empty, and the path + represents the absolute or relative path to the desired + socket + +ipv4:host:port - a pre-resolved ipv4 dotted decimal address/port combination + +ipv6:[host]:port - a pre-resolved ipv6 address/port combination diff --git a/src/core/lib/client_config/client_config.c b/src/core/lib/client_config/client_config.c new file mode 100644 index 0000000000..c500af25ee --- /dev/null +++ b/src/core/lib/client_config/client_config.c @@ -0,0 +1,74 @@ +/* + * + * Copyright 2015-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/client_config/client_config.h" + +#include + +#include + +struct grpc_client_config { + gpr_refcount refs; + grpc_lb_policy *lb_policy; +}; + +grpc_client_config *grpc_client_config_create() { + grpc_client_config *c = gpr_malloc(sizeof(*c)); + memset(c, 0, sizeof(*c)); + gpr_ref_init(&c->refs, 1); + return c; +} + +void grpc_client_config_ref(grpc_client_config *c) { gpr_ref(&c->refs); } + +void grpc_client_config_unref(grpc_exec_ctx *exec_ctx, grpc_client_config *c) { + if (gpr_unref(&c->refs)) { + if (c->lb_policy != NULL) { + GRPC_LB_POLICY_UNREF(exec_ctx, c->lb_policy, "client_config"); + } + gpr_free(c); + } +} + +void grpc_client_config_set_lb_policy(grpc_client_config *c, + grpc_lb_policy *lb_policy) { + GPR_ASSERT(c->lb_policy == NULL); + if (lb_policy) { + GRPC_LB_POLICY_REF(lb_policy, "client_config"); + } + c->lb_policy = lb_policy; +} + +grpc_lb_policy *grpc_client_config_get_lb_policy(grpc_client_config *c) { + return c->lb_policy; +} diff --git a/src/core/lib/client_config/client_config.h b/src/core/lib/client_config/client_config.h new file mode 100644 index 0000000000..9b37fdc211 --- /dev/null +++ b/src/core/lib/client_config/client_config.h @@ -0,0 +1,53 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_CLIENT_CONFIG_H +#define GRPC_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H + +#include "src/core/client_config/lb_policy.h" + +/** Total configuration for a client. Provided, and updated, by + grpc_resolver */ +typedef struct grpc_client_config grpc_client_config; + +grpc_client_config *grpc_client_config_create(); +void grpc_client_config_ref(grpc_client_config *client_config); +void grpc_client_config_unref(grpc_exec_ctx *exec_ctx, + grpc_client_config *client_config); + +void grpc_client_config_set_lb_policy(grpc_client_config *client_config, + grpc_lb_policy *lb_policy); +grpc_lb_policy *grpc_client_config_get_lb_policy( + grpc_client_config *client_config); + +#endif /* GRPC_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H */ diff --git a/src/core/lib/client_config/connector.c b/src/core/lib/client_config/connector.c new file mode 100644 index 0000000000..aa34aa7fab --- /dev/null +++ b/src/core/lib/client_config/connector.c @@ -0,0 +1,55 @@ +/* + * + * Copyright 2015-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/client_config/connector.h" + +grpc_connector* grpc_connector_ref(grpc_connector* connector) { + connector->vtable->ref(connector); + return connector; +} + +void grpc_connector_unref(grpc_exec_ctx* exec_ctx, grpc_connector* connector) { + connector->vtable->unref(exec_ctx, connector); +} + +void grpc_connector_connect(grpc_exec_ctx* exec_ctx, grpc_connector* connector, + const grpc_connect_in_args* in_args, + grpc_connect_out_args* out_args, + grpc_closure* notify) { + connector->vtable->connect(exec_ctx, connector, in_args, out_args, notify); +} + +void grpc_connector_shutdown(grpc_exec_ctx* exec_ctx, + grpc_connector* connector) { + connector->vtable->shutdown(exec_ctx, connector); +} diff --git a/src/core/lib/client_config/connector.h b/src/core/lib/client_config/connector.h new file mode 100644 index 0000000000..93248fca4b --- /dev/null +++ b/src/core/lib/client_config/connector.h @@ -0,0 +1,92 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_CONNECTOR_H +#define GRPC_CORE_CLIENT_CONFIG_CONNECTOR_H + +#include "src/core/channel/channel_stack.h" +#include "src/core/iomgr/sockaddr.h" +#include "src/core/transport/transport.h" + +typedef struct grpc_connector grpc_connector; +typedef struct grpc_connector_vtable grpc_connector_vtable; + +struct grpc_connector { + const grpc_connector_vtable *vtable; +}; + +typedef struct { + /** set of pollsets interested in this connection */ + grpc_pollset_set *interested_parties; + /** address to connect to */ + const struct sockaddr *addr; + size_t addr_len; + /** initial connect string to send */ + gpr_slice initial_connect_string; + /** deadline for connection */ + gpr_timespec deadline; + /** channel arguments (to be passed to transport) */ + const grpc_channel_args *channel_args; +} grpc_connect_in_args; + +typedef struct { + /** the connected transport */ + grpc_transport *transport; + + /** channel arguments (to be passed to the filters) */ + const grpc_channel_args *channel_args; +} grpc_connect_out_args; + +struct grpc_connector_vtable { + void (*ref)(grpc_connector *connector); + void (*unref)(grpc_exec_ctx *exec_ctx, grpc_connector *connector); + /** Implementation of grpc_connector_shutdown */ + void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_connector *connector); + /** Implementation of grpc_connector_connect */ + void (*connect)(grpc_exec_ctx *exec_ctx, grpc_connector *connector, + const grpc_connect_in_args *in_args, + grpc_connect_out_args *out_args, grpc_closure *notify); +}; + +grpc_connector *grpc_connector_ref(grpc_connector *connector); +void grpc_connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *connector); +/** Connect using the connector: max one outstanding call at a time */ +void grpc_connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *connector, + const grpc_connect_in_args *in_args, + grpc_connect_out_args *out_args, + grpc_closure *notify); +/** Cancel any pending connection */ +void grpc_connector_shutdown(grpc_exec_ctx *exec_ctx, + grpc_connector *connector); + +#endif /* GRPC_CORE_CLIENT_CONFIG_CONNECTOR_H */ diff --git a/src/core/lib/client_config/default_initial_connect_string.c b/src/core/lib/client_config/default_initial_connect_string.c new file mode 100644 index 0000000000..6a4e23e6f2 --- /dev/null +++ b/src/core/lib/client_config/default_initial_connect_string.c @@ -0,0 +1,39 @@ +/* + * + * Copyright 2015, 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 +#include "src/core/iomgr/sockaddr.h" + +void grpc_set_default_initial_connect_string(struct sockaddr **addr, + size_t *addr_len, + gpr_slice *initial_str) {} diff --git a/src/core/lib/client_config/initial_connect_string.c b/src/core/lib/client_config/initial_connect_string.c new file mode 100644 index 0000000000..19afa1675a --- /dev/null +++ b/src/core/lib/client_config/initial_connect_string.c @@ -0,0 +1,53 @@ +/* + * + * Copyright 2015, 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/client_config/initial_connect_string.h" + +#include + +extern void grpc_set_default_initial_connect_string(struct sockaddr **addr, + size_t *addr_len, + gpr_slice *initial_str); + +static grpc_set_initial_connect_string_func g_set_initial_connect_string_func = + grpc_set_default_initial_connect_string; + +void grpc_test_set_initial_connect_string_function( + grpc_set_initial_connect_string_func func) { + g_set_initial_connect_string_func = func; +} + +void grpc_set_initial_connect_string(struct sockaddr **addr, size_t *addr_len, + gpr_slice *initial_str) { + g_set_initial_connect_string_func(addr, addr_len, initial_str); +} diff --git a/src/core/lib/client_config/initial_connect_string.h b/src/core/lib/client_config/initial_connect_string.h new file mode 100644 index 0000000000..e6d2d8f8fe --- /dev/null +++ b/src/core/lib/client_config/initial_connect_string.h @@ -0,0 +1,50 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H +#define GRPC_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H + +#include +#include "src/core/iomgr/sockaddr.h" + +typedef void (*grpc_set_initial_connect_string_func)(struct sockaddr **addr, + size_t *addr_len, + gpr_slice *initial_str); +void grpc_test_set_initial_connect_string_function( + grpc_set_initial_connect_string_func func); + +/** Set a string to be sent once connected. Optionally reset addr. */ +void grpc_set_initial_connect_string(struct sockaddr **addr, size_t *addr_len, + gpr_slice *connect_string); + +#endif /* GRPC_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H */ diff --git a/src/core/lib/client_config/lb_policies/load_balancer_api.c b/src/core/lib/client_config/lb_policies/load_balancer_api.c new file mode 100644 index 0000000000..a6b5785fe4 --- /dev/null +++ b/src/core/lib/client_config/lb_policies/load_balancer_api.c @@ -0,0 +1,163 @@ +/* + * + * 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/client_config/lb_policies/load_balancer_api.h" +#include "third_party/nanopb/pb_decode.h" +#include "third_party/nanopb/pb_encode.h" + +#include + +typedef struct decode_serverlist_arg { + int first_pass; + int i; + size_t num_servers; + grpc_grpclb_server **servers; +} decode_serverlist_arg; + +/* invoked once for every Server in ServerList */ +static bool decode_serverlist(pb_istream_t *stream, const pb_field_t *field, + void **arg) { + decode_serverlist_arg *dec_arg = *arg; + if (dec_arg->first_pass != 0) { /* first pass */ + grpc_grpclb_server server; + if (!pb_decode(stream, grpc_lb_v0_Server_fields, &server)) { + return false; + } + dec_arg->num_servers++; + } else { /* second pass */ + grpc_grpclb_server *server = gpr_malloc(sizeof(grpc_grpclb_server)); + GPR_ASSERT(dec_arg->num_servers > 0); + if (dec_arg->i == 0) { /* first iteration of second pass */ + dec_arg->servers = + gpr_malloc(sizeof(grpc_grpclb_server *) * dec_arg->num_servers); + } + if (!pb_decode(stream, grpc_lb_v0_Server_fields, server)) { + return false; + } + dec_arg->servers[dec_arg->i++] = server; + } + + return true; +} + +grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name) { + grpc_grpclb_request *req = gpr_malloc(sizeof(grpc_grpclb_request)); + + req->has_client_stats = 0; /* TODO(dgq): add support for stats once defined */ + req->has_initial_request = 1; + req->initial_request.has_name = 1; + strncpy(req->initial_request.name, lb_service_name, + GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH); + return req; +} + +gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request) { + size_t encoded_length; + pb_ostream_t sizestream; + pb_ostream_t outputstream; + gpr_slice slice; + memset(&sizestream, 0, sizeof(pb_ostream_t)); + pb_encode(&sizestream, grpc_lb_v0_LoadBalanceRequest_fields, request); + encoded_length = sizestream.bytes_written; + + slice = gpr_slice_malloc(encoded_length); + outputstream = + pb_ostream_from_buffer(GPR_SLICE_START_PTR(slice), encoded_length); + GPR_ASSERT(pb_encode(&outputstream, grpc_lb_v0_LoadBalanceRequest_fields, + request) != 0); + return slice; +} + +void grpc_grpclb_request_destroy(grpc_grpclb_request *request) { + gpr_free(request); +} + +grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response) { + bool status; + pb_istream_t stream = + pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response), + GPR_SLICE_LENGTH(encoded_response)); + grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response)); + memset(res, 0, sizeof(*res)); + status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res); + GPR_ASSERT(status == true); + return res; +} + +grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist( + gpr_slice encoded_response) { + grpc_grpclb_serverlist *sl = gpr_malloc(sizeof(grpc_grpclb_serverlist)); + bool status; + decode_serverlist_arg arg; + pb_istream_t stream = + pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response), + GPR_SLICE_LENGTH(encoded_response)); + pb_istream_t stream_at_start = stream; + grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response)); + memset(res, 0, sizeof(*res)); + memset(&arg, 0, sizeof(decode_serverlist_arg)); + + res->server_list.servers.funcs.decode = decode_serverlist; + res->server_list.servers.arg = &arg; + arg.first_pass = 1; + status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res); + GPR_ASSERT(status == true); + GPR_ASSERT(arg.num_servers > 0); + + arg.first_pass = 0; + status = + pb_decode(&stream_at_start, grpc_lb_v0_LoadBalanceResponse_fields, res); + GPR_ASSERT(status == true); + GPR_ASSERT(arg.servers != NULL); + + sl->num_servers = arg.num_servers; + sl->servers = arg.servers; + if (res->server_list.has_expiration_interval) { + sl->expiration_interval = res->server_list.expiration_interval; + } + grpc_grpclb_response_destroy(res); + return sl; +} + +void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist) { + size_t i; + for (i = 0; i < serverlist->num_servers; i++) { + gpr_free(serverlist->servers[i]); + } + gpr_free(serverlist->servers); + gpr_free(serverlist); +} + +void grpc_grpclb_response_destroy(grpc_grpclb_response *response) { + gpr_free(response); +} diff --git a/src/core/lib/client_config/lb_policies/load_balancer_api.h b/src/core/lib/client_config/lb_policies/load_balancer_api.h new file mode 100644 index 0000000000..b7a4c9c8f5 --- /dev/null +++ b/src/core/lib/client_config/lb_policies/load_balancer_api.h @@ -0,0 +1,85 @@ +/* + * + * 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_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H +#define GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H + +#include + +#include "src/core/client_config/lb_policy_factory.h" +#include "src/core/proto/grpc/lb/v0/load_balancer.pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128 + +typedef grpc_lb_v0_LoadBalanceRequest grpc_grpclb_request; +typedef grpc_lb_v0_LoadBalanceResponse grpc_grpclb_response; +typedef grpc_lb_v0_Server grpc_grpclb_server; +typedef grpc_lb_v0_Duration grpc_grpclb_duration; +typedef struct grpc_grpclb_serverlist { + grpc_grpclb_server **servers; + size_t num_servers; + grpc_grpclb_duration expiration_interval; +} grpc_grpclb_serverlist; + +/** Create a request for a gRPC LB service under \a lb_service_name */ +grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name); + +/** Protocol Buffers v3-encode \a request */ +gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request); + +/** Destroy \a request */ +void grpc_grpclb_request_destroy(grpc_grpclb_request *request); + +/** Parse (ie, decode) the bytes in \a encoded_response as a \a + * grpc_grpclb_response */ +grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response); + +/** Destroy \a serverlist */ +void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist); + +/** Parse the list of servers from an encoded \a grpc_grpclb_response */ +grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist( + gpr_slice encoded_response); + +/** Destroy \a response */ +void grpc_grpclb_response_destroy(grpc_grpclb_response *response); + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H */ diff --git a/src/core/lib/client_config/lb_policies/pick_first.c b/src/core/lib/client_config/lb_policies/pick_first.c new file mode 100644 index 0000000000..2833f112f4 --- /dev/null +++ b/src/core/lib/client_config/lb_policies/pick_first.c @@ -0,0 +1,421 @@ +/* + * + * Copyright 2015-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/client_config/lb_policies/pick_first.h" +#include "src/core/client_config/lb_policy_factory.h" + +#include + +#include +#include "src/core/transport/connectivity_state.h" + +typedef struct pending_pick { + struct pending_pick *next; + grpc_pollset *pollset; + grpc_connected_subchannel **target; + grpc_closure *on_complete; +} pending_pick; + +typedef struct { + /** base policy: must be first */ + grpc_lb_policy base; + /** all our subchannels */ + grpc_subchannel **subchannels; + size_t num_subchannels; + + grpc_closure connectivity_changed; + + /** the selected channel (a grpc_connected_subchannel) */ + gpr_atm selected; + + /** mutex protecting remaining members */ + gpr_mu mu; + /** have we started picking? */ + int started_picking; + /** are we shut down? */ + int shutdown; + /** which subchannel are we watching? */ + size_t checking_subchannel; + /** what is the connectivity of that channel? */ + grpc_connectivity_state checking_connectivity; + /** list of picks that are waiting on connectivity */ + pending_pick *pending_picks; + + /** our connectivity state tracker */ + grpc_connectivity_state_tracker state_tracker; +} pick_first_lb_policy; + +#define GET_SELECTED(p) \ + ((grpc_connected_subchannel *)gpr_atm_acq_load(&(p)->selected)) + +void pf_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { + pick_first_lb_policy *p = (pick_first_lb_policy *)pol; + grpc_connected_subchannel *selected = GET_SELECTED(p); + size_t i; + GPR_ASSERT(p->pending_picks == NULL); + for (i = 0; i < p->num_subchannels; i++) { + GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[i], "pick_first"); + } + if (selected != NULL) { + GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, selected, "picked_first"); + } + grpc_connectivity_state_destroy(exec_ctx, &p->state_tracker); + gpr_free(p->subchannels); + gpr_mu_destroy(&p->mu); + gpr_free(p); +} + +void pf_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { + pick_first_lb_policy *p = (pick_first_lb_policy *)pol; + pending_pick *pp; + grpc_connected_subchannel *selected; + gpr_mu_lock(&p->mu); + selected = GET_SELECTED(p); + p->shutdown = 1; + pp = p->pending_picks; + p->pending_picks = NULL; + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + GRPC_CHANNEL_FATAL_FAILURE, "shutdown"); + /* cancel subscription */ + if (selected != NULL) { + grpc_connected_subchannel_notify_on_state_change( + exec_ctx, selected, NULL, NULL, &p->connectivity_changed); + } else { + grpc_subchannel_notify_on_state_change( + exec_ctx, p->subchannels[p->checking_subchannel], NULL, NULL, + &p->connectivity_changed); + } + gpr_mu_unlock(&p->mu); + while (pp != NULL) { + pending_pick *next = pp->next; + *pp->target = NULL; + grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties, + pp->pollset); + grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL); + gpr_free(pp); + pp = next; + } +} + +static void pf_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, + grpc_connected_subchannel **target) { + pick_first_lb_policy *p = (pick_first_lb_policy *)pol; + pending_pick *pp; + gpr_mu_lock(&p->mu); + pp = p->pending_picks; + p->pending_picks = NULL; + while (pp != NULL) { + pending_pick *next = pp->next; + if (pp->target == target) { + grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties, + pp->pollset); + *target = NULL; + grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL); + gpr_free(pp); + } else { + pp->next = p->pending_picks; + p->pending_picks = pp; + } + pp = next; + } + gpr_mu_unlock(&p->mu); +} + +static void start_picking(grpc_exec_ctx *exec_ctx, pick_first_lb_policy *p) { + p->started_picking = 1; + p->checking_subchannel = 0; + p->checking_connectivity = GRPC_CHANNEL_IDLE; + GRPC_LB_POLICY_WEAK_REF(&p->base, "pick_first_connectivity"); + grpc_subchannel_notify_on_state_change( + exec_ctx, p->subchannels[p->checking_subchannel], + p->base.interested_parties, &p->checking_connectivity, + &p->connectivity_changed); +} + +void pf_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { + pick_first_lb_policy *p = (pick_first_lb_policy *)pol; + gpr_mu_lock(&p->mu); + if (!p->started_picking) { + start_picking(exec_ctx, p); + } + gpr_mu_unlock(&p->mu); +} + +int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, grpc_pollset *pollset, + grpc_metadata_batch *initial_metadata, + grpc_connected_subchannel **target, grpc_closure *on_complete) { + pick_first_lb_policy *p = (pick_first_lb_policy *)pol; + pending_pick *pp; + + /* Check atomically for a selected channel */ + grpc_connected_subchannel *selected = GET_SELECTED(p); + if (selected != NULL) { + *target = selected; + return 1; + } + + /* No subchannel selected yet, so acquire lock and then attempt again */ + gpr_mu_lock(&p->mu); + selected = GET_SELECTED(p); + if (selected) { + gpr_mu_unlock(&p->mu); + *target = selected; + return 1; + } else { + if (!p->started_picking) { + start_picking(exec_ctx, p); + } + grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset); + pp = gpr_malloc(sizeof(*pp)); + pp->next = p->pending_picks; + pp->pollset = pollset; + pp->target = target; + pp->on_complete = on_complete; + p->pending_picks = pp; + gpr_mu_unlock(&p->mu); + return 0; + } +} + +static void destroy_subchannels(grpc_exec_ctx *exec_ctx, void *arg, + bool iomgr_success) { + pick_first_lb_policy *p = arg; + size_t i; + size_t num_subchannels = p->num_subchannels; + grpc_subchannel **subchannels; + + gpr_mu_lock(&p->mu); + subchannels = p->subchannels; + p->num_subchannels = 0; + p->subchannels = NULL; + gpr_mu_unlock(&p->mu); + GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "destroy_subchannels"); + + for (i = 0; i < num_subchannels; i++) { + GRPC_SUBCHANNEL_UNREF(exec_ctx, subchannels[i], "pick_first"); + } + + gpr_free(subchannels); +} + +static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg, + bool iomgr_success) { + pick_first_lb_policy *p = arg; + grpc_subchannel *selected_subchannel; + pending_pick *pp; + grpc_connected_subchannel *selected; + + gpr_mu_lock(&p->mu); + + selected = GET_SELECTED(p); + + if (p->shutdown) { + gpr_mu_unlock(&p->mu); + GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "pick_first_connectivity"); + return; + } else if (selected != NULL) { + if (p->checking_connectivity == GRPC_CHANNEL_TRANSIENT_FAILURE) { + /* if the selected channel goes bad, we're done */ + p->checking_connectivity = GRPC_CHANNEL_FATAL_FAILURE; + } + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + p->checking_connectivity, "selected_changed"); + if (p->checking_connectivity != GRPC_CHANNEL_FATAL_FAILURE) { + grpc_connected_subchannel_notify_on_state_change( + exec_ctx, selected, p->base.interested_parties, + &p->checking_connectivity, &p->connectivity_changed); + } else { + GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "pick_first_connectivity"); + } + } else { + loop: + switch (p->checking_connectivity) { + case GRPC_CHANNEL_READY: + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + GRPC_CHANNEL_READY, "connecting_ready"); + selected_subchannel = p->subchannels[p->checking_subchannel]; + selected = + grpc_subchannel_get_connected_subchannel(selected_subchannel); + GPR_ASSERT(selected != NULL); + GRPC_CONNECTED_SUBCHANNEL_REF(selected, "picked_first"); + /* drop the pick list: we are connected now */ + GRPC_LB_POLICY_WEAK_REF(&p->base, "destroy_subchannels"); + gpr_atm_rel_store(&p->selected, (gpr_atm)selected); + grpc_exec_ctx_enqueue( + exec_ctx, grpc_closure_create(destroy_subchannels, p), true, NULL); + /* update any calls that were waiting for a pick */ + while ((pp = p->pending_picks)) { + p->pending_picks = pp->next; + *pp->target = selected; + grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties, + pp->pollset); + grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL); + gpr_free(pp); + } + grpc_connected_subchannel_notify_on_state_change( + exec_ctx, selected, p->base.interested_parties, + &p->checking_connectivity, &p->connectivity_changed); + break; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + GRPC_CHANNEL_TRANSIENT_FAILURE, + "connecting_transient_failure"); + p->checking_subchannel = + (p->checking_subchannel + 1) % p->num_subchannels; + p->checking_connectivity = grpc_subchannel_check_connectivity( + p->subchannels[p->checking_subchannel]); + if (p->checking_connectivity == GRPC_CHANNEL_TRANSIENT_FAILURE) { + grpc_subchannel_notify_on_state_change( + exec_ctx, p->subchannels[p->checking_subchannel], + p->base.interested_parties, &p->checking_connectivity, + &p->connectivity_changed); + } else { + goto loop; + } + break; + case GRPC_CHANNEL_CONNECTING: + case GRPC_CHANNEL_IDLE: + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + GRPC_CHANNEL_CONNECTING, + "connecting_changed"); + grpc_subchannel_notify_on_state_change( + exec_ctx, p->subchannels[p->checking_subchannel], + p->base.interested_parties, &p->checking_connectivity, + &p->connectivity_changed); + break; + case GRPC_CHANNEL_FATAL_FAILURE: + p->num_subchannels--; + GPR_SWAP(grpc_subchannel *, p->subchannels[p->checking_subchannel], + p->subchannels[p->num_subchannels]); + GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[p->num_subchannels], + "pick_first"); + if (p->num_subchannels == 0) { + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + GRPC_CHANNEL_FATAL_FAILURE, + "no_more_channels"); + while ((pp = p->pending_picks)) { + p->pending_picks = pp->next; + *pp->target = NULL; + grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL); + gpr_free(pp); + } + GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, + "pick_first_connectivity"); + } else { + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + GRPC_CHANNEL_TRANSIENT_FAILURE, + "subchannel_failed"); + p->checking_subchannel %= p->num_subchannels; + p->checking_connectivity = grpc_subchannel_check_connectivity( + p->subchannels[p->checking_subchannel]); + goto loop; + } + } + } + + gpr_mu_unlock(&p->mu); +} + +static grpc_connectivity_state pf_check_connectivity(grpc_exec_ctx *exec_ctx, + grpc_lb_policy *pol) { + pick_first_lb_policy *p = (pick_first_lb_policy *)pol; + grpc_connectivity_state st; + gpr_mu_lock(&p->mu); + st = grpc_connectivity_state_check(&p->state_tracker); + gpr_mu_unlock(&p->mu); + return st; +} + +void pf_notify_on_state_change(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, + grpc_connectivity_state *current, + grpc_closure *notify) { + pick_first_lb_policy *p = (pick_first_lb_policy *)pol; + gpr_mu_lock(&p->mu); + grpc_connectivity_state_notify_on_state_change(exec_ctx, &p->state_tracker, + current, notify); + gpr_mu_unlock(&p->mu); +} + +void pf_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, + grpc_closure *closure) { + pick_first_lb_policy *p = (pick_first_lb_policy *)pol; + grpc_connected_subchannel *selected = GET_SELECTED(p); + if (selected) { + grpc_connected_subchannel_ping(exec_ctx, selected, closure); + } else { + grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL); + } +} + +static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = { + pf_destroy, + pf_shutdown, + pf_pick, + pf_cancel_pick, + pf_ping_one, + pf_exit_idle, + pf_check_connectivity, + pf_notify_on_state_change}; + +static void pick_first_factory_ref(grpc_lb_policy_factory *factory) {} + +static void pick_first_factory_unref(grpc_lb_policy_factory *factory) {} + +static grpc_lb_policy *create_pick_first(grpc_lb_policy_factory *factory, + grpc_lb_policy_args *args) { + if (args->num_subchannels == 0) return NULL; + pick_first_lb_policy *p = gpr_malloc(sizeof(*p)); + memset(p, 0, sizeof(*p)); + grpc_lb_policy_init(&p->base, &pick_first_lb_policy_vtable); + p->subchannels = + gpr_malloc(sizeof(grpc_subchannel *) * args->num_subchannels); + p->num_subchannels = args->num_subchannels; + grpc_connectivity_state_init(&p->state_tracker, GRPC_CHANNEL_IDLE, + "pick_first"); + memcpy(p->subchannels, args->subchannels, + sizeof(grpc_subchannel *) * args->num_subchannels); + grpc_closure_init(&p->connectivity_changed, pf_connectivity_changed, p); + gpr_mu_init(&p->mu); + return &p->base; +} + +static const grpc_lb_policy_factory_vtable pick_first_factory_vtable = { + pick_first_factory_ref, pick_first_factory_unref, create_pick_first, + "pick_first"}; + +static grpc_lb_policy_factory pick_first_lb_policy_factory = { + &pick_first_factory_vtable}; + +grpc_lb_policy_factory *grpc_pick_first_lb_factory_create() { + return &pick_first_lb_policy_factory; +} diff --git a/src/core/lib/client_config/lb_policies/pick_first.h b/src/core/lib/client_config/lb_policies/pick_first.h new file mode 100644 index 0000000000..3a3f195df5 --- /dev/null +++ b/src/core/lib/client_config/lb_policies/pick_first.h @@ -0,0 +1,43 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H +#define GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H + +#include "src/core/client_config/lb_policy_factory.h" + +/** Returns a load balancing factory for the pick first policy, which picks up + * the first subchannel from \a subchannels to succesfully connect */ +grpc_lb_policy_factory *grpc_pick_first_lb_factory_create(); + +#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H */ diff --git a/src/core/lib/client_config/lb_policies/round_robin.c b/src/core/lib/client_config/lb_policies/round_robin.c new file mode 100644 index 0000000000..114ece6e4d --- /dev/null +++ b/src/core/lib/client_config/lb_policies/round_robin.c @@ -0,0 +1,542 @@ +/* + * + * Copyright 2015-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/client_config/lb_policies/round_robin.h" + +#include + +#include +#include "src/core/transport/connectivity_state.h" + +typedef struct round_robin_lb_policy round_robin_lb_policy; + +int grpc_lb_round_robin_trace = 0; + +/** List of entities waiting for a pick. + * + * Once a pick is available, \a target is updated and \a on_complete called. */ +typedef struct pending_pick { + struct pending_pick *next; + grpc_pollset *pollset; + grpc_connected_subchannel **target; + grpc_closure *on_complete; +} pending_pick; + +/** List of subchannels in a connectivity READY state */ +typedef struct ready_list { + grpc_subchannel *subchannel; + struct ready_list *next; + struct ready_list *prev; +} ready_list; + +typedef struct { + /** index within policy->subchannels */ + size_t index; + /** backpointer to owning policy */ + round_robin_lb_policy *policy; + /** subchannel itself */ + grpc_subchannel *subchannel; + /** notification that connectivity has changed on subchannel */ + grpc_closure connectivity_changed_closure; + /** this subchannels current position in subchannel->ready_list */ + ready_list *ready_list_node; + /** last observed connectivity */ + grpc_connectivity_state connectivity_state; +} subchannel_data; + +struct round_robin_lb_policy { + /** base policy: must be first */ + grpc_lb_policy base; + + /** all our subchannels */ + size_t num_subchannels; + subchannel_data **subchannels; + + /** mutex protecting remaining members */ + gpr_mu mu; + /** have we started picking? */ + int started_picking; + /** are we shutting down? */ + int shutdown; + /** List of picks that are waiting on connectivity */ + pending_pick *pending_picks; + + /** our connectivity state tracker */ + grpc_connectivity_state_tracker state_tracker; + + /** (Dummy) root of the doubly linked list containing READY subchannels */ + ready_list ready_list; + /** Last pick from the ready list. */ + ready_list *ready_list_last_pick; +}; + +/** Returns the next subchannel from the connected list or NULL if the list is + * empty. + * + * Note that this function does *not* advance p->ready_list_last_pick. Use \a + * advance_last_picked_locked() for that. */ +static ready_list *peek_next_connected_locked(const round_robin_lb_policy *p) { + ready_list *selected; + selected = p->ready_list_last_pick->next; + + while (selected != NULL) { + if (selected == &p->ready_list) { + GPR_ASSERT(selected->subchannel == NULL); + /* skip dummy root */ + selected = selected->next; + } else { + GPR_ASSERT(selected->subchannel != NULL); + return selected; + } + } + return NULL; +} + +/** Advance the \a ready_list picking head. */ +static void advance_last_picked_locked(round_robin_lb_policy *p) { + if (p->ready_list_last_pick->next != NULL) { /* non-empty list */ + p->ready_list_last_pick = p->ready_list_last_pick->next; + if (p->ready_list_last_pick == &p->ready_list) { + /* skip dummy root */ + p->ready_list_last_pick = p->ready_list_last_pick->next; + } + } else { /* should be an empty list */ + GPR_ASSERT(p->ready_list_last_pick == &p->ready_list); + } + + if (grpc_lb_round_robin_trace) { + gpr_log(GPR_DEBUG, "[READYLIST] ADVANCED LAST PICK. NOW AT NODE %p (SC %p)", + p->ready_list_last_pick, p->ready_list_last_pick->subchannel); + } +} + +/** Prepends (relative to the root at p->ready_list) the connected subchannel \a + * csc to the list of ready subchannels. */ +static ready_list *add_connected_sc_locked(round_robin_lb_policy *p, + grpc_subchannel *sc) { + ready_list *new_elem = gpr_malloc(sizeof(ready_list)); + new_elem->subchannel = sc; + if (p->ready_list.prev == NULL) { + /* first element */ + new_elem->next = &p->ready_list; + new_elem->prev = &p->ready_list; + p->ready_list.next = new_elem; + p->ready_list.prev = new_elem; + } else { + new_elem->next = &p->ready_list; + new_elem->prev = p->ready_list.prev; + p->ready_list.prev->next = new_elem; + p->ready_list.prev = new_elem; + } + if (grpc_lb_round_robin_trace) { + gpr_log(GPR_DEBUG, "[READYLIST] ADDING NODE %p (SC %p)", new_elem, sc); + } + return new_elem; +} + +/** Removes \a node from the list of connected subchannels */ +static void remove_disconnected_sc_locked(round_robin_lb_policy *p, + ready_list *node) { + if (node == NULL) { + return; + } + if (node == p->ready_list_last_pick) { + /* If removing the lastly picked node, reset the last pick pointer to the + * dummy root of the list */ + p->ready_list_last_pick = &p->ready_list; + } + + /* removing last item */ + if (node->next == &p->ready_list && node->prev == &p->ready_list) { + GPR_ASSERT(p->ready_list.next == node); + GPR_ASSERT(p->ready_list.prev == node); + p->ready_list.next = NULL; + p->ready_list.prev = NULL; + } else { + node->prev->next = node->next; + node->next->prev = node->prev; + } + + if (grpc_lb_round_robin_trace) { + gpr_log(GPR_DEBUG, "[READYLIST] REMOVED NODE %p (SC %p)", node, + node->subchannel); + } + + node->next = NULL; + node->prev = NULL; + node->subchannel = NULL; + + gpr_free(node); +} + +void rr_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { + round_robin_lb_policy *p = (round_robin_lb_policy *)pol; + size_t i; + ready_list *elem; + for (i = 0; i < p->num_subchannels; i++) { + subchannel_data *sd = p->subchannels[i]; + GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "round_robin"); + gpr_free(sd); + } + + grpc_connectivity_state_destroy(exec_ctx, &p->state_tracker); + gpr_free(p->subchannels); + gpr_mu_destroy(&p->mu); + + elem = p->ready_list.next; + while (elem != NULL && elem != &p->ready_list) { + ready_list *tmp; + tmp = elem->next; + elem->next = NULL; + elem->prev = NULL; + elem->subchannel = NULL; + gpr_free(elem); + elem = tmp; + } + gpr_free(p); +} + +void rr_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { + round_robin_lb_policy *p = (round_robin_lb_policy *)pol; + pending_pick *pp; + size_t i; + + gpr_mu_lock(&p->mu); + + p->shutdown = 1; + while ((pp = p->pending_picks)) { + p->pending_picks = pp->next; + *pp->target = NULL; + grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL); + gpr_free(pp); + } + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + GRPC_CHANNEL_FATAL_FAILURE, "shutdown"); + for (i = 0; i < p->num_subchannels; i++) { + subchannel_data *sd = p->subchannels[i]; + grpc_subchannel_notify_on_state_change(exec_ctx, sd->subchannel, NULL, NULL, + &sd->connectivity_changed_closure); + } + gpr_mu_unlock(&p->mu); +} + +static void rr_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, + grpc_connected_subchannel **target) { + round_robin_lb_policy *p = (round_robin_lb_policy *)pol; + pending_pick *pp; + gpr_mu_lock(&p->mu); + pp = p->pending_picks; + p->pending_picks = NULL; + while (pp != NULL) { + pending_pick *next = pp->next; + if (pp->target == target) { + grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties, + pp->pollset); + *target = NULL; + grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL); + gpr_free(pp); + } else { + pp->next = p->pending_picks; + p->pending_picks = pp; + } + pp = next; + } + gpr_mu_unlock(&p->mu); +} + +static void start_picking(grpc_exec_ctx *exec_ctx, round_robin_lb_policy *p) { + size_t i; + p->started_picking = 1; + + gpr_log(GPR_DEBUG, "LB_POLICY: p=%p num_subchannels=%d", p, + p->num_subchannels); + + for (i = 0; i < p->num_subchannels; i++) { + subchannel_data *sd = p->subchannels[i]; + sd->connectivity_state = GRPC_CHANNEL_IDLE; + grpc_subchannel_notify_on_state_change( + exec_ctx, sd->subchannel, p->base.interested_parties, + &sd->connectivity_state, &sd->connectivity_changed_closure); + GRPC_LB_POLICY_WEAK_REF(&p->base, "round_robin_connectivity"); + } +} + +void rr_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { + round_robin_lb_policy *p = (round_robin_lb_policy *)pol; + gpr_mu_lock(&p->mu); + if (!p->started_picking) { + start_picking(exec_ctx, p); + } + gpr_mu_unlock(&p->mu); +} + +int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, grpc_pollset *pollset, + grpc_metadata_batch *initial_metadata, + grpc_connected_subchannel **target, grpc_closure *on_complete) { + round_robin_lb_policy *p = (round_robin_lb_policy *)pol; + pending_pick *pp; + ready_list *selected; + gpr_mu_lock(&p->mu); + if ((selected = peek_next_connected_locked(p))) { + gpr_mu_unlock(&p->mu); + *target = grpc_subchannel_get_connected_subchannel(selected->subchannel); + if (grpc_lb_round_robin_trace) { + gpr_log(GPR_DEBUG, + "[RR PICK] TARGET <-- CONNECTED SUBCHANNEL %p (NODE %p)", + selected->subchannel, selected); + } + /* only advance the last picked pointer if the selection was used */ + advance_last_picked_locked(p); + return 1; + } else { + if (!p->started_picking) { + start_picking(exec_ctx, p); + } + grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset); + pp = gpr_malloc(sizeof(*pp)); + pp->next = p->pending_picks; + pp->pollset = pollset; + pp->target = target; + pp->on_complete = on_complete; + p->pending_picks = pp; + gpr_mu_unlock(&p->mu); + return 0; + } +} + +static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg, + bool iomgr_success) { + subchannel_data *sd = arg; + round_robin_lb_policy *p = sd->policy; + pending_pick *pp; + ready_list *selected; + + int unref = 0; + + gpr_mu_lock(&p->mu); + + if (p->shutdown) { + unref = 1; + } else { + switch (sd->connectivity_state) { + case GRPC_CHANNEL_READY: + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + GRPC_CHANNEL_READY, "connecting_ready"); + /* add the newly connected subchannel to the list of connected ones. + * Note that it goes to the "end of the line". */ + sd->ready_list_node = add_connected_sc_locked(p, sd->subchannel); + /* at this point we know there's at least one suitable subchannel. Go + * ahead and pick one and notify the pending suitors in + * p->pending_picks. This preemtively replicates rr_pick()'s actions. */ + selected = peek_next_connected_locked(p); + if (p->pending_picks != NULL) { + /* if the selected subchannel is going to be used for the pending + * picks, update the last picked pointer */ + advance_last_picked_locked(p); + } + while ((pp = p->pending_picks)) { + p->pending_picks = pp->next; + *pp->target = + grpc_subchannel_get_connected_subchannel(selected->subchannel); + if (grpc_lb_round_robin_trace) { + gpr_log(GPR_DEBUG, + "[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)", + selected->subchannel, selected); + } + grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties, + pp->pollset); + grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL); + gpr_free(pp); + } + grpc_subchannel_notify_on_state_change( + exec_ctx, sd->subchannel, p->base.interested_parties, + &sd->connectivity_state, &sd->connectivity_changed_closure); + break; + case GRPC_CHANNEL_CONNECTING: + case GRPC_CHANNEL_IDLE: + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + sd->connectivity_state, + "connecting_changed"); + grpc_subchannel_notify_on_state_change( + exec_ctx, sd->subchannel, p->base.interested_parties, + &sd->connectivity_state, &sd->connectivity_changed_closure); + break; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + /* renew state notification */ + grpc_subchannel_notify_on_state_change( + exec_ctx, sd->subchannel, p->base.interested_parties, + &sd->connectivity_state, &sd->connectivity_changed_closure); + + /* remove from ready list if still present */ + if (sd->ready_list_node != NULL) { + remove_disconnected_sc_locked(p, sd->ready_list_node); + sd->ready_list_node = NULL; + } + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + GRPC_CHANNEL_TRANSIENT_FAILURE, + "connecting_transient_failure"); + break; + case GRPC_CHANNEL_FATAL_FAILURE: + if (sd->ready_list_node != NULL) { + remove_disconnected_sc_locked(p, sd->ready_list_node); + sd->ready_list_node = NULL; + } + + p->num_subchannels--; + GPR_SWAP(subchannel_data *, p->subchannels[sd->index], + p->subchannels[p->num_subchannels]); + GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "round_robin"); + p->subchannels[sd->index]->index = sd->index; + gpr_free(sd); + + unref = 1; + if (p->num_subchannels == 0) { + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + GRPC_CHANNEL_FATAL_FAILURE, + "no_more_channels"); + while ((pp = p->pending_picks)) { + p->pending_picks = pp->next; + *pp->target = NULL; + grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL); + gpr_free(pp); + } + } else { + grpc_connectivity_state_set(exec_ctx, &p->state_tracker, + GRPC_CHANNEL_TRANSIENT_FAILURE, + "subchannel_failed"); + } + } /* switch */ + } /* !unref */ + + gpr_mu_unlock(&p->mu); + + if (unref) { + GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "round_robin_connectivity"); + } +} + +static grpc_connectivity_state rr_check_connectivity(grpc_exec_ctx *exec_ctx, + grpc_lb_policy *pol) { + round_robin_lb_policy *p = (round_robin_lb_policy *)pol; + grpc_connectivity_state st; + gpr_mu_lock(&p->mu); + st = grpc_connectivity_state_check(&p->state_tracker); + gpr_mu_unlock(&p->mu); + return st; +} + +static void rr_notify_on_state_change(grpc_exec_ctx *exec_ctx, + grpc_lb_policy *pol, + grpc_connectivity_state *current, + grpc_closure *notify) { + round_robin_lb_policy *p = (round_robin_lb_policy *)pol; + gpr_mu_lock(&p->mu); + grpc_connectivity_state_notify_on_state_change(exec_ctx, &p->state_tracker, + current, notify); + gpr_mu_unlock(&p->mu); +} + +static void rr_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, + grpc_closure *closure) { + round_robin_lb_policy *p = (round_robin_lb_policy *)pol; + ready_list *selected; + grpc_connected_subchannel *target; + gpr_mu_lock(&p->mu); + if ((selected = peek_next_connected_locked(p))) { + gpr_mu_unlock(&p->mu); + target = grpc_subchannel_get_connected_subchannel(selected->subchannel); + grpc_connected_subchannel_ping(exec_ctx, target, closure); + } else { + gpr_mu_unlock(&p->mu); + grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL); + } +} + +static const grpc_lb_policy_vtable round_robin_lb_policy_vtable = { + rr_destroy, + rr_shutdown, + rr_pick, + rr_cancel_pick, + rr_ping_one, + rr_exit_idle, + rr_check_connectivity, + rr_notify_on_state_change}; + +static void round_robin_factory_ref(grpc_lb_policy_factory *factory) {} + +static void round_robin_factory_unref(grpc_lb_policy_factory *factory) {} + +static grpc_lb_policy *create_round_robin(grpc_lb_policy_factory *factory, + grpc_lb_policy_args *args) { + size_t i; + round_robin_lb_policy *p = gpr_malloc(sizeof(*p)); + GPR_ASSERT(args->num_subchannels > 0); + memset(p, 0, sizeof(*p)); + grpc_lb_policy_init(&p->base, &round_robin_lb_policy_vtable); + p->num_subchannels = args->num_subchannels; + p->subchannels = gpr_malloc(sizeof(*p->subchannels) * p->num_subchannels); + memset(p->subchannels, 0, sizeof(*p->subchannels) * p->num_subchannels); + grpc_connectivity_state_init(&p->state_tracker, GRPC_CHANNEL_IDLE, + "round_robin"); + + gpr_mu_init(&p->mu); + for (i = 0; i < args->num_subchannels; i++) { + subchannel_data *sd = gpr_malloc(sizeof(*sd)); + memset(sd, 0, sizeof(*sd)); + p->subchannels[i] = sd; + sd->policy = p; + sd->index = i; + sd->subchannel = args->subchannels[i]; + grpc_closure_init(&sd->connectivity_changed_closure, + rr_connectivity_changed, sd); + } + + /* The (dummy node) root of the ready list */ + p->ready_list.subchannel = NULL; + p->ready_list.prev = NULL; + p->ready_list.next = NULL; + p->ready_list_last_pick = &p->ready_list; + + return &p->base; +} + +static const grpc_lb_policy_factory_vtable round_robin_factory_vtable = { + round_robin_factory_ref, round_robin_factory_unref, create_round_robin, + "round_robin"}; + +static grpc_lb_policy_factory round_robin_lb_policy_factory = { + &round_robin_factory_vtable}; + +grpc_lb_policy_factory *grpc_round_robin_lb_factory_create() { + return &round_robin_lb_policy_factory; +} diff --git a/src/core/lib/client_config/lb_policies/round_robin.h b/src/core/lib/client_config/lb_policies/round_robin.h new file mode 100644 index 0000000000..7e6f1769e4 --- /dev/null +++ b/src/core/lib/client_config/lb_policies/round_robin.h @@ -0,0 +1,46 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H +#define GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H + +#include "src/core/client_config/lb_policy.h" + +extern int grpc_lb_round_robin_trace; + +#include "src/core/client_config/lb_policy_factory.h" + +/** Returns a load balancing factory for the round robin policy */ +grpc_lb_policy_factory *grpc_round_robin_lb_factory_create(); + +#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H */ diff --git a/src/core/lib/client_config/lb_policy.c b/src/core/lib/client_config/lb_policy.c new file mode 100644 index 0000000000..0d8b007336 --- /dev/null +++ b/src/core/lib/client_config/lb_policy.c @@ -0,0 +1,134 @@ +/* + * + * Copyright 2015-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/client_config/lb_policy.h" + +#define WEAK_REF_BITS 16 + +void grpc_lb_policy_init(grpc_lb_policy *policy, + const grpc_lb_policy_vtable *vtable) { + policy->vtable = vtable; + gpr_atm_no_barrier_store(&policy->ref_pair, 1 << WEAK_REF_BITS); + policy->interested_parties = grpc_pollset_set_create(); +} + +#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG +#define REF_FUNC_EXTRA_ARGS , const char *file, int line, const char *reason +#define REF_MUTATE_EXTRA_ARGS REF_FUNC_EXTRA_ARGS, const char *purpose +#define REF_FUNC_PASS_ARGS(new_reason) , file, line, new_reason +#define REF_MUTATE_PASS_ARGS(purpose) , file, line, reason, purpose +#else +#define REF_FUNC_EXTRA_ARGS +#define REF_MUTATE_EXTRA_ARGS +#define REF_FUNC_PASS_ARGS(new_reason) +#define REF_MUTATE_PASS_ARGS(x) +#endif + +static gpr_atm ref_mutate(grpc_lb_policy *c, gpr_atm delta, + int barrier REF_MUTATE_EXTRA_ARGS) { + gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta) + : gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta); +#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "LB_POLICY: %p % 12s 0x%08x -> 0x%08x [%s]", c, purpose, old_val, + old_val + delta, reason); +#endif + return old_val; +} + +void grpc_lb_policy_ref(grpc_lb_policy *policy REF_FUNC_EXTRA_ARGS) { + ref_mutate(policy, 1 << WEAK_REF_BITS, 0 REF_MUTATE_PASS_ARGS("STRONG_REF")); +} + +void grpc_lb_policy_unref(grpc_exec_ctx *exec_ctx, + grpc_lb_policy *policy REF_FUNC_EXTRA_ARGS) { + gpr_atm old_val = + ref_mutate(policy, (gpr_atm)1 - (gpr_atm)(1 << WEAK_REF_BITS), + 1 REF_MUTATE_PASS_ARGS("STRONG_UNREF")); + gpr_atm mask = ~(gpr_atm)((1 << WEAK_REF_BITS) - 1); + gpr_atm check = 1 << WEAK_REF_BITS; + if ((old_val & mask) == check) { + policy->vtable->shutdown(exec_ctx, policy); + } + grpc_lb_policy_weak_unref(exec_ctx, + policy REF_FUNC_PASS_ARGS("strong-unref")); +} + +void grpc_lb_policy_weak_ref(grpc_lb_policy *policy REF_FUNC_EXTRA_ARGS) { + ref_mutate(policy, 1, 0 REF_MUTATE_PASS_ARGS("WEAK_REF")); +} + +void grpc_lb_policy_weak_unref(grpc_exec_ctx *exec_ctx, + grpc_lb_policy *policy REF_FUNC_EXTRA_ARGS) { + gpr_atm old_val = + ref_mutate(policy, -(gpr_atm)1, 1 REF_MUTATE_PASS_ARGS("WEAK_UNREF")); + if (old_val == 1) { + grpc_pollset_set_destroy(policy->interested_parties); + policy->vtable->destroy(exec_ctx, policy); + } +} + +int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + grpc_pollset *pollset, + grpc_metadata_batch *initial_metadata, + grpc_connected_subchannel **target, + grpc_closure *on_complete) { + return policy->vtable->pick(exec_ctx, policy, pollset, initial_metadata, + target, on_complete); +} + +void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + grpc_connected_subchannel **target) { + policy->vtable->cancel_pick(exec_ctx, policy, target); +} + +void grpc_lb_policy_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy) { + policy->vtable->exit_idle(exec_ctx, policy); +} + +void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + grpc_closure *closure) { + policy->vtable->ping_one(exec_ctx, policy, closure); +} + +void grpc_lb_policy_notify_on_state_change(grpc_exec_ctx *exec_ctx, + grpc_lb_policy *policy, + grpc_connectivity_state *state, + grpc_closure *closure) { + policy->vtable->notify_on_state_change(exec_ctx, policy, state, closure); +} + +grpc_connectivity_state grpc_lb_policy_check_connectivity( + grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy) { + return policy->vtable->check_connectivity(exec_ctx, policy); +} diff --git a/src/core/lib/client_config/lb_policy.h b/src/core/lib/client_config/lb_policy.h new file mode 100644 index 0000000000..ffebc2a69c --- /dev/null +++ b/src/core/lib/client_config/lb_policy.h @@ -0,0 +1,144 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_LB_POLICY_H +#define GRPC_CORE_CLIENT_CONFIG_LB_POLICY_H + +#include "src/core/client_config/subchannel.h" +#include "src/core/transport/connectivity_state.h" + +/** A load balancing policy: specified by a vtable and a struct (which + is expected to be extended to contain some parameters) */ +typedef struct grpc_lb_policy grpc_lb_policy; +typedef struct grpc_lb_policy_vtable grpc_lb_policy_vtable; + +typedef void (*grpc_lb_completion)(void *cb_arg, grpc_subchannel *subchannel, + grpc_status_code status, const char *errmsg); + +struct grpc_lb_policy { + const grpc_lb_policy_vtable *vtable; + gpr_atm ref_pair; + /* owned pointer to interested parties in load balancing decisions */ + grpc_pollset_set *interested_parties; +}; + +struct grpc_lb_policy_vtable { + void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); + + void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); + + /** implement grpc_lb_policy_pick */ + int (*pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + grpc_pollset *pollset, grpc_metadata_batch *initial_metadata, + grpc_connected_subchannel **target, grpc_closure *on_complete); + void (*cancel_pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + grpc_connected_subchannel **target); + + void (*ping_one)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + grpc_closure *closure); + + /** try to enter a READY connectivity state */ + void (*exit_idle)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); + + /** check the current connectivity of the lb_policy */ + grpc_connectivity_state (*check_connectivity)(grpc_exec_ctx *exec_ctx, + grpc_lb_policy *policy); + + /** call notify when the connectivity state of a channel changes from *state. + Updates *state with the new state of the policy */ + void (*notify_on_state_change)(grpc_exec_ctx *exec_ctx, + grpc_lb_policy *policy, + grpc_connectivity_state *state, + grpc_closure *closure); +}; + +/*#define GRPC_LB_POLICY_REFCOUNT_DEBUG*/ +#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG +#define GRPC_LB_POLICY_REF(p, r) \ + grpc_lb_policy_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_LB_POLICY_UNREF(exec_ctx, p, r) \ + grpc_lb_policy_unref((exec_ctx), (p), __FILE__, __LINE__, (r)) +#define GRPC_LB_POLICY_WEAK_REF(p, r) \ + grpc_lb_policy_weak_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, p, r) \ + grpc_lb_policy_weak_unref((exec_ctx), (p), __FILE__, __LINE__, (r)) +void grpc_lb_policy_ref(grpc_lb_policy *policy, const char *file, int line, + const char *reason); +void grpc_lb_policy_unref(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + const char *file, int line, const char *reason); +void grpc_lb_policy_weak_ref(grpc_lb_policy *policy, const char *file, int line, + const char *reason); +void grpc_lb_policy_weak_unref(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + const char *file, int line, const char *reason); +#else +#define GRPC_LB_POLICY_REF(p, r) grpc_lb_policy_ref((p)) +#define GRPC_LB_POLICY_UNREF(cl, p, r) grpc_lb_policy_unref((cl), (p)) +#define GRPC_LB_POLICY_WEAK_REF(p, r) grpc_lb_policy_weak_ref((p)) +#define GRPC_LB_POLICY_WEAK_UNREF(cl, p, r) grpc_lb_policy_weak_unref((cl), (p)) +void grpc_lb_policy_ref(grpc_lb_policy *policy); +void grpc_lb_policy_unref(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); +void grpc_lb_policy_weak_ref(grpc_lb_policy *policy); +void grpc_lb_policy_weak_unref(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); +#endif + +/** called by concrete implementations to initialize the base struct */ +void grpc_lb_policy_init(grpc_lb_policy *policy, + const grpc_lb_policy_vtable *vtable); + +/** Given initial metadata in \a initial_metadata, find an appropriate + target for this rpc, and 'return' it by calling \a on_complete after setting + \a target. + Picking can be asynchronous. Any IO should be done under \a pollset. */ +int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + grpc_pollset *pollset, + grpc_metadata_batch *initial_metadata, + grpc_connected_subchannel **target, + grpc_closure *on_complete); + +void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + grpc_closure *closure); + +void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + grpc_connected_subchannel **target); + +void grpc_lb_policy_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); + +void grpc_lb_policy_notify_on_state_change(grpc_exec_ctx *exec_ctx, + grpc_lb_policy *policy, + grpc_connectivity_state *state, + grpc_closure *closure); + +grpc_connectivity_state grpc_lb_policy_check_connectivity( + grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); + +#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICY_H */ diff --git a/src/core/lib/client_config/lb_policy_factory.c b/src/core/lib/client_config/lb_policy_factory.c new file mode 100644 index 0000000000..e49de544e3 --- /dev/null +++ b/src/core/lib/client_config/lb_policy_factory.c @@ -0,0 +1,48 @@ +/* + * + * Copyright 2015, 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/client_config/lb_policy_factory.h" + +void grpc_lb_policy_factory_ref(grpc_lb_policy_factory* factory) { + factory->vtable->ref(factory); +} + +void grpc_lb_policy_factory_unref(grpc_lb_policy_factory* factory) { + factory->vtable->unref(factory); +} + +grpc_lb_policy* grpc_lb_policy_factory_create_lb_policy( + grpc_lb_policy_factory* factory, grpc_lb_policy_args* args) { + if (factory == NULL) return NULL; + return factory->vtable->create_lb_policy(factory, args); +} diff --git a/src/core/lib/client_config/lb_policy_factory.h b/src/core/lib/client_config/lb_policy_factory.h new file mode 100644 index 0000000000..842ba96098 --- /dev/null +++ b/src/core/lib/client_config/lb_policy_factory.h @@ -0,0 +1,73 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_LB_POLICY_FACTORY_H +#define GRPC_CORE_CLIENT_CONFIG_LB_POLICY_FACTORY_H + +#include "src/core/client_config/lb_policy.h" +#include "src/core/client_config/subchannel.h" + +typedef struct grpc_lb_policy_factory grpc_lb_policy_factory; +typedef struct grpc_lb_policy_factory_vtable grpc_lb_policy_factory_vtable; + +/** grpc_lb_policy provides grpc_client_config objects to grpc_channel + objects */ +struct grpc_lb_policy_factory { + const grpc_lb_policy_factory_vtable *vtable; +}; + +typedef struct grpc_lb_policy_args { + grpc_subchannel **subchannels; + size_t num_subchannels; +} grpc_lb_policy_args; + +struct grpc_lb_policy_factory_vtable { + void (*ref)(grpc_lb_policy_factory *factory); + void (*unref)(grpc_lb_policy_factory *factory); + + /** Implementation of grpc_lb_policy_factory_create_lb_policy */ + grpc_lb_policy *(*create_lb_policy)(grpc_lb_policy_factory *factory, + grpc_lb_policy_args *args); + + /** Name for the LB policy this factory implements */ + const char *name; +}; + +void grpc_lb_policy_factory_ref(grpc_lb_policy_factory *factory); +void grpc_lb_policy_factory_unref(grpc_lb_policy_factory *factory); + +/** Create a lb_policy instance. */ +grpc_lb_policy *grpc_lb_policy_factory_create_lb_policy( + grpc_lb_policy_factory *factory, grpc_lb_policy_args *args); + +#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICY_FACTORY_H */ diff --git a/src/core/lib/client_config/lb_policy_registry.c b/src/core/lib/client_config/lb_policy_registry.c new file mode 100644 index 0000000000..fc302e82d7 --- /dev/null +++ b/src/core/lib/client_config/lb_policy_registry.c @@ -0,0 +1,88 @@ +/* + * + * Copyright 2015, 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/client_config/lb_policy_registry.h" + +#include + +#define MAX_POLICIES 10 + +static grpc_lb_policy_factory *g_all_of_the_lb_policies[MAX_POLICIES]; +static int g_number_of_lb_policies = 0; + +static grpc_lb_policy_factory *g_default_lb_policy_factory; + +void grpc_lb_policy_registry_init(grpc_lb_policy_factory *default_factory) { + g_number_of_lb_policies = 0; + g_default_lb_policy_factory = default_factory; +} + +void grpc_lb_policy_registry_shutdown(void) { + int i; + for (i = 0; i < g_number_of_lb_policies; i++) { + grpc_lb_policy_factory_unref(g_all_of_the_lb_policies[i]); + } +} + +void grpc_register_lb_policy(grpc_lb_policy_factory *factory) { + int i; + for (i = 0; i < g_number_of_lb_policies; i++) { + GPR_ASSERT(0 != strcmp(factory->vtable->name, + g_all_of_the_lb_policies[i]->vtable->name)); + } + GPR_ASSERT(g_number_of_lb_policies != MAX_POLICIES); + grpc_lb_policy_factory_ref(factory); + g_all_of_the_lb_policies[g_number_of_lb_policies++] = factory; +} + +static grpc_lb_policy_factory *lookup_factory(const char *name) { + int i; + + if (name == NULL) return NULL; + + for (i = 0; i < g_number_of_lb_policies; i++) { + if (0 == strcmp(name, g_all_of_the_lb_policies[i]->vtable->name)) { + return g_all_of_the_lb_policies[i]; + } + } + + return NULL; +} + +grpc_lb_policy *grpc_lb_policy_create(const char *name, + grpc_lb_policy_args *args) { + grpc_lb_policy_factory *factory = lookup_factory(name); + grpc_lb_policy *lb_policy = + grpc_lb_policy_factory_create_lb_policy(factory, args); + return lb_policy; +} diff --git a/src/core/lib/client_config/lb_policy_registry.h b/src/core/lib/client_config/lb_policy_registry.h new file mode 100644 index 0000000000..f3a08a3558 --- /dev/null +++ b/src/core/lib/client_config/lb_policy_registry.h @@ -0,0 +1,54 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_LB_POLICY_REGISTRY_H +#define GRPC_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H + +#include "src/core/client_config/lb_policy_factory.h" + +/** Initialize the registry and set \a default_factory as the factory to be + * returned when no name is provided in a lookup */ +void grpc_lb_policy_registry_init(grpc_lb_policy_factory *default_factory); +void grpc_lb_policy_registry_shutdown(void); + +/** Register a LB policy factory. */ +void grpc_register_lb_policy(grpc_lb_policy_factory *factory); + +/** Create a \a grpc_lb_policy instance. + * + * If \a name is NULL, the default factory from \a grpc_lb_policy_registry_init + * will be returned. */ +grpc_lb_policy *grpc_lb_policy_create(const char *name, + grpc_lb_policy_args *args); + +#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H */ diff --git a/src/core/lib/client_config/resolver.c b/src/core/lib/client_config/resolver.c new file mode 100644 index 0000000000..eda01e72ba --- /dev/null +++ b/src/core/lib/client_config/resolver.c @@ -0,0 +1,82 @@ +/* + * + * Copyright 2015, 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/client_config/resolver.h" + +void grpc_resolver_init(grpc_resolver *resolver, + const grpc_resolver_vtable *vtable) { + resolver->vtable = vtable; + gpr_ref_init(&resolver->refs, 1); +} + +#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG +void grpc_resolver_ref(grpc_resolver *resolver, grpc_closure_list *closure_list, + const char *file, int line, const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "RESOLVER:%p ref %d -> %d %s", + resolver, (int)resolver->refs.count, (int)resolver->refs.count + 1, + reason); +#else +void grpc_resolver_ref(grpc_resolver *resolver) { +#endif + gpr_ref(&resolver->refs); +} + +#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG +void grpc_resolver_unref(grpc_resolver *resolver, + grpc_closure_list *closure_list, const char *file, + int line, const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "RESOLVER:%p unref %d -> %d %s", + resolver, (int)resolver->refs.count, (int)resolver->refs.count - 1, + reason); +#else +void grpc_resolver_unref(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) { +#endif + if (gpr_unref(&resolver->refs)) { + resolver->vtable->destroy(exec_ctx, resolver); + } +} + +void grpc_resolver_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) { + resolver->vtable->shutdown(exec_ctx, resolver); +} + +void grpc_resolver_channel_saw_error(grpc_exec_ctx *exec_ctx, + grpc_resolver *resolver) { + resolver->vtable->channel_saw_error(exec_ctx, resolver); +} + +void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, + grpc_client_config **target_config, + grpc_closure *on_complete) { + resolver->vtable->next(exec_ctx, resolver, target_config, on_complete); +} diff --git a/src/core/lib/client_config/resolver.h b/src/core/lib/client_config/resolver.h new file mode 100644 index 0000000000..96f88fef84 --- /dev/null +++ b/src/core/lib/client_config/resolver.h @@ -0,0 +1,94 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_RESOLVER_H +#define GRPC_CORE_CLIENT_CONFIG_RESOLVER_H + +#include "src/core/client_config/client_config.h" +#include "src/core/client_config/subchannel.h" +#include "src/core/iomgr/iomgr.h" + +typedef struct grpc_resolver grpc_resolver; +typedef struct grpc_resolver_vtable grpc_resolver_vtable; + +/** grpc_resolver provides grpc_client_config objects to grpc_channel + objects */ +struct grpc_resolver { + const grpc_resolver_vtable *vtable; + gpr_refcount refs; +}; + +struct grpc_resolver_vtable { + void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver); + void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver); + void (*channel_saw_error)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver); + void (*next)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, + grpc_client_config **target_config, grpc_closure *on_complete); +}; + +#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG +#define GRPC_RESOLVER_REF(p, r) grpc_resolver_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_RESOLVER_UNREF(cl, p, r) \ + grpc_resolver_unref((cl), (p), __FILE__, __LINE__, (r)) +void grpc_resolver_ref(grpc_resolver *policy, const char *file, int line, + const char *reason); +void grpc_resolver_unref(grpc_resolver *policy, grpc_closure_list *closure_list, + const char *file, int line, const char *reason); +#else +#define GRPC_RESOLVER_REF(p, r) grpc_resolver_ref((p)) +#define GRPC_RESOLVER_UNREF(cl, p, r) grpc_resolver_unref((cl), (p)) +void grpc_resolver_ref(grpc_resolver *policy); +void grpc_resolver_unref(grpc_exec_ctx *exec_ctx, grpc_resolver *policy); +#endif + +void grpc_resolver_init(grpc_resolver *resolver, + const grpc_resolver_vtable *vtable); + +void grpc_resolver_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver); + +/** Notification that the channel has seen an error on some address. + Can be used as a hint that re-resolution is desirable soon. */ +void grpc_resolver_channel_saw_error(grpc_exec_ctx *exec_ctx, + grpc_resolver *resolver); + +/** Get the next client config. Called by the channel to fetch a new + configuration. Expected to set *target_config with a new configuration, + and then schedule on_complete for execution. + + If resolution is fatally broken, set *target_config to NULL and + schedule on_complete. */ +void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, + grpc_client_config **target_config, + grpc_closure *on_complete); + +#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVER_H */ diff --git a/src/core/lib/client_config/resolver_factory.c b/src/core/lib/client_config/resolver_factory.c new file mode 100644 index 0000000000..e7e9196ac4 --- /dev/null +++ b/src/core/lib/client_config/resolver_factory.c @@ -0,0 +1,55 @@ +/* + * + * Copyright 2015, 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/client_config/resolver_factory.h" + +void grpc_resolver_factory_ref(grpc_resolver_factory* factory) { + factory->vtable->ref(factory); +} + +void grpc_resolver_factory_unref(grpc_resolver_factory* factory) { + factory->vtable->unref(factory); +} + +/** Create a resolver instance for a name */ +grpc_resolver* grpc_resolver_factory_create_resolver( + grpc_resolver_factory* factory, grpc_resolver_args* args) { + if (factory == NULL) return NULL; + return factory->vtable->create_resolver(factory, args); +} + +char* grpc_resolver_factory_get_default_authority( + grpc_resolver_factory* factory, grpc_uri* uri) { + if (factory == NULL) return NULL; + return factory->vtable->get_default_authority(factory, uri); +} diff --git a/src/core/lib/client_config/resolver_factory.h b/src/core/lib/client_config/resolver_factory.h new file mode 100644 index 0000000000..477f8db7f7 --- /dev/null +++ b/src/core/lib/client_config/resolver_factory.h @@ -0,0 +1,82 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_RESOLVER_FACTORY_H +#define GRPC_CORE_CLIENT_CONFIG_RESOLVER_FACTORY_H + +#include "src/core/client_config/resolver.h" +#include "src/core/client_config/subchannel_factory.h" +#include "src/core/client_config/uri_parser.h" + +typedef struct grpc_resolver_factory grpc_resolver_factory; +typedef struct grpc_resolver_factory_vtable grpc_resolver_factory_vtable; + +/** grpc_resolver provides grpc_client_config objects to grpc_channel + objects */ +struct grpc_resolver_factory { + const grpc_resolver_factory_vtable *vtable; +}; + +typedef struct grpc_resolver_args { + grpc_uri *uri; + grpc_subchannel_factory *subchannel_factory; +} grpc_resolver_args; + +struct grpc_resolver_factory_vtable { + void (*ref)(grpc_resolver_factory *factory); + void (*unref)(grpc_resolver_factory *factory); + + /** Implementation of grpc_resolver_factory_create_resolver */ + grpc_resolver *(*create_resolver)(grpc_resolver_factory *factory, + grpc_resolver_args *args); + + /** Implementation of grpc_resolver_factory_get_default_authority */ + char *(*get_default_authority)(grpc_resolver_factory *factory, grpc_uri *uri); + + /** URI scheme that this factory implements */ + const char *scheme; +}; + +void grpc_resolver_factory_ref(grpc_resolver_factory *resolver); +void grpc_resolver_factory_unref(grpc_resolver_factory *resolver); + +/** Create a resolver instance for a name */ +grpc_resolver *grpc_resolver_factory_create_resolver( + grpc_resolver_factory *factory, grpc_resolver_args *args); + +/** Return a (freshly allocated with gpr_malloc) string representing + the default authority to use for this scheme. */ +char *grpc_resolver_factory_get_default_authority( + grpc_resolver_factory *factory, grpc_uri *uri); + +#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVER_FACTORY_H */ diff --git a/src/core/lib/client_config/resolver_registry.c b/src/core/lib/client_config/resolver_registry.c new file mode 100644 index 0000000000..89a945c2d3 --- /dev/null +++ b/src/core/lib/client_config/resolver_registry.c @@ -0,0 +1,137 @@ +/* + * + * Copyright 2015, 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/client_config/resolver_registry.h" + +#include + +#include +#include +#include + +#define MAX_RESOLVERS 10 + +static grpc_resolver_factory *g_all_of_the_resolvers[MAX_RESOLVERS]; +static int g_number_of_resolvers = 0; + +static char *g_default_resolver_prefix; + +void grpc_resolver_registry_init(const char *default_resolver_prefix) { + g_number_of_resolvers = 0; + g_default_resolver_prefix = gpr_strdup(default_resolver_prefix); +} + +void grpc_resolver_registry_shutdown(void) { + int i; + for (i = 0; i < g_number_of_resolvers; i++) { + grpc_resolver_factory_unref(g_all_of_the_resolvers[i]); + } + gpr_free(g_default_resolver_prefix); +} + +void grpc_register_resolver_type(grpc_resolver_factory *factory) { + int i; + for (i = 0; i < g_number_of_resolvers; i++) { + GPR_ASSERT(0 != strcmp(factory->vtable->scheme, + g_all_of_the_resolvers[i]->vtable->scheme)); + } + GPR_ASSERT(g_number_of_resolvers != MAX_RESOLVERS); + grpc_resolver_factory_ref(factory); + g_all_of_the_resolvers[g_number_of_resolvers++] = factory; +} + +static grpc_resolver_factory *lookup_factory(grpc_uri *uri) { + int i; + + /* handling NULL uri's here simplifies grpc_resolver_create */ + if (!uri) return NULL; + + for (i = 0; i < g_number_of_resolvers; i++) { + if (0 == strcmp(uri->scheme, g_all_of_the_resolvers[i]->vtable->scheme)) { + return g_all_of_the_resolvers[i]; + } + } + + return NULL; +} + +static grpc_resolver_factory *resolve_factory(const char *target, + grpc_uri **uri) { + char *tmp; + grpc_resolver_factory *factory = NULL; + + GPR_ASSERT(uri != NULL); + *uri = grpc_uri_parse(target, 1); + factory = lookup_factory(*uri); + if (factory == NULL) { + if (g_default_resolver_prefix != NULL) { + grpc_uri_destroy(*uri); + gpr_asprintf(&tmp, "%s%s", g_default_resolver_prefix, target); + *uri = grpc_uri_parse(tmp, 1); + factory = lookup_factory(*uri); + if (factory == NULL) { + grpc_uri_destroy(grpc_uri_parse(target, 0)); + grpc_uri_destroy(grpc_uri_parse(tmp, 0)); + gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target, + tmp); + } + gpr_free(tmp); + } else { + grpc_uri_destroy(grpc_uri_parse(target, 0)); + gpr_log(GPR_ERROR, "don't know how to resolve '%s'", target); + } + } + return factory; +} + +grpc_resolver *grpc_resolver_create( + const char *target, grpc_subchannel_factory *subchannel_factory) { + grpc_uri *uri = NULL; + grpc_resolver_factory *factory = resolve_factory(target, &uri); + grpc_resolver *resolver; + grpc_resolver_args args; + memset(&args, 0, sizeof(args)); + args.uri = uri; + args.subchannel_factory = subchannel_factory; + resolver = grpc_resolver_factory_create_resolver(factory, &args); + grpc_uri_destroy(uri); + return resolver; +} + +char *grpc_get_default_authority(const char *target) { + grpc_uri *uri = NULL; + grpc_resolver_factory *factory = resolve_factory(target, &uri); + char *authority = grpc_resolver_factory_get_default_authority(factory, uri); + grpc_uri_destroy(uri); + return authority; +} diff --git a/src/core/lib/client_config/resolver_registry.h b/src/core/lib/client_config/resolver_registry.h new file mode 100644 index 0000000000..1e4cebee0b --- /dev/null +++ b/src/core/lib/client_config/resolver_registry.h @@ -0,0 +1,65 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_RESOLVER_REGISTRY_H +#define GRPC_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H + +#include "src/core/client_config/resolver_factory.h" + +void grpc_resolver_registry_init(const char *default_prefix); +void grpc_resolver_registry_shutdown(void); + +/** Register a resolver type. + URI's of \a scheme will be resolved with the given resolver. + If \a priority is greater than zero, then the resolver will be eligible + to resolve names that are passed in with no scheme. Higher priority + resolvers will be tried before lower priority schemes. */ +void grpc_register_resolver_type(grpc_resolver_factory *factory); + +/** Create a resolver given \a target. + First tries to parse \a target as a URI. If this succeeds, tries + to locate a registered resolver factory based on the URI scheme. + If parsing or location fails, prefixes default_prefix from + grpc_resolver_registry_init to target, and tries again (if default_prefix + was not NULL). + If a resolver factory was found, use it to instantiate a resolver and + return it. + If a resolver factory was not found, return NULL. */ +grpc_resolver *grpc_resolver_create( + const char *target, grpc_subchannel_factory *subchannel_factory); + +/** 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); + +#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H */ diff --git a/src/core/lib/client_config/resolvers/dns_resolver.c b/src/core/lib/client_config/resolvers/dns_resolver.c new file mode 100644 index 0000000000..2b2ee97e12 --- /dev/null +++ b/src/core/lib/client_config/resolvers/dns_resolver.c @@ -0,0 +1,309 @@ +/* + * + * Copyright 2015-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/client_config/resolvers/dns_resolver.h" + +#include + +#include +#include +#include + +#include "src/core/client_config/lb_policy_registry.h" +#include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/timer.h" +#include "src/core/support/backoff.h" +#include "src/core/support/string.h" + +#define BACKOFF_MULTIPLIER 1.6 +#define BACKOFF_JITTER 0.2 +#define BACKOFF_MIN_SECONDS 1 +#define BACKOFF_MAX_SECONDS 120 + +typedef struct { + /** base class: must be first */ + grpc_resolver base; + /** refcount */ + gpr_refcount refs; + /** name to resolve */ + char *name; + /** default port to use */ + char *default_port; + /** subchannel factory */ + grpc_subchannel_factory *subchannel_factory; + /** load balancing policy name */ + char *lb_policy_name; + + /** mutex guarding the rest of the state */ + gpr_mu mu; + /** are we currently resolving? */ + int resolving; + /** which version of resolved_config have we published? */ + int published_version; + /** which version of resolved_config is current? */ + int resolved_version; + /** pending next completion, or NULL */ + grpc_closure *next_completion; + /** target config address for next completion */ + grpc_client_config **target_config; + /** current (fully resolved) config */ + grpc_client_config *resolved_config; + /** retry timer */ + bool have_retry_timer; + grpc_timer retry_timer; + /** retry backoff state */ + gpr_backoff backoff_state; +} dns_resolver; + +static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r); + +static void dns_start_resolving_locked(dns_resolver *r); +static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, + dns_resolver *r); + +static void dns_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r); +static void dns_channel_saw_error(grpc_exec_ctx *exec_ctx, grpc_resolver *r); +static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r, + grpc_client_config **target_config, + grpc_closure *on_complete); + +static const grpc_resolver_vtable dns_resolver_vtable = { + dns_destroy, dns_shutdown, dns_channel_saw_error, dns_next}; + +static void dns_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) { + dns_resolver *r = (dns_resolver *)resolver; + gpr_mu_lock(&r->mu); + if (r->have_retry_timer) { + grpc_timer_cancel(exec_ctx, &r->retry_timer); + } + if (r->next_completion != NULL) { + *r->target_config = NULL; + grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL); + r->next_completion = NULL; + } + gpr_mu_unlock(&r->mu); +} + +static void dns_channel_saw_error(grpc_exec_ctx *exec_ctx, + grpc_resolver *resolver) { + dns_resolver *r = (dns_resolver *)resolver; + gpr_mu_lock(&r->mu); + if (!r->resolving) { + gpr_backoff_reset(&r->backoff_state); + dns_start_resolving_locked(r); + } + gpr_mu_unlock(&r->mu); +} + +static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, + grpc_client_config **target_config, + grpc_closure *on_complete) { + dns_resolver *r = (dns_resolver *)resolver; + gpr_mu_lock(&r->mu); + GPR_ASSERT(!r->next_completion); + r->next_completion = on_complete; + r->target_config = target_config; + if (r->resolved_version == 0 && !r->resolving) { + gpr_backoff_reset(&r->backoff_state); + dns_start_resolving_locked(r); + } else { + dns_maybe_finish_next_locked(exec_ctx, r); + } + gpr_mu_unlock(&r->mu); +} + +static void dns_on_retry_timer(grpc_exec_ctx *exec_ctx, void *arg, + bool success) { + dns_resolver *r = arg; + + gpr_mu_lock(&r->mu); + r->have_retry_timer = false; + if (success) { + if (!r->resolving) { + dns_start_resolving_locked(r); + } + } + gpr_mu_unlock(&r->mu); + + GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "retry-timer"); +} + +static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg, + grpc_resolved_addresses *addresses) { + dns_resolver *r = arg; + grpc_client_config *config = NULL; + grpc_subchannel **subchannels; + grpc_subchannel_args args; + grpc_lb_policy *lb_policy; + size_t i; + gpr_mu_lock(&r->mu); + GPR_ASSERT(r->resolving); + r->resolving = 0; + if (addresses != NULL) { + grpc_lb_policy_args lb_policy_args; + config = grpc_client_config_create(); + subchannels = gpr_malloc(sizeof(grpc_subchannel *) * addresses->naddrs); + size_t naddrs = 0; + for (i = 0; i < addresses->naddrs; i++) { + memset(&args, 0, sizeof(args)); + args.addr = (struct sockaddr *)(addresses->addrs[i].addr); + args.addr_len = (size_t)addresses->addrs[i].len; + grpc_subchannel *subchannel = grpc_subchannel_factory_create_subchannel( + exec_ctx, r->subchannel_factory, &args); + if (subchannel != NULL) { + subchannels[naddrs++] = subchannel; + } + } + memset(&lb_policy_args, 0, sizeof(lb_policy_args)); + lb_policy_args.subchannels = subchannels; + lb_policy_args.num_subchannels = naddrs; + lb_policy = grpc_lb_policy_create(r->lb_policy_name, &lb_policy_args); + if (lb_policy != NULL) { + grpc_client_config_set_lb_policy(config, lb_policy); + GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "construction"); + } + grpc_resolved_addresses_destroy(addresses); + gpr_free(subchannels); + } else { + gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); + gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now); + gpr_timespec timeout = gpr_time_sub(next_try, now); + gpr_log(GPR_DEBUG, "dns resolution failed: retrying in %d.%09d seconds", + timeout.tv_sec, timeout.tv_nsec); + GPR_ASSERT(!r->have_retry_timer); + r->have_retry_timer = true; + GRPC_RESOLVER_REF(&r->base, "retry-timer"); + grpc_timer_init(exec_ctx, &r->retry_timer, next_try, dns_on_retry_timer, r, + now); + } + if (r->resolved_config) { + grpc_client_config_unref(exec_ctx, r->resolved_config); + } + r->resolved_config = config; + r->resolved_version++; + dns_maybe_finish_next_locked(exec_ctx, r); + gpr_mu_unlock(&r->mu); + + GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "dns-resolving"); +} + +static void dns_start_resolving_locked(dns_resolver *r) { + GRPC_RESOLVER_REF(&r->base, "dns-resolving"); + GPR_ASSERT(!r->resolving); + r->resolving = 1; + grpc_resolve_address(r->name, r->default_port, dns_on_resolved, r); +} + +static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, + dns_resolver *r) { + if (r->next_completion != NULL && + r->resolved_version != r->published_version) { + *r->target_config = r->resolved_config; + if (r->resolved_config) { + grpc_client_config_ref(r->resolved_config); + } + grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL); + r->next_completion = NULL; + r->published_version = r->resolved_version; + } +} + +static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) { + dns_resolver *r = (dns_resolver *)gr; + gpr_mu_destroy(&r->mu); + if (r->resolved_config) { + grpc_client_config_unref(exec_ctx, r->resolved_config); + } + grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory); + gpr_free(r->name); + gpr_free(r->default_port); + gpr_free(r->lb_policy_name); + gpr_free(r); +} + +static grpc_resolver *dns_create(grpc_resolver_args *args, + const char *default_port, + const char *lb_policy_name) { + dns_resolver *r; + const char *path = args->uri->path; + + if (0 != strcmp(args->uri->authority, "")) { + gpr_log(GPR_ERROR, "authority based dns uri's not supported"); + return NULL; + } + + if (path[0] == '/') ++path; + + r = gpr_malloc(sizeof(dns_resolver)); + memset(r, 0, sizeof(*r)); + gpr_ref_init(&r->refs, 1); + gpr_mu_init(&r->mu); + grpc_resolver_init(&r->base, &dns_resolver_vtable); + r->name = gpr_strdup(path); + r->default_port = gpr_strdup(default_port); + r->subchannel_factory = args->subchannel_factory; + gpr_backoff_init(&r->backoff_state, BACKOFF_MULTIPLIER, BACKOFF_JITTER, + BACKOFF_MIN_SECONDS * 1000, BACKOFF_MAX_SECONDS * 1000); + grpc_subchannel_factory_ref(r->subchannel_factory); + r->lb_policy_name = gpr_strdup(lb_policy_name); + return &r->base; +} + +/* + * FACTORY + */ + +static void dns_factory_ref(grpc_resolver_factory *factory) {} + +static void dns_factory_unref(grpc_resolver_factory *factory) {} + +static grpc_resolver *dns_factory_create_resolver( + grpc_resolver_factory *factory, grpc_resolver_args *args) { + return dns_create(args, "https", "pick_first"); +} + +char *dns_factory_get_default_host_name(grpc_resolver_factory *factory, + grpc_uri *uri) { + const char *path = uri->path; + if (path[0] == '/') ++path; + return gpr_strdup(path); +} + +static const grpc_resolver_factory_vtable dns_factory_vtable = { + dns_factory_ref, dns_factory_unref, dns_factory_create_resolver, + dns_factory_get_default_host_name, "dns"}; +static grpc_resolver_factory dns_resolver_factory = {&dns_factory_vtable}; + +grpc_resolver_factory *grpc_dns_resolver_factory_create() { + return &dns_resolver_factory; +} diff --git a/src/core/lib/client_config/resolvers/dns_resolver.h b/src/core/lib/client_config/resolvers/dns_resolver.h new file mode 100644 index 0000000000..b24280b507 --- /dev/null +++ b/src/core/lib/client_config/resolvers/dns_resolver.h @@ -0,0 +1,42 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H +#define GRPC_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H + +#include "src/core/client_config/resolver_factory.h" + +/** Create a dns resolver factory */ +grpc_resolver_factory *grpc_dns_resolver_factory_create(void); + +#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H */ diff --git a/src/core/lib/client_config/resolvers/sockaddr_resolver.c b/src/core/lib/client_config/resolvers/sockaddr_resolver.c new file mode 100644 index 0000000000..3cb7d79b67 --- /dev/null +++ b/src/core/lib/client_config/resolvers/sockaddr_resolver.c @@ -0,0 +1,372 @@ +/* + * + * Copyright 2015-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 + +#include "src/core/client_config/resolvers/sockaddr_resolver.h" + +#include +#include + +#include +#include +#include + +#include "src/core/client_config/lb_policy_registry.h" +#include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/unix_sockets_posix.h" +#include "src/core/support/string.h" + +typedef struct { + /** base class: must be first */ + grpc_resolver base; + /** refcount */ + gpr_refcount refs; + /** subchannel factory */ + grpc_subchannel_factory *subchannel_factory; + /** load balancing policy name */ + char *lb_policy_name; + + /** the addresses that we've 'resolved' */ + struct sockaddr_storage *addrs; + /** the corresponding length of the addresses */ + size_t *addrs_len; + /** how many elements in \a addrs */ + size_t num_addrs; + + /** mutex guarding the rest of the state */ + gpr_mu mu; + /** have we published? */ + int published; + /** pending next completion, or NULL */ + grpc_closure *next_completion; + /** target config address for next completion */ + grpc_client_config **target_config; +} sockaddr_resolver; + +static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r); + +static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, + sockaddr_resolver *r); + +static void sockaddr_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r); +static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx, + grpc_resolver *r); +static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r, + grpc_client_config **target_config, + grpc_closure *on_complete); + +static const grpc_resolver_vtable sockaddr_resolver_vtable = { + sockaddr_destroy, sockaddr_shutdown, sockaddr_channel_saw_error, + sockaddr_next}; + +static void sockaddr_shutdown(grpc_exec_ctx *exec_ctx, + grpc_resolver *resolver) { + sockaddr_resolver *r = (sockaddr_resolver *)resolver; + gpr_mu_lock(&r->mu); + if (r->next_completion != NULL) { + *r->target_config = NULL; + grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL); + r->next_completion = NULL; + } + gpr_mu_unlock(&r->mu); +} + +static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx, + grpc_resolver *resolver) { + sockaddr_resolver *r = (sockaddr_resolver *)resolver; + gpr_mu_lock(&r->mu); + r->published = 0; + sockaddr_maybe_finish_next_locked(exec_ctx, r); + gpr_mu_unlock(&r->mu); +} + +static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, + grpc_client_config **target_config, + grpc_closure *on_complete) { + sockaddr_resolver *r = (sockaddr_resolver *)resolver; + gpr_mu_lock(&r->mu); + GPR_ASSERT(!r->next_completion); + r->next_completion = on_complete; + r->target_config = target_config; + sockaddr_maybe_finish_next_locked(exec_ctx, r); + gpr_mu_unlock(&r->mu); +} + +static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, + sockaddr_resolver *r) { + grpc_client_config *cfg; + grpc_lb_policy *lb_policy; + grpc_lb_policy_args lb_policy_args; + grpc_subchannel **subchannels; + grpc_subchannel_args args; + + if (r->next_completion != NULL && !r->published) { + size_t i; + cfg = grpc_client_config_create(); + subchannels = gpr_malloc(sizeof(grpc_subchannel *) * r->num_addrs); + for (i = 0; i < r->num_addrs; i++) { + memset(&args, 0, sizeof(args)); + args.addr = (struct sockaddr *)&r->addrs[i]; + args.addr_len = r->addrs_len[i]; + subchannels[i] = grpc_subchannel_factory_create_subchannel( + exec_ctx, r->subchannel_factory, &args); + } + memset(&lb_policy_args, 0, sizeof(lb_policy_args)); + lb_policy_args.subchannels = subchannels; + lb_policy_args.num_subchannels = r->num_addrs; + lb_policy = grpc_lb_policy_create(r->lb_policy_name, &lb_policy_args); + gpr_free(subchannels); + grpc_client_config_set_lb_policy(cfg, lb_policy); + GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "sockaddr"); + r->published = 1; + *r->target_config = cfg; + grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL); + r->next_completion = NULL; + } +} + +static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) { + sockaddr_resolver *r = (sockaddr_resolver *)gr; + gpr_mu_destroy(&r->mu); + grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory); + gpr_free(r->addrs); + gpr_free(r->addrs_len); + gpr_free(r->lb_policy_name); + gpr_free(r); +} + +static char *ip_get_default_authority(grpc_uri *uri) { + const char *path = uri->path; + if (path[0] == '/') ++path; + return gpr_strdup(path); +} + +static char *ipv4_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) { + return ip_get_default_authority(uri); +} + +static char *ipv6_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) { + return ip_get_default_authority(uri); +} + +static int parse_ipv4(grpc_uri *uri, struct sockaddr_storage *addr, + size_t *len) { + const char *host_port = uri->path; + char *host; + char *port; + int port_num; + int result = 0; + struct sockaddr_in *in = (struct sockaddr_in *)addr; + + if (*host_port == '/') ++host_port; + if (!gpr_split_host_port(host_port, &host, &port)) { + return 0; + } + + memset(in, 0, sizeof(*in)); + *len = sizeof(*in); + in->sin_family = AF_INET; + if (inet_pton(AF_INET, host, &in->sin_addr) == 0) { + gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host); + goto done; + } + + if (port != NULL) { + if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || + port_num > 65535) { + gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port); + goto done; + } + in->sin_port = htons((uint16_t)port_num); + } else { + gpr_log(GPR_ERROR, "no port given for ipv4 scheme"); + goto done; + } + + result = 1; +done: + gpr_free(host); + gpr_free(port); + return result; +} + +static int parse_ipv6(grpc_uri *uri, struct sockaddr_storage *addr, + size_t *len) { + const char *host_port = uri->path; + char *host; + char *port; + int port_num; + int result = 0; + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr; + + if (*host_port == '/') ++host_port; + if (!gpr_split_host_port(host_port, &host, &port)) { + return 0; + } + + memset(in6, 0, sizeof(*in6)); + *len = sizeof(*in6); + in6->sin6_family = AF_INET6; + if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) { + gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host); + goto done; + } + + if (port != NULL) { + if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || + port_num > 65535) { + gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port); + goto done; + } + in6->sin6_port = htons((uint16_t)port_num); + } else { + gpr_log(GPR_ERROR, "no port given for ipv6 scheme"); + goto done; + } + + result = 1; +done: + gpr_free(host); + gpr_free(port); + return result; +} + +static void do_nothing(void *ignored) {} + +static grpc_resolver *sockaddr_create( + grpc_resolver_args *args, const char *default_lb_policy_name, + int parse(grpc_uri *uri, struct sockaddr_storage *dst, size_t *len)) { + size_t i; + int errors_found = 0; /* GPR_FALSE */ + sockaddr_resolver *r; + gpr_slice path_slice; + gpr_slice_buffer path_parts; + + if (0 != strcmp(args->uri->authority, "")) { + gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme", + args->uri->scheme); + return NULL; + } + + r = gpr_malloc(sizeof(sockaddr_resolver)); + memset(r, 0, sizeof(*r)); + + r->lb_policy_name = NULL; + if (0 != strcmp(args->uri->query, "")) { + gpr_slice query_slice; + gpr_slice_buffer query_parts; + + query_slice = + gpr_slice_new(args->uri->query, strlen(args->uri->query), do_nothing); + gpr_slice_buffer_init(&query_parts); + gpr_slice_split(query_slice, "=", &query_parts); + GPR_ASSERT(query_parts.count == 2); + if (0 == gpr_slice_str_cmp(query_parts.slices[0], "lb_policy")) { + r->lb_policy_name = gpr_dump_slice(query_parts.slices[1], GPR_DUMP_ASCII); + } + gpr_slice_buffer_destroy(&query_parts); + gpr_slice_unref(query_slice); + } + if (r->lb_policy_name == NULL) { + r->lb_policy_name = gpr_strdup(default_lb_policy_name); + } + + path_slice = + gpr_slice_new(args->uri->path, strlen(args->uri->path), do_nothing); + gpr_slice_buffer_init(&path_parts); + + gpr_slice_split(path_slice, ",", &path_parts); + r->num_addrs = path_parts.count; + r->addrs = gpr_malloc(sizeof(struct sockaddr_storage) * r->num_addrs); + r->addrs_len = gpr_malloc(sizeof(*r->addrs_len) * r->num_addrs); + + for (i = 0; i < r->num_addrs; i++) { + grpc_uri ith_uri = *args->uri; + char *part_str = gpr_dump_slice(path_parts.slices[i], GPR_DUMP_ASCII); + ith_uri.path = part_str; + if (!parse(&ith_uri, &r->addrs[i], &r->addrs_len[i])) { + errors_found = 1; /* GPR_TRUE */ + } + gpr_free(part_str); + if (errors_found) break; + } + + gpr_slice_buffer_destroy(&path_parts); + gpr_slice_unref(path_slice); + if (errors_found) { + gpr_free(r->lb_policy_name); + gpr_free(r->addrs); + gpr_free(r->addrs_len); + gpr_free(r); + return NULL; + } + + gpr_ref_init(&r->refs, 1); + gpr_mu_init(&r->mu); + grpc_resolver_init(&r->base, &sockaddr_resolver_vtable); + r->subchannel_factory = args->subchannel_factory; + grpc_subchannel_factory_ref(r->subchannel_factory); + + return &r->base; +} + +/* + * FACTORY + */ + +static void sockaddr_factory_ref(grpc_resolver_factory *factory) {} + +static void sockaddr_factory_unref(grpc_resolver_factory *factory) {} + +#define DECL_FACTORY(name, prefix) \ + static grpc_resolver *name##_factory_create_resolver( \ + grpc_resolver_factory *factory, grpc_resolver_args *args) { \ + return sockaddr_create(args, "pick_first", prefix##parse_##name); \ + } \ + static const grpc_resolver_factory_vtable name##_factory_vtable = { \ + sockaddr_factory_ref, sockaddr_factory_unref, \ + name##_factory_create_resolver, prefix##name##_get_default_authority, \ + #name}; \ + static grpc_resolver_factory name##_resolver_factory = { \ + &name##_factory_vtable}; \ + grpc_resolver_factory *grpc_##name##_resolver_factory_create() { \ + return &name##_resolver_factory; \ + } + +#ifdef GPR_HAVE_UNIX_SOCKET +DECL_FACTORY(unix, grpc_) +#endif +DECL_FACTORY(ipv4, ) DECL_FACTORY(ipv6, ) diff --git a/src/core/lib/client_config/resolvers/sockaddr_resolver.h b/src/core/lib/client_config/resolvers/sockaddr_resolver.h new file mode 100644 index 0000000000..f050329431 --- /dev/null +++ b/src/core/lib/client_config/resolvers/sockaddr_resolver.h @@ -0,0 +1,50 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H +#define GRPC_CORE_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H + +#include + +#include "src/core/client_config/resolver_factory.h" + +grpc_resolver_factory *grpc_ipv4_resolver_factory_create(void); + +grpc_resolver_factory *grpc_ipv6_resolver_factory_create(void); + +#ifdef GPR_POSIX_SOCKET +/** Create a unix resolver factory */ +grpc_resolver_factory *grpc_unix_resolver_factory_create(void); +#endif + +#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H */ diff --git a/src/core/lib/client_config/resolvers/zookeeper_resolver.c b/src/core/lib/client_config/resolvers/zookeeper_resolver.c new file mode 100644 index 0000000000..e0e18792a2 --- /dev/null +++ b/src/core/lib/client_config/resolvers/zookeeper_resolver.c @@ -0,0 +1,520 @@ +/* + * + * Copyright 2015-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/client_config/resolvers/zookeeper_resolver.h" + +#include + +#include +#include + +#include +#include + +#include "src/core/client_config/lb_policy_registry.h" +#include "src/core/client_config/resolver_registry.h" +#include "src/core/iomgr/resolve_address.h" +#include "src/core/json/json.h" +#include "src/core/support/string.h" +#include "src/core/surface/api_trace.h" + +/** Zookeeper session expiration time in milliseconds */ +#define GRPC_ZOOKEEPER_SESSION_TIMEOUT 15000 + +typedef struct { + /** base class: must be first */ + grpc_resolver base; + /** refcount */ + gpr_refcount refs; + /** name to resolve */ + char *name; + /** subchannel factory */ + grpc_subchannel_factory *subchannel_factory; + /** load balancing policy name */ + char *lb_policy_name; + + /** mutex guarding the rest of the state */ + gpr_mu mu; + /** are we currently resolving? */ + int resolving; + /** which version of resolved_config have we published? */ + int published_version; + /** which version of resolved_config is current? */ + int resolved_version; + /** pending next completion, or NULL */ + grpc_closure *next_completion; + /** target config address for next completion */ + grpc_client_config **target_config; + /** current (fully resolved) config */ + grpc_client_config *resolved_config; + + /** zookeeper handle */ + zhandle_t *zookeeper_handle; + /** zookeeper resolved addresses */ + grpc_resolved_addresses *resolved_addrs; + /** total number of addresses to be resolved */ + int resolved_total; + /** number of addresses resolved */ + int resolved_num; +} zookeeper_resolver; + +static void zookeeper_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r); + +static void zookeeper_start_resolving_locked(zookeeper_resolver *r); +static void zookeeper_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, + zookeeper_resolver *r); + +static void zookeeper_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r); +static void zookeeper_channel_saw_error(grpc_exec_ctx *exec_ctx, + grpc_resolver *r); +static void zookeeper_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r, + grpc_client_config **target_config, + grpc_closure *on_complete); + +static const grpc_resolver_vtable zookeeper_resolver_vtable = { + zookeeper_destroy, zookeeper_shutdown, zookeeper_channel_saw_error, + zookeeper_next}; + +static void zookeeper_shutdown(grpc_exec_ctx *exec_ctx, + grpc_resolver *resolver) { + zookeeper_resolver *r = (zookeeper_resolver *)resolver; + grpc_closure *call = NULL; + gpr_mu_lock(&r->mu); + if (r->next_completion != NULL) { + *r->target_config = NULL; + call = r->next_completion; + r->next_completion = NULL; + } + zookeeper_close(r->zookeeper_handle); + gpr_mu_unlock(&r->mu); + if (call != NULL) { + call->cb(exec_ctx, call->cb_arg, 1); + } +} + +static void zookeeper_channel_saw_error(grpc_exec_ctx *exec_ctx, + grpc_resolver *resolver) { + zookeeper_resolver *r = (zookeeper_resolver *)resolver; + gpr_mu_lock(&r->mu); + if (r->resolving == 0) { + zookeeper_start_resolving_locked(r); + } + gpr_mu_unlock(&r->mu); +} + +static void zookeeper_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, + grpc_client_config **target_config, + grpc_closure *on_complete) { + zookeeper_resolver *r = (zookeeper_resolver *)resolver; + gpr_mu_lock(&r->mu); + GPR_ASSERT(r->next_completion == NULL); + r->next_completion = on_complete; + r->target_config = target_config; + if (r->resolved_version == 0 && r->resolving == 0) { + zookeeper_start_resolving_locked(r); + } else { + zookeeper_maybe_finish_next_locked(exec_ctx, r); + } + gpr_mu_unlock(&r->mu); +} + +/** Zookeeper global watcher for connection management + TODO: better connection management besides logs */ +static void zookeeper_global_watcher(zhandle_t *zookeeper_handle, int type, + int state, const char *path, + void *watcher_ctx) { + if (type == ZOO_SESSION_EVENT) { + if (state == ZOO_EXPIRED_SESSION_STATE) { + gpr_log(GPR_ERROR, "Zookeeper session expired"); + } else if (state == ZOO_AUTH_FAILED_STATE) { + gpr_log(GPR_ERROR, "Zookeeper authentication failed"); + } + } +} + +/** Zookeeper watcher triggered by changes to watched nodes + Once triggered, it tries to resolve again to get updated addresses */ +static void zookeeper_watcher(zhandle_t *zookeeper_handle, int type, int state, + const char *path, void *watcher_ctx) { + if (watcher_ctx != NULL) { + zookeeper_resolver *r = (zookeeper_resolver *)watcher_ctx; + if (state == ZOO_CONNECTED_STATE) { + gpr_mu_lock(&r->mu); + if (r->resolving == 0) { + zookeeper_start_resolving_locked(r); + } + gpr_mu_unlock(&r->mu); + } + } +} + +/** Callback function after getting all resolved addresses + Creates a subchannel for each address */ +static void zookeeper_on_resolved(grpc_exec_ctx *exec_ctx, void *arg, + grpc_resolved_addresses *addresses) { + zookeeper_resolver *r = arg; + grpc_client_config *config = NULL; + grpc_subchannel **subchannels; + grpc_subchannel_args args; + grpc_lb_policy *lb_policy; + size_t i; + if (addresses != NULL) { + grpc_lb_policy_args lb_policy_args; + config = grpc_client_config_create(); + subchannels = gpr_malloc(sizeof(grpc_subchannel *) * addresses->naddrs); + for (i = 0; i < addresses->naddrs; i++) { + memset(&args, 0, sizeof(args)); + args.addr = (struct sockaddr *)(addresses->addrs[i].addr); + args.addr_len = addresses->addrs[i].len; + subchannels[i] = grpc_subchannel_factory_create_subchannel( + exec_ctx, r->subchannel_factory, &args); + } + lb_policy_args.subchannels = subchannels; + lb_policy_args.num_subchannels = addresses->naddrs; + lb_policy = grpc_lb_policy_create(r->lb_policy_name, &lb_policy_args); + grpc_client_config_set_lb_policy(config, lb_policy); + GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "construction"); + grpc_resolved_addresses_destroy(addresses); + gpr_free(subchannels); + } + gpr_mu_lock(&r->mu); + GPR_ASSERT(r->resolving == 1); + r->resolving = 0; + if (r->resolved_config != NULL) { + grpc_client_config_unref(exec_ctx, r->resolved_config); + } + r->resolved_config = config; + r->resolved_version++; + zookeeper_maybe_finish_next_locked(exec_ctx, r); + gpr_mu_unlock(&r->mu); + + GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "zookeeper-resolving"); +} + +/** Callback function for each DNS resolved address */ +static void zookeeper_dns_resolved(grpc_exec_ctx *exec_ctx, void *arg, + grpc_resolved_addresses *addresses) { + size_t i; + zookeeper_resolver *r = arg; + int resolve_done = 0; + + gpr_mu_lock(&r->mu); + r->resolved_num++; + r->resolved_addrs->addrs = + gpr_realloc(r->resolved_addrs->addrs, + sizeof(grpc_resolved_address) * + (r->resolved_addrs->naddrs + addresses->naddrs)); + for (i = 0; i < addresses->naddrs; i++) { + memcpy(r->resolved_addrs->addrs[i + r->resolved_addrs->naddrs].addr, + addresses->addrs[i].addr, addresses->addrs[i].len); + r->resolved_addrs->addrs[i + r->resolved_addrs->naddrs].len = + addresses->addrs[i].len; + } + + r->resolved_addrs->naddrs += addresses->naddrs; + grpc_resolved_addresses_destroy(addresses); + + /** Wait for all addresses to be resolved */ + resolve_done = (r->resolved_num == r->resolved_total); + gpr_mu_unlock(&r->mu); + if (resolve_done) { + zookeeper_on_resolved(exec_ctx, r, r->resolved_addrs); + } +} + +/** Parses JSON format address of a zookeeper node */ +static char *zookeeper_parse_address(const char *value, size_t value_len) { + grpc_json *json; + grpc_json *cur; + const char *host; + const char *port; + char *buffer; + char *address = NULL; + + buffer = gpr_malloc(value_len); + memcpy(buffer, value, value_len); + json = grpc_json_parse_string_with_len(buffer, value_len); + if (json != NULL) { + host = NULL; + port = NULL; + for (cur = json->child; cur != NULL; cur = cur->next) { + if (!strcmp(cur->key, "host")) { + host = cur->value; + if (port != NULL) { + break; + } + } else if (!strcmp(cur->key, "port")) { + port = cur->value; + if (host != NULL) { + break; + } + } + } + if (host != NULL && port != NULL) { + gpr_asprintf(&address, "%s:%s", host, port); + } + grpc_json_destroy(json); + } + gpr_free(buffer); + + return address; +} + +static void zookeeper_get_children_node_completion(int rc, const char *value, + int value_len, + const struct Stat *stat, + const void *arg) { + char *address = NULL; + zookeeper_resolver *r = (zookeeper_resolver *)arg; + int resolve_done = 0; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + if (rc != 0) { + gpr_log(GPR_ERROR, "Error in getting a child node of %s", r->name); + grpc_exec_ctx_finish(&exec_ctx); + return; + } + + address = zookeeper_parse_address(value, (size_t)value_len); + if (address != NULL) { + /** Further resolves address by DNS */ + grpc_resolve_address(address, NULL, zookeeper_dns_resolved, r); + gpr_free(address); + } else { + gpr_log(GPR_ERROR, "Error in resolving a child node of %s", r->name); + gpr_mu_lock(&r->mu); + r->resolved_total--; + resolve_done = (r->resolved_num == r->resolved_total); + gpr_mu_unlock(&r->mu); + if (resolve_done) { + zookeeper_on_resolved(&exec_ctx, r, r->resolved_addrs); + } + } + + grpc_exec_ctx_finish(&exec_ctx); +} + +static void zookeeper_get_children_completion( + int rc, const struct String_vector *children, const void *arg) { + char *path; + int status; + int i; + zookeeper_resolver *r = (zookeeper_resolver *)arg; + + if (rc != 0) { + gpr_log(GPR_ERROR, "Error in getting zookeeper children of %s", r->name); + return; + } + + if (children->count == 0) { + gpr_log(GPR_ERROR, "Error in resolving zookeeper address %s", r->name); + return; + } + + r->resolved_addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); + r->resolved_addrs->addrs = NULL; + r->resolved_addrs->naddrs = 0; + r->resolved_total = children->count; + + /** TODO: Replace expensive heap allocation with stack + if we can get maximum length of zookeeper path */ + for (i = 0; i < children->count; i++) { + gpr_asprintf(&path, "%s/%s", r->name, children->data[i]); + status = zoo_awget(r->zookeeper_handle, path, zookeeper_watcher, r, + zookeeper_get_children_node_completion, r); + gpr_free(path); + if (status != 0) { + gpr_log(GPR_ERROR, "Error in getting zookeeper node %s", path); + } + } +} + +static void zookeeper_get_node_completion(int rc, const char *value, + int value_len, + const struct Stat *stat, + const void *arg) { + int status; + char *address = NULL; + zookeeper_resolver *r = (zookeeper_resolver *)arg; + r->resolved_addrs = NULL; + r->resolved_total = 0; + r->resolved_num = 0; + + if (rc != 0) { + gpr_log(GPR_ERROR, "Error in getting zookeeper node %s", r->name); + return; + } + + /** If zookeeper node of path r->name does not have address + (i.e. service node), get its children */ + address = zookeeper_parse_address(value, (size_t)value_len); + if (address != NULL) { + r->resolved_addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); + r->resolved_addrs->addrs = NULL; + r->resolved_addrs->naddrs = 0; + r->resolved_total = 1; + /** Further resolves address by DNS */ + grpc_resolve_address(address, NULL, zookeeper_dns_resolved, r); + gpr_free(address); + return; + } + + status = zoo_awget_children(r->zookeeper_handle, r->name, zookeeper_watcher, + r, zookeeper_get_children_completion, r); + if (status != 0) { + gpr_log(GPR_ERROR, "Error in getting zookeeper children of %s", r->name); + } +} + +static void zookeeper_resolve_address(zookeeper_resolver *r) { + int status; + status = zoo_awget(r->zookeeper_handle, r->name, zookeeper_watcher, r, + zookeeper_get_node_completion, r); + if (status != 0) { + gpr_log(GPR_ERROR, "Error in getting zookeeper node %s", r->name); + } +} + +static void zookeeper_start_resolving_locked(zookeeper_resolver *r) { + GRPC_RESOLVER_REF(&r->base, "zookeeper-resolving"); + GPR_ASSERT(r->resolving == 0); + r->resolving = 1; + zookeeper_resolve_address(r); +} + +static void zookeeper_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, + zookeeper_resolver *r) { + if (r->next_completion != NULL && + r->resolved_version != r->published_version) { + *r->target_config = r->resolved_config; + if (r->resolved_config != NULL) { + grpc_client_config_ref(r->resolved_config); + } + grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL); + r->next_completion = NULL; + r->published_version = r->resolved_version; + } +} + +static void zookeeper_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) { + zookeeper_resolver *r = (zookeeper_resolver *)gr; + gpr_mu_destroy(&r->mu); + if (r->resolved_config != NULL) { + grpc_client_config_unref(exec_ctx, r->resolved_config); + } + grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory); + gpr_free(r->name); + gpr_free(r->lb_policy_name); + gpr_free(r); +} + +static grpc_resolver *zookeeper_create(grpc_resolver_args *args, + const char *lb_policy_name) { + zookeeper_resolver *r; + size_t length; + char *path = args->uri->path; + + if (0 == strcmp(args->uri->authority, "")) { + gpr_log(GPR_ERROR, "No authority specified in zookeeper uri"); + return NULL; + } + + /** Removes the trailing slash if exists */ + length = strlen(path); + if (length > 1 && path[length - 1] == '/') { + path[length - 1] = 0; + } + + r = gpr_malloc(sizeof(zookeeper_resolver)); + memset(r, 0, sizeof(*r)); + gpr_ref_init(&r->refs, 1); + gpr_mu_init(&r->mu); + grpc_resolver_init(&r->base, &zookeeper_resolver_vtable); + r->name = gpr_strdup(path); + + r->subchannel_factory = args->subchannel_factory; + grpc_subchannel_factory_ref(r->subchannel_factory); + + r->lb_policy_name = gpr_strdup(lb_policy_name); + + /** Initializes zookeeper client */ + zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); + r->zookeeper_handle = + zookeeper_init(args->uri->authority, zookeeper_global_watcher, + GRPC_ZOOKEEPER_SESSION_TIMEOUT, 0, 0, 0); + if (r->zookeeper_handle == NULL) { + gpr_log(GPR_ERROR, "Unable to connect to zookeeper server"); + return NULL; + } + + return &r->base; +} + +static void zookeeper_plugin_init() { + grpc_register_resolver_type(grpc_zookeeper_resolver_factory_create()); +} + +void grpc_zookeeper_register() { + GRPC_API_TRACE("grpc_zookeeper_register(void)", 0, ()); + grpc_register_plugin(zookeeper_plugin_init, NULL); +} + +/* + * FACTORY + */ + +static void zookeeper_factory_ref(grpc_resolver_factory *factory) {} + +static void zookeeper_factory_unref(grpc_resolver_factory *factory) {} + +static char *zookeeper_factory_get_default_hostname( + grpc_resolver_factory *factory, grpc_uri *uri) { + return NULL; +} + +static grpc_resolver *zookeeper_factory_create_resolver( + grpc_resolver_factory *factory, grpc_resolver_args *args) { + return zookeeper_create(args, "pick_first"); +} + +static const grpc_resolver_factory_vtable zookeeper_factory_vtable = { + zookeeper_factory_ref, zookeeper_factory_unref, + zookeeper_factory_create_resolver, zookeeper_factory_get_default_hostname, + "zookeeper"}; + +static grpc_resolver_factory zookeeper_resolver_factory = { + &zookeeper_factory_vtable}; + +grpc_resolver_factory *grpc_zookeeper_resolver_factory_create() { + return &zookeeper_resolver_factory; +} diff --git a/src/core/lib/client_config/resolvers/zookeeper_resolver.h b/src/core/lib/client_config/resolvers/zookeeper_resolver.h new file mode 100644 index 0000000000..04bd3ca875 --- /dev/null +++ b/src/core/lib/client_config/resolvers/zookeeper_resolver.h @@ -0,0 +1,42 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H +#define GRPC_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H + +#include "src/core/client_config/resolver_factory.h" + +/** Create a zookeeper resolver factory */ +grpc_resolver_factory *grpc_zookeeper_resolver_factory_create(void); + +#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H */ diff --git a/src/core/lib/client_config/subchannel.c b/src/core/lib/client_config/subchannel.c new file mode 100644 index 0000000000..c5cd504929 --- /dev/null +++ b/src/core/lib/client_config/subchannel.c @@ -0,0 +1,678 @@ +/* + * + * Copyright 2015-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/client_config/subchannel.h" + +#include + +#include +#include + +#include "src/core/channel/channel_args.h" +#include "src/core/channel/client_channel.h" +#include "src/core/channel/connected_channel.h" +#include "src/core/client_config/initial_connect_string.h" +#include "src/core/client_config/subchannel_index.h" +#include "src/core/iomgr/timer.h" +#include "src/core/profiling/timers.h" +#include "src/core/support/backoff.h" +#include "src/core/surface/channel.h" +#include "src/core/surface/channel_init.h" +#include "src/core/transport/connectivity_state.h" + +#define INTERNAL_REF_BITS 16 +#define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1)) + +#define GRPC_SUBCHANNEL_MIN_CONNECT_TIMEOUT_SECONDS 20 +#define GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS 1 +#define GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER 1.6 +#define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120 +#define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2 + +#define GET_CONNECTED_SUBCHANNEL(subchannel, barrier) \ + ((grpc_connected_subchannel *)(gpr_atm_##barrier##_load( \ + &(subchannel)->connected_subchannel))) + +typedef struct { + grpc_closure closure; + grpc_subchannel *subchannel; + grpc_connectivity_state connectivity_state; +} state_watcher; + +typedef struct external_state_watcher { + grpc_subchannel *subchannel; + grpc_pollset_set *pollset_set; + grpc_closure *notify; + grpc_closure closure; + struct external_state_watcher *next; + struct external_state_watcher *prev; +} external_state_watcher; + +struct grpc_subchannel { + grpc_connector *connector; + + /** refcount + - lower INTERNAL_REF_BITS bits are for internal references: + these do not keep the subchannel open. + - upper remaining bits are for public references: these do + keep the subchannel open */ + gpr_atm ref_pair; + + /** non-transport related channel filters */ + const grpc_channel_filter **filters; + size_t num_filters; + /** channel arguments */ + grpc_channel_args *args; + /** address to connect to */ + struct sockaddr *addr; + size_t addr_len; + + grpc_subchannel_key *key; + + /** initial string to send to peer */ + gpr_slice initial_connect_string; + + /** set during connection */ + grpc_connect_out_args connecting_result; + + /** callback for connection finishing */ + grpc_closure connected; + + /** pollset_set tracking who's interested in a connection + being setup */ + grpc_pollset_set *pollset_set; + + /** active connection, or null; of type grpc_connected_subchannel */ + gpr_atm connected_subchannel; + + /** mutex protecting remaining elements */ + gpr_mu mu; + + /** have we seen a disconnection? */ + int disconnected; + /** are we connecting */ + int connecting; + /** connectivity state tracking */ + grpc_connectivity_state_tracker state_tracker; + + external_state_watcher root_external_state_watcher; + + /** next connect attempt time */ + gpr_timespec next_attempt; + /** backoff state */ + gpr_backoff backoff_state; + /** do we have an active alarm? */ + int have_alarm; + /** our alarm */ + grpc_timer alarm; + /** current random value */ + uint32_t random; +}; + +struct grpc_subchannel_call { + grpc_connected_subchannel *connection; +}; + +#define SUBCHANNEL_CALL_TO_CALL_STACK(call) ((grpc_call_stack *)((call) + 1)) +#define CHANNEL_STACK_FROM_CONNECTION(con) ((grpc_channel_stack *)(con)) +#define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \ + (((grpc_subchannel_call *)(callstack)) - 1) + +static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *subchannel, + bool iomgr_success); + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +#define REF_REASON reason +#define REF_LOG(name, p) \ + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%s: %p ref %d -> %d %s", \ + (name), (p), (p)->refs.count, (p)->refs.count + 1, reason) +#define UNREF_LOG(name, p) \ + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%s: %p unref %d -> %d %s", \ + (name), (p), (p)->refs.count, (p)->refs.count - 1, reason) +#define REF_MUTATE_EXTRA_ARGS \ + GRPC_SUBCHANNEL_REF_EXTRA_ARGS, const char *purpose +#define REF_MUTATE_PURPOSE(x) , file, line, reason, x +#else +#define REF_REASON "" +#define REF_LOG(name, p) \ + do { \ + } while (0) +#define UNREF_LOG(name, p) \ + do { \ + } while (0) +#define REF_MUTATE_EXTRA_ARGS +#define REF_MUTATE_PURPOSE(x) +#endif + +/* + * connection implementation + */ + +static void connection_destroy(grpc_exec_ctx *exec_ctx, void *arg, + bool success) { + grpc_connected_subchannel *c = arg; + grpc_channel_stack_destroy(exec_ctx, CHANNEL_STACK_FROM_CONNECTION(c)); + gpr_free(c); +} + +void grpc_connected_subchannel_ref( + grpc_connected_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + GRPC_CHANNEL_STACK_REF(CHANNEL_STACK_FROM_CONNECTION(c), REF_REASON); +} + +void grpc_connected_subchannel_unref(grpc_exec_ctx *exec_ctx, + grpc_connected_subchannel *c + GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + GRPC_CHANNEL_STACK_UNREF(exec_ctx, CHANNEL_STACK_FROM_CONNECTION(c), + REF_REASON); +} + +/* + * grpc_subchannel implementation + */ + +static void subchannel_destroy(grpc_exec_ctx *exec_ctx, void *arg, + bool success) { + grpc_subchannel *c = arg; + gpr_free((void *)c->filters); + grpc_channel_args_destroy(c->args); + gpr_free(c->addr); + gpr_slice_unref(c->initial_connect_string); + grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker); + grpc_connector_unref(exec_ctx, c->connector); + grpc_pollset_set_destroy(c->pollset_set); + grpc_subchannel_key_destroy(exec_ctx, c->key); + gpr_free(c); +} + +static gpr_atm ref_mutate(grpc_subchannel *c, gpr_atm delta, + int barrier REF_MUTATE_EXTRA_ARGS) { + gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta) + : gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta); +#ifdef GRPC_STREAM_REFCOUNT_DEBUG + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "SUBCHANNEL: %p % 12s 0x%08x -> 0x%08x [%s]", c, purpose, old_val, + old_val + delta, reason); +#endif + return old_val; +} + +grpc_subchannel *grpc_subchannel_ref( + grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = ref_mutate(c, (1 << INTERNAL_REF_BITS), + 0 REF_MUTATE_PURPOSE("STRONG_REF")); + GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0); + return c; +} + +grpc_subchannel *grpc_subchannel_weak_ref( + grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = ref_mutate(c, 1, 0 REF_MUTATE_PURPOSE("WEAK_REF")); + GPR_ASSERT(old_refs != 0); + return c; +} + +grpc_subchannel *grpc_subchannel_ref_from_weak_ref( + grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + if (!c) return NULL; + for (;;) { + gpr_atm old_refs = gpr_atm_acq_load(&c->ref_pair); + if (old_refs >= (1 << INTERNAL_REF_BITS)) { + gpr_atm new_refs = old_refs + (1 << INTERNAL_REF_BITS); + if (gpr_atm_rel_cas(&c->ref_pair, old_refs, new_refs)) { + return c; + } + } else { + return NULL; + } + } +} + +static void disconnect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) { + grpc_connected_subchannel *con; + grpc_subchannel_index_unregister(exec_ctx, c->key, c); + gpr_mu_lock(&c->mu); + GPR_ASSERT(!c->disconnected); + c->disconnected = 1; + grpc_connector_shutdown(exec_ctx, c->connector); + con = GET_CONNECTED_SUBCHANNEL(c, no_barrier); + if (con != NULL) { + GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, con, "connection"); + gpr_atm_no_barrier_store(&c->connected_subchannel, 0xdeadbeef); + } + gpr_mu_unlock(&c->mu); +} + +void grpc_subchannel_unref(grpc_exec_ctx *exec_ctx, + grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = ref_mutate(c, (gpr_atm)1 - (gpr_atm)(1 << INTERNAL_REF_BITS), + 1 REF_MUTATE_PURPOSE("STRONG_UNREF")); + if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) { + disconnect(exec_ctx, c); + } + GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "strong-unref"); +} + +void grpc_subchannel_weak_unref(grpc_exec_ctx *exec_ctx, + grpc_subchannel *c + GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = ref_mutate(c, -(gpr_atm)1, 1 REF_MUTATE_PURPOSE("WEAK_UNREF")); + if (old_refs == 1) { + grpc_exec_ctx_enqueue(exec_ctx, grpc_closure_create(subchannel_destroy, c), + true, NULL); + } +} + +static uint32_t random_seed() { + return (uint32_t)(gpr_time_to_millis(gpr_now(GPR_CLOCK_MONOTONIC))); +} + +grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx, + grpc_connector *connector, + grpc_subchannel_args *args) { + grpc_subchannel_key *key = grpc_subchannel_key_create(connector, args); + grpc_subchannel *c = grpc_subchannel_index_find(exec_ctx, key); + if (c) { + grpc_subchannel_key_destroy(exec_ctx, key); + return c; + } + + c = gpr_malloc(sizeof(*c)); + memset(c, 0, sizeof(*c)); + c->key = key; + gpr_atm_no_barrier_store(&c->ref_pair, 1 << INTERNAL_REF_BITS); + c->connector = connector; + grpc_connector_ref(c->connector); + c->num_filters = args->filter_count; + if (c->num_filters > 0) { + c->filters = gpr_malloc(sizeof(grpc_channel_filter *) * c->num_filters); + memcpy((void *)c->filters, args->filters, + sizeof(grpc_channel_filter *) * c->num_filters); + } else { + c->filters = NULL; + } + c->addr = gpr_malloc(args->addr_len); + memcpy(c->addr, args->addr, args->addr_len); + c->pollset_set = grpc_pollset_set_create(); + c->addr_len = args->addr_len; + grpc_set_initial_connect_string(&c->addr, &c->addr_len, + &c->initial_connect_string); + c->args = grpc_channel_args_copy(args->args); + c->random = random_seed(); + c->root_external_state_watcher.next = c->root_external_state_watcher.prev = + &c->root_external_state_watcher; + grpc_closure_init(&c->connected, subchannel_connected, c); + grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE, + "subchannel"); + gpr_backoff_init(&c->backoff_state, + GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER, + GRPC_SUBCHANNEL_RECONNECT_JITTER, + GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000, + GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS * 1000); + if (c->args) { + for (size_t i = 0; i < c->args->num_args; i++) { + if (0 == strcmp(c->args->args[i].key, + "grpc.testing.fixed_reconnect_backoff")) { + GPR_ASSERT(c->args->args[i].type == GRPC_ARG_INTEGER); + gpr_backoff_init(&c->backoff_state, 1.0, 0.0, + c->args->args[i].value.integer, + c->args->args[i].value.integer); + } + } + } + gpr_mu_init(&c->mu); + + return grpc_subchannel_index_register(exec_ctx, key, c); +} + +static void continue_connect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) { + grpc_connect_in_args args; + + args.interested_parties = c->pollset_set; + args.addr = c->addr; + args.addr_len = c->addr_len; + args.deadline = c->next_attempt; + args.channel_args = c->args; + args.initial_connect_string = c->initial_connect_string; + + grpc_connectivity_state_set(exec_ctx, &c->state_tracker, + GRPC_CHANNEL_CONNECTING, "state_change"); + grpc_connector_connect(exec_ctx, c->connector, &args, &c->connecting_result, + &c->connected); +} + +static void start_connect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) { + c->next_attempt = + gpr_backoff_begin(&c->backoff_state, gpr_now(GPR_CLOCK_MONOTONIC)); + continue_connect(exec_ctx, c); +} + +grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel *c) { + grpc_connectivity_state state; + gpr_mu_lock(&c->mu); + state = grpc_connectivity_state_check(&c->state_tracker); + gpr_mu_unlock(&c->mu); + return state; +} + +static void on_external_state_watcher_done(grpc_exec_ctx *exec_ctx, void *arg, + bool success) { + external_state_watcher *w = arg; + grpc_closure *follow_up = w->notify; + if (w->pollset_set != NULL) { + grpc_pollset_set_del_pollset_set(exec_ctx, w->subchannel->pollset_set, + w->pollset_set); + } + gpr_mu_lock(&w->subchannel->mu); + w->next->prev = w->prev; + w->prev->next = w->next; + gpr_mu_unlock(&w->subchannel->mu); + GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, w->subchannel, "external_state_watcher"); + gpr_free(w); + follow_up->cb(exec_ctx, follow_up->cb_arg, success); +} + +void grpc_subchannel_notify_on_state_change( + grpc_exec_ctx *exec_ctx, grpc_subchannel *c, + grpc_pollset_set *interested_parties, grpc_connectivity_state *state, + grpc_closure *notify) { + external_state_watcher *w; + + if (state == NULL) { + gpr_mu_lock(&c->mu); + for (w = c->root_external_state_watcher.next; + w != &c->root_external_state_watcher; w = w->next) { + if (w->notify == notify) { + grpc_connectivity_state_notify_on_state_change( + exec_ctx, &c->state_tracker, NULL, &w->closure); + } + } + gpr_mu_unlock(&c->mu); + } else { + w = gpr_malloc(sizeof(*w)); + w->subchannel = c; + w->pollset_set = interested_parties; + w->notify = notify; + grpc_closure_init(&w->closure, on_external_state_watcher_done, w); + if (interested_parties != NULL) { + grpc_pollset_set_add_pollset_set(exec_ctx, c->pollset_set, + interested_parties); + } + GRPC_SUBCHANNEL_WEAK_REF(c, "external_state_watcher"); + gpr_mu_lock(&c->mu); + w->next = &c->root_external_state_watcher; + w->prev = w->next->prev; + w->next->prev = w->prev->next = w; + if (grpc_connectivity_state_notify_on_state_change( + exec_ctx, &c->state_tracker, state, &w->closure)) { + c->connecting = 1; + /* released by connection */ + GRPC_SUBCHANNEL_WEAK_REF(c, "connecting"); + start_connect(exec_ctx, c); + } + gpr_mu_unlock(&c->mu); + } +} + +void grpc_connected_subchannel_process_transport_op( + grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con, + grpc_transport_op *op) { + grpc_channel_stack *channel_stack = CHANNEL_STACK_FROM_CONNECTION(con); + grpc_channel_element *top_elem = grpc_channel_stack_element(channel_stack, 0); + top_elem->filter->start_transport_op(exec_ctx, top_elem, op); +} + +static void subchannel_on_child_state_changed(grpc_exec_ctx *exec_ctx, void *p, + bool iomgr_success) { + state_watcher *sw = p; + grpc_subchannel *c = sw->subchannel; + gpr_mu *mu = &c->mu; + + gpr_mu_lock(mu); + + /* if we failed just leave this closure */ + if (iomgr_success) { + if (sw->connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { + /* any errors on a subchannel ==> we're done, create a new one */ + sw->connectivity_state = GRPC_CHANNEL_FATAL_FAILURE; + } + grpc_connectivity_state_set(exec_ctx, &c->state_tracker, + sw->connectivity_state, "reflect_child"); + if (sw->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) { + grpc_connected_subchannel_notify_on_state_change( + exec_ctx, GET_CONNECTED_SUBCHANNEL(c, no_barrier), NULL, + &sw->connectivity_state, &sw->closure); + GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher"); + sw = NULL; + } + } + + gpr_mu_unlock(mu); + GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "state_watcher"); + gpr_free(sw); +} + +static void connected_subchannel_state_op(grpc_exec_ctx *exec_ctx, + grpc_connected_subchannel *con, + grpc_pollset_set *interested_parties, + grpc_connectivity_state *state, + grpc_closure *closure) { + grpc_transport_op op; + grpc_channel_element *elem; + memset(&op, 0, sizeof(op)); + op.connectivity_state = state; + op.on_connectivity_state_change = closure; + op.bind_pollset_set = interested_parties; + elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(con), 0); + elem->filter->start_transport_op(exec_ctx, elem, &op); +} + +void grpc_connected_subchannel_notify_on_state_change( + grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con, + grpc_pollset_set *interested_parties, grpc_connectivity_state *state, + grpc_closure *closure) { + connected_subchannel_state_op(exec_ctx, con, interested_parties, state, + closure); +} + +void grpc_connected_subchannel_ping(grpc_exec_ctx *exec_ctx, + grpc_connected_subchannel *con, + grpc_closure *closure) { + grpc_transport_op op; + grpc_channel_element *elem; + memset(&op, 0, sizeof(op)); + op.send_ping = closure; + elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(con), 0); + elem->filter->start_transport_op(exec_ctx, elem, &op); +} + +static void publish_transport_locked(grpc_exec_ctx *exec_ctx, + grpc_subchannel *c) { + grpc_connected_subchannel *con; + grpc_channel_stack *stk; + state_watcher *sw_subchannel; + + /* construct channel stack */ + con = grpc_channel_init_create_stack( + exec_ctx, GRPC_CLIENT_SUBCHANNEL, 0, c->connecting_result.channel_args, 1, + connection_destroy, NULL, c->connecting_result.transport); + stk = CHANNEL_STACK_FROM_CONNECTION(con); + memset(&c->connecting_result, 0, sizeof(c->connecting_result)); + + /* initialize state watcher */ + sw_subchannel = gpr_malloc(sizeof(*sw_subchannel)); + sw_subchannel->subchannel = c; + sw_subchannel->connectivity_state = GRPC_CHANNEL_READY; + grpc_closure_init(&sw_subchannel->closure, subchannel_on_child_state_changed, + sw_subchannel); + + if (c->disconnected) { + gpr_free(sw_subchannel); + grpc_channel_stack_destroy(exec_ctx, stk); + gpr_free(con); + GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting"); + return; + } + + /* publish */ + /* TODO(ctiller): this full barrier seems to clear up a TSAN failure. + I'd have expected the rel_cas below to be enough, but + seemingly it's not. + Re-evaluate if we really need this. */ + gpr_atm_full_barrier(); + GPR_ASSERT(gpr_atm_rel_cas(&c->connected_subchannel, 0, (gpr_atm)con)); + c->connecting = 0; + + /* setup subchannel watching connected subchannel for changes; subchannel ref + for connecting is donated + to the state watcher */ + GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher"); + GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting"); + grpc_connected_subchannel_notify_on_state_change( + exec_ctx, con, c->pollset_set, &sw_subchannel->connectivity_state, + &sw_subchannel->closure); + + /* signal completion */ + grpc_connectivity_state_set(exec_ctx, &c->state_tracker, GRPC_CHANNEL_READY, + "connected"); +} + +static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, bool iomgr_success) { + grpc_subchannel *c = arg; + gpr_mu_lock(&c->mu); + c->have_alarm = 0; + if (c->disconnected) { + iomgr_success = 0; + } + if (iomgr_success) { + c->next_attempt = + gpr_backoff_step(&c->backoff_state, gpr_now(GPR_CLOCK_MONOTONIC)); + continue_connect(exec_ctx, c); + gpr_mu_unlock(&c->mu); + } else { + gpr_mu_unlock(&c->mu); + GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting"); + } +} + +static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg, + bool iomgr_success) { + grpc_subchannel *c = arg; + + GRPC_SUBCHANNEL_WEAK_REF(c, "connected"); + gpr_mu_lock(&c->mu); + if (c->connecting_result.transport != NULL) { + publish_transport_locked(exec_ctx, c); + } else if (c->disconnected) { + GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting"); + } else { + gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); + GPR_ASSERT(!c->have_alarm); + c->have_alarm = 1; + grpc_connectivity_state_set(exec_ctx, &c->state_tracker, + GRPC_CHANNEL_TRANSIENT_FAILURE, + "connect_failed"); + grpc_timer_init(exec_ctx, &c->alarm, c->next_attempt, on_alarm, c, now); + } + gpr_mu_unlock(&c->mu); + GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting"); +} + +/* + * grpc_subchannel_call implementation + */ + +static void subchannel_call_destroy(grpc_exec_ctx *exec_ctx, void *call, + bool success) { + grpc_subchannel_call *c = call; + GPR_TIMER_BEGIN("grpc_subchannel_call_unref.destroy", 0); + grpc_call_stack_destroy(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c)); + GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, c->connection, "subchannel_call"); + gpr_free(c); + GPR_TIMER_END("grpc_subchannel_call_unref.destroy", 0); +} + +void grpc_subchannel_call_ref( + grpc_subchannel_call *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); +} + +void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call *c + GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + GRPC_CALL_STACK_UNREF(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); +} + +char *grpc_subchannel_call_get_peer(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call *call) { + grpc_call_stack *call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call); + grpc_call_element *top_elem = grpc_call_stack_element(call_stack, 0); + return top_elem->filter->get_peer(exec_ctx, top_elem); +} + +void grpc_subchannel_call_process_op(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call *call, + grpc_transport_stream_op *op) { + grpc_call_stack *call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call); + grpc_call_element *top_elem = grpc_call_stack_element(call_stack, 0); + top_elem->filter->start_transport_stream_op(exec_ctx, top_elem, op); +} + +grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel( + grpc_subchannel *c) { + return GET_CONNECTED_SUBCHANNEL(c, acq); +} + +grpc_subchannel_call *grpc_connected_subchannel_create_call( + grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con, + grpc_pollset *pollset) { + grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con); + grpc_subchannel_call *call = + gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size); + grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call); + call->connection = con; + GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call"); + grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, call, + NULL, NULL, callstk); + grpc_call_stack_set_pollset(exec_ctx, callstk, pollset); + return call; +} + +grpc_call_stack *grpc_subchannel_call_get_call_stack( + grpc_subchannel_call *subchannel_call) { + return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call); +} diff --git a/src/core/lib/client_config/subchannel.h b/src/core/lib/client_config/subchannel.h new file mode 100644 index 0000000000..83e1c58a4c --- /dev/null +++ b/src/core/lib/client_config/subchannel.h @@ -0,0 +1,174 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_SUBCHANNEL_H +#define GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_H + +#include "src/core/channel/channel_stack.h" +#include "src/core/client_config/connector.h" +#include "src/core/transport/connectivity_state.h" + +/** A (sub-)channel that knows how to connect to exactly one target + address. Provides a target for load balancing. */ +typedef struct grpc_subchannel grpc_subchannel; +typedef struct grpc_connected_subchannel grpc_connected_subchannel; +typedef struct grpc_subchannel_call grpc_subchannel_call; +typedef struct grpc_subchannel_args grpc_subchannel_args; + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +#define GRPC_SUBCHANNEL_REF(p, r) \ + grpc_subchannel_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ + grpc_subchannel_ref_from_weak_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_UNREF(cl, p, r) \ + grpc_subchannel_unref((cl), (p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_WEAK_REF(p, r) \ + grpc_subchannel_weak_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_WEAK_UNREF(cl, p, r) \ + grpc_subchannel_weak_unref((cl), (p), __FILE__, __LINE__, (r)) +#define GRPC_CONNECTED_SUBCHANNEL_REF(p, r) \ + grpc_connected_subchannel_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_CONNECTED_SUBCHANNEL_UNREF(cl, p, r) \ + grpc_connected_subchannel_unref((cl), (p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_CALL_REF(p, r) \ + grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_CALL_UNREF(cl, p, r) \ + grpc_subchannel_call_unref((cl), (p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_REF_EXTRA_ARGS \ + , const char *file, int line, const char *reason +#else +#define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p)) +#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ + grpc_subchannel_ref_from_weak_ref((p)) +#define GRPC_SUBCHANNEL_UNREF(cl, p, r) grpc_subchannel_unref((cl), (p)) +#define GRPC_SUBCHANNEL_WEAK_REF(p, r) grpc_subchannel_weak_ref((p)) +#define GRPC_SUBCHANNEL_WEAK_UNREF(cl, p, r) \ + grpc_subchannel_weak_unref((cl), (p)) +#define GRPC_CONNECTED_SUBCHANNEL_REF(p, r) grpc_connected_subchannel_ref((p)) +#define GRPC_CONNECTED_SUBCHANNEL_UNREF(cl, p, r) \ + grpc_connected_subchannel_unref((cl), (p)) +#define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p)) +#define GRPC_SUBCHANNEL_CALL_UNREF(cl, p, r) \ + grpc_subchannel_call_unref((cl), (p)) +#define GRPC_SUBCHANNEL_REF_EXTRA_ARGS +#endif + +grpc_subchannel *grpc_subchannel_ref( + grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +grpc_subchannel *grpc_subchannel_ref_from_weak_ref( + grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_unref(grpc_exec_ctx *exec_ctx, + grpc_subchannel *channel + GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +grpc_subchannel *grpc_subchannel_weak_ref( + grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_weak_unref(grpc_exec_ctx *exec_ctx, + grpc_subchannel *channel + GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_connected_subchannel_ref( + grpc_connected_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_connected_subchannel_unref(grpc_exec_ctx *exec_ctx, + grpc_connected_subchannel *channel + GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_call_ref( + grpc_subchannel_call *call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call *call + GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + +/** construct a subchannel call */ +grpc_subchannel_call *grpc_connected_subchannel_create_call( + grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel, + grpc_pollset *pollset); + +/** process a transport level op */ +void grpc_connected_subchannel_process_transport_op( + grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *subchannel, + grpc_transport_op *op); + +/** poll the current connectivity state of a channel */ +grpc_connectivity_state grpc_subchannel_check_connectivity( + grpc_subchannel *channel); + +/** call notify when the connectivity state of a channel changes from *state. + Updates *state with the new state of the channel */ +void grpc_subchannel_notify_on_state_change( + grpc_exec_ctx *exec_ctx, grpc_subchannel *channel, + grpc_pollset_set *interested_parties, grpc_connectivity_state *state, + grpc_closure *notify); +void grpc_connected_subchannel_notify_on_state_change( + grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *channel, + grpc_pollset_set *interested_parties, grpc_connectivity_state *state, + grpc_closure *notify); +void grpc_connected_subchannel_ping(grpc_exec_ctx *exec_ctx, + grpc_connected_subchannel *channel, + grpc_closure *notify); + +/** retrieve the grpc_connected_subchannel - or NULL if called before + the subchannel becomes connected */ +grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel( + grpc_subchannel *subchannel); + +/** continue processing a transport op */ +void grpc_subchannel_call_process_op(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call *subchannel_call, + grpc_transport_stream_op *op); + +/** continue querying for peer */ +char *grpc_subchannel_call_get_peer(grpc_exec_ctx *exec_ctx, + grpc_subchannel_call *subchannel_call); + +grpc_call_stack *grpc_subchannel_call_get_call_stack( + grpc_subchannel_call *subchannel_call); + +struct grpc_subchannel_args { + /* When updating this struct, also update subchannel_index.c */ + + /** Channel filters for this channel - wrapped factories will likely + want to mutate this */ + const grpc_channel_filter **filters; + /** The number of filters in the above array */ + size_t filter_count; + /** Channel arguments to be supplied to the newly created channel */ + const grpc_channel_args *args; + /** Address to connect to */ + struct sockaddr *addr; + size_t addr_len; +}; + +/** create a subchannel given a connector */ +grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx, + grpc_connector *connector, + grpc_subchannel_args *args); + +#endif /* GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_H */ diff --git a/src/core/lib/client_config/subchannel_factory.c b/src/core/lib/client_config/subchannel_factory.c new file mode 100644 index 0000000000..2c64219e8b --- /dev/null +++ b/src/core/lib/client_config/subchannel_factory.c @@ -0,0 +1,49 @@ +/* + * + * Copyright 2015, 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/client_config/subchannel_factory.h" + +void grpc_subchannel_factory_ref(grpc_subchannel_factory* factory) { + factory->vtable->ref(factory); +} + +void grpc_subchannel_factory_unref(grpc_exec_ctx* exec_ctx, + grpc_subchannel_factory* factory) { + factory->vtable->unref(exec_ctx, factory); +} + +grpc_subchannel* grpc_subchannel_factory_create_subchannel( + grpc_exec_ctx* exec_ctx, grpc_subchannel_factory* factory, + grpc_subchannel_args* args) { + return factory->vtable->create_subchannel(exec_ctx, factory, args); +} diff --git a/src/core/lib/client_config/subchannel_factory.h b/src/core/lib/client_config/subchannel_factory.h new file mode 100644 index 0000000000..c638f377a6 --- /dev/null +++ b/src/core/lib/client_config/subchannel_factory.h @@ -0,0 +1,66 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H +#define GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H + +#include "src/core/channel/channel_stack.h" +#include "src/core/client_config/subchannel.h" + +typedef struct grpc_subchannel_factory grpc_subchannel_factory; +typedef struct grpc_subchannel_factory_vtable grpc_subchannel_factory_vtable; + +/** Constructor for new configured channels. + Creating decorators around this type is encouraged to adapt behavior. */ +struct grpc_subchannel_factory { + const grpc_subchannel_factory_vtable *vtable; +}; + +struct grpc_subchannel_factory_vtable { + void (*ref)(grpc_subchannel_factory *factory); + void (*unref)(grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory); + grpc_subchannel *(*create_subchannel)(grpc_exec_ctx *exec_ctx, + grpc_subchannel_factory *factory, + grpc_subchannel_args *args); +}; + +void grpc_subchannel_factory_ref(grpc_subchannel_factory *factory); +void grpc_subchannel_factory_unref(grpc_exec_ctx *exec_ctx, + grpc_subchannel_factory *factory); + +/** Create a new grpc_subchannel */ +grpc_subchannel *grpc_subchannel_factory_create_subchannel( + grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory, + grpc_subchannel_args *args); + +#endif /* GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H */ diff --git a/src/core/lib/client_config/subchannel_index.c b/src/core/lib/client_config/subchannel_index.c new file mode 100644 index 0000000000..24cc76cf22 --- /dev/null +++ b/src/core/lib/client_config/subchannel_index.c @@ -0,0 +1,262 @@ +// +// +// 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/client_config/subchannel_index.h" + +#include +#include + +#include +#include +#include + +#include "src/core/channel/channel_args.h" + +// a map of subchannel_key --> subchannel, used for detecting connections +// to the same destination in order to share them +static gpr_avl g_subchannel_index; + +static gpr_mu g_mu; + +struct grpc_subchannel_key { + grpc_connector *connector; + grpc_subchannel_args args; +}; + +GPR_TLS_DECL(subchannel_index_exec_ctx); + +static void enter_ctx(grpc_exec_ctx *exec_ctx) { + GPR_ASSERT(gpr_tls_get(&subchannel_index_exec_ctx) == 0); + gpr_tls_set(&subchannel_index_exec_ctx, (intptr_t)exec_ctx); +} + +static void leave_ctx(grpc_exec_ctx *exec_ctx) { + GPR_ASSERT(gpr_tls_get(&subchannel_index_exec_ctx) == (intptr_t)exec_ctx); + gpr_tls_set(&subchannel_index_exec_ctx, 0); +} + +static grpc_exec_ctx *current_ctx() { + grpc_exec_ctx *c = (grpc_exec_ctx *)gpr_tls_get(&subchannel_index_exec_ctx); + GPR_ASSERT(c != NULL); + return c; +} + +static grpc_subchannel_key *create_key( + grpc_connector *connector, grpc_subchannel_args *args, + grpc_channel_args *(*copy_channel_args)(const grpc_channel_args *args)) { + grpc_subchannel_key *k = gpr_malloc(sizeof(*k)); + k->connector = grpc_connector_ref(connector); + k->args.filter_count = args->filter_count; + k->args.filters = gpr_malloc(sizeof(*k->args.filters) * k->args.filter_count); + memcpy((grpc_channel_filter *)k->args.filters, args->filters, + sizeof(*k->args.filters) * k->args.filter_count); + k->args.addr_len = args->addr_len; + k->args.addr = gpr_malloc(args->addr_len); + memcpy(k->args.addr, args->addr, k->args.addr_len); + k->args.args = copy_channel_args(args->args); + return k; +} + +grpc_subchannel_key *grpc_subchannel_key_create(grpc_connector *connector, + grpc_subchannel_args *args) { + return create_key(connector, args, grpc_channel_args_normalize); +} + +static grpc_subchannel_key *subchannel_key_copy(grpc_subchannel_key *k) { + return create_key(k->connector, &k->args, grpc_channel_args_copy); +} + +static int subchannel_key_compare(grpc_subchannel_key *a, + grpc_subchannel_key *b) { + int c = GPR_ICMP(a->connector, b->connector); + if (c != 0) return c; + c = GPR_ICMP(a->args.addr_len, b->args.addr_len); + if (c != 0) return c; + c = GPR_ICMP(a->args.filter_count, b->args.filter_count); + if (c != 0) return c; + c = memcmp(a->args.addr, b->args.addr, a->args.addr_len); + if (c != 0) return c; + c = memcmp(a->args.filters, b->args.filters, + a->args.filter_count * sizeof(*a->args.filters)); + if (c != 0) return c; + return grpc_channel_args_compare(a->args.args, b->args.args); +} + +void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx, + grpc_subchannel_key *k) { + grpc_connector_unref(exec_ctx, k->connector); + gpr_free(k->args.addr); + gpr_free((grpc_channel_args *)k->args.filters); + grpc_channel_args_destroy((grpc_channel_args *)k->args.args); + gpr_free(k); +} + +static void sck_avl_destroy(void *p) { + grpc_subchannel_key_destroy(current_ctx(), p); +} + +static void *sck_avl_copy(void *p) { return subchannel_key_copy(p); } + +static long sck_avl_compare(void *a, void *b) { + return subchannel_key_compare(a, b); +} + +static void scv_avl_destroy(void *p) { + GRPC_SUBCHANNEL_WEAK_UNREF(current_ctx(), p, "subchannel_index"); +} + +static void *scv_avl_copy(void *p) { + GRPC_SUBCHANNEL_WEAK_REF(p, "subchannel_index"); + return p; +} + +static const gpr_avl_vtable subchannel_avl_vtable = { + .destroy_key = sck_avl_destroy, + .copy_key = sck_avl_copy, + .compare_keys = sck_avl_compare, + .destroy_value = scv_avl_destroy, + .copy_value = scv_avl_copy}; + +void grpc_subchannel_index_init(void) { + g_subchannel_index = gpr_avl_create(&subchannel_avl_vtable); + gpr_mu_init(&g_mu); + gpr_tls_init(&subchannel_index_exec_ctx); +} + +void grpc_subchannel_index_shutdown(void) { + gpr_mu_destroy(&g_mu); + gpr_avl_unref(g_subchannel_index); + gpr_tls_destroy(&subchannel_index_exec_ctx); +} + +grpc_subchannel *grpc_subchannel_index_find(grpc_exec_ctx *exec_ctx, + grpc_subchannel_key *key) { + enter_ctx(exec_ctx); + + // Lock, and take a reference to the subchannel index. + // We don't need to do the search under a lock as avl's are immutable. + gpr_mu_lock(&g_mu); + gpr_avl index = gpr_avl_ref(g_subchannel_index); + gpr_mu_unlock(&g_mu); + + grpc_subchannel *c = + GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(gpr_avl_get(index, key), "index_find"); + gpr_avl_unref(index); + + leave_ctx(exec_ctx); + return c; +} + +grpc_subchannel *grpc_subchannel_index_register(grpc_exec_ctx *exec_ctx, + grpc_subchannel_key *key, + grpc_subchannel *constructed) { + enter_ctx(exec_ctx); + + grpc_subchannel *c = NULL; + + while (c == NULL) { + // Compare and swap loop: + // - take a reference to the current index + gpr_mu_lock(&g_mu); + gpr_avl index = gpr_avl_ref(g_subchannel_index); + gpr_mu_unlock(&g_mu); + + // - Check to see if a subchannel already exists + c = gpr_avl_get(index, key); + if (c != NULL) { + // yes -> we're done + GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, constructed, "index_register"); + } else { + // no -> update the avl and compare/swap + gpr_avl updated = + gpr_avl_add(gpr_avl_ref(index), subchannel_key_copy(key), + GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register")); + + // it may happen (but it's expected to be unlikely) + // that some other thread has changed the index: + // compare/swap here to check that, and retry as necessary + gpr_mu_lock(&g_mu); + if (index.root == g_subchannel_index.root) { + GPR_SWAP(gpr_avl, updated, g_subchannel_index); + c = constructed; + } + gpr_mu_unlock(&g_mu); + + gpr_avl_unref(updated); + } + gpr_avl_unref(index); + } + + leave_ctx(exec_ctx); + + return c; +} + +void grpc_subchannel_index_unregister(grpc_exec_ctx *exec_ctx, + grpc_subchannel_key *key, + grpc_subchannel *constructed) { + enter_ctx(exec_ctx); + + bool done = false; + while (!done) { + // Compare and swap loop: + // - take a reference to the current index + gpr_mu_lock(&g_mu); + gpr_avl index = gpr_avl_ref(g_subchannel_index); + gpr_mu_unlock(&g_mu); + + // Check to see if this key still refers to the previously + // registered subchannel + grpc_subchannel *c = gpr_avl_get(index, key); + if (c != constructed) { + gpr_avl_unref(index); + break; + } + + // compare and swap the update (some other thread may have + // mutated the index behind us) + gpr_avl updated = gpr_avl_remove(gpr_avl_ref(index), key); + + gpr_mu_lock(&g_mu); + if (index.root == g_subchannel_index.root) { + GPR_SWAP(gpr_avl, updated, g_subchannel_index); + done = true; + } + gpr_mu_unlock(&g_mu); + + gpr_avl_unref(updated); + gpr_avl_unref(index); + } + + leave_ctx(exec_ctx); +} diff --git a/src/core/lib/client_config/subchannel_index.h b/src/core/lib/client_config/subchannel_index.h new file mode 100644 index 0000000000..3cd5d12349 --- /dev/null +++ b/src/core/lib/client_config/subchannel_index.h @@ -0,0 +1,77 @@ +/* + * + * 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_CLIENT_CONFIG_SUBCHANNEL_INDEX_H +#define GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H + +#include "src/core/client_config/connector.h" +#include "src/core/client_config/subchannel.h" + +/** \file Provides an index of active subchannels so that they can be + shared amongst channels */ + +typedef struct grpc_subchannel_key grpc_subchannel_key; + +/** Create a key that can be used to uniquely identify a subchannel */ +grpc_subchannel_key *grpc_subchannel_key_create(grpc_connector *con, + grpc_subchannel_args *args); + +/** Destroy a subchannel key */ +void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx, + grpc_subchannel_key *key); + +/** Given a subchannel key, find the subchannel registered for it. + Returns NULL if no such channel exists. + Thread-safe. */ +grpc_subchannel *grpc_subchannel_index_find(grpc_exec_ctx *exec_ctx, + grpc_subchannel_key *key); + +/** Register a subchannel against a key. + Takes ownership of \a constructed. + Returns the registered subchannel. This may be different from + \a constructed in the case of a registration race. */ +grpc_subchannel *grpc_subchannel_index_register(grpc_exec_ctx *exec_ctx, + grpc_subchannel_key *key, + grpc_subchannel *constructed); + +/** Remove \a constructed as the registered subchannel for \a key. */ +void grpc_subchannel_index_unregister(grpc_exec_ctx *exec_ctx, + grpc_subchannel_key *key, + grpc_subchannel *constructed); + +/** Initialize the subchannel index (global) */ +void grpc_subchannel_index_init(void); +/** Shutdown the subchannel index (global) */ +void grpc_subchannel_index_shutdown(void); + +#endif /* GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H */ diff --git a/src/core/lib/client_config/uri_parser.c b/src/core/lib/client_config/uri_parser.c new file mode 100644 index 0000000000..cbdfffcf8e --- /dev/null +++ b/src/core/lib/client_config/uri_parser.c @@ -0,0 +1,242 @@ +/* + * + * Copyright 2015, 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/client_config/uri_parser.h" + +#include + +#include +#include +#include +#include + +/** a size_t default value... maps to all 1's */ +#define NOT_SET (~(size_t)0) + +static grpc_uri *bad_uri(const char *uri_text, size_t pos, const char *section, + int suppress_errors) { + char *line_prefix; + size_t pfx_len; + + if (!suppress_errors) { + gpr_asprintf(&line_prefix, "bad uri.%s: '", section); + pfx_len = strlen(line_prefix) + pos; + gpr_log(GPR_ERROR, "%s%s'", line_prefix, uri_text); + gpr_free(line_prefix); + + line_prefix = gpr_malloc(pfx_len + 1); + memset(line_prefix, ' ', pfx_len); + line_prefix[pfx_len] = 0; + gpr_log(GPR_ERROR, "%s^ here", line_prefix); + gpr_free(line_prefix); + } + + return NULL; +} + +/** Returns a copy of \a src[begin, end) */ +static char *copy_component(const char *src, size_t begin, size_t end) { + char *out = gpr_malloc(end - begin + 1); + memcpy(out, src + begin, end - begin); + out[end - begin] = 0; + return out; +} + +/** Returns how many chars to advance if \a uri_text[i] begins a valid \a pchar + * production. If \a uri_text[i] introduces an invalid \a pchar (such as percent + * sign not followed by two hex digits), NOT_SET is returned. */ +static size_t parse_pchar(const char *uri_text, size_t i) { + /* pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * pct-encoded = "%" HEXDIG HEXDIG + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + / "*" / "+" / "," / ";" / "=" */ + char c = uri_text[i]; + if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || + ((c >= '0') && (c <= '9')) || + (c == '-' || c == '.' || c == '_' || c == '~') || /* unreserved */ + (c == '!' || c == '$' || c == '&' || c == '\'' || c == '$' || c == '&' || + c == '(' || c == ')' || c == '*' || c == '+' || c == ',' || c == ';' || + c == '=') /* sub-delims */) { + return 1; + } + if (c == '%') { /* pct-encoded */ + size_t j; + if (uri_text[i + 1] == 0 || uri_text[i + 2] == 0) { + return NOT_SET; + } + for (j = i + 1; j < 2; j++) { + c = uri_text[j]; + if (!(((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f')) || + ((c >= 'A') && (c <= 'F')))) { + return NOT_SET; + } + } + return 2; + } + return 0; +} + +/* *( pchar / "?" / "/" ) */ +static int parse_fragment_or_query(const char *uri_text, size_t *i) { + char c; + while ((c = uri_text[*i]) != 0) { + const size_t advance = parse_pchar(uri_text, *i); /* pchar */ + switch (advance) { + case 0: /* uri_text[i] isn't in pchar */ + /* maybe it's ? or / */ + if (uri_text[*i] == '?' || uri_text[*i] == '/') { + (*i)++; + break; + } else { + return 1; + } + GPR_UNREACHABLE_CODE(return 0); + default: + (*i) += advance; + break; + case NOT_SET: /* uri_text[i] introduces an invalid URI */ + return 0; + } + } + /* *i is the first uri_text position past the \a query production, maybe \0 */ + return 1; +} + +grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) { + grpc_uri *uri; + size_t scheme_begin = 0; + size_t scheme_end = NOT_SET; + size_t authority_begin = NOT_SET; + size_t authority_end = NOT_SET; + size_t path_begin = NOT_SET; + size_t path_end = NOT_SET; + size_t query_begin = NOT_SET; + size_t query_end = NOT_SET; + size_t fragment_begin = NOT_SET; + size_t fragment_end = NOT_SET; + size_t i; + + for (i = scheme_begin; uri_text[i] != 0; i++) { + if (uri_text[i] == ':') { + scheme_end = i; + break; + } + if (uri_text[i] >= 'a' && uri_text[i] <= 'z') continue; + if (uri_text[i] >= 'A' && uri_text[i] <= 'Z') continue; + if (i != scheme_begin) { + if (uri_text[i] >= '0' && uri_text[i] <= '9') continue; + if (uri_text[i] == '+') continue; + if (uri_text[i] == '-') continue; + if (uri_text[i] == '.') continue; + } + break; + } + if (scheme_end == NOT_SET) { + return bad_uri(uri_text, i, "scheme", suppress_errors); + } + + if (uri_text[scheme_end + 1] == '/' && uri_text[scheme_end + 2] == '/') { + authority_begin = scheme_end + 3; + for (i = authority_begin; uri_text[i] != 0 && authority_end == NOT_SET; + i++) { + if (uri_text[i] == '/' || uri_text[i] == '?' || uri_text[i] == '#') { + authority_end = i; + } + } + if (authority_end == NOT_SET && uri_text[i] == 0) { + authority_end = i; + } + if (authority_end == NOT_SET) { + return bad_uri(uri_text, i, "authority", suppress_errors); + } + /* TODO(ctiller): parse the authority correctly */ + path_begin = authority_end; + } else { + path_begin = scheme_end + 1; + } + + for (i = path_begin; uri_text[i] != 0; i++) { + if (uri_text[i] == '?' || uri_text[i] == '#') { + path_end = i; + break; + } + } + if (path_end == NOT_SET && uri_text[i] == 0) { + path_end = i; + } + if (path_end == NOT_SET) { + return bad_uri(uri_text, i, "path", suppress_errors); + } + + if (uri_text[i] == '?') { + query_begin = ++i; + if (!parse_fragment_or_query(uri_text, &i)) { + return bad_uri(uri_text, i, "query", suppress_errors); + } else if (uri_text[i] != 0 && uri_text[i] != '#') { + /* We must be at the end or at the beginning of a fragment */ + return bad_uri(uri_text, i, "query", suppress_errors); + } + query_end = i; + } + if (uri_text[i] == '#') { + fragment_begin = ++i; + if (!parse_fragment_or_query(uri_text, &i)) { + return bad_uri(uri_text, i - fragment_end, "fragment", suppress_errors); + } else if (uri_text[i] != 0) { + /* We must be at the end */ + return bad_uri(uri_text, i, "fragment", suppress_errors); + } + fragment_end = i; + } + + uri = gpr_malloc(sizeof(*uri)); + memset(uri, 0, sizeof(*uri)); + uri->scheme = copy_component(uri_text, scheme_begin, scheme_end); + uri->authority = copy_component(uri_text, authority_begin, authority_end); + uri->path = copy_component(uri_text, path_begin, path_end); + uri->query = copy_component(uri_text, query_begin, query_end); + uri->fragment = copy_component(uri_text, fragment_begin, fragment_end); + + return uri; +} + +void grpc_uri_destroy(grpc_uri *uri) { + if (!uri) return; + gpr_free(uri->scheme); + gpr_free(uri->authority); + gpr_free(uri->path); + gpr_free(uri->query); + gpr_free(uri->fragment); + gpr_free(uri); +} diff --git a/src/core/lib/client_config/uri_parser.h b/src/core/lib/client_config/uri_parser.h new file mode 100644 index 0000000000..af013d8cac --- /dev/null +++ b/src/core/lib/client_config/uri_parser.h @@ -0,0 +1,51 @@ +/* + * + * Copyright 2015-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_CLIENT_CONFIG_URI_PARSER_H +#define GRPC_CORE_CLIENT_CONFIG_URI_PARSER_H + +typedef struct { + char *scheme; + char *authority; + char *path; + char *query; + char *fragment; +} grpc_uri; + +/** parse a uri, return NULL on failure */ +grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors); + +/** destroy a uri */ +void grpc_uri_destroy(grpc_uri *uri); + +#endif /* GRPC_CORE_CLIENT_CONFIG_URI_PARSER_H */ diff --git a/src/core/lib/compression/algorithm_metadata.h b/src/core/lib/compression/algorithm_metadata.h new file mode 100644 index 0000000000..34abf1dba2 --- /dev/null +++ b/src/core/lib/compression/algorithm_metadata.h @@ -0,0 +1,53 @@ +/* + * + * Copyright 2015-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_COMPRESSION_ALGORITHM_METADATA_H +#define GRPC_CORE_COMPRESSION_ALGORITHM_METADATA_H + +#include +#include "src/core/transport/metadata.h" + +/** Return compression algorithm based metadata value */ +grpc_mdstr *grpc_compression_algorithm_mdstr( + grpc_compression_algorithm algorithm); + +/** Return compression algorithm based metadata element (grpc-encoding: xxx) */ +grpc_mdelem *grpc_compression_encoding_mdelem( + grpc_compression_algorithm algorithm); + +/** Find compression algorithm based on passed in mdstr - returns + * GRPC_COMPRESS_ALGORITHM_COUNT on failure */ +grpc_compression_algorithm grpc_compression_algorithm_from_mdstr( + grpc_mdstr *str); + +#endif /* GRPC_CORE_COMPRESSION_ALGORITHM_METADATA_H */ diff --git a/src/core/lib/compression/compression_algorithm.c b/src/core/lib/compression/compression_algorithm.c new file mode 100644 index 0000000000..2810a38b68 --- /dev/null +++ b/src/core/lib/compression/compression_algorithm.c @@ -0,0 +1,203 @@ +/* + * + * Copyright 2015-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 +#include + +#include +#include + +#include "src/core/compression/algorithm_metadata.h" +#include "src/core/surface/api_trace.h" +#include "src/core/transport/static_metadata.h" + +int grpc_compression_algorithm_parse(const char *name, size_t name_length, + grpc_compression_algorithm *algorithm) { + /* we use strncmp not only because it's safer (even though in this case it + * doesn't matter, given that we are comparing against string literals, but + * because this way we needn't have "name" nil-terminated (useful for slice + * data, for example) */ + GRPC_API_TRACE( + "grpc_compression_algorithm_parse(" + "name=%*.*s, name_length=%lu, algorithm=%p)", + 5, ((int)name_length, (int)name_length, name, (unsigned long)name_length, + algorithm)); + if (name_length == 0) { + return 0; + } + if (strncmp(name, "identity", name_length) == 0) { + *algorithm = GRPC_COMPRESS_NONE; + } else if (strncmp(name, "gzip", name_length) == 0) { + *algorithm = GRPC_COMPRESS_GZIP; + } else if (strncmp(name, "deflate", name_length) == 0) { + *algorithm = GRPC_COMPRESS_DEFLATE; + } else { + return 0; + } + return 1; +} + +int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm, + char **name) { + GRPC_API_TRACE("grpc_compression_algorithm_parse(algorithm=%d, name=%p)", 2, + ((int)algorithm, name)); + switch (algorithm) { + case GRPC_COMPRESS_NONE: + *name = "identity"; + return 1; + case GRPC_COMPRESS_DEFLATE: + *name = "deflate"; + return 1; + case GRPC_COMPRESS_GZIP: + *name = "gzip"; + return 1; + case GRPC_COMPRESS_ALGORITHMS_COUNT: + return 0; + } + return 0; +} + +grpc_compression_algorithm grpc_compression_algorithm_from_mdstr( + grpc_mdstr *str) { + if (str == GRPC_MDSTR_IDENTITY) return GRPC_COMPRESS_NONE; + if (str == GRPC_MDSTR_DEFLATE) return GRPC_COMPRESS_DEFLATE; + if (str == GRPC_MDSTR_GZIP) return GRPC_COMPRESS_GZIP; + return GRPC_COMPRESS_ALGORITHMS_COUNT; +} + +grpc_mdstr *grpc_compression_algorithm_mdstr( + grpc_compression_algorithm algorithm) { + switch (algorithm) { + case GRPC_COMPRESS_NONE: + return GRPC_MDSTR_IDENTITY; + case GRPC_COMPRESS_DEFLATE: + return GRPC_MDSTR_DEFLATE; + case GRPC_COMPRESS_GZIP: + return GRPC_MDSTR_GZIP; + case GRPC_COMPRESS_ALGORITHMS_COUNT: + return NULL; + } + return NULL; +} + +grpc_mdelem *grpc_compression_encoding_mdelem( + grpc_compression_algorithm algorithm) { + switch (algorithm) { + case GRPC_COMPRESS_NONE: + return GRPC_MDELEM_GRPC_ENCODING_IDENTITY; + case GRPC_COMPRESS_DEFLATE: + return GRPC_MDELEM_GRPC_ENCODING_DEFLATE; + case GRPC_COMPRESS_GZIP: + return GRPC_MDELEM_GRPC_ENCODING_GZIP; + default: + break; + } + return NULL; +} + +/* TODO(dgq): Add the ability to specify parameters to the individual + * compression algorithms */ +grpc_compression_algorithm grpc_compression_algorithm_for_level( + grpc_compression_level level, uint32_t accepted_encodings) { + GRPC_API_TRACE("grpc_compression_algorithm_for_level(level=%d)", 1, + ((int)level)); + if (level > GRPC_COMPRESS_LEVEL_HIGH) { + gpr_log(GPR_ERROR, "Unknown compression level %d.", (int)level); + abort(); + } + + const size_t num_supported = + GPR_BITCOUNT(accepted_encodings) - 1; /* discard NONE */ + if (level == GRPC_COMPRESS_LEVEL_NONE || num_supported == 0) { + return GRPC_COMPRESS_NONE; + } + + GPR_ASSERT(level > 0); + + /* Establish a "ranking" or compression algorithms in increasing order of + * compression. + * This is simplistic and we will probably want to introduce other dimensions + * in the future (cpu/memory cost, etc). */ + const grpc_compression_algorithm algos_ranking[] = {GRPC_COMPRESS_GZIP, + GRPC_COMPRESS_DEFLATE}; + + /* intersect algos_ranking with the supported ones keeping the ranked order */ + grpc_compression_algorithm + sorted_supported_algos[GRPC_COMPRESS_ALGORITHMS_COUNT]; + size_t algos_supported_idx = 0; + for (size_t i = 0; i < GPR_ARRAY_SIZE(algos_ranking); i++) { + const grpc_compression_algorithm alg = algos_ranking[i]; + for (size_t j = 0; j < num_supported; j++) { + if (GPR_BITGET(accepted_encodings, alg) == 1) { + /* if \a alg in supported */ + sorted_supported_algos[algos_supported_idx++] = alg; + break; + } + } + if (algos_supported_idx == num_supported) break; + } + + switch (level) { + case GRPC_COMPRESS_LEVEL_NONE: + abort(); /* should have been handled already */ + case GRPC_COMPRESS_LEVEL_LOW: + return sorted_supported_algos[0]; + case GRPC_COMPRESS_LEVEL_MED: + return sorted_supported_algos[num_supported / 2]; + case GRPC_COMPRESS_LEVEL_HIGH: + return sorted_supported_algos[num_supported - 1]; + default: + abort(); + }; +} + +void grpc_compression_options_init(grpc_compression_options *opts) { + opts->enabled_algorithms_bitset = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; + opts->default_compression_algorithm = GRPC_COMPRESS_NONE; +} + +void grpc_compression_options_enable_algorithm( + grpc_compression_options *opts, grpc_compression_algorithm algorithm) { + GPR_BITSET(&opts->enabled_algorithms_bitset, algorithm); +} + +void grpc_compression_options_disable_algorithm( + grpc_compression_options *opts, grpc_compression_algorithm algorithm) { + GPR_BITCLEAR(&opts->enabled_algorithms_bitset, algorithm); +} + +int grpc_compression_options_is_algorithm_enabled( + const grpc_compression_options *opts, + grpc_compression_algorithm algorithm) { + return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm); +} diff --git a/src/core/lib/compression/message_compress.c b/src/core/lib/compression/message_compress.c new file mode 100644 index 0000000000..edc21a9eb7 --- /dev/null +++ b/src/core/lib/compression/message_compress.c @@ -0,0 +1,198 @@ +/* + * + * Copyright 2015, 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/compression/message_compress.h" + +#include + +#include +#include + +#include + +#define OUTPUT_BLOCK_SIZE 1024 + +static int zlib_body(z_stream* zs, gpr_slice_buffer* input, + gpr_slice_buffer* output, + int (*flate)(z_stream* zs, int flush)) { + int r; + int flush; + size_t i; + gpr_slice outbuf = gpr_slice_malloc(OUTPUT_BLOCK_SIZE); + const uInt uint_max = ~(uInt)0; + + GPR_ASSERT(GPR_SLICE_LENGTH(outbuf) <= uint_max); + zs->avail_out = (uInt)GPR_SLICE_LENGTH(outbuf); + zs->next_out = GPR_SLICE_START_PTR(outbuf); + flush = Z_NO_FLUSH; + for (i = 0; i < input->count; i++) { + if (i == input->count - 1) flush = Z_FINISH; + GPR_ASSERT(GPR_SLICE_LENGTH(input->slices[i]) <= uint_max); + zs->avail_in = (uInt)GPR_SLICE_LENGTH(input->slices[i]); + zs->next_in = GPR_SLICE_START_PTR(input->slices[i]); + do { + if (zs->avail_out == 0) { + gpr_slice_buffer_add_indexed(output, outbuf); + outbuf = gpr_slice_malloc(OUTPUT_BLOCK_SIZE); + GPR_ASSERT(GPR_SLICE_LENGTH(outbuf) <= uint_max); + zs->avail_out = (uInt)GPR_SLICE_LENGTH(outbuf); + zs->next_out = GPR_SLICE_START_PTR(outbuf); + } + r = flate(zs, flush); + if (r < 0 && r != Z_BUF_ERROR /* not fatal */) { + gpr_log(GPR_INFO, "zlib error (%d)", r); + goto error; + } + } while (zs->avail_out == 0); + if (zs->avail_in) { + gpr_log(GPR_INFO, "zlib: not all input consumed"); + goto error; + } + } + + GPR_ASSERT(outbuf.refcount); + outbuf.data.refcounted.length -= zs->avail_out; + gpr_slice_buffer_add_indexed(output, outbuf); + + return 1; + +error: + gpr_slice_unref(outbuf); + return 0; +} + +static void* zalloc_gpr(void* opaque, unsigned int items, unsigned int size) { + return gpr_malloc(items * size); +} + +static void zfree_gpr(void* opaque, void* address) { gpr_free(address); } + +static int zlib_compress(gpr_slice_buffer* input, gpr_slice_buffer* output, + int gzip) { + z_stream zs; + int r; + size_t i; + size_t count_before = output->count; + size_t length_before = output->length; + memset(&zs, 0, sizeof(zs)); + zs.zalloc = zalloc_gpr; + zs.zfree = zfree_gpr; + r = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | (gzip ? 16 : 0), + 8, Z_DEFAULT_STRATEGY); + GPR_ASSERT(r == Z_OK); + r = zlib_body(&zs, input, output, deflate) && output->length < input->length; + if (!r) { + for (i = count_before; i < output->count; i++) { + gpr_slice_unref(output->slices[i]); + } + output->count = count_before; + output->length = length_before; + } + deflateEnd(&zs); + return r; +} + +static int zlib_decompress(gpr_slice_buffer* input, gpr_slice_buffer* output, + int gzip) { + z_stream zs; + int r; + size_t i; + size_t count_before = output->count; + size_t length_before = output->length; + memset(&zs, 0, sizeof(zs)); + zs.zalloc = zalloc_gpr; + zs.zfree = zfree_gpr; + r = inflateInit2(&zs, 15 | (gzip ? 16 : 0)); + GPR_ASSERT(r == Z_OK); + r = zlib_body(&zs, input, output, inflate); + if (!r) { + for (i = count_before; i < output->count; i++) { + gpr_slice_unref(output->slices[i]); + } + output->count = count_before; + output->length = length_before; + } + inflateEnd(&zs); + return r; +} + +static int copy(gpr_slice_buffer* input, gpr_slice_buffer* output) { + size_t i; + for (i = 0; i < input->count; i++) { + gpr_slice_buffer_add(output, gpr_slice_ref(input->slices[i])); + } + return 1; +} + +static int compress_inner(grpc_compression_algorithm algorithm, + gpr_slice_buffer* input, gpr_slice_buffer* output) { + switch (algorithm) { + case GRPC_COMPRESS_NONE: + /* the fallback path always needs to be send uncompressed: we simply + rely on that here */ + return 0; + case GRPC_COMPRESS_DEFLATE: + return zlib_compress(input, output, 0); + case GRPC_COMPRESS_GZIP: + return zlib_compress(input, output, 1); + case GRPC_COMPRESS_ALGORITHMS_COUNT: + break; + } + gpr_log(GPR_ERROR, "invalid compression algorithm %d", algorithm); + return 0; +} + +int grpc_msg_compress(grpc_compression_algorithm algorithm, + gpr_slice_buffer* input, gpr_slice_buffer* output) { + if (!compress_inner(algorithm, input, output)) { + copy(input, output); + return 0; + } + return 1; +} + +int grpc_msg_decompress(grpc_compression_algorithm algorithm, + gpr_slice_buffer* input, gpr_slice_buffer* output) { + switch (algorithm) { + case GRPC_COMPRESS_NONE: + return copy(input, output); + case GRPC_COMPRESS_DEFLATE: + return zlib_decompress(input, output, 0); + case GRPC_COMPRESS_GZIP: + return zlib_decompress(input, output, 1); + case GRPC_COMPRESS_ALGORITHMS_COUNT: + break; + } + gpr_log(GPR_ERROR, "invalid compression algorithm %d", algorithm); + return 0; +} diff --git a/src/core/lib/compression/message_compress.h b/src/core/lib/compression/message_compress.h new file mode 100644 index 0000000000..20b78c063b --- /dev/null +++ b/src/core/lib/compression/message_compress.h @@ -0,0 +1,52 @@ +/* + * + * Copyright 2015-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_COMPRESSION_MESSAGE_COMPRESS_H +#define GRPC_CORE_COMPRESSION_MESSAGE_COMPRESS_H + +#include +#include + +/* compress 'input' to 'output' using 'algorithm'. + On success, appends compressed slices to output and returns 1. + On failure, appends uncompressed slices to output and returns 0. */ +int grpc_msg_compress(grpc_compression_algorithm algorithm, + gpr_slice_buffer* input, gpr_slice_buffer* output); + +/* decompress 'input' to 'output' using 'algorithm'. + On success, appends slices to output and returns 1. + On failure, output is unchanged, and returns 0. */ +int grpc_msg_decompress(grpc_compression_algorithm algorithm, + gpr_slice_buffer* input, gpr_slice_buffer* output); + +#endif /* GRPC_CORE_COMPRESSION_MESSAGE_COMPRESS_H */ diff --git a/src/core/lib/debug/trace.c b/src/core/lib/debug/trace.c new file mode 100644 index 0000000000..3b35d81cd8 --- /dev/null +++ b/src/core/lib/debug/trace.c @@ -0,0 +1,136 @@ +/* + * + * Copyright 2015, 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/debug/trace.h" + +#include + +#include +#include +#include +#include "src/core/support/env.h" + +typedef struct tracer { + const char *name; + int *flag; + struct tracer *next; +} tracer; +static tracer *tracers; + +void grpc_register_tracer(const char *name, int *flag) { + tracer *t = gpr_malloc(sizeof(*t)); + t->name = name; + t->flag = flag; + t->next = tracers; + *flag = 0; + tracers = t; +} + +static void add(const char *beg, const char *end, char ***ss, size_t *ns) { + size_t n = *ns; + size_t np = n + 1; + char *s; + size_t len; + GPR_ASSERT(end >= beg); + len = (size_t)(end - beg); + s = gpr_malloc(len + 1); + memcpy(s, beg, len); + s[len] = 0; + *ss = gpr_realloc(*ss, sizeof(char **) * np); + (*ss)[n] = s; + *ns = np; +} + +static void split(const char *s, char ***ss, size_t *ns) { + const char *c = strchr(s, ','); + if (c == NULL) { + add(s, s + strlen(s), ss, ns); + } else { + add(s, c, ss, ns); + split(c + 1, ss, ns); + } +} + +static void parse(const char *s) { + char **strings = NULL; + size_t nstrings = 0; + size_t i; + split(s, &strings, &nstrings); + + for (i = 0; i < nstrings; i++) { + grpc_tracer_set_enabled(strings[i], 1); + } + + for (i = 0; i < nstrings; i++) { + gpr_free(strings[i]); + } + gpr_free(strings); +} + +void grpc_tracer_init(const char *env_var) { + char *e = gpr_getenv(env_var); + if (e != NULL) { + parse(e); + gpr_free(e); + } +} + +void grpc_tracer_shutdown(void) { + while (tracers) { + tracer *t = tracers; + tracers = t->next; + gpr_free(t); + } +} + +int grpc_tracer_set_enabled(const char *name, int enabled) { + tracer *t; + if (0 == strcmp(name, "all")) { + for (t = tracers; t; t = t->next) { + *t->flag = 1; + } + } else { + int found = 0; + for (t = tracers; t; t = t->next) { + if (0 == strcmp(name, t->name)) { + *t->flag = enabled; + found = 1; + } + } + if (!found) { + gpr_log(GPR_ERROR, "Unknown trace var: '%s'", name); + return 0; /* early return */ + } + } + return 1; +} diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h new file mode 100644 index 0000000000..91ec14052e --- /dev/null +++ b/src/core/lib/debug/trace.h @@ -0,0 +1,43 @@ +/* + * + * Copyright 2015-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_DEBUG_TRACE_H +#define GRPC_CORE_DEBUG_TRACE_H + +#include + +void grpc_register_tracer(const char *name, int *flag); +void grpc_tracer_init(const char *env_var_name); +void grpc_tracer_shutdown(void); + +#endif /* GRPC_CORE_DEBUG_TRACE_H */ diff --git a/src/core/lib/http/format_request.c b/src/core/lib/http/format_request.c new file mode 100644 index 0000000000..ac9bb8aeb8 --- /dev/null +++ b/src/core/lib/http/format_request.c @@ -0,0 +1,120 @@ +/* + * + * Copyright 2015-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/http/format_request.h" + +#include +#include +#include + +#include +#include +#include +#include +#include "src/core/support/string.h" + +static void fill_common_header(const grpc_httpcli_request *request, + gpr_strvec *buf) { + size_t i; + gpr_strvec_add(buf, gpr_strdup(request->http.path)); + gpr_strvec_add(buf, gpr_strdup(" HTTP/1.0\r\n")); + /* just in case some crazy server really expects HTTP/1.1 */ + gpr_strvec_add(buf, gpr_strdup("Host: ")); + gpr_strvec_add(buf, gpr_strdup(request->host)); + gpr_strvec_add(buf, gpr_strdup("\r\n")); + gpr_strvec_add(buf, gpr_strdup("Connection: close\r\n")); + gpr_strvec_add(buf, + gpr_strdup("User-Agent: " GRPC_HTTPCLI_USER_AGENT "\r\n")); + /* user supplied headers */ + for (i = 0; i < request->http.hdr_count; i++) { + gpr_strvec_add(buf, gpr_strdup(request->http.hdrs[i].key)); + gpr_strvec_add(buf, gpr_strdup(": ")); + gpr_strvec_add(buf, gpr_strdup(request->http.hdrs[i].value)); + gpr_strvec_add(buf, gpr_strdup("\r\n")); + } +} + +gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request) { + gpr_strvec out; + char *flat; + size_t flat_len; + + gpr_strvec_init(&out); + gpr_strvec_add(&out, gpr_strdup("GET ")); + fill_common_header(request, &out); + gpr_strvec_add(&out, gpr_strdup("\r\n")); + + flat = gpr_strvec_flatten(&out, &flat_len); + gpr_strvec_destroy(&out); + + return gpr_slice_new(flat, flat_len, gpr_free); +} + +gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, + const char *body_bytes, + size_t body_size) { + gpr_strvec out; + char *tmp; + size_t out_len; + size_t i; + + gpr_strvec_init(&out); + + gpr_strvec_add(&out, gpr_strdup("POST ")); + fill_common_header(request, &out); + if (body_bytes) { + uint8_t has_content_type = 0; + for (i = 0; i < request->http.hdr_count; i++) { + if (strcmp(request->http.hdrs[i].key, "Content-Type") == 0) { + has_content_type = 1; + break; + } + } + if (!has_content_type) { + gpr_strvec_add(&out, gpr_strdup("Content-Type: text/plain\r\n")); + } + gpr_asprintf(&tmp, "Content-Length: %lu\r\n", (unsigned long)body_size); + gpr_strvec_add(&out, tmp); + } + gpr_strvec_add(&out, gpr_strdup("\r\n")); + tmp = gpr_strvec_flatten(&out, &out_len); + gpr_strvec_destroy(&out); + + if (body_bytes) { + tmp = gpr_realloc(tmp, out_len + body_size); + memcpy(tmp + out_len, body_bytes, body_size); + out_len += body_size; + } + + return gpr_slice_new(tmp, out_len, gpr_free); +} diff --git a/src/core/lib/http/format_request.h b/src/core/lib/http/format_request.h new file mode 100644 index 0000000000..dfd6fadbde --- /dev/null +++ b/src/core/lib/http/format_request.h @@ -0,0 +1,45 @@ +/* + * + * Copyright 2015-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_HTTP_FORMAT_REQUEST_H +#define GRPC_CORE_HTTP_FORMAT_REQUEST_H + +#include +#include "src/core/http/httpcli.h" + +gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request); +gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, + const char *body_bytes, + size_t body_size); + +#endif /* GRPC_CORE_HTTP_FORMAT_REQUEST_H */ diff --git a/src/core/lib/http/httpcli.c b/src/core/lib/http/httpcli.c new file mode 100644 index 0000000000..1c0d3336ea --- /dev/null +++ b/src/core/lib/http/httpcli.c @@ -0,0 +1,293 @@ +/* + * + * Copyright 2015-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/http/httpcli.h" +#include "src/core/iomgr/sockaddr.h" + +#include + +#include +#include +#include + +#include "src/core/http/format_request.h" +#include "src/core/http/parser.h" +#include "src/core/iomgr/endpoint.h" +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/tcp_client.h" +#include "src/core/support/string.h" + +typedef struct { + gpr_slice request_text; + grpc_http_parser parser; + grpc_resolved_addresses *addresses; + size_t next_address; + grpc_endpoint *ep; + char *host; + char *ssl_host_override; + gpr_timespec deadline; + int have_read_byte; + const grpc_httpcli_handshaker *handshaker; + grpc_httpcli_response_cb on_response; + void *user_data; + grpc_httpcli_context *context; + grpc_pollset *pollset; + grpc_iomgr_object iomgr_obj; + gpr_slice_buffer incoming; + gpr_slice_buffer outgoing; + grpc_closure on_read; + grpc_closure done_write; + grpc_closure connected; +} internal_request; + +static grpc_httpcli_get_override g_get_override = NULL; +static grpc_httpcli_post_override g_post_override = NULL; + +static void plaintext_handshake(grpc_exec_ctx *exec_ctx, void *arg, + grpc_endpoint *endpoint, const char *host, + void (*on_done)(grpc_exec_ctx *exec_ctx, + void *arg, + grpc_endpoint *endpoint)) { + on_done(exec_ctx, arg, endpoint); +} + +const grpc_httpcli_handshaker grpc_httpcli_plaintext = {"http", + plaintext_handshake}; + +void grpc_httpcli_context_init(grpc_httpcli_context *context) { + context->pollset_set = grpc_pollset_set_create(); +} + +void grpc_httpcli_context_destroy(grpc_httpcli_context *context) { + grpc_pollset_set_destroy(context->pollset_set); +} + +static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req); + +static void finish(grpc_exec_ctx *exec_ctx, internal_request *req, + int success) { + grpc_pollset_set_del_pollset(exec_ctx, req->context->pollset_set, + req->pollset); + req->on_response(exec_ctx, req->user_data, + success ? &req->parser.http.response : NULL); + grpc_http_parser_destroy(&req->parser); + if (req->addresses != NULL) { + grpc_resolved_addresses_destroy(req->addresses); + } + if (req->ep != NULL) { + grpc_endpoint_destroy(exec_ctx, req->ep); + } + gpr_slice_unref(req->request_text); + gpr_free(req->host); + gpr_free(req->ssl_host_override); + grpc_iomgr_unregister_object(&req->iomgr_obj); + gpr_slice_buffer_destroy(&req->incoming); + gpr_slice_buffer_destroy(&req->outgoing); + gpr_free(req); +} + +static void on_read(grpc_exec_ctx *exec_ctx, void *user_data, bool success); + +static void do_read(grpc_exec_ctx *exec_ctx, internal_request *req) { + grpc_endpoint_read(exec_ctx, req->ep, &req->incoming, &req->on_read); +} + +static void on_read(grpc_exec_ctx *exec_ctx, void *user_data, bool success) { + internal_request *req = user_data; + size_t i; + + for (i = 0; i < req->incoming.count; i++) { + if (GPR_SLICE_LENGTH(req->incoming.slices[i])) { + req->have_read_byte = 1; + if (!grpc_http_parser_parse(&req->parser, req->incoming.slices[i])) { + finish(exec_ctx, req, 0); + return; + } + } + } + + if (success) { + do_read(exec_ctx, req); + } else if (!req->have_read_byte) { + next_address(exec_ctx, req); + } else { + int parse_success = grpc_http_parser_eof(&req->parser); + if (parse_success && (req->parser.type != GRPC_HTTP_RESPONSE)) { + parse_success = 0; + } + finish(exec_ctx, req, parse_success); + } +} + +static void on_written(grpc_exec_ctx *exec_ctx, internal_request *req) { + do_read(exec_ctx, req); +} + +static void done_write(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + internal_request *req = arg; + if (success) { + on_written(exec_ctx, req); + } else { + next_address(exec_ctx, req); + } +} + +static void start_write(grpc_exec_ctx *exec_ctx, internal_request *req) { + gpr_slice_ref(req->request_text); + gpr_slice_buffer_add(&req->outgoing, req->request_text); + grpc_endpoint_write(exec_ctx, req->ep, &req->outgoing, &req->done_write); +} + +static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, + grpc_endpoint *ep) { + internal_request *req = arg; + + if (!ep) { + next_address(exec_ctx, req); + return; + } + + req->ep = ep; + start_write(exec_ctx, req); +} + +static void on_connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + internal_request *req = arg; + + if (!req->ep) { + next_address(exec_ctx, req); + return; + } + req->handshaker->handshake( + exec_ctx, req, req->ep, + req->ssl_host_override ? req->ssl_host_override : req->host, + on_handshake_done); +} + +static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req) { + grpc_resolved_address *addr; + if (req->next_address == req->addresses->naddrs) { + finish(exec_ctx, req, 0); + return; + } + addr = &req->addresses->addrs[req->next_address++]; + grpc_closure_init(&req->connected, on_connected, req); + grpc_tcp_client_connect( + exec_ctx, &req->connected, &req->ep, req->context->pollset_set, + (struct sockaddr *)&addr->addr, addr->len, req->deadline); +} + +static void on_resolved(grpc_exec_ctx *exec_ctx, void *arg, + grpc_resolved_addresses *addresses) { + internal_request *req = arg; + if (!addresses) { + finish(exec_ctx, req, 0); + return; + } + req->addresses = addresses; + req->next_address = 0; + next_address(exec_ctx, req); +} + +static void internal_request_begin( + grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, + grpc_pollset *pollset, const grpc_httpcli_request *request, + gpr_timespec deadline, grpc_httpcli_response_cb on_response, + void *user_data, const char *name, gpr_slice request_text) { + internal_request *req = gpr_malloc(sizeof(internal_request)); + memset(req, 0, sizeof(*req)); + req->request_text = request_text; + grpc_http_parser_init(&req->parser); + req->on_response = on_response; + req->user_data = user_data; + req->deadline = deadline; + req->handshaker = + request->handshaker ? request->handshaker : &grpc_httpcli_plaintext; + req->context = context; + req->pollset = pollset; + grpc_closure_init(&req->on_read, on_read, req); + grpc_closure_init(&req->done_write, done_write, req); + gpr_slice_buffer_init(&req->incoming); + gpr_slice_buffer_init(&req->outgoing); + grpc_iomgr_register_object(&req->iomgr_obj, name); + req->host = gpr_strdup(request->host); + req->ssl_host_override = gpr_strdup(request->ssl_host_override); + + grpc_pollset_set_add_pollset(exec_ctx, req->context->pollset_set, + req->pollset); + grpc_resolve_address(request->host, req->handshaker->default_port, + on_resolved, req); +} + +void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, + grpc_pollset *pollset, + const grpc_httpcli_request *request, + gpr_timespec deadline, + grpc_httpcli_response_cb on_response, void *user_data) { + char *name; + if (g_get_override && + g_get_override(exec_ctx, request, deadline, on_response, user_data)) { + return; + } + gpr_asprintf(&name, "HTTP:GET:%s:%s", request->host, request->http.path); + internal_request_begin(exec_ctx, context, pollset, request, deadline, + on_response, user_data, name, + grpc_httpcli_format_get_request(request)); + gpr_free(name); +} + +void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, + grpc_pollset *pollset, + const grpc_httpcli_request *request, + const char *body_bytes, size_t body_size, + gpr_timespec deadline, + grpc_httpcli_response_cb on_response, void *user_data) { + char *name; + if (g_post_override && + g_post_override(exec_ctx, request, body_bytes, body_size, deadline, + on_response, user_data)) { + return; + } + gpr_asprintf(&name, "HTTP:POST:%s:%s", request->host, request->http.path); + internal_request_begin( + exec_ctx, context, pollset, request, deadline, on_response, user_data, + name, grpc_httpcli_format_post_request(request, body_bytes, body_size)); + gpr_free(name); +} + +void grpc_httpcli_set_override(grpc_httpcli_get_override get, + grpc_httpcli_post_override post) { + g_get_override = get; + g_post_override = post; +} diff --git a/src/core/lib/http/httpcli.h b/src/core/lib/http/httpcli.h new file mode 100644 index 0000000000..0bf4f2f445 --- /dev/null +++ b/src/core/lib/http/httpcli.h @@ -0,0 +1,144 @@ +/* + * + * Copyright 2015-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_HTTP_HTTPCLI_H +#define GRPC_CORE_HTTP_HTTPCLI_H + +#include + +#include + +#include "src/core/http/parser.h" +#include "src/core/iomgr/endpoint.h" +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/pollset_set.h" + +/* User agent this library reports */ +#define GRPC_HTTPCLI_USER_AGENT "grpc-httpcli/0.0" + +/* Tracks in-progress http requests + TODO(ctiller): allow caching and capturing multiple requests for the + same content and combining them */ +typedef struct grpc_httpcli_context { + grpc_pollset_set *pollset_set; +} grpc_httpcli_context; + +typedef struct { + const char *default_port; + void (*handshake)(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *endpoint, + const char *host, + void (*on_done)(grpc_exec_ctx *exec_ctx, void *arg, + grpc_endpoint *endpoint)); +} grpc_httpcli_handshaker; + +extern const grpc_httpcli_handshaker grpc_httpcli_plaintext; +extern const grpc_httpcli_handshaker grpc_httpcli_ssl; + +/* A request */ +typedef struct grpc_httpcli_request { + /* The host name to connect to */ + char *host; + /* The host to verify in the SSL handshake (or NULL) */ + char *ssl_host_override; + /* The main part of the request + The following headers are supplied automatically and MUST NOT be set here: + Host, Connection, User-Agent */ + grpc_http_request http; + /* handshaker to use ssl for the request */ + const grpc_httpcli_handshaker *handshaker; +} grpc_httpcli_request; + +/* Expose the parser response type as a httpcli response too */ +typedef struct grpc_http_response grpc_httpcli_response; + +/* Callback for grpc_httpcli_get and grpc_httpcli_post. */ +typedef void (*grpc_httpcli_response_cb)(grpc_exec_ctx *exec_ctx, + void *user_data, + const grpc_http_response *response); + +void grpc_httpcli_context_init(grpc_httpcli_context *context); +void grpc_httpcli_context_destroy(grpc_httpcli_context *context); + +/* Asynchronously perform a HTTP GET. + 'context' specifies the http context under which to do the get + 'pollset' indicates a grpc_pollset that is interested in the result + of the get - work on this pollset may be used to progress the get + operation + 'request' contains request parameters - these are caller owned and can be + destroyed once the call returns + 'deadline' contains a deadline for the request (or gpr_inf_future) + 'on_response' is a callback to report results to (and 'user_data' is a user + supplied pointer to pass to said call) */ +void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, + grpc_pollset *pollset, + const grpc_httpcli_request *request, + gpr_timespec deadline, + grpc_httpcli_response_cb on_response, void *user_data); + +/* Asynchronously perform a HTTP POST. + 'context' specifies the http context under which to do the post + 'pollset' indicates a grpc_pollset that is interested in the result + of the post - work on this pollset may be used to progress the post + operation + 'request' contains request parameters - these are caller owned and can be + destroyed once the call returns + 'body_bytes' and 'body_size' specify the payload for the post. + When there is no body, pass in NULL as body_bytes. + 'deadline' contains a deadline for the request (or gpr_inf_future) + 'em' points to a caller owned event manager that must be alive for the + lifetime of the request + 'on_response' is a callback to report results to (and 'user_data' is a user + supplied pointer to pass to said call) + Does not support ?var1=val1&var2=val2 in the path. */ +void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, + grpc_pollset *pollset, + const grpc_httpcli_request *request, + const char *body_bytes, size_t body_size, + gpr_timespec deadline, + grpc_httpcli_response_cb on_response, void *user_data); + +/* override functions return 1 if they handled the request, 0 otherwise */ +typedef int (*grpc_httpcli_get_override)(grpc_exec_ctx *exec_ctx, + const grpc_httpcli_request *request, + gpr_timespec deadline, + grpc_httpcli_response_cb on_response, + void *user_data); +typedef int (*grpc_httpcli_post_override)( + grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, + const char *body_bytes, size_t body_size, gpr_timespec deadline, + grpc_httpcli_response_cb on_response, void *user_data); + +void grpc_httpcli_set_override(grpc_httpcli_get_override get, + grpc_httpcli_post_override post); + +#endif /* GRPC_CORE_HTTP_HTTPCLI_H */ diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c new file mode 100644 index 0000000000..a1a32f7558 --- /dev/null +++ b/src/core/lib/http/httpcli_security_connector.c @@ -0,0 +1,188 @@ +/* + * + * Copyright 2015-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/http/httpcli.h" + +#include + +#include +#include +#include +#include "src/core/security/handshake.h" +#include "src/core/support/string.h" +#include "src/core/tsi/ssl_transport_security.h" + +typedef struct { + grpc_channel_security_connector base; + tsi_ssl_handshaker_factory *handshaker_factory; + char *secure_peer_name; +} grpc_httpcli_ssl_channel_security_connector; + +static void httpcli_ssl_destroy(grpc_security_connector *sc) { + grpc_httpcli_ssl_channel_security_connector *c = + (grpc_httpcli_ssl_channel_security_connector *)sc; + if (c->handshaker_factory != NULL) { + tsi_ssl_handshaker_factory_destroy(c->handshaker_factory); + } + if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name); + gpr_free(sc); +} + +static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, + grpc_channel_security_connector *sc, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *user_data) { + grpc_httpcli_ssl_channel_security_connector *c = + (grpc_httpcli_ssl_channel_security_connector *)sc; + tsi_result result = TSI_OK; + tsi_handshaker *handshaker; + if (c->handshaker_factory == NULL) { + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); + return; + } + result = tsi_ssl_handshaker_factory_create_handshaker( + c->handshaker_factory, c->secure_peer_name, &handshaker); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); + } else { + grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true, + nonsecure_endpoint, cb, user_data); + } +} + +static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx, + grpc_security_connector *sc, tsi_peer peer, + grpc_security_peer_check_cb cb, + void *user_data) { + grpc_httpcli_ssl_channel_security_connector *c = + (grpc_httpcli_ssl_channel_security_connector *)sc; + grpc_security_status status = GRPC_SECURITY_OK; + + /* Check the peer name. */ + if (c->secure_peer_name != NULL && + !tsi_ssl_peer_matches_name(&peer, c->secure_peer_name)) { + gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", + c->secure_peer_name); + status = GRPC_SECURITY_ERROR; + } + cb(exec_ctx, user_data, status, NULL); + tsi_peer_destruct(&peer); +} + +static grpc_security_connector_vtable httpcli_ssl_vtable = { + httpcli_ssl_destroy, httpcli_ssl_check_peer}; + +static grpc_security_status httpcli_ssl_channel_security_connector_create( + const unsigned char *pem_root_certs, size_t pem_root_certs_size, + const char *secure_peer_name, grpc_channel_security_connector **sc) { + tsi_result result = TSI_OK; + grpc_httpcli_ssl_channel_security_connector *c; + + if (secure_peer_name != NULL && pem_root_certs == NULL) { + gpr_log(GPR_ERROR, + "Cannot assert a secure peer name without a trust root."); + return GRPC_SECURITY_ERROR; + } + + c = gpr_malloc(sizeof(grpc_httpcli_ssl_channel_security_connector)); + memset(c, 0, sizeof(grpc_httpcli_ssl_channel_security_connector)); + + gpr_ref_init(&c->base.base.refcount, 1); + c->base.base.vtable = &httpcli_ssl_vtable; + if (secure_peer_name != NULL) { + c->secure_peer_name = gpr_strdup(secure_peer_name); + } + result = tsi_create_ssl_client_handshaker_factory( + NULL, 0, NULL, 0, pem_root_certs, pem_root_certs_size, NULL, NULL, NULL, + 0, &c->handshaker_factory); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + httpcli_ssl_destroy(&c->base.base); + *sc = NULL; + return GRPC_SECURITY_ERROR; + } + c->base.do_handshake = httpcli_ssl_do_handshake; + *sc = &c->base; + return GRPC_SECURITY_OK; +} + +/* handshaker */ + +typedef struct { + void (*func)(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *endpoint); + void *arg; +} on_done_closure; + +static void on_secure_transport_setup_done(grpc_exec_ctx *exec_ctx, void *rp, + grpc_security_status status, + grpc_endpoint *secure_endpoint, + grpc_auth_context *auth_context) { + on_done_closure *c = rp; + if (status != GRPC_SECURITY_OK) { + gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status); + c->func(exec_ctx, c->arg, NULL); + } else { + c->func(exec_ctx, c->arg, secure_endpoint); + } + gpr_free(c); +} + +static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg, + grpc_endpoint *tcp, const char *host, + void (*on_done)(grpc_exec_ctx *exec_ctx, void *arg, + grpc_endpoint *endpoint)) { + grpc_channel_security_connector *sc = NULL; + const unsigned char *pem_root_certs = NULL; + on_done_closure *c = gpr_malloc(sizeof(*c)); + size_t pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs); + if (pem_root_certs == NULL || pem_root_certs_size == 0) { + gpr_log(GPR_ERROR, "Could not get default pem root certs."); + on_done(exec_ctx, arg, NULL); + gpr_free(c); + return; + } + c->func = on_done; + c->arg = arg; + GPR_ASSERT(httpcli_ssl_channel_security_connector_create( + pem_root_certs, pem_root_certs_size, host, &sc) == + GRPC_SECURITY_OK); + grpc_channel_security_connector_do_handshake( + exec_ctx, sc, tcp, on_secure_transport_setup_done, c); + GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); +} + +const grpc_httpcli_handshaker grpc_httpcli_ssl = {"https", ssl_handshake}; diff --git a/src/core/lib/http/parser.c b/src/core/lib/http/parser.c new file mode 100644 index 0000000000..ebec8a5157 --- /dev/null +++ b/src/core/lib/http/parser.c @@ -0,0 +1,313 @@ +/* + * + * Copyright 2015-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/http/parser.h" + +#include + +#include +#include +#include + +static char *buf2str(void *buffer, size_t length) { + char *out = gpr_malloc(length + 1); + memcpy(out, buffer, length); + out[length] = 0; + return out; +} + +static int handle_response_line(grpc_http_parser *parser) { + uint8_t *beg = parser->cur_line; + uint8_t *cur = beg; + uint8_t *end = beg + parser->cur_line_length; + + if (cur == end || *cur++ != 'H') goto error; + if (cur == end || *cur++ != 'T') goto error; + if (cur == end || *cur++ != 'T') goto error; + if (cur == end || *cur++ != 'P') goto error; + if (cur == end || *cur++ != '/') goto error; + if (cur == end || *cur++ != '1') goto error; + if (cur == end || *cur++ != '.') goto error; + if (cur == end || *cur < '0' || *cur++ > '1') goto error; + if (cur == end || *cur++ != ' ') goto error; + if (cur == end || *cur < '1' || *cur++ > '9') goto error; + if (cur == end || *cur < '0' || *cur++ > '9') goto error; + if (cur == end || *cur < '0' || *cur++ > '9') goto error; + parser->http.response.status = + (cur[-3] - '0') * 100 + (cur[-2] - '0') * 10 + (cur[-1] - '0'); + if (cur == end || *cur++ != ' ') goto error; + + /* we don't really care about the status code message */ + + return 1; + +error: + gpr_log(GPR_ERROR, "Failed parsing response line"); + return 0; +} + +static int handle_request_line(grpc_http_parser *parser) { + uint8_t *beg = parser->cur_line; + uint8_t *cur = beg; + uint8_t *end = beg + parser->cur_line_length; + uint8_t vers_major = 0; + uint8_t vers_minor = 0; + + while (cur != end && *cur++ != ' ') + ; + if (cur == end) goto error; + parser->http.request.method = buf2str(beg, (size_t)(cur - beg - 1)); + + beg = cur; + while (cur != end && *cur++ != ' ') + ; + if (cur == end) goto error; + parser->http.request.path = buf2str(beg, (size_t)(cur - beg - 1)); + + if (cur == end || *cur++ != 'H') goto error; + if (cur == end || *cur++ != 'T') goto error; + if (cur == end || *cur++ != 'T') goto error; + if (cur == end || *cur++ != 'P') goto error; + if (cur == end || *cur++ != '/') goto error; + vers_major = (uint8_t)(*cur++ - '1' + 1); + ++cur; + if (cur == end) goto error; + vers_minor = (uint8_t)(*cur++ - '1' + 1); + + if (vers_major == 1) { + if (vers_minor == 0) { + parser->http.request.version = GRPC_HTTP_HTTP10; + } else if (vers_minor == 1) { + parser->http.request.version = GRPC_HTTP_HTTP11; + } else { + goto error; + } + } else if (vers_major == 2) { + if (vers_minor == 0) { + parser->http.request.version = GRPC_HTTP_HTTP20; + } else { + goto error; + } + } else { + goto error; + } + + return 1; + +error: + gpr_log(GPR_ERROR, "Failed parsing request line"); + return 0; +} + +static int handle_first_line(grpc_http_parser *parser) { + if (parser->cur_line[0] == 'H') { + parser->type = GRPC_HTTP_RESPONSE; + return handle_response_line(parser); + } else { + parser->type = GRPC_HTTP_REQUEST; + return handle_request_line(parser); + } +} + +static int add_header(grpc_http_parser *parser) { + uint8_t *beg = parser->cur_line; + uint8_t *cur = beg; + uint8_t *end = beg + parser->cur_line_length; + size_t *hdr_count = NULL; + grpc_http_header **hdrs = NULL; + grpc_http_header hdr = {NULL, NULL}; + + GPR_ASSERT(cur != end); + + if (*cur == ' ' || *cur == '\t') { + gpr_log(GPR_ERROR, "Continued header lines not supported yet"); + goto error; + } + + while (cur != end && *cur != ':') { + cur++; + } + if (cur == end) { + gpr_log(GPR_ERROR, "Didn't find ':' in header string"); + goto error; + } + GPR_ASSERT(cur >= beg); + hdr.key = buf2str(beg, (size_t)(cur - beg)); + cur++; /* skip : */ + + while (cur != end && (*cur == ' ' || *cur == '\t')) { + cur++; + } + GPR_ASSERT(end - cur >= 2); + hdr.value = buf2str(cur, (size_t)(end - cur) - 2); + + if (parser->type == GRPC_HTTP_RESPONSE) { + hdr_count = &parser->http.response.hdr_count; + hdrs = &parser->http.response.hdrs; + } else if (parser->type == GRPC_HTTP_REQUEST) { + hdr_count = &parser->http.request.hdr_count; + hdrs = &parser->http.request.hdrs; + } else { + return 0; + } + + if (*hdr_count == parser->hdr_capacity) { + parser->hdr_capacity = + GPR_MAX(parser->hdr_capacity + 1, parser->hdr_capacity * 3 / 2); + *hdrs = gpr_realloc(*hdrs, parser->hdr_capacity * sizeof(**hdrs)); + } + (*hdrs)[(*hdr_count)++] = hdr; + return 1; + +error: + gpr_free(hdr.key); + gpr_free(hdr.value); + return 0; +} + +static int finish_line(grpc_http_parser *parser) { + switch (parser->state) { + case GRPC_HTTP_FIRST_LINE: + if (!handle_first_line(parser)) { + return 0; + } + parser->state = GRPC_HTTP_HEADERS; + break; + case GRPC_HTTP_HEADERS: + if (parser->cur_line_length == 2) { + parser->state = GRPC_HTTP_BODY; + break; + } + if (!add_header(parser)) { + return 0; + } + break; + case GRPC_HTTP_BODY: + GPR_UNREACHABLE_CODE(return 0); + } + + parser->cur_line_length = 0; + return 1; +} + +static int addbyte_body(grpc_http_parser *parser, uint8_t byte) { + size_t *body_length = NULL; + char **body = NULL; + + if (parser->type == GRPC_HTTP_RESPONSE) { + body_length = &parser->http.response.body_length; + body = &parser->http.response.body; + } else if (parser->type == GRPC_HTTP_REQUEST) { + body_length = &parser->http.request.body_length; + body = &parser->http.request.body; + } else { + return 0; + } + + if (*body_length == parser->body_capacity) { + parser->body_capacity = GPR_MAX(8, parser->body_capacity * 3 / 2); + *body = gpr_realloc((void *)*body, parser->body_capacity); + } + (*body)[*body_length] = (char)byte; + (*body_length)++; + + return 1; +} + +static int addbyte(grpc_http_parser *parser, uint8_t byte) { + switch (parser->state) { + case GRPC_HTTP_FIRST_LINE: + case GRPC_HTTP_HEADERS: + if (parser->cur_line_length >= GRPC_HTTP_PARSER_MAX_HEADER_LENGTH) { + gpr_log(GPR_ERROR, "HTTP client max line length (%d) exceeded", + GRPC_HTTP_PARSER_MAX_HEADER_LENGTH); + return 0; + } + parser->cur_line[parser->cur_line_length] = byte; + parser->cur_line_length++; + if (parser->cur_line_length >= 2 && + parser->cur_line[parser->cur_line_length - 2] == '\r' && + parser->cur_line[parser->cur_line_length - 1] == '\n') { + return finish_line(parser); + } else { + return 1; + } + GPR_UNREACHABLE_CODE(return 0); + case GRPC_HTTP_BODY: + return addbyte_body(parser, byte); + } + GPR_UNREACHABLE_CODE(return 0); +} + +void grpc_http_parser_init(grpc_http_parser *parser) { + memset(parser, 0, sizeof(*parser)); + parser->state = GRPC_HTTP_FIRST_LINE; + parser->type = GRPC_HTTP_UNKNOWN; +} + +void grpc_http_parser_destroy(grpc_http_parser *parser) { + size_t i; + if (parser->type == GRPC_HTTP_RESPONSE) { + gpr_free(parser->http.response.body); + for (i = 0; i < parser->http.response.hdr_count; i++) { + gpr_free(parser->http.response.hdrs[i].key); + gpr_free(parser->http.response.hdrs[i].value); + } + gpr_free(parser->http.response.hdrs); + } else if (parser->type == GRPC_HTTP_REQUEST) { + gpr_free(parser->http.request.body); + for (i = 0; i < parser->http.request.hdr_count; i++) { + gpr_free(parser->http.request.hdrs[i].key); + gpr_free(parser->http.request.hdrs[i].value); + } + gpr_free(parser->http.request.hdrs); + gpr_free(parser->http.request.method); + gpr_free(parser->http.request.path); + } +} + +int grpc_http_parser_parse(grpc_http_parser *parser, gpr_slice slice) { + size_t i; + + for (i = 0; i < GPR_SLICE_LENGTH(slice); i++) { + if (!addbyte(parser, GPR_SLICE_START_PTR(slice)[i])) { + return 0; + } + } + + return 1; +} + +int grpc_http_parser_eof(grpc_http_parser *parser) { + return parser->state == GRPC_HTTP_BODY; +} diff --git a/src/core/lib/http/parser.h b/src/core/lib/http/parser.h new file mode 100644 index 0000000000..39517e485a --- /dev/null +++ b/src/core/lib/http/parser.h @@ -0,0 +1,116 @@ +/* + * + * Copyright 2015-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_HTTP_PARSER_H +#define GRPC_CORE_HTTP_PARSER_H + +#include +#include + +/* Maximum length of a header string of the form 'Key: Value\r\n' */ +#define GRPC_HTTP_PARSER_MAX_HEADER_LENGTH 4096 + +/* A single header to be passed in a request */ +typedef struct grpc_http_header { + char *key; + char *value; +} grpc_http_header; + +typedef enum { + GRPC_HTTP_FIRST_LINE, + GRPC_HTTP_HEADERS, + GRPC_HTTP_BODY +} grpc_http_parser_state; + +typedef enum { + GRPC_HTTP_HTTP10, + GRPC_HTTP_HTTP11, + GRPC_HTTP_HTTP20, +} grpc_http_version; + +typedef enum { + GRPC_HTTP_RESPONSE, + GRPC_HTTP_REQUEST, + GRPC_HTTP_UNKNOWN +} grpc_http_type; + +/* A request */ +typedef struct grpc_http_request { + /* Method of the request (e.g. GET, POST) */ + char *method; + /* The path of the resource to fetch */ + char *path; + /* HTTP version to use */ + grpc_http_version version; + /* Headers attached to the request */ + size_t hdr_count; + grpc_http_header *hdrs; + /* Body: length and contents; contents are NOT null-terminated */ + size_t body_length; + char *body; +} grpc_http_request; + +/* A response */ +typedef struct grpc_http_response { + /* HTTP status code */ + int status; + /* Headers: count and key/values */ + size_t hdr_count; + grpc_http_header *hdrs; + /* Body: length and contents; contents are NOT null-terminated */ + size_t body_length; + char *body; +} grpc_http_response; + +typedef struct { + grpc_http_parser_state state; + grpc_http_type type; + + union { + grpc_http_response response; + grpc_http_request request; + } http; + size_t body_capacity; + size_t hdr_capacity; + + uint8_t cur_line[GRPC_HTTP_PARSER_MAX_HEADER_LENGTH]; + size_t cur_line_length; +} grpc_http_parser; + +void grpc_http_parser_init(grpc_http_parser *parser); +void grpc_http_parser_destroy(grpc_http_parser *parser); + +int grpc_http_parser_parse(grpc_http_parser *parser, gpr_slice slice); +int grpc_http_parser_eof(grpc_http_parser *parser); + +#endif /* GRPC_CORE_HTTP_PARSER_H */ diff --git a/src/core/lib/iomgr/closure.c b/src/core/lib/iomgr/closure.c new file mode 100644 index 0000000000..3a96f7385f --- /dev/null +++ b/src/core/lib/iomgr/closure.c @@ -0,0 +1,98 @@ +/* + * + * Copyright 2015-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/iomgr/closure.h" + +#include + +void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb, + void *cb_arg) { + closure->cb = cb; + closure->cb_arg = cb_arg; + closure->final_data = 0; +} + +void grpc_closure_list_add(grpc_closure_list *closure_list, + grpc_closure *closure, bool success) { + if (closure == NULL) return; + closure->final_data = (success != 0); + if (closure_list->head == NULL) { + closure_list->head = closure; + } else { + closure_list->tail->final_data |= (uintptr_t)closure; + } + closure_list->tail = closure; +} + +bool grpc_closure_list_empty(grpc_closure_list closure_list) { + return closure_list.head == NULL; +} + +void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst) { + if (src->head == NULL) { + return; + } + if (dst->head == NULL) { + *dst = *src; + } else { + dst->tail->final_data |= (uintptr_t)src->head; + dst->tail = src->tail; + } + src->head = src->tail = NULL; +} + +typedef struct { + grpc_iomgr_cb_func cb; + void *cb_arg; + grpc_closure wrapper; +} wrapped_closure; + +static void closure_wrapper(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + wrapped_closure *wc = arg; + grpc_iomgr_cb_func cb = wc->cb; + void *cb_arg = wc->cb_arg; + gpr_free(wc); + cb(exec_ctx, cb_arg, success); +} + +grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg) { + wrapped_closure *wc = gpr_malloc(sizeof(*wc)); + wc->cb = cb; + wc->cb_arg = cb_arg; + grpc_closure_init(&wc->wrapper, closure_wrapper, wc); + return &wc->wrapper; +} + +grpc_closure *grpc_closure_next(grpc_closure *closure) { + return (grpc_closure *)(closure->final_data & ~(uintptr_t)1); +} diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h new file mode 100644 index 0000000000..d5e1f455b9 --- /dev/null +++ b/src/core/lib/iomgr/closure.h @@ -0,0 +1,98 @@ +/* + * + * Copyright 2015-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_IOMGR_CLOSURE_H +#define GRPC_CORE_IOMGR_CLOSURE_H + +#include +#include + +struct grpc_closure; +typedef struct grpc_closure grpc_closure; + +/* forward declaration for exec_ctx.h */ +struct grpc_exec_ctx; +typedef struct grpc_exec_ctx grpc_exec_ctx; + +typedef struct grpc_closure_list { + grpc_closure *head; + grpc_closure *tail; +} grpc_closure_list; + +/** gRPC Callback definition. + * + * \param arg Arbitrary input. + * \param success An indication on the state of the iomgr. On false, cleanup + * actions should be taken (eg, shutdown). */ +typedef void (*grpc_iomgr_cb_func)(grpc_exec_ctx *exec_ctx, void *arg, + bool success); + +/** A closure over a grpc_iomgr_cb_func. */ +struct grpc_closure { + /** Bound callback. */ + grpc_iomgr_cb_func cb; + + /** Arguments to be passed to "cb". */ + void *cb_arg; + + /** Once enqueued, contains in the lower bit the success of the closure, + and in the upper bits the pointer to the next closure in the list. + Before enqueing for execution, this is usable for scratch data. */ + uintptr_t final_data; +}; + +/** Initializes \a closure with \a cb and \a cb_arg. */ +void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb, + void *cb_arg); + +/* Create a heap allocated closure: try to avoid except for very rare events */ +grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg); + +#define GRPC_CLOSURE_LIST_INIT \ + { NULL, NULL } + +/** add \a closure to the end of \a list and set \a closure's success to \a + * success */ +void grpc_closure_list_add(grpc_closure_list *list, grpc_closure *closure, + bool success); + +/** append all closures from \a src to \a dst and empty \a src. */ +void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst); + +/** return whether \a list is empty. */ +bool grpc_closure_list_empty(grpc_closure_list list); + +/** return the next pointer for a queued closure list */ +grpc_closure *grpc_closure_next(grpc_closure *closure); + +#endif /* GRPC_CORE_IOMGR_CLOSURE_H */ diff --git a/src/core/lib/iomgr/endpoint.c b/src/core/lib/iomgr/endpoint.c new file mode 100644 index 0000000000..bd64707669 --- /dev/null +++ b/src/core/lib/iomgr/endpoint.c @@ -0,0 +1,67 @@ +/* + * + * Copyright 2015, 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/iomgr/endpoint.h" + +void grpc_endpoint_read(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep, + gpr_slice_buffer* slices, grpc_closure* cb) { + ep->vtable->read(exec_ctx, ep, slices, cb); +} + +void grpc_endpoint_write(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep, + gpr_slice_buffer* slices, grpc_closure* cb) { + ep->vtable->write(exec_ctx, ep, slices, cb); +} + +void grpc_endpoint_add_to_pollset(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep, + grpc_pollset* pollset) { + ep->vtable->add_to_pollset(exec_ctx, ep, pollset); +} + +void grpc_endpoint_add_to_pollset_set(grpc_exec_ctx* exec_ctx, + grpc_endpoint* ep, + grpc_pollset_set* pollset_set) { + ep->vtable->add_to_pollset_set(exec_ctx, ep, pollset_set); +} + +void grpc_endpoint_shutdown(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep) { + ep->vtable->shutdown(exec_ctx, ep); +} + +void grpc_endpoint_destroy(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep) { + ep->vtable->destroy(exec_ctx, ep); +} + +char* grpc_endpoint_get_peer(grpc_endpoint* ep) { + return ep->vtable->get_peer(ep); +} diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h new file mode 100644 index 0000000000..b4be852e33 --- /dev/null +++ b/src/core/lib/iomgr/endpoint.h @@ -0,0 +1,102 @@ +/* + * + * Copyright 2015-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_IOMGR_ENDPOINT_H +#define GRPC_CORE_IOMGR_ENDPOINT_H + +#include +#include +#include +#include "src/core/iomgr/pollset.h" +#include "src/core/iomgr/pollset_set.h" + +/* An endpoint caps a streaming channel between two communicating processes. + Examples may be: a tcp socket, , or some shared memory. */ + +typedef struct grpc_endpoint grpc_endpoint; +typedef struct grpc_endpoint_vtable grpc_endpoint_vtable; + +struct grpc_endpoint_vtable { + void (*read)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + gpr_slice_buffer *slices, grpc_closure *cb); + void (*write)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + gpr_slice_buffer *slices, grpc_closure *cb); + void (*add_to_pollset)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + grpc_pollset *pollset); + void (*add_to_pollset_set)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + grpc_pollset_set *pollset); + void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep); + void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep); + char *(*get_peer)(grpc_endpoint *ep); +}; + +/* When data is available on the connection, calls the callback with slices. + Callback success indicates that the endpoint can accept more reads, failure + indicates the endpoint is closed. + Valid slices may be placed into \a slices even on callback success == 0. */ +void grpc_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + gpr_slice_buffer *slices, grpc_closure *cb); + +char *grpc_endpoint_get_peer(grpc_endpoint *ep); + +/* Write slices out to the socket. + + If the connection is ready for more data after the end of the call, it + returns GRPC_ENDPOINT_DONE. + Otherwise it returns GRPC_ENDPOINT_PENDING and calls cb when the + connection is ready for more data. + \a slices may be mutated at will by the endpoint until cb is called. + No guarantee is made to the content of slices after a write EXCEPT that + it is a valid slice buffer. + */ +void grpc_endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + gpr_slice_buffer *slices, grpc_closure *cb); + +/* Causes any pending read/write callbacks to run immediately with + success==0 */ +void grpc_endpoint_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep); +void grpc_endpoint_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep); + +/* Add an endpoint to a pollset, so that when the pollset is polled, events from + this endpoint are considered */ +void grpc_endpoint_add_to_pollset(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + grpc_pollset *pollset); +void grpc_endpoint_add_to_pollset_set(grpc_exec_ctx *exec_ctx, + grpc_endpoint *ep, + grpc_pollset_set *pollset_set); + +struct grpc_endpoint { + const grpc_endpoint_vtable *vtable; +}; + +#endif /* GRPC_CORE_IOMGR_ENDPOINT_H */ diff --git a/src/core/lib/iomgr/endpoint_pair.h b/src/core/lib/iomgr/endpoint_pair.h new file mode 100644 index 0000000000..59015d8ffb --- /dev/null +++ b/src/core/lib/iomgr/endpoint_pair.h @@ -0,0 +1,47 @@ +/* + * + * Copyright 2015-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_IOMGR_ENDPOINT_PAIR_H +#define GRPC_CORE_IOMGR_ENDPOINT_PAIR_H + +#include "src/core/iomgr/endpoint.h" + +typedef struct { + grpc_endpoint *client; + grpc_endpoint *server; +} grpc_endpoint_pair; + +grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name, + size_t read_slice_size); + +#endif /* GRPC_CORE_IOMGR_ENDPOINT_PAIR_H */ diff --git a/src/core/lib/iomgr/endpoint_pair_posix.c b/src/core/lib/iomgr/endpoint_pair_posix.c new file mode 100644 index 0000000000..66d19a486c --- /dev/null +++ b/src/core/lib/iomgr/endpoint_pair_posix.c @@ -0,0 +1,83 @@ +/* + * + * 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 + +#ifdef GPR_POSIX_SOCKET + +#include "src/core/iomgr/endpoint_pair.h" +#include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/iomgr/unix_sockets_posix.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include "src/core/iomgr/tcp_posix.h" +#include "src/core/support/string.h" + +static void create_sockets(int sv[2]) { + int flags; + grpc_create_socketpair_if_unix(sv); + flags = fcntl(sv[0], F_GETFL, 0); + GPR_ASSERT(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK) == 0); + flags = fcntl(sv[1], F_GETFL, 0); + GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0); + GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv[0])); + GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv[1])); +} + +grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name, + size_t read_slice_size) { + int sv[2]; + grpc_endpoint_pair p; + char *final_name; + create_sockets(sv); + + gpr_asprintf(&final_name, "%s:client", name); + p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name), read_slice_size, + "socketpair-server"); + gpr_free(final_name); + gpr_asprintf(&final_name, "%s:server", name); + p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name), read_slice_size, + "socketpair-client"); + gpr_free(final_name); + return p; +} + +#endif diff --git a/src/core/lib/iomgr/endpoint_pair_windows.c b/src/core/lib/iomgr/endpoint_pair_windows.c new file mode 100644 index 0000000000..2024f58143 --- /dev/null +++ b/src/core/lib/iomgr/endpoint_pair_windows.c @@ -0,0 +1,97 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_WINSOCK_SOCKET +#include "src/core/iomgr/endpoint_pair.h" +#include "src/core/iomgr/sockaddr_utils.h" + +#include +#include +#include + +#include +#include "src/core/iomgr/socket_windows.h" +#include "src/core/iomgr/tcp_windows.h" + +static void create_sockets(SOCKET sv[2]) { + SOCKET svr_sock = INVALID_SOCKET; + SOCKET lst_sock = INVALID_SOCKET; + SOCKET cli_sock = INVALID_SOCKET; + SOCKADDR_IN addr; + int addr_len = sizeof(addr); + + lst_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED); + GPR_ASSERT(lst_sock != INVALID_SOCKET); + + memset(&addr, 0, sizeof(addr)); + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_family = AF_INET; + GPR_ASSERT(bind(lst_sock, (struct sockaddr *)&addr, sizeof(addr)) != + SOCKET_ERROR); + GPR_ASSERT(listen(lst_sock, SOMAXCONN) != SOCKET_ERROR); + GPR_ASSERT(getsockname(lst_sock, (struct sockaddr *)&addr, &addr_len) != + SOCKET_ERROR); + + cli_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED); + GPR_ASSERT(cli_sock != INVALID_SOCKET); + + GPR_ASSERT(WSAConnect(cli_sock, (struct sockaddr *)&addr, addr_len, NULL, + NULL, NULL, NULL) == 0); + svr_sock = accept(lst_sock, (struct sockaddr *)&addr, &addr_len); + GPR_ASSERT(svr_sock != INVALID_SOCKET); + + closesocket(lst_sock); + grpc_tcp_prepare_socket(cli_sock); + grpc_tcp_prepare_socket(svr_sock); + + sv[1] = cli_sock; + sv[0] = svr_sock; +} + +grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name, + size_t read_slice_size) { + SOCKET sv[2]; + grpc_endpoint_pair p; + create_sockets(sv); + p.client = grpc_tcp_create(grpc_winsocket_create(sv[1], "endpoint:client"), + "endpoint:server"); + p.server = grpc_tcp_create(grpc_winsocket_create(sv[0], "endpoint:server"), + "endpoint:client"); + return p; +} + +#endif diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c new file mode 100644 index 0000000000..893fe4515c --- /dev/null +++ b/src/core/lib/iomgr/exec_ctx.c @@ -0,0 +1,151 @@ +/* + * + * Copyright 2015-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/iomgr/exec_ctx.h" + +#include +#include +#include + +#include "src/core/profiling/timers.h" + +#ifndef GRPC_EXECUTION_CONTEXT_SANITIZER +bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { + bool did_something = 0; + GPR_TIMER_BEGIN("grpc_exec_ctx_flush", 0); + while (!grpc_closure_list_empty(exec_ctx->closure_list)) { + grpc_closure *c = exec_ctx->closure_list.head; + exec_ctx->closure_list.head = exec_ctx->closure_list.tail = NULL; + while (c != NULL) { + bool success = (bool)(c->final_data & 1); + grpc_closure *next = (grpc_closure *)(c->final_data & ~(uintptr_t)1); + did_something = true; + GPR_TIMER_BEGIN("grpc_exec_ctx_flush.cb", 0); + c->cb(exec_ctx, c->cb_arg, success); + GPR_TIMER_END("grpc_exec_ctx_flush.cb", 0); + c = next; + } + } + GPR_TIMER_END("grpc_exec_ctx_flush", 0); + return did_something; +} + +void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) { + grpc_exec_ctx_flush(exec_ctx); +} + +void grpc_exec_ctx_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure, + bool success, + grpc_workqueue *offload_target_or_null) { + GPR_ASSERT(offload_target_or_null == NULL); + grpc_closure_list_add(&exec_ctx->closure_list, closure, success); +} + +void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx, + grpc_closure_list *list, + grpc_workqueue *offload_target_or_null) { + GPR_ASSERT(offload_target_or_null == NULL); + grpc_closure_list_move(list, &exec_ctx->closure_list); +} + +void grpc_exec_ctx_global_init(void) {} +void grpc_exec_ctx_global_shutdown(void) {} +#else +static gpr_mu g_mu; +static gpr_cv g_cv; +static int g_threads = 0; + +static void run_closure(void *arg) { + grpc_closure *closure = arg; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + closure->cb(&exec_ctx, closure->cb_arg, (closure->final_data & 1) != 0); + grpc_exec_ctx_finish(&exec_ctx); + gpr_mu_lock(&g_mu); + if (--g_threads == 0) { + gpr_cv_signal(&g_cv); + } + gpr_mu_unlock(&g_mu); +} + +static void start_closure(grpc_closure *closure) { + gpr_thd_id id; + gpr_mu_lock(&g_mu); + g_threads++; + gpr_mu_unlock(&g_mu); + gpr_thd_new(&id, run_closure, closure, NULL); +} + +bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { return false; } + +void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) {} + +void grpc_exec_ctx_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure, + bool success, + grpc_workqueue *offload_target_or_null) { + GPR_ASSERT(offload_target_or_null == NULL); + if (closure == NULL) return; + closure->final_data = success; + start_closure(closure); +} + +void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx, + grpc_closure_list *list, + grpc_workqueue *offload_target_or_null) { + GPR_ASSERT(offload_target_or_null == NULL); + if (list == NULL) return; + grpc_closure *p = list->head; + while (p) { + grpc_closure *start = p; + p = grpc_closure_next(start); + start_closure(start); + } + grpc_closure_list r = GRPC_CLOSURE_LIST_INIT; + *list = r; +} + +void grpc_exec_ctx_global_init(void) { + gpr_mu_init(&g_mu); + gpr_cv_init(&g_cv); +} + +void grpc_exec_ctx_global_shutdown(void) { + gpr_mu_lock(&g_mu); + while (g_threads != 0) { + gpr_cv_wait(&g_cv, &g_mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + } + gpr_mu_unlock(&g_mu); + + gpr_mu_destroy(&g_mu); + gpr_cv_destroy(&g_cv); +} +#endif diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h new file mode 100644 index 0000000000..07b54a0ab8 --- /dev/null +++ b/src/core/lib/iomgr/exec_ctx.h @@ -0,0 +1,98 @@ +/* + * + * Copyright 2015-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_IOMGR_EXEC_CTX_H +#define GRPC_CORE_IOMGR_EXEC_CTX_H + +#include "src/core/iomgr/closure.h" + +/* #define GRPC_EXECUTION_CONTEXT_SANITIZER 1 */ + +/** A workqueue represents a list of work to be executed asynchronously. + Forward declared here to avoid a circular dependency with workqueue.h. */ +struct grpc_workqueue; +typedef struct grpc_workqueue grpc_workqueue; + +#ifndef GRPC_EXECUTION_CONTEXT_SANITIZER +/** Execution context. + * A bag of data that collects information along a callstack. + * Generally created at public API entry points, and passed down as + * pointer to child functions that manipulate it. + * + * Specific responsibilities (this may grow in the future): + * - track a list of work that needs to be delayed until the top of the + * call stack (this provides a convenient mechanism to run callbacks + * without worrying about locking issues) + * + * CONVENTIONS: + * Instance of this must ALWAYS be constructed on the stack, never + * heap allocated. Instances and pointers to them must always be called + * exec_ctx. Instances are always passed as the first argument + * to a function that takes it, and always as a pointer (grpc_exec_ctx + * is never copied). + */ +struct grpc_exec_ctx { + grpc_closure_list closure_list; +}; + +#define GRPC_EXEC_CTX_INIT \ + { GRPC_CLOSURE_LIST_INIT } +#else +struct grpc_exec_ctx { + int unused; +}; +#define GRPC_EXEC_CTX_INIT \ + { 0 } +#endif + +/** Flush any work that has been enqueued onto this grpc_exec_ctx. + * Caller must guarantee that no interfering locks are held. + * Returns true if work was performed, false otherwise. */ +bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx); +/** Finish any pending work for a grpc_exec_ctx. Must be called before + * the instance is destroyed, or work may be lost. */ +void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx); +/** Add a closure to be executed at the next flush/finish point */ +void grpc_exec_ctx_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure, + bool success, + grpc_workqueue *offload_target_or_null); +/** Add a list of closures to be executed at the next flush/finish point. + * Leaves \a list empty. */ +void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx, + grpc_closure_list *list, + grpc_workqueue *offload_target_or_null); + +void grpc_exec_ctx_global_init(void); +void grpc_exec_ctx_global_shutdown(void); + +#endif /* GRPC_CORE_IOMGR_EXEC_CTX_H */ diff --git a/src/core/lib/iomgr/executor.c b/src/core/lib/iomgr/executor.c new file mode 100644 index 0000000000..f22d8f30ac --- /dev/null +++ b/src/core/lib/iomgr/executor.c @@ -0,0 +1,143 @@ +/* + * + * Copyright 2015-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/iomgr/executor.h" + +#include + +#include +#include +#include +#include +#include "src/core/iomgr/exec_ctx.h" + +typedef struct grpc_executor_data { + int busy; /**< is the thread currently running? */ + int shutting_down; /**< has \a grpc_shutdown() been invoked? */ + int pending_join; /**< has the thread finished but not been joined? */ + grpc_closure_list closures; /**< collection of pending work */ + gpr_thd_id tid; /**< thread id of the thread, only valid if \a busy or \a + pending_join are true */ + gpr_thd_options options; + gpr_mu mu; +} grpc_executor; + +static grpc_executor g_executor; + +void grpc_executor_init() { + memset(&g_executor, 0, sizeof(grpc_executor)); + gpr_mu_init(&g_executor.mu); + g_executor.options = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&g_executor.options); +} + +/* thread body */ +static void closure_exec_thread_func(void *ignored) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + while (1) { + gpr_mu_lock(&g_executor.mu); + if (g_executor.shutting_down != 0) { + gpr_mu_unlock(&g_executor.mu); + break; + } + if (grpc_closure_list_empty(g_executor.closures)) { + /* no more work, time to die */ + GPR_ASSERT(g_executor.busy == 1); + g_executor.busy = 0; + gpr_mu_unlock(&g_executor.mu); + break; + } else { + grpc_exec_ctx_enqueue_list(&exec_ctx, &g_executor.closures, NULL); + } + gpr_mu_unlock(&g_executor.mu); + grpc_exec_ctx_flush(&exec_ctx); + } + grpc_exec_ctx_finish(&exec_ctx); +} + +/* Spawn the thread if new work has arrived a no thread is up */ +static void maybe_spawn_locked() { + if (grpc_closure_list_empty(g_executor.closures) == 1) { + return; + } + if (g_executor.shutting_down == 1) { + return; + } + + if (g_executor.busy != 0) { + /* Thread still working. New work will be picked up by already running + * thread. Not spawning anything. */ + return; + } else if (g_executor.pending_join != 0) { + /* Pickup the remains of the previous incarnations of the thread. */ + gpr_thd_join(g_executor.tid); + g_executor.pending_join = 0; + } + + /* All previous instances of the thread should have been joined at this point. + * Spawn time! */ + g_executor.busy = 1; + gpr_thd_new(&g_executor.tid, closure_exec_thread_func, NULL, + &g_executor.options); + g_executor.pending_join = 1; +} + +void grpc_executor_enqueue(grpc_closure *closure, bool success) { + gpr_mu_lock(&g_executor.mu); + if (g_executor.shutting_down == 0) { + grpc_closure_list_add(&g_executor.closures, closure, success); + maybe_spawn_locked(); + } + gpr_mu_unlock(&g_executor.mu); +} + +void grpc_executor_shutdown() { + int pending_join; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + gpr_mu_lock(&g_executor.mu); + pending_join = g_executor.pending_join; + g_executor.shutting_down = 1; + gpr_mu_unlock(&g_executor.mu); + /* we can release the lock at this point despite the access to the closure + * list below because we aren't accepting new work */ + + /* Execute pending callbacks, some may be performing cleanups */ + grpc_exec_ctx_enqueue_list(&exec_ctx, &g_executor.closures, NULL); + grpc_exec_ctx_finish(&exec_ctx); + GPR_ASSERT(grpc_closure_list_empty(g_executor.closures)); + if (pending_join) { + gpr_thd_join(g_executor.tid); + } + gpr_mu_destroy(&g_executor.mu); +} diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h new file mode 100644 index 0000000000..f66b3560e3 --- /dev/null +++ b/src/core/lib/iomgr/executor.h @@ -0,0 +1,53 @@ +/* + * + * Copyright 2015-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_IOMGR_EXECUTOR_H +#define GRPC_CORE_IOMGR_EXECUTOR_H + +#include "src/core/iomgr/closure.h" + +/** Initialize the global executor. + * + * This mechanism is meant to outsource work (grpc_closure instances) to a + * thread, for those cases where blocking isn't an option but there isn't a + * non-blocking solution available. */ +void grpc_executor_init(); + +/** Enqueue \a closure for its eventual execution of \a f(arg) on a separate + * thread */ +void grpc_executor_enqueue(grpc_closure *closure, bool success); + +/** Shutdown the executor, running all pending work as part of the call */ +void grpc_executor_shutdown(); + +#endif /* GRPC_CORE_IOMGR_EXECUTOR_H */ diff --git a/src/core/lib/iomgr/fd_posix.c b/src/core/lib/iomgr/fd_posix.c new file mode 100644 index 0000000000..b4d038a3a1 --- /dev/null +++ b/src/core/lib/iomgr/fd_posix.c @@ -0,0 +1,454 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_SOCKET + +#include "src/core/iomgr/fd_posix.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include "src/core/iomgr/pollset_posix.h" + +#define CLOSURE_NOT_READY ((grpc_closure *)0) +#define CLOSURE_READY ((grpc_closure *)1) + +/* We need to keep a freelist not because of any concerns of malloc performance + * but instead so that implementations with multiple threads in (for example) + * epoll_wait deal with the race between pollset removal and incoming poll + * notifications. + * + * The problem is that the poller ultimately holds a reference to this + * object, so it is very difficult to know when is safe to free it, at least + * without some expensive synchronization. + * + * If we keep the object freelisted, in the worst case losing this race just + * becomes a spurious read notification on a reused fd. + */ +/* TODO(klempner): We could use some form of polling generation count to know + * when these are safe to free. */ +/* TODO(klempner): Consider disabling freelisting if we don't have multiple + * threads in poll on the same fd */ +/* TODO(klempner): Batch these allocations to reduce fragmentation */ +static grpc_fd *fd_freelist = NULL; +static gpr_mu fd_freelist_mu; + +static void freelist_fd(grpc_fd *fd) { + gpr_mu_lock(&fd_freelist_mu); + fd->freelist_next = fd_freelist; + fd_freelist = fd; + grpc_iomgr_unregister_object(&fd->iomgr_object); + gpr_mu_unlock(&fd_freelist_mu); +} + +static grpc_fd *alloc_fd(int fd) { + grpc_fd *r = NULL; + gpr_mu_lock(&fd_freelist_mu); + if (fd_freelist != NULL) { + r = fd_freelist; + fd_freelist = fd_freelist->freelist_next; + } + gpr_mu_unlock(&fd_freelist_mu); + if (r == NULL) { + r = gpr_malloc(sizeof(grpc_fd)); + gpr_mu_init(&r->mu); + } + + gpr_mu_lock(&r->mu); + r->shutdown = 0; + r->read_closure = CLOSURE_NOT_READY; + r->write_closure = CLOSURE_NOT_READY; + r->fd = fd; + r->inactive_watcher_root.next = r->inactive_watcher_root.prev = + &r->inactive_watcher_root; + r->freelist_next = NULL; + r->read_watcher = r->write_watcher = NULL; + r->on_done_closure = NULL; + r->closed = 0; + r->released = 0; + gpr_atm_rel_store(&r->refst, 1); + gpr_mu_unlock(&r->mu); + + return r; +} + +static void destroy(grpc_fd *fd) { + gpr_mu_destroy(&fd->mu); + gpr_free(fd); +} + +#ifdef GRPC_FD_REF_COUNT_DEBUG +#define REF_BY(fd, n, reason) ref_by(fd, n, reason, __FILE__, __LINE__) +#define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__) +static void ref_by(grpc_fd *fd, int n, const char *reason, const char *file, + int line) { + gpr_log(GPR_DEBUG, "FD %d %p ref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n, + gpr_atm_no_barrier_load(&fd->refst), + gpr_atm_no_barrier_load(&fd->refst) + n, reason, file, line); +#else +#define REF_BY(fd, n, reason) ref_by(fd, n) +#define UNREF_BY(fd, n, reason) unref_by(fd, n) +static void ref_by(grpc_fd *fd, int n) { +#endif + GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0); +} + +#ifdef GRPC_FD_REF_COUNT_DEBUG +static void unref_by(grpc_fd *fd, int n, const char *reason, const char *file, + int line) { + gpr_atm old; + gpr_log(GPR_DEBUG, "FD %d %p unref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n, + gpr_atm_no_barrier_load(&fd->refst), + gpr_atm_no_barrier_load(&fd->refst) - n, reason, file, line); +#else +static void unref_by(grpc_fd *fd, int n) { + gpr_atm old; +#endif + old = gpr_atm_full_fetch_add(&fd->refst, -n); + if (old == n) { + freelist_fd(fd); + } else { + GPR_ASSERT(old > n); + } +} + +void grpc_fd_global_init(void) { gpr_mu_init(&fd_freelist_mu); } + +void grpc_fd_global_shutdown(void) { + gpr_mu_lock(&fd_freelist_mu); + gpr_mu_unlock(&fd_freelist_mu); + while (fd_freelist != NULL) { + grpc_fd *fd = fd_freelist; + fd_freelist = fd_freelist->freelist_next; + destroy(fd); + } + gpr_mu_destroy(&fd_freelist_mu); +} + +grpc_fd *grpc_fd_create(int fd, const char *name) { + grpc_fd *r = alloc_fd(fd); + char *name2; + gpr_asprintf(&name2, "%s fd=%d", name, fd); + grpc_iomgr_register_object(&r->iomgr_object, name2); + gpr_free(name2); +#ifdef GRPC_FD_REF_COUNT_DEBUG + gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, r, name); +#endif + return r; +} + +int grpc_fd_is_orphaned(grpc_fd *fd) { + return (gpr_atm_acq_load(&fd->refst) & 1) == 0; +} + +static void pollset_kick_locked(grpc_fd_watcher *watcher) { + gpr_mu_lock(&watcher->pollset->mu); + GPR_ASSERT(watcher->worker); + grpc_pollset_kick_ext(watcher->pollset, watcher->worker, + GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP); + gpr_mu_unlock(&watcher->pollset->mu); +} + +static void maybe_wake_one_watcher_locked(grpc_fd *fd) { + if (fd->inactive_watcher_root.next != &fd->inactive_watcher_root) { + pollset_kick_locked(fd->inactive_watcher_root.next); + } else if (fd->read_watcher) { + pollset_kick_locked(fd->read_watcher); + } else if (fd->write_watcher) { + pollset_kick_locked(fd->write_watcher); + } +} + +static void wake_all_watchers_locked(grpc_fd *fd) { + grpc_fd_watcher *watcher; + for (watcher = fd->inactive_watcher_root.next; + watcher != &fd->inactive_watcher_root; watcher = watcher->next) { + pollset_kick_locked(watcher); + } + if (fd->read_watcher) { + pollset_kick_locked(fd->read_watcher); + } + if (fd->write_watcher && fd->write_watcher != fd->read_watcher) { + pollset_kick_locked(fd->write_watcher); + } +} + +static int has_watchers(grpc_fd *fd) { + return fd->read_watcher != NULL || fd->write_watcher != NULL || + fd->inactive_watcher_root.next != &fd->inactive_watcher_root; +} + +static void close_fd_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { + fd->closed = 1; + if (!fd->released) { + close(fd->fd); + } else { + grpc_remove_fd_from_all_epoll_sets(fd->fd); + } + grpc_exec_ctx_enqueue(exec_ctx, fd->on_done_closure, true, NULL); +} + +int grpc_fd_wrapped_fd(grpc_fd *fd) { + if (fd->released || fd->closed) { + return -1; + } else { + return fd->fd; + } +} + +void grpc_fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done, + int *release_fd, const char *reason) { + fd->on_done_closure = on_done; + fd->released = release_fd != NULL; + if (!fd->released) { + shutdown(fd->fd, SHUT_RDWR); + } else { + *release_fd = fd->fd; + } + gpr_mu_lock(&fd->mu); + REF_BY(fd, 1, reason); /* remove active status, but keep referenced */ + if (!has_watchers(fd)) { + close_fd_locked(exec_ctx, fd); + } else { + wake_all_watchers_locked(fd); + } + gpr_mu_unlock(&fd->mu); + UNREF_BY(fd, 2, reason); /* drop the reference */ +} + +/* increment refcount by two to avoid changing the orphan bit */ +#ifdef GRPC_FD_REF_COUNT_DEBUG +void grpc_fd_ref(grpc_fd *fd, const char *reason, const char *file, int line) { + ref_by(fd, 2, reason, file, line); +} + +void grpc_fd_unref(grpc_fd *fd, const char *reason, const char *file, + int line) { + unref_by(fd, 2, reason, file, line); +} +#else +void grpc_fd_ref(grpc_fd *fd) { ref_by(fd, 2); } + +void grpc_fd_unref(grpc_fd *fd) { unref_by(fd, 2); } +#endif + +static void notify_on_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd, + grpc_closure **st, grpc_closure *closure) { + if (*st == CLOSURE_NOT_READY) { + /* not ready ==> switch to a waiting state by setting the closure */ + *st = closure; + } else if (*st == CLOSURE_READY) { + /* already ready ==> queue the closure to run immediately */ + *st = CLOSURE_NOT_READY; + grpc_exec_ctx_enqueue(exec_ctx, closure, !fd->shutdown, NULL); + maybe_wake_one_watcher_locked(fd); + } else { + /* upcallptr was set to a different closure. This is an error! */ + gpr_log(GPR_ERROR, + "User called a notify_on function with a previous callback still " + "pending"); + abort(); + } +} + +/* returns 1 if state becomes not ready */ +static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd, + grpc_closure **st) { + if (*st == CLOSURE_READY) { + /* duplicate ready ==> ignore */ + return 0; + } else if (*st == CLOSURE_NOT_READY) { + /* not ready, and not waiting ==> flag ready */ + *st = CLOSURE_READY; + return 0; + } else { + /* waiting ==> queue closure */ + grpc_exec_ctx_enqueue(exec_ctx, *st, !fd->shutdown, NULL); + *st = CLOSURE_NOT_READY; + return 1; + } +} + +static void set_ready(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure **st) { + /* only one set_ready can be active at once (but there may be a racing + notify_on) */ + gpr_mu_lock(&fd->mu); + set_ready_locked(exec_ctx, fd, st); + gpr_mu_unlock(&fd->mu); +} + +void grpc_fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { + gpr_mu_lock(&fd->mu); + GPR_ASSERT(!fd->shutdown); + fd->shutdown = 1; + set_ready_locked(exec_ctx, fd, &fd->read_closure); + set_ready_locked(exec_ctx, fd, &fd->write_closure); + gpr_mu_unlock(&fd->mu); +} + +void grpc_fd_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_fd *fd, + grpc_closure *closure) { + gpr_mu_lock(&fd->mu); + notify_on_locked(exec_ctx, fd, &fd->read_closure, closure); + gpr_mu_unlock(&fd->mu); +} + +void grpc_fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd, + grpc_closure *closure) { + gpr_mu_lock(&fd->mu); + notify_on_locked(exec_ctx, fd, &fd->write_closure, closure); + gpr_mu_unlock(&fd->mu); +} + +uint32_t grpc_fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset, + grpc_pollset_worker *worker, uint32_t read_mask, + uint32_t write_mask, grpc_fd_watcher *watcher) { + uint32_t mask = 0; + grpc_closure *cur; + int requested; + /* keep track of pollers that have requested our events, in case they change + */ + GRPC_FD_REF(fd, "poll"); + + gpr_mu_lock(&fd->mu); + + /* if we are shutdown, then don't add to the watcher set */ + if (fd->shutdown) { + watcher->fd = NULL; + watcher->pollset = NULL; + watcher->worker = NULL; + gpr_mu_unlock(&fd->mu); + GRPC_FD_UNREF(fd, "poll"); + return 0; + } + + /* if there is nobody polling for read, but we need to, then start doing so */ + cur = fd->read_closure; + requested = cur != CLOSURE_READY; + if (read_mask && fd->read_watcher == NULL && requested) { + fd->read_watcher = watcher; + mask |= read_mask; + } + /* if there is nobody polling for write, but we need to, then start doing so + */ + cur = fd->write_closure; + requested = cur != CLOSURE_READY; + if (write_mask && fd->write_watcher == NULL && requested) { + fd->write_watcher = watcher; + mask |= write_mask; + } + /* if not polling, remember this watcher in case we need someone to later */ + if (mask == 0 && worker != NULL) { + watcher->next = &fd->inactive_watcher_root; + watcher->prev = watcher->next->prev; + watcher->next->prev = watcher->prev->next = watcher; + } + watcher->pollset = pollset; + watcher->worker = worker; + watcher->fd = fd; + gpr_mu_unlock(&fd->mu); + + return mask; +} + +void grpc_fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher, + int got_read, int got_write) { + int was_polling = 0; + int kick = 0; + grpc_fd *fd = watcher->fd; + + if (fd == NULL) { + return; + } + + gpr_mu_lock(&fd->mu); + + if (watcher == fd->read_watcher) { + /* remove read watcher, kick if we still need a read */ + was_polling = 1; + if (!got_read) { + kick = 1; + } + fd->read_watcher = NULL; + } + if (watcher == fd->write_watcher) { + /* remove write watcher, kick if we still need a write */ + was_polling = 1; + if (!got_write) { + kick = 1; + } + fd->write_watcher = NULL; + } + if (!was_polling && watcher->worker != NULL) { + /* remove from inactive list */ + watcher->next->prev = watcher->prev; + watcher->prev->next = watcher->next; + } + if (got_read) { + if (set_ready_locked(exec_ctx, fd, &fd->read_closure)) { + kick = 1; + } + } + if (got_write) { + if (set_ready_locked(exec_ctx, fd, &fd->write_closure)) { + kick = 1; + } + } + if (kick) { + maybe_wake_one_watcher_locked(fd); + } + if (grpc_fd_is_orphaned(fd) && !has_watchers(fd) && !fd->closed) { + close_fd_locked(exec_ctx, fd); + } + gpr_mu_unlock(&fd->mu); + + GRPC_FD_UNREF(fd, "poll"); +} + +void grpc_fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { + set_ready(exec_ctx, fd, &fd->read_closure); +} + +void grpc_fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { + set_ready(exec_ctx, fd, &fd->write_closure); +} + +#endif diff --git a/src/core/lib/iomgr/fd_posix.h b/src/core/lib/iomgr/fd_posix.h new file mode 100644 index 0000000000..1993ada79f --- /dev/null +++ b/src/core/lib/iomgr/fd_posix.h @@ -0,0 +1,192 @@ +/* + * + * Copyright 2015-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_IOMGR_FD_POSIX_H +#define GRPC_CORE_IOMGR_FD_POSIX_H + +#include +#include +#include +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/pollset.h" + +typedef struct grpc_fd grpc_fd; + +typedef struct grpc_fd_watcher { + struct grpc_fd_watcher *next; + struct grpc_fd_watcher *prev; + grpc_pollset *pollset; + grpc_pollset_worker *worker; + grpc_fd *fd; +} grpc_fd_watcher; + +struct grpc_fd { + int fd; + /* refst format: + bit0: 1=active/0=orphaned + bit1-n: refcount + meaning that mostly we ref by two to avoid altering the orphaned bit, + and just unref by 1 when we're ready to flag the object as orphaned */ + gpr_atm refst; + + gpr_mu mu; + int shutdown; + int closed; + int released; + + /* The watcher list. + + The following watcher related fields are protected by watcher_mu. + + An fd_watcher is an ephemeral object created when an fd wants to + begin polling, and destroyed after the poll. + + It denotes the fd's interest in whether to read poll or write poll + or both or neither on this fd. + + If a watcher is asked to poll for reads or writes, the read_watcher + or write_watcher fields are set respectively. A watcher may be asked + to poll for both, in which case both fields will be set. + + read_watcher and write_watcher may be NULL if no watcher has been + asked to poll for reads or writes. + + If an fd_watcher is not asked to poll for reads or writes, it's added + to a linked list of inactive watchers, rooted at inactive_watcher_root. + If at a later time there becomes need of a poller to poll, one of + the inactive pollers may be kicked out of their poll loops to take + that responsibility. */ + grpc_fd_watcher inactive_watcher_root; + grpc_fd_watcher *read_watcher; + grpc_fd_watcher *write_watcher; + + grpc_closure *read_closure; + grpc_closure *write_closure; + + struct grpc_fd *freelist_next; + + grpc_closure *on_done_closure; + + grpc_iomgr_object iomgr_object; +}; + +/* Create a wrapped file descriptor. + Requires fd is a non-blocking file descriptor. + This takes ownership of closing fd. */ +grpc_fd *grpc_fd_create(int fd, const char *name); + +/* Return the wrapped fd, or -1 if it has been released or closed. */ +int grpc_fd_wrapped_fd(grpc_fd *fd); + +/* Releases fd to be asynchronously destroyed. + on_done is called when the underlying file descriptor is definitely close()d. + If on_done is NULL, no callback will be made. + If release_fd is not NULL, it's set to fd and fd will not be closed. + Requires: *fd initialized; no outstanding notify_on_read or + notify_on_write. + MUST NOT be called with a pollset lock taken */ +void grpc_fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done, + int *release_fd, const char *reason); + +/* Begin polling on an fd. + Registers that the given pollset is interested in this fd - so that if read + or writability interest changes, the pollset can be kicked to pick up that + new interest. + Return value is: + (fd_needs_read? read_mask : 0) | (fd_needs_write? write_mask : 0) + i.e. a combination of read_mask and write_mask determined by the fd's current + interest in said events. + Polling strategies that do not need to alter their behavior depending on the + fd's current interest (such as epoll) do not need to call this function. + MUST NOT be called with a pollset lock taken */ +uint32_t grpc_fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset, + grpc_pollset_worker *worker, uint32_t read_mask, + uint32_t write_mask, grpc_fd_watcher *rec); +/* Complete polling previously started with grpc_fd_begin_poll + MUST NOT be called with a pollset lock taken + if got_read or got_write are 1, also does the become_{readable,writable} as + appropriate. */ +void grpc_fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *rec, + int got_read, int got_write); + +/* Return 1 if this fd is orphaned, 0 otherwise */ +int grpc_fd_is_orphaned(grpc_fd *fd); + +/* Cause any current callbacks to error out with GRPC_CALLBACK_CANCELLED. */ +void grpc_fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd); + +/* Register read interest, causing read_cb to be called once when fd becomes + readable, on deadline specified by deadline, or on shutdown triggered by + grpc_fd_shutdown. + read_cb will be called with read_cb_arg when *fd becomes readable. + read_cb is Called with status of GRPC_CALLBACK_SUCCESS if readable, + GRPC_CALLBACK_TIMED_OUT if the call timed out, + and CANCELLED if the call was cancelled. + + Requires:This method must not be called before the read_cb for any previous + call runs. Edge triggered events are used whenever they are supported by the + underlying platform. This means that users must drain fd in read_cb before + calling notify_on_read again. Users are also expected to handle spurious + events, i.e read_cb is called while nothing can be readable from fd */ +void grpc_fd_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_fd *fd, + grpc_closure *closure); + +/* Exactly the same semantics as above, except based on writable events. */ +void grpc_fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd, + grpc_closure *closure); + +/* Notification from the poller to an fd that it has become readable or + writable. + If allow_synchronous_callback is 1, allow running the fd callback inline + in this callstack, otherwise register an asynchronous callback and return */ +void grpc_fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd); +void grpc_fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd); + +/* Reference counting for fds */ +/*#define GRPC_FD_REF_COUNT_DEBUG*/ +#ifdef GRPC_FD_REF_COUNT_DEBUG +void grpc_fd_ref(grpc_fd *fd, const char *reason, const char *file, int line); +void grpc_fd_unref(grpc_fd *fd, const char *reason, const char *file, int line); +#define GRPC_FD_REF(fd, reason) grpc_fd_ref(fd, reason, __FILE__, __LINE__) +#define GRPC_FD_UNREF(fd, reason) grpc_fd_unref(fd, reason, __FILE__, __LINE__) +#else +void grpc_fd_ref(grpc_fd *fd); +void grpc_fd_unref(grpc_fd *fd); +#define GRPC_FD_REF(fd, reason) grpc_fd_ref(fd) +#define GRPC_FD_UNREF(fd, reason) grpc_fd_unref(fd) +#endif + +void grpc_fd_global_init(void); +void grpc_fd_global_shutdown(void); + +#endif /* GRPC_CORE_IOMGR_FD_POSIX_H */ diff --git a/src/core/lib/iomgr/iocp_windows.c b/src/core/lib/iomgr/iocp_windows.c new file mode 100644 index 0000000000..37e277dcc1 --- /dev/null +++ b/src/core/lib/iomgr/iocp_windows.c @@ -0,0 +1,208 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_WINSOCK_SOCKET + +#include + +#include +#include +#include +#include + +#include "src/core/iomgr/iocp_windows.h" +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/socket_windows.h" +#include "src/core/iomgr/timer.h" + +static ULONG g_iocp_kick_token; +static OVERLAPPED g_iocp_custom_overlap; + +static gpr_atm g_custom_events = 0; + +static HANDLE g_iocp; + +static DWORD deadline_to_millis_timeout(gpr_timespec deadline, + gpr_timespec now) { + gpr_timespec timeout; + static const int64_t max_spin_polling_us = 10; + if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) == 0) { + return INFINITE; + } + if (gpr_time_cmp(deadline, gpr_time_add(now, gpr_time_from_micros( + max_spin_polling_us, + GPR_TIMESPAN))) <= 0) { + return 0; + } + timeout = gpr_time_sub(deadline, now); + return (DWORD)gpr_time_to_millis(gpr_time_add( + timeout, gpr_time_from_nanos(GPR_NS_PER_MS - 1, GPR_TIMESPAN))); +} + +grpc_iocp_work_status grpc_iocp_work(grpc_exec_ctx *exec_ctx, + gpr_timespec deadline) { + BOOL success; + DWORD bytes = 0; + DWORD flags = 0; + ULONG_PTR completion_key; + 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))); + if (success == 0 && overlapped == NULL) { + return GRPC_IOCP_WORK_TIMEOUT; + } + GPR_ASSERT(completion_key && overlapped); + if (overlapped == &g_iocp_custom_overlap) { + gpr_atm_full_fetch_add(&g_custom_events, -1); + if (completion_key == (ULONG_PTR)&g_iocp_kick_token) { + /* We were awoken from a kick. */ + return GRPC_IOCP_WORK_KICK; + } + gpr_log(GPR_ERROR, "Unknown custom completion key."); + abort(); + } + + socket = (grpc_winsocket *)completion_key; + if (overlapped == &socket->write_info.overlapped) { + info = &socket->write_info; + } else if (overlapped == &socket->read_info.overlapped) { + info = &socket->read_info; + } else { + gpr_log(GPR_ERROR, "Unknown IOCP operation"); + abort(); + } + success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes, + FALSE, &flags); + info->bytes_transfered = bytes; + info->wsa_error = success ? 0 : WSAGetLastError(); + GPR_ASSERT(overlapped == &info->overlapped); + GPR_ASSERT(!info->has_pending_iocp); + gpr_mu_lock(&socket->state_mu); + if (info->closure) { + closure = info->closure; + info->closure = NULL; + } else { + info->has_pending_iocp = 1; + } + gpr_mu_unlock(&socket->state_mu); + grpc_exec_ctx_enqueue(exec_ctx, closure, true, NULL); + return GRPC_IOCP_WORK_WORK; +} + +void grpc_iocp_init(void) { + g_iocp = + CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, (ULONG_PTR)NULL, 0); + GPR_ASSERT(g_iocp); +} + +void grpc_iocp_kick(void) { + BOOL success; + + gpr_atm_full_fetch_add(&g_custom_events, 1); + success = PostQueuedCompletionStatus(g_iocp, 0, (ULONG_PTR)&g_iocp_kick_token, + &g_iocp_custom_overlap); + GPR_ASSERT(success); +} + +void grpc_iocp_flush(void) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_iocp_work_status work_status; + + do { + work_status = grpc_iocp_work(&exec_ctx, gpr_inf_past(GPR_CLOCK_MONOTONIC)); + } while (work_status == GRPC_IOCP_WORK_KICK || + grpc_exec_ctx_flush(&exec_ctx)); +} + +void grpc_iocp_shutdown(void) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + while (gpr_atm_acq_load(&g_custom_events)) { + grpc_iocp_work(&exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC)); + grpc_exec_ctx_flush(&exec_ctx); + } + grpc_exec_ctx_finish(&exec_ctx); + GPR_ASSERT(CloseHandle(g_iocp)); +} + +void grpc_iocp_add_socket(grpc_winsocket *socket) { + HANDLE ret; + if (socket->added_to_iocp) return; + ret = CreateIoCompletionPort((HANDLE)socket->socket, g_iocp, + (uintptr_t)socket, 0); + if (!ret) { + char *utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, "Unable to add socket to iocp: %s", utf8_message); + gpr_free(utf8_message); + __debugbreak(); + abort(); + } + socket->added_to_iocp = 1; + GPR_ASSERT(ret == g_iocp); +} + +/* Calling notify_on_read or write means either of two things: + -) The IOCP already completed in the background, and we need to call + the callback now. + -) The IOCP hasn't completed yet, and we're queuing it for later. */ +static void socket_notify_on_iocp(grpc_exec_ctx *exec_ctx, + grpc_winsocket *socket, grpc_closure *closure, + grpc_winsocket_callback_info *info) { + GPR_ASSERT(info->closure == NULL); + gpr_mu_lock(&socket->state_mu); + if (info->has_pending_iocp) { + info->has_pending_iocp = 0; + grpc_exec_ctx_enqueue(exec_ctx, closure, true, NULL); + } else { + info->closure = closure; + } + gpr_mu_unlock(&socket->state_mu); +} + +void grpc_socket_notify_on_write(grpc_exec_ctx *exec_ctx, + grpc_winsocket *socket, + grpc_closure *closure) { + socket_notify_on_iocp(exec_ctx, socket, closure, &socket->write_info); +} + +void grpc_socket_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_winsocket *socket, + grpc_closure *closure) { + socket_notify_on_iocp(exec_ctx, socket, closure, &socket->read_info); +} + +#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/iocp_windows.h b/src/core/lib/iomgr/iocp_windows.h new file mode 100644 index 0000000000..570b8925aa --- /dev/null +++ b/src/core/lib/iomgr/iocp_windows.h @@ -0,0 +1,63 @@ +/* + * + * Copyright 2015-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_IOMGR_IOCP_WINDOWS_H +#define GRPC_CORE_IOMGR_IOCP_WINDOWS_H + +#include + +#include "src/core/iomgr/socket_windows.h" + +typedef enum { + GRPC_IOCP_WORK_WORK, + GRPC_IOCP_WORK_TIMEOUT, + GRPC_IOCP_WORK_KICK +} grpc_iocp_work_status; + +grpc_iocp_work_status grpc_iocp_work(grpc_exec_ctx *exec_ctx, + gpr_timespec deadline); +void grpc_iocp_init(void); +void grpc_iocp_kick(void); +void grpc_iocp_flush(void); +void grpc_iocp_shutdown(void); +void grpc_iocp_add_socket(grpc_winsocket *); + +void grpc_socket_notify_on_write(grpc_exec_ctx *exec_ctx, + grpc_winsocket *winsocket, + grpc_closure *closure); + +void grpc_socket_notify_on_read(grpc_exec_ctx *exec_ctx, + grpc_winsocket *winsocket, + grpc_closure *closure); + +#endif /* GRPC_CORE_IOMGR_IOCP_WINDOWS_H */ diff --git a/src/core/lib/iomgr/iomgr.c b/src/core/lib/iomgr/iomgr.c new file mode 100644 index 0000000000..3ab4430668 --- /dev/null +++ b/src/core/lib/iomgr/iomgr.c @@ -0,0 +1,175 @@ +/* + * + * Copyright 2015-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/iomgr/iomgr.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/timer.h" +#include "src/core/support/env.h" +#include "src/core/support/string.h" + +static gpr_mu g_mu; +static gpr_cv g_rcv; +static int g_shutdown; +static grpc_iomgr_object g_root_object; + +void grpc_iomgr_init(void) { + g_shutdown = 0; + gpr_mu_init(&g_mu); + gpr_cv_init(&g_rcv); + grpc_exec_ctx_global_init(); + grpc_timer_list_init(gpr_now(GPR_CLOCK_MONOTONIC)); + g_root_object.next = g_root_object.prev = &g_root_object; + g_root_object.name = "root"; + grpc_iomgr_platform_init(); + grpc_pollset_global_init(); +} + +static size_t count_objects(void) { + grpc_iomgr_object *obj; + size_t n = 0; + for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) { + n++; + } + return n; +} + +static void dump_objects(const char *kind) { + grpc_iomgr_object *obj; + for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) { + gpr_log(GPR_DEBUG, "%s OBJECT: %s %p", kind, obj->name, obj); + } +} + +void grpc_iomgr_shutdown(void) { + gpr_timespec shutdown_deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(10, GPR_TIMESPAN)); + gpr_timespec last_warning_time = gpr_now(GPR_CLOCK_REALTIME); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + grpc_iomgr_platform_flush(); + + gpr_mu_lock(&g_mu); + g_shutdown = 1; + while (g_root_object.next != &g_root_object) { + if (gpr_time_cmp( + gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), last_warning_time), + gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) { + if (g_root_object.next != &g_root_object) { + gpr_log(GPR_DEBUG, "Waiting for %d iomgr objects to be destroyed", + count_objects()); + } + last_warning_time = gpr_now(GPR_CLOCK_REALTIME); + } + if (grpc_timer_check(&exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC), + NULL)) { + gpr_mu_unlock(&g_mu); + grpc_exec_ctx_flush(&exec_ctx); + gpr_mu_lock(&g_mu); + continue; + } + if (g_root_object.next != &g_root_object) { + gpr_timespec short_deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(100, GPR_TIMESPAN)); + if (gpr_cv_wait(&g_rcv, &g_mu, short_deadline)) { + if (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), shutdown_deadline) > 0) { + if (g_root_object.next != &g_root_object) { + gpr_log(GPR_DEBUG, + "Failed to free %d iomgr objects before shutdown deadline: " + "memory leaks are likely", + count_objects()); + dump_objects("LEAKED"); + if (grpc_iomgr_abort_on_leaks()) { + abort(); + } + } + break; + } + } + } + } + gpr_mu_unlock(&g_mu); + + grpc_timer_list_shutdown(&exec_ctx); + grpc_exec_ctx_finish(&exec_ctx); + + /* ensure all threads have left g_mu */ + gpr_mu_lock(&g_mu); + gpr_mu_unlock(&g_mu); + + grpc_pollset_global_shutdown(); + grpc_iomgr_platform_shutdown(); + grpc_exec_ctx_global_shutdown(); + gpr_mu_destroy(&g_mu); + gpr_cv_destroy(&g_rcv); +} + +void grpc_iomgr_register_object(grpc_iomgr_object *obj, const char *name) { + obj->name = gpr_strdup(name); + gpr_mu_lock(&g_mu); + obj->next = &g_root_object; + obj->prev = g_root_object.prev; + obj->next->prev = obj->prev->next = obj; + gpr_mu_unlock(&g_mu); +} + +void grpc_iomgr_unregister_object(grpc_iomgr_object *obj) { + gpr_mu_lock(&g_mu); + obj->next->prev = obj->prev; + obj->prev->next = obj->next; + gpr_cv_signal(&g_rcv); + gpr_mu_unlock(&g_mu); + gpr_free(obj->name); +} + +bool grpc_iomgr_abort_on_leaks(void) { + char *env = gpr_getenv("GRPC_ABORT_ON_LEAKS"); + if (env == NULL) return false; + static const char *truthy[] = {"yes", "Yes", "YES", "true", + "True", "TRUE", "1"}; + for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) { + if (0 == strcmp(env, truthy[i])) return true; + } + return false; +} diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h new file mode 100644 index 0000000000..e1237a4533 --- /dev/null +++ b/src/core/lib/iomgr/iomgr.h @@ -0,0 +1,43 @@ +/* + * + * Copyright 2015-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_IOMGR_IOMGR_H +#define GRPC_CORE_IOMGR_IOMGR_H + +/** Initializes the iomgr. */ +void grpc_iomgr_init(void); + +/** Signals the intention to shutdown the iomgr. */ +void grpc_iomgr_shutdown(void); + +#endif /* GRPC_CORE_IOMGR_IOMGR_H */ diff --git a/src/core/lib/iomgr/iomgr_internal.h b/src/core/lib/iomgr/iomgr_internal.h new file mode 100644 index 0000000000..1cad3182ec --- /dev/null +++ b/src/core/lib/iomgr/iomgr_internal.h @@ -0,0 +1,62 @@ +/* + * + * Copyright 2015-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_IOMGR_IOMGR_INTERNAL_H +#define GRPC_CORE_IOMGR_IOMGR_INTERNAL_H + +#include + +#include +#include "src/core/iomgr/iomgr.h" + +typedef struct grpc_iomgr_object { + char *name; + struct grpc_iomgr_object *next; + struct grpc_iomgr_object *prev; +} grpc_iomgr_object; + +void grpc_pollset_global_init(void); +void grpc_pollset_global_shutdown(void); + +void grpc_iomgr_register_object(grpc_iomgr_object *obj, const char *name); +void grpc_iomgr_unregister_object(grpc_iomgr_object *obj); + +void grpc_iomgr_platform_init(void); +/** flush any globally queued work from iomgr */ +void grpc_iomgr_platform_flush(void); +/** tear down all platform specific global iomgr structures */ +void grpc_iomgr_platform_shutdown(void); + +bool grpc_iomgr_abort_on_leaks(void); + +#endif /* GRPC_CORE_IOMGR_IOMGR_INTERNAL_H */ diff --git a/src/core/lib/iomgr/iomgr_posix.c b/src/core/lib/iomgr/iomgr_posix.c new file mode 100644 index 0000000000..2f7f34746b --- /dev/null +++ b/src/core/lib/iomgr/iomgr_posix.c @@ -0,0 +1,52 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_SOCKET + +#include "src/core/debug/trace.h" +#include "src/core/iomgr/fd_posix.h" +#include "src/core/iomgr/iomgr_posix.h" +#include "src/core/iomgr/tcp_posix.h" + +void grpc_iomgr_platform_init(void) { + grpc_fd_global_init(); + grpc_register_tracer("tcp", &grpc_tcp_trace); +} + +void grpc_iomgr_platform_flush(void) {} + +void grpc_iomgr_platform_shutdown(void) { grpc_fd_global_shutdown(); } + +#endif /* GRPC_POSIX_SOCKET */ diff --git a/src/core/lib/iomgr/iomgr_posix.h b/src/core/lib/iomgr/iomgr_posix.h new file mode 100644 index 0000000000..698fb6aee7 --- /dev/null +++ b/src/core/lib/iomgr/iomgr_posix.h @@ -0,0 +1,39 @@ +/* + * + * Copyright 2015-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_IOMGR_IOMGR_POSIX_H +#define GRPC_CORE_IOMGR_IOMGR_POSIX_H + +#include "src/core/iomgr/iomgr_internal.h" + +#endif /* GRPC_CORE_IOMGR_IOMGR_POSIX_H */ diff --git a/src/core/lib/iomgr/iomgr_windows.c b/src/core/lib/iomgr/iomgr_windows.c new file mode 100644 index 0000000000..2d104130f7 --- /dev/null +++ b/src/core/lib/iomgr/iomgr_windows.c @@ -0,0 +1,73 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_WINSOCK_SOCKET + +#include "src/core/iomgr/sockaddr_win32.h" + +#include + +#include "src/core/iomgr/iocp_windows.h" +#include "src/core/iomgr/iomgr.h" +#include "src/core/iomgr/socket_windows.h" + +/* Windows' io manager is going to be fully designed using IO completion + ports. All of what we're doing here is basically make sure that + Windows sockets are initialized in and out. */ + +static void winsock_init(void) { + WSADATA wsaData; + int status = WSAStartup(MAKEWORD(2, 0), &wsaData); + GPR_ASSERT(status == 0); +} + +static void winsock_shutdown(void) { + int status = WSACleanup(); + GPR_ASSERT(status == 0); +} + +void grpc_iomgr_platform_init(void) { + winsock_init(); + grpc_iocp_init(); +} + +void grpc_iomgr_platform_flush(void) { grpc_iocp_flush(); } + +void grpc_iomgr_platform_shutdown(void) { + grpc_iocp_shutdown(); + winsock_shutdown(); +} + +#endif /* GRPC_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/pollset.h b/src/core/lib/iomgr/pollset.h new file mode 100644 index 0000000000..9500b1a73a --- /dev/null +++ b/src/core/lib/iomgr/pollset.h @@ -0,0 +1,94 @@ +/* + * + * Copyright 2015-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_IOMGR_POLLSET_H +#define GRPC_CORE_IOMGR_POLLSET_H + +#include +#include +#include + +#include "src/core/iomgr/exec_ctx.h" + +#define GRPC_POLLSET_KICK_BROADCAST ((grpc_pollset_worker *)1) + +/* A grpc_pollset is a set of file descriptors that a higher level item is + interested in. For example: + - a server will typically keep a pollset containing all connected channels, + so that it can find new calls to service + - a completion queue might keep a pollset with an entry for each transport + that is servicing a call that it's tracking */ + +typedef struct grpc_pollset grpc_pollset; +typedef struct grpc_pollset_worker grpc_pollset_worker; + +size_t grpc_pollset_size(void); +void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu); +/* Begin shutting down the pollset, and call closure when done. + * pollset's mutex must be held */ +void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, + grpc_closure *closure); +/** Reset the pollset to its initial state (perhaps with some cached objects); + * must have been previously shutdown */ +void grpc_pollset_reset(grpc_pollset *pollset); +void grpc_pollset_destroy(grpc_pollset *pollset); + +/* Do some work on a pollset. + May involve invoking asynchronous callbacks, or actually polling file + descriptors. + Requires pollset's mutex locked. + May unlock its mutex during its execution. + + worker is a (platform-specific) handle that can be used to wake up + from grpc_pollset_work before any events are received and before the timeout + has expired. It is both initialized and destroyed by grpc_pollset_work. + Initialization of worker is guaranteed to occur BEFORE the + pollset's mutex is released for the first time by grpc_pollset_work + and it is guaranteed that it will not be released by grpc_pollset_work + AFTER worker has been destroyed. + + Tries not to block past deadline. + May call grpc_closure_list_run on grpc_closure_list, without holding the + pollset + lock */ +void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, + grpc_pollset_worker **worker, gpr_timespec now, + gpr_timespec deadline); + +/* Break one polling thread out of polling work for this pollset. + If specific_worker is GRPC_POLLSET_KICK_BROADCAST, kick ALL the workers. + Otherwise, if specific_worker is non-NULL, then kick that worker. */ +void grpc_pollset_kick(grpc_pollset *pollset, + grpc_pollset_worker *specific_worker); + +#endif /* GRPC_CORE_IOMGR_POLLSET_H */ diff --git a/src/core/lib/iomgr/pollset_multipoller_with_epoll.c b/src/core/lib/iomgr/pollset_multipoller_with_epoll.c new file mode 100644 index 0000000000..2e0f27fab8 --- /dev/null +++ b/src/core/lib/iomgr/pollset_multipoller_with_epoll.c @@ -0,0 +1,324 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_LINUX_MULTIPOLL_WITH_EPOLL + +#include +#include +#include +#include +#include + +#include +#include +#include +#include "src/core/iomgr/fd_posix.h" +#include "src/core/iomgr/pollset_posix.h" +#include "src/core/profiling/timers.h" +#include "src/core/support/block_annotate.h" + +struct epoll_fd_list { + int *epoll_fds; + size_t count; + size_t capacity; +}; + +static struct epoll_fd_list epoll_fd_global_list; +static gpr_once init_epoll_fd_list_mu = GPR_ONCE_INIT; +static gpr_mu epoll_fd_list_mu; + +static void init_mu(void) { gpr_mu_init(&epoll_fd_list_mu); } + +static void add_epoll_fd_to_global_list(int epoll_fd) { + gpr_once_init(&init_epoll_fd_list_mu, init_mu); + + gpr_mu_lock(&epoll_fd_list_mu); + if (epoll_fd_global_list.count == epoll_fd_global_list.capacity) { + epoll_fd_global_list.capacity = + GPR_MAX((size_t)8, epoll_fd_global_list.capacity * 2); + epoll_fd_global_list.epoll_fds = + gpr_realloc(epoll_fd_global_list.epoll_fds, + epoll_fd_global_list.capacity * sizeof(int)); + } + epoll_fd_global_list.epoll_fds[epoll_fd_global_list.count++] = epoll_fd; + gpr_mu_unlock(&epoll_fd_list_mu); +} + +static void remove_epoll_fd_from_global_list(int epoll_fd) { + gpr_mu_lock(&epoll_fd_list_mu); + GPR_ASSERT(epoll_fd_global_list.count > 0); + for (size_t i = 0; i < epoll_fd_global_list.count; i++) { + if (epoll_fd == epoll_fd_global_list.epoll_fds[i]) { + epoll_fd_global_list.epoll_fds[i] = + epoll_fd_global_list.epoll_fds[--(epoll_fd_global_list.count)]; + break; + } + } + gpr_mu_unlock(&epoll_fd_list_mu); +} + +void grpc_remove_fd_from_all_epoll_sets(int fd) { + int err; + gpr_once_init(&init_epoll_fd_list_mu, init_mu); + gpr_mu_lock(&epoll_fd_list_mu); + if (epoll_fd_global_list.count == 0) { + gpr_mu_unlock(&epoll_fd_list_mu); + return; + } + for (size_t i = 0; i < epoll_fd_global_list.count; i++) { + err = epoll_ctl(epoll_fd_global_list.epoll_fds[i], EPOLL_CTL_DEL, fd, NULL); + if (err < 0 && errno != ENOENT) { + gpr_log(GPR_ERROR, "epoll_ctl del for %d failed: %s", fd, + strerror(errno)); + } + } + gpr_mu_unlock(&epoll_fd_list_mu); +} + +typedef struct { + grpc_pollset *pollset; + grpc_fd *fd; + grpc_closure closure; +} delayed_add; + +typedef struct { int epoll_fd; } pollset_hdr; + +static void finally_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, + grpc_fd *fd) { + pollset_hdr *h = pollset->data.ptr; + struct epoll_event ev; + int err; + grpc_fd_watcher watcher; + + /* We pretend to be polling whilst adding an fd to keep the fd from being + closed during the add. This may result in a spurious wakeup being assigned + to this pollset whilst adding, but that should be benign. */ + GPR_ASSERT(grpc_fd_begin_poll(fd, pollset, NULL, 0, 0, &watcher) == 0); + if (watcher.fd != NULL) { + ev.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET); + ev.data.ptr = fd; + err = epoll_ctl(h->epoll_fd, EPOLL_CTL_ADD, fd->fd, &ev); + if (err < 0) { + /* FDs may be added to a pollset multiple times, so EEXIST is normal. */ + if (errno != EEXIST) { + gpr_log(GPR_ERROR, "epoll_ctl add for %d failed: %s", fd->fd, + strerror(errno)); + } + } + } + grpc_fd_end_poll(exec_ctx, &watcher, 0, 0); +} + +static void perform_delayed_add(grpc_exec_ctx *exec_ctx, void *arg, + bool iomgr_status) { + delayed_add *da = arg; + + if (!grpc_fd_is_orphaned(da->fd)) { + finally_add_fd(exec_ctx, da->pollset, da->fd); + } + + gpr_mu_lock(&da->pollset->mu); + da->pollset->in_flight_cbs--; + if (da->pollset->shutting_down) { + /* We don't care about this pollset anymore. */ + if (da->pollset->in_flight_cbs == 0 && !da->pollset->called_shutdown) { + da->pollset->called_shutdown = 1; + grpc_exec_ctx_enqueue(exec_ctx, da->pollset->shutdown_done, true, NULL); + } + } + gpr_mu_unlock(&da->pollset->mu); + + GRPC_FD_UNREF(da->fd, "delayed_add"); + + gpr_free(da); +} + +static void multipoll_with_epoll_pollset_add_fd(grpc_exec_ctx *exec_ctx, + grpc_pollset *pollset, + grpc_fd *fd, + int and_unlock_pollset) { + if (and_unlock_pollset) { + gpr_mu_unlock(&pollset->mu); + finally_add_fd(exec_ctx, pollset, fd); + } else { + delayed_add *da = gpr_malloc(sizeof(*da)); + da->pollset = pollset; + da->fd = fd; + GRPC_FD_REF(fd, "delayed_add"); + grpc_closure_init(&da->closure, perform_delayed_add, da); + pollset->in_flight_cbs++; + grpc_exec_ctx_enqueue(exec_ctx, &da->closure, true, NULL); + } +} + +/* TODO(klempner): We probably want to turn this down a bit */ +#define GRPC_EPOLL_MAX_EVENTS 1000 + +static void multipoll_with_epoll_pollset_maybe_work_and_unlock( + grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker *worker, + gpr_timespec deadline, gpr_timespec now) { + struct epoll_event ep_ev[GRPC_EPOLL_MAX_EVENTS]; + int ep_rv; + int poll_rv; + pollset_hdr *h = pollset->data.ptr; + int timeout_ms; + struct pollfd pfds[2]; + + /* If you want to ignore epoll's ability to sanely handle parallel pollers, + * for a more apples-to-apples performance comparison with poll, add a + * if (pollset->counter != 0) { return 0; } + * here. + */ + + gpr_mu_unlock(&pollset->mu); + + timeout_ms = grpc_poll_deadline_to_millis_timeout(deadline, now); + + pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd->fd); + pfds[0].events = POLLIN; + pfds[0].revents = 0; + pfds[1].fd = h->epoll_fd; + pfds[1].events = POLLIN; + pfds[1].revents = 0; + + /* TODO(vpai): Consider first doing a 0 timeout poll here to avoid + even going into the blocking annotation if possible */ + GPR_TIMER_BEGIN("poll", 0); + GRPC_SCHEDULING_START_BLOCKING_REGION; + poll_rv = grpc_poll_function(pfds, 2, timeout_ms); + GRPC_SCHEDULING_END_BLOCKING_REGION; + GPR_TIMER_END("poll", 0); + + if (poll_rv < 0) { + if (errno != EINTR) { + gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); + } + } else if (poll_rv == 0) { + /* do nothing */ + } else { + if (pfds[0].revents) { + grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd); + } + if (pfds[1].revents) { + do { + /* The following epoll_wait never blocks; it has a timeout of 0 */ + ep_rv = epoll_wait(h->epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, 0); + if (ep_rv < 0) { + if (errno != EINTR) { + gpr_log(GPR_ERROR, "epoll_wait() failed: %s", strerror(errno)); + } + } else { + int i; + for (i = 0; i < ep_rv; ++i) { + grpc_fd *fd = ep_ev[i].data.ptr; + /* TODO(klempner): We might want to consider making err and pri + * separate events */ + int cancel = ep_ev[i].events & (EPOLLERR | EPOLLHUP); + int read_ev = ep_ev[i].events & (EPOLLIN | EPOLLPRI); + int write_ev = ep_ev[i].events & EPOLLOUT; + if (fd == NULL) { + grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd); + } else { + if (read_ev || cancel) { + grpc_fd_become_readable(exec_ctx, fd); + } + if (write_ev || cancel) { + grpc_fd_become_writable(exec_ctx, fd); + } + } + } + } + } while (ep_rv == GRPC_EPOLL_MAX_EVENTS); + } + } +} + +static void multipoll_with_epoll_pollset_finish_shutdown( + grpc_pollset *pollset) {} + +static void multipoll_with_epoll_pollset_destroy(grpc_pollset *pollset) { + pollset_hdr *h = pollset->data.ptr; + close(h->epoll_fd); + remove_epoll_fd_from_global_list(h->epoll_fd); + gpr_free(h); +} + +static const grpc_pollset_vtable multipoll_with_epoll_pollset = { + multipoll_with_epoll_pollset_add_fd, + multipoll_with_epoll_pollset_maybe_work_and_unlock, + multipoll_with_epoll_pollset_finish_shutdown, + multipoll_with_epoll_pollset_destroy}; + +static void epoll_become_multipoller(grpc_exec_ctx *exec_ctx, + grpc_pollset *pollset, grpc_fd **fds, + size_t nfds) { + size_t i; + pollset_hdr *h = gpr_malloc(sizeof(pollset_hdr)); + struct epoll_event ev; + int err; + + pollset->vtable = &multipoll_with_epoll_pollset; + pollset->data.ptr = h; + h->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + if (h->epoll_fd < 0) { + /* TODO(klempner): Fall back to poll here, especially on ENOSYS */ + gpr_log(GPR_ERROR, "epoll_create1 failed: %s", strerror(errno)); + abort(); + } + add_epoll_fd_to_global_list(h->epoll_fd); + + ev.events = (uint32_t)(EPOLLIN | EPOLLET); + ev.data.ptr = NULL; + err = epoll_ctl(h->epoll_fd, EPOLL_CTL_ADD, + GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd), &ev); + if (err < 0) { + gpr_log(GPR_ERROR, "epoll_ctl add for %d failed: %s", + GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd), + strerror(errno)); + } + + for (i = 0; i < nfds; i++) { + multipoll_with_epoll_pollset_add_fd(exec_ctx, pollset, fds[i], 0); + } +} + +grpc_platform_become_multipoller_type grpc_platform_become_multipoller = + epoll_become_multipoller; + +#else /* GPR_LINUX_MULTIPOLL_WITH_EPOLL */ + +void grpc_remove_fd_from_all_epoll_sets(int fd) {} + +#endif /* GPR_LINUX_MULTIPOLL_WITH_EPOLL */ diff --git a/src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c b/src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c new file mode 100644 index 0000000000..92d6fb7241 --- /dev/null +++ b/src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c @@ -0,0 +1,234 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_SOCKET + +#include "src/core/iomgr/pollset_posix.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include "src/core/iomgr/fd_posix.h" +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/pollset_posix.h" +#include "src/core/support/block_annotate.h" + +typedef struct { + /* all polled fds */ + size_t fd_count; + size_t fd_capacity; + grpc_fd **fds; + /* fds that have been removed from the pollset explicitly */ + size_t del_count; + size_t del_capacity; + grpc_fd **dels; +} pollset_hdr; + +static void multipoll_with_poll_pollset_add_fd(grpc_exec_ctx *exec_ctx, + grpc_pollset *pollset, + grpc_fd *fd, + int and_unlock_pollset) { + size_t i; + pollset_hdr *h = pollset->data.ptr; + /* TODO(ctiller): this is O(num_fds^2); maybe switch to a hash set here */ + for (i = 0; i < h->fd_count; i++) { + if (h->fds[i] == fd) goto exit; + } + if (h->fd_count == h->fd_capacity) { + h->fd_capacity = GPR_MAX(h->fd_capacity + 8, h->fd_count * 3 / 2); + h->fds = gpr_realloc(h->fds, sizeof(grpc_fd *) * h->fd_capacity); + } + h->fds[h->fd_count++] = fd; + GRPC_FD_REF(fd, "multipoller"); +exit: + if (and_unlock_pollset) { + gpr_mu_unlock(&pollset->mu); + } +} + +static void multipoll_with_poll_pollset_maybe_work_and_unlock( + grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker *worker, + gpr_timespec deadline, gpr_timespec now) { +#define POLLOUT_CHECK (POLLOUT | POLLHUP | POLLERR) +#define POLLIN_CHECK (POLLIN | POLLHUP | POLLERR) + + int timeout; + int r; + size_t i, j, fd_count; + nfds_t pfd_count; + pollset_hdr *h; + /* TODO(ctiller): inline some elements to avoid an allocation */ + grpc_fd_watcher *watchers; + struct pollfd *pfds; + + h = pollset->data.ptr; + timeout = grpc_poll_deadline_to_millis_timeout(deadline, now); + /* TODO(ctiller): perform just one malloc here if we exceed the inline case */ + pfds = gpr_malloc(sizeof(*pfds) * (h->fd_count + 2)); + watchers = gpr_malloc(sizeof(*watchers) * (h->fd_count + 2)); + fd_count = 0; + pfd_count = 2; + pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd); + pfds[0].events = POLLIN; + pfds[0].revents = 0; + pfds[1].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd->fd); + pfds[1].events = POLLIN; + pfds[1].revents = 0; + for (i = 0; i < h->fd_count; i++) { + int remove = grpc_fd_is_orphaned(h->fds[i]); + for (j = 0; !remove && j < h->del_count; j++) { + if (h->fds[i] == h->dels[j]) remove = 1; + } + if (remove) { + GRPC_FD_UNREF(h->fds[i], "multipoller"); + } else { + h->fds[fd_count++] = h->fds[i]; + watchers[pfd_count].fd = h->fds[i]; + GRPC_FD_REF(watchers[pfd_count].fd, "multipoller_start"); + pfds[pfd_count].fd = h->fds[i]->fd; + pfds[pfd_count].revents = 0; + pfd_count++; + } + } + for (j = 0; j < h->del_count; j++) { + GRPC_FD_UNREF(h->dels[j], "multipoller_del"); + } + h->del_count = 0; + h->fd_count = fd_count; + gpr_mu_unlock(&pollset->mu); + + for (i = 2; i < pfd_count; i++) { + grpc_fd *fd = watchers[i].fd; + pfds[i].events = (short)grpc_fd_begin_poll(fd, pollset, worker, POLLIN, + POLLOUT, &watchers[i]); + GRPC_FD_UNREF(fd, "multipoller_start"); + } + + /* TODO(vpai): Consider first doing a 0 timeout poll here to avoid + even going into the blocking annotation if possible */ + GRPC_SCHEDULING_START_BLOCKING_REGION; + r = grpc_poll_function(pfds, pfd_count, timeout); + GRPC_SCHEDULING_END_BLOCKING_REGION; + + if (r < 0) { + if (errno != EINTR) { + gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); + } + for (i = 2; i < pfd_count; i++) { + grpc_fd_end_poll(exec_ctx, &watchers[i], 0, 0); + } + } else if (r == 0) { + for (i = 2; i < pfd_count; i++) { + grpc_fd_end_poll(exec_ctx, &watchers[i], 0, 0); + } + } else { + if (pfds[0].revents & POLLIN_CHECK) { + grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd); + } + if (pfds[1].revents & POLLIN_CHECK) { + grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd); + } + for (i = 2; i < pfd_count; i++) { + if (watchers[i].fd == NULL) { + grpc_fd_end_poll(exec_ctx, &watchers[i], 0, 0); + continue; + } + grpc_fd_end_poll(exec_ctx, &watchers[i], pfds[i].revents & POLLIN_CHECK, + pfds[i].revents & POLLOUT_CHECK); + } + } + + gpr_free(pfds); + gpr_free(watchers); +} + +static void multipoll_with_poll_pollset_finish_shutdown(grpc_pollset *pollset) { + size_t i; + pollset_hdr *h = pollset->data.ptr; + for (i = 0; i < h->fd_count; i++) { + GRPC_FD_UNREF(h->fds[i], "multipoller"); + } + for (i = 0; i < h->del_count; i++) { + GRPC_FD_UNREF(h->dels[i], "multipoller_del"); + } + h->fd_count = 0; + h->del_count = 0; +} + +static void multipoll_with_poll_pollset_destroy(grpc_pollset *pollset) { + pollset_hdr *h = pollset->data.ptr; + multipoll_with_poll_pollset_finish_shutdown(pollset); + gpr_free(h->fds); + gpr_free(h->dels); + gpr_free(h); +} + +static const grpc_pollset_vtable multipoll_with_poll_pollset = { + multipoll_with_poll_pollset_add_fd, + multipoll_with_poll_pollset_maybe_work_and_unlock, + multipoll_with_poll_pollset_finish_shutdown, + multipoll_with_poll_pollset_destroy}; + +void grpc_poll_become_multipoller(grpc_exec_ctx *exec_ctx, + grpc_pollset *pollset, grpc_fd **fds, + size_t nfds) { + size_t i; + pollset_hdr *h = gpr_malloc(sizeof(pollset_hdr)); + pollset->vtable = &multipoll_with_poll_pollset; + pollset->data.ptr = h; + h->fd_count = nfds; + h->fd_capacity = nfds; + h->fds = gpr_malloc(nfds * sizeof(grpc_fd *)); + h->del_count = 0; + h->del_capacity = 0; + h->dels = NULL; + for (i = 0; i < nfds; i++) { + h->fds[i] = fds[i]; + GRPC_FD_REF(fds[i], "multipoller"); + } +} + +#endif /* GPR_POSIX_SOCKET */ + +#ifdef GPR_POSIX_MULTIPOLL_WITH_POLL +grpc_platform_become_multipoller_type grpc_platform_become_multipoller = + grpc_poll_become_multipoller; +#endif diff --git a/src/core/lib/iomgr/pollset_posix.c b/src/core/lib/iomgr/pollset_posix.c new file mode 100644 index 0000000000..e895a77884 --- /dev/null +++ b/src/core/lib/iomgr/pollset_posix.c @@ -0,0 +1,633 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_SOCKET + +#include "src/core/iomgr/pollset_posix.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "src/core/iomgr/fd_posix.h" +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/profiling/timers.h" +#include "src/core/support/block_annotate.h" + +GPR_TLS_DECL(g_current_thread_poller); +GPR_TLS_DECL(g_current_thread_worker); + +/** Default poll() function - a pointer so that it can be overridden by some + * tests */ +grpc_poll_function_type grpc_poll_function = poll; + +/** The alarm system needs to be able to wakeup 'some poller' sometimes + * (specifically when a new alarm needs to be triggered earlier than the next + * alarm 'epoch'). + * This wakeup_fd gives us something to alert on when such a case occurs. */ +grpc_wakeup_fd grpc_global_wakeup_fd; + +static void remove_worker(grpc_pollset *p, grpc_pollset_worker *worker) { + worker->prev->next = worker->next; + worker->next->prev = worker->prev; +} + +int grpc_pollset_has_workers(grpc_pollset *p) { + return p->root_worker.next != &p->root_worker; +} + +static grpc_pollset_worker *pop_front_worker(grpc_pollset *p) { + if (grpc_pollset_has_workers(p)) { + grpc_pollset_worker *w = p->root_worker.next; + remove_worker(p, w); + return w; + } else { + return NULL; + } +} + +static void push_back_worker(grpc_pollset *p, grpc_pollset_worker *worker) { + worker->next = &p->root_worker; + worker->prev = worker->next->prev; + worker->prev->next = worker->next->prev = worker; +} + +static void push_front_worker(grpc_pollset *p, grpc_pollset_worker *worker) { + worker->prev = &p->root_worker; + worker->next = worker->prev->next; + worker->prev->next = worker->next->prev = worker; +} + +size_t grpc_pollset_size(void) { return sizeof(grpc_pollset); } + +void grpc_pollset_kick_ext(grpc_pollset *p, + grpc_pollset_worker *specific_worker, + uint32_t flags) { + GPR_TIMER_BEGIN("grpc_pollset_kick_ext", 0); + + /* pollset->mu already held */ + if (specific_worker != NULL) { + if (specific_worker == GRPC_POLLSET_KICK_BROADCAST) { + GPR_TIMER_BEGIN("grpc_pollset_kick_ext.broadcast", 0); + GPR_ASSERT((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) == 0); + for (specific_worker = p->root_worker.next; + specific_worker != &p->root_worker; + specific_worker = specific_worker->next) { + grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd); + } + p->kicked_without_pollers = 1; + GPR_TIMER_END("grpc_pollset_kick_ext.broadcast", 0); + } else if (gpr_tls_get(&g_current_thread_worker) != + (intptr_t)specific_worker) { + GPR_TIMER_MARK("different_thread_worker", 0); + if ((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) != 0) { + specific_worker->reevaluate_polling_on_wakeup = 1; + } + specific_worker->kicked_specifically = 1; + grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd); + } else if ((flags & GRPC_POLLSET_CAN_KICK_SELF) != 0) { + GPR_TIMER_MARK("kick_yoself", 0); + if ((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) != 0) { + specific_worker->reevaluate_polling_on_wakeup = 1; + } + specific_worker->kicked_specifically = 1; + grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd); + } + } else if (gpr_tls_get(&g_current_thread_poller) != (intptr_t)p) { + GPR_ASSERT((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) == 0); + GPR_TIMER_MARK("kick_anonymous", 0); + specific_worker = pop_front_worker(p); + if (specific_worker != NULL) { + if (gpr_tls_get(&g_current_thread_worker) == (intptr_t)specific_worker) { + GPR_TIMER_MARK("kick_anonymous_not_self", 0); + push_back_worker(p, specific_worker); + specific_worker = pop_front_worker(p); + if ((flags & GRPC_POLLSET_CAN_KICK_SELF) == 0 && + gpr_tls_get(&g_current_thread_worker) == + (intptr_t)specific_worker) { + push_back_worker(p, specific_worker); + specific_worker = NULL; + } + } + if (specific_worker != NULL) { + GPR_TIMER_MARK("finally_kick", 0); + push_back_worker(p, specific_worker); + grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd); + } + } else { + GPR_TIMER_MARK("kicked_no_pollers", 0); + p->kicked_without_pollers = 1; + } + } + + GPR_TIMER_END("grpc_pollset_kick_ext", 0); +} + +void grpc_pollset_kick(grpc_pollset *p, grpc_pollset_worker *specific_worker) { + grpc_pollset_kick_ext(p, specific_worker, 0); +} + +/* global state management */ + +void grpc_pollset_global_init(void) { + gpr_tls_init(&g_current_thread_poller); + gpr_tls_init(&g_current_thread_worker); + grpc_wakeup_fd_global_init(); + grpc_wakeup_fd_init(&grpc_global_wakeup_fd); +} + +void grpc_pollset_global_shutdown(void) { + grpc_wakeup_fd_destroy(&grpc_global_wakeup_fd); + gpr_tls_destroy(&g_current_thread_poller); + gpr_tls_destroy(&g_current_thread_worker); + grpc_wakeup_fd_global_destroy(); +} + +void grpc_kick_poller(void) { grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd); } + +/* main interface */ + +static void become_basic_pollset(grpc_pollset *pollset, grpc_fd *fd_or_null); + +void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) { + gpr_mu_init(&pollset->mu); + *mu = &pollset->mu; + pollset->root_worker.next = pollset->root_worker.prev = &pollset->root_worker; + pollset->in_flight_cbs = 0; + pollset->shutting_down = 0; + pollset->called_shutdown = 0; + pollset->kicked_without_pollers = 0; + pollset->idle_jobs.head = pollset->idle_jobs.tail = NULL; + pollset->local_wakeup_cache = NULL; + pollset->kicked_without_pollers = 0; + become_basic_pollset(pollset, NULL); +} + +void grpc_pollset_destroy(grpc_pollset *pollset) { + GPR_ASSERT(pollset->in_flight_cbs == 0); + GPR_ASSERT(!grpc_pollset_has_workers(pollset)); + GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail); + pollset->vtable->destroy(pollset); + while (pollset->local_wakeup_cache) { + grpc_cached_wakeup_fd *next = pollset->local_wakeup_cache->next; + grpc_wakeup_fd_destroy(&pollset->local_wakeup_cache->fd); + gpr_free(pollset->local_wakeup_cache); + pollset->local_wakeup_cache = next; + } +} + +void grpc_pollset_reset(grpc_pollset *pollset) { + GPR_ASSERT(pollset->shutting_down); + GPR_ASSERT(pollset->in_flight_cbs == 0); + GPR_ASSERT(!grpc_pollset_has_workers(pollset)); + GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail); + pollset->vtable->destroy(pollset); + pollset->shutting_down = 0; + pollset->called_shutdown = 0; + pollset->kicked_without_pollers = 0; + become_basic_pollset(pollset, NULL); +} + +void grpc_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, + grpc_fd *fd) { + gpr_mu_lock(&pollset->mu); + pollset->vtable->add_fd(exec_ctx, pollset, fd, 1); +/* the following (enabled only in debug) will reacquire and then release + our lock - meaning that if the unlocking flag passed to add_fd above is + not respected, the code will deadlock (in a way that we have a chance of + debugging) */ +#ifndef NDEBUG + gpr_mu_lock(&pollset->mu); + gpr_mu_unlock(&pollset->mu); +#endif +} + +static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset) { + GPR_ASSERT(grpc_closure_list_empty(pollset->idle_jobs)); + pollset->vtable->finish_shutdown(pollset); + grpc_exec_ctx_enqueue(exec_ctx, pollset->shutdown_done, true, NULL); +} + +void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, + grpc_pollset_worker **worker_hdl, gpr_timespec now, + gpr_timespec deadline) { + grpc_pollset_worker worker; + *worker_hdl = &worker; + + /* pollset->mu already held */ + int added_worker = 0; + int locked = 1; + int queued_work = 0; + int keep_polling = 0; + GPR_TIMER_BEGIN("grpc_pollset_work", 0); + /* this must happen before we (potentially) drop pollset->mu */ + worker.next = worker.prev = NULL; + worker.reevaluate_polling_on_wakeup = 0; + if (pollset->local_wakeup_cache != NULL) { + worker.wakeup_fd = pollset->local_wakeup_cache; + pollset->local_wakeup_cache = worker.wakeup_fd->next; + } else { + worker.wakeup_fd = gpr_malloc(sizeof(*worker.wakeup_fd)); + grpc_wakeup_fd_init(&worker.wakeup_fd->fd); + } + worker.kicked_specifically = 0; + /* If there's work waiting for the pollset to be idle, and the + pollset is idle, then do that work */ + if (!grpc_pollset_has_workers(pollset) && + !grpc_closure_list_empty(pollset->idle_jobs)) { + GPR_TIMER_MARK("grpc_pollset_work.idle_jobs", 0); + grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL); + goto done; + } + /* If we're shutting down then we don't execute any extended work */ + if (pollset->shutting_down) { + GPR_TIMER_MARK("grpc_pollset_work.shutting_down", 0); + goto done; + } + /* Give do_promote priority so we don't starve it out */ + if (pollset->in_flight_cbs) { + GPR_TIMER_MARK("grpc_pollset_work.in_flight_cbs", 0); + gpr_mu_unlock(&pollset->mu); + locked = 0; + goto done; + } + /* Start polling, and keep doing so while we're being asked to + re-evaluate our pollers (this allows poll() based pollers to + ensure they don't miss wakeups) */ + keep_polling = 1; + while (keep_polling) { + keep_polling = 0; + if (!pollset->kicked_without_pollers) { + if (!added_worker) { + push_front_worker(pollset, &worker); + added_worker = 1; + gpr_tls_set(&g_current_thread_worker, (intptr_t)&worker); + } + gpr_tls_set(&g_current_thread_poller, (intptr_t)pollset); + GPR_TIMER_BEGIN("maybe_work_and_unlock", 0); + pollset->vtable->maybe_work_and_unlock(exec_ctx, pollset, &worker, + deadline, now); + GPR_TIMER_END("maybe_work_and_unlock", 0); + locked = 0; + gpr_tls_set(&g_current_thread_poller, 0); + } else { + GPR_TIMER_MARK("grpc_pollset_work.kicked_without_pollers", 0); + pollset->kicked_without_pollers = 0; + } + /* Finished execution - start cleaning up. + Note that we may arrive here from outside the enclosing while() loop. + In that case we won't loop though as we haven't added worker to the + worker list, which means nobody could ask us to re-evaluate polling). */ + done: + if (!locked) { + queued_work |= grpc_exec_ctx_flush(exec_ctx); + gpr_mu_lock(&pollset->mu); + locked = 1; + } + /* If we're forced to re-evaluate polling (via grpc_pollset_kick with + GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) then we land here and force + a loop */ + if (worker.reevaluate_polling_on_wakeup) { + worker.reevaluate_polling_on_wakeup = 0; + pollset->kicked_without_pollers = 0; + if (queued_work || worker.kicked_specifically) { + /* If there's queued work on the list, then set the deadline to be + immediate so we get back out of the polling loop quickly */ + deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC); + } + keep_polling = 1; + } + } + if (added_worker) { + remove_worker(pollset, &worker); + gpr_tls_set(&g_current_thread_worker, 0); + } + /* release wakeup fd to the local pool */ + worker.wakeup_fd->next = pollset->local_wakeup_cache; + pollset->local_wakeup_cache = worker.wakeup_fd; + /* check shutdown conditions */ + if (pollset->shutting_down) { + if (grpc_pollset_has_workers(pollset)) { + grpc_pollset_kick(pollset, NULL); + } else if (!pollset->called_shutdown && pollset->in_flight_cbs == 0) { + pollset->called_shutdown = 1; + gpr_mu_unlock(&pollset->mu); + finish_shutdown(exec_ctx, pollset); + grpc_exec_ctx_flush(exec_ctx); + /* Continuing to access pollset here is safe -- it is the caller's + * responsibility to not destroy when it has outstanding calls to + * grpc_pollset_work. + * TODO(dklempner): Can we refactor the shutdown logic to avoid this? */ + gpr_mu_lock(&pollset->mu); + } else if (!grpc_closure_list_empty(pollset->idle_jobs)) { + grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL); + gpr_mu_unlock(&pollset->mu); + grpc_exec_ctx_flush(exec_ctx); + gpr_mu_lock(&pollset->mu); + } + } + *worker_hdl = NULL; + GPR_TIMER_END("grpc_pollset_work", 0); +} + +void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, + grpc_closure *closure) { + GPR_ASSERT(!pollset->shutting_down); + pollset->shutting_down = 1; + pollset->shutdown_done = closure; + grpc_pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST); + if (!grpc_pollset_has_workers(pollset)) { + grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL); + } + if (!pollset->called_shutdown && pollset->in_flight_cbs == 0 && + !grpc_pollset_has_workers(pollset)) { + pollset->called_shutdown = 1; + finish_shutdown(exec_ctx, pollset); + } +} + +int grpc_poll_deadline_to_millis_timeout(gpr_timespec deadline, + gpr_timespec now) { + gpr_timespec timeout; + static const int64_t max_spin_polling_us = 10; + if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) == 0) { + return -1; + } + if (gpr_time_cmp(deadline, gpr_time_add(now, gpr_time_from_micros( + max_spin_polling_us, + GPR_TIMESPAN))) <= 0) { + return 0; + } + timeout = gpr_time_sub(deadline, now); + return gpr_time_to_millis(gpr_time_add( + timeout, gpr_time_from_nanos(GPR_NS_PER_MS - 1, GPR_TIMESPAN))); +} + +/* + * basic_pollset - a vtable that provides polling for zero or one file + * descriptor via poll() + */ + +typedef struct grpc_unary_promote_args { + const grpc_pollset_vtable *original_vtable; + grpc_pollset *pollset; + grpc_fd *fd; + grpc_closure promotion_closure; +} grpc_unary_promote_args; + +static void basic_do_promote(grpc_exec_ctx *exec_ctx, void *args, + bool success) { + grpc_unary_promote_args *up_args = args; + const grpc_pollset_vtable *original_vtable = up_args->original_vtable; + grpc_pollset *pollset = up_args->pollset; + grpc_fd *fd = up_args->fd; + + /* + * This is quite tricky. There are a number of cases to keep in mind here: + * 1. fd may have been orphaned + * 2. The pollset may no longer be a unary poller (and we can't let case #1 + * leak to other pollset types!) + * 3. pollset's fd (which may have changed) may have been orphaned + * 4. The pollset may be shutting down. + */ + + gpr_mu_lock(&pollset->mu); + /* First we need to ensure that nobody is polling concurrently */ + GPR_ASSERT(!grpc_pollset_has_workers(pollset)); + + gpr_free(up_args); + /* At this point the pollset may no longer be a unary poller. In that case + * we should just call the right add function and be done. */ + /* TODO(klempner): If we're not careful this could cause infinite recursion. + * That's not a problem for now because empty_pollset has a trivial poller + * and we don't have any mechanism to unbecome multipoller. */ + pollset->in_flight_cbs--; + if (pollset->shutting_down) { + /* We don't care about this pollset anymore. */ + if (pollset->in_flight_cbs == 0 && !pollset->called_shutdown) { + pollset->called_shutdown = 1; + finish_shutdown(exec_ctx, pollset); + } + } else if (grpc_fd_is_orphaned(fd)) { + /* Don't try to add it to anything, we'll drop our ref on it below */ + } else if (pollset->vtable != original_vtable) { + pollset->vtable->add_fd(exec_ctx, pollset, fd, 0); + } else if (fd != pollset->data.ptr) { + grpc_fd *fds[2]; + fds[0] = pollset->data.ptr; + fds[1] = fd; + + if (fds[0] && !grpc_fd_is_orphaned(fds[0])) { + grpc_platform_become_multipoller(exec_ctx, pollset, fds, + GPR_ARRAY_SIZE(fds)); + GRPC_FD_UNREF(fds[0], "basicpoll"); + } else { + /* old fd is orphaned and we haven't cleaned it up until now, so remain a + * unary poller */ + /* Note that it is possible that fds[1] is also orphaned at this point. + * That's okay, we'll correct it at the next add or poll. */ + if (fds[0]) GRPC_FD_UNREF(fds[0], "basicpoll"); + pollset->data.ptr = fd; + GRPC_FD_REF(fd, "basicpoll"); + } + } + + gpr_mu_unlock(&pollset->mu); + + /* Matching ref in basic_pollset_add_fd */ + GRPC_FD_UNREF(fd, "basicpoll_add"); +} + +static void basic_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, + grpc_fd *fd, int and_unlock_pollset) { + grpc_unary_promote_args *up_args; + GPR_ASSERT(fd); + if (fd == pollset->data.ptr) goto exit; + + if (!grpc_pollset_has_workers(pollset)) { + /* Fast path -- no in flight cbs */ + /* TODO(klempner): Comment this out and fix any test failures or establish + * they are due to timing issues */ + grpc_fd *fds[2]; + fds[0] = pollset->data.ptr; + fds[1] = fd; + + if (fds[0] == NULL) { + pollset->data.ptr = fd; + GRPC_FD_REF(fd, "basicpoll"); + } else if (!grpc_fd_is_orphaned(fds[0])) { + grpc_platform_become_multipoller(exec_ctx, pollset, fds, + GPR_ARRAY_SIZE(fds)); + GRPC_FD_UNREF(fds[0], "basicpoll"); + } else { + /* old fd is orphaned and we haven't cleaned it up until now, so remain a + * unary poller */ + GRPC_FD_UNREF(fds[0], "basicpoll"); + pollset->data.ptr = fd; + GRPC_FD_REF(fd, "basicpoll"); + } + goto exit; + } + + /* Now we need to promote. This needs to happen when we're not polling. Since + * this may be called from poll, the wait needs to happen asynchronously. */ + GRPC_FD_REF(fd, "basicpoll_add"); + pollset->in_flight_cbs++; + up_args = gpr_malloc(sizeof(*up_args)); + up_args->fd = fd; + up_args->original_vtable = pollset->vtable; + up_args->pollset = pollset; + up_args->promotion_closure.cb = basic_do_promote; + up_args->promotion_closure.cb_arg = up_args; + + grpc_closure_list_add(&pollset->idle_jobs, &up_args->promotion_closure, 1); + grpc_pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST); + +exit: + if (and_unlock_pollset) { + gpr_mu_unlock(&pollset->mu); + } +} + +static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx, + grpc_pollset *pollset, + grpc_pollset_worker *worker, + gpr_timespec deadline, + gpr_timespec now) { +#define POLLOUT_CHECK (POLLOUT | POLLHUP | POLLERR) +#define POLLIN_CHECK (POLLIN | POLLHUP | POLLERR) + + struct pollfd pfd[3]; + grpc_fd *fd; + grpc_fd_watcher fd_watcher; + int timeout; + int r; + nfds_t nfds; + + fd = pollset->data.ptr; + if (fd && grpc_fd_is_orphaned(fd)) { + GRPC_FD_UNREF(fd, "basicpoll"); + fd = pollset->data.ptr = NULL; + } + timeout = grpc_poll_deadline_to_millis_timeout(deadline, now); + pfd[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd); + pfd[0].events = POLLIN; + pfd[0].revents = 0; + pfd[1].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd->fd); + pfd[1].events = POLLIN; + pfd[1].revents = 0; + nfds = 2; + if (fd) { + pfd[2].fd = fd->fd; + pfd[2].revents = 0; + GRPC_FD_REF(fd, "basicpoll_begin"); + gpr_mu_unlock(&pollset->mu); + pfd[2].events = (short)grpc_fd_begin_poll(fd, pollset, worker, POLLIN, + POLLOUT, &fd_watcher); + if (pfd[2].events != 0) { + nfds++; + } + } else { + gpr_mu_unlock(&pollset->mu); + } + + /* TODO(vpai): Consider first doing a 0 timeout poll here to avoid + even going into the blocking annotation if possible */ + /* poll fd count (argument 2) is shortened by one if we have no events + to poll on - such that it only includes the kicker */ + GPR_TIMER_BEGIN("poll", 0); + GRPC_SCHEDULING_START_BLOCKING_REGION; + r = grpc_poll_function(pfd, nfds, timeout); + GRPC_SCHEDULING_END_BLOCKING_REGION; + GPR_TIMER_END("poll", 0); + + if (r < 0) { + if (errno != EINTR) { + gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); + } + if (fd) { + grpc_fd_end_poll(exec_ctx, &fd_watcher, 0, 0); + } + } else if (r == 0) { + if (fd) { + grpc_fd_end_poll(exec_ctx, &fd_watcher, 0, 0); + } + } else { + if (pfd[0].revents & POLLIN_CHECK) { + grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd); + } + if (pfd[1].revents & POLLIN_CHECK) { + grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd); + } + if (nfds > 2) { + grpc_fd_end_poll(exec_ctx, &fd_watcher, pfd[2].revents & POLLIN_CHECK, + pfd[2].revents & POLLOUT_CHECK); + } else if (fd) { + grpc_fd_end_poll(exec_ctx, &fd_watcher, 0, 0); + } + } + + if (fd) { + GRPC_FD_UNREF(fd, "basicpoll_begin"); + } +} + +static void basic_pollset_destroy(grpc_pollset *pollset) { + if (pollset->data.ptr != NULL) { + GRPC_FD_UNREF(pollset->data.ptr, "basicpoll"); + pollset->data.ptr = NULL; + } +} + +static const grpc_pollset_vtable basic_pollset = { + basic_pollset_add_fd, basic_pollset_maybe_work_and_unlock, + basic_pollset_destroy, basic_pollset_destroy}; + +static void become_basic_pollset(grpc_pollset *pollset, grpc_fd *fd_or_null) { + pollset->vtable = &basic_pollset; + pollset->data.ptr = fd_or_null; + if (fd_or_null != NULL) { + GRPC_FD_REF(fd_or_null, "basicpoll"); + } +} + +#endif /* GPR_POSIX_POLLSET */ diff --git a/src/core/lib/iomgr/pollset_posix.h b/src/core/lib/iomgr/pollset_posix.h new file mode 100644 index 0000000000..e0cfc44395 --- /dev/null +++ b/src/core/lib/iomgr/pollset_posix.h @@ -0,0 +1,153 @@ +/* + * + * Copyright 2015-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_IOMGR_POLLSET_POSIX_H +#define GRPC_CORE_IOMGR_POLLSET_POSIX_H + +#include + +#include + +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/iomgr/iomgr.h" +#include "src/core/iomgr/pollset.h" +#include "src/core/iomgr/wakeup_fd_posix.h" + +typedef struct grpc_pollset_vtable grpc_pollset_vtable; + +/* forward declare only in this file to avoid leaking impl details via + pollset.h; real users of grpc_fd should always include 'fd_posix.h' and not + use the struct tag */ +struct grpc_fd; + +typedef struct grpc_cached_wakeup_fd { + grpc_wakeup_fd fd; + struct grpc_cached_wakeup_fd *next; +} grpc_cached_wakeup_fd; + +struct grpc_pollset_worker { + grpc_cached_wakeup_fd *wakeup_fd; + int reevaluate_polling_on_wakeup; + int kicked_specifically; + struct grpc_pollset_worker *next; + struct grpc_pollset_worker *prev; +}; + +struct grpc_pollset { + /* pollsets under posix can mutate representation as fds are added and + removed. + For example, we may choose a poll() based implementation on linux for + few fds, and an epoll() based implementation for many fds */ + const grpc_pollset_vtable *vtable; + gpr_mu mu; + grpc_pollset_worker root_worker; + int in_flight_cbs; + int shutting_down; + int called_shutdown; + int kicked_without_pollers; + grpc_closure *shutdown_done; + grpc_closure_list idle_jobs; + union { + int fd; + void *ptr; + } data; + /* Local cache of eventfds for workers */ + grpc_cached_wakeup_fd *local_wakeup_cache; +}; + +struct grpc_pollset_vtable { + void (*add_fd)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, + struct grpc_fd *fd, int and_unlock_pollset); + void (*maybe_work_and_unlock)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, + grpc_pollset_worker *worker, + gpr_timespec deadline, gpr_timespec now); + void (*finish_shutdown)(grpc_pollset *pollset); + void (*destroy)(grpc_pollset *pollset); +}; + +/* Add an fd to a pollset */ +void grpc_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, + struct grpc_fd *fd); + +/* Returns the fd to listen on for kicks */ +int grpc_kick_read_fd(grpc_pollset *p); +/* Call after polling has been kicked to leave the kicked state */ +void grpc_kick_drain(grpc_pollset *p); + +/* Convert a timespec to milliseconds: + - very small or negative poll times are clamped to zero to do a + non-blocking poll (which becomes spin polling) + - other small values are rounded up to one millisecond + - longer than a millisecond polls are rounded up to the next nearest + millisecond to avoid spinning + - infinite timeouts are converted to -1 */ +int grpc_poll_deadline_to_millis_timeout(gpr_timespec deadline, + gpr_timespec now); + +/* Allow kick to wakeup the currently polling worker */ +#define GRPC_POLLSET_CAN_KICK_SELF 1 +/* Force the wakee to repoll when awoken */ +#define GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP 2 +/* As per grpc_pollset_kick, with an extended set of flags (defined above) + -- mostly for fd_posix's use. */ +void grpc_pollset_kick_ext(grpc_pollset *p, + grpc_pollset_worker *specific_worker, + uint32_t flags); + +/* turn a pollset into a multipoller: platform specific */ +typedef void (*grpc_platform_become_multipoller_type)(grpc_exec_ctx *exec_ctx, + grpc_pollset *pollset, + struct grpc_fd **fds, + size_t fd_count); +extern grpc_platform_become_multipoller_type grpc_platform_become_multipoller; + +void grpc_poll_become_multipoller(grpc_exec_ctx *exec_ctx, + grpc_pollset *pollset, struct grpc_fd **fds, + size_t fd_count); + +/* Return 1 if the pollset has active threads in grpc_pollset_work (pollset must + * be locked) */ +int grpc_pollset_has_workers(grpc_pollset *pollset); + +void grpc_remove_fd_from_all_epoll_sets(int fd); + +/* override to allow tests to hook poll() usage */ +/* NOTE: Any changes to grpc_poll_function must take place when the gRPC + is certainly not doing any polling anywhere. + Otherwise, there might be a race between changing the variable and actually + doing a polling operation */ +typedef int (*grpc_poll_function_type)(struct pollfd *, nfds_t, int); +extern grpc_poll_function_type grpc_poll_function; +extern grpc_wakeup_fd grpc_global_wakeup_fd; + +#endif /* GRPC_CORE_IOMGR_POLLSET_POSIX_H */ diff --git a/src/core/lib/iomgr/pollset_set.h b/src/core/lib/iomgr/pollset_set.h new file mode 100644 index 0000000000..204c625933 --- /dev/null +++ b/src/core/lib/iomgr/pollset_set.h @@ -0,0 +1,61 @@ +/* + * + * Copyright 2015-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_IOMGR_POLLSET_SET_H +#define GRPC_CORE_IOMGR_POLLSET_SET_H + +#include "src/core/iomgr/pollset.h" + +/* A grpc_pollset_set is a set of pollsets that are interested in an + action. Adding a pollset to a pollset_set automatically adds any + fd's (etc) that have been registered with the set_set to that pollset. + Registering fd's automatically adds them to all current pollsets. */ + +typedef struct grpc_pollset_set grpc_pollset_set; + +grpc_pollset_set *grpc_pollset_set_create(void); +void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set); +void grpc_pollset_set_add_pollset(grpc_exec_ctx *exec_ctx, + grpc_pollset_set *pollset_set, + grpc_pollset *pollset); +void grpc_pollset_set_del_pollset(grpc_exec_ctx *exec_ctx, + grpc_pollset_set *pollset_set, + grpc_pollset *pollset); +void grpc_pollset_set_add_pollset_set(grpc_exec_ctx *exec_ctx, + grpc_pollset_set *bag, + grpc_pollset_set *item); +void grpc_pollset_set_del_pollset_set(grpc_exec_ctx *exec_ctx, + grpc_pollset_set *bag, + grpc_pollset_set *item); + +#endif /* GRPC_CORE_IOMGR_POLLSET_SET_H */ diff --git a/src/core/lib/iomgr/pollset_set_posix.c b/src/core/lib/iomgr/pollset_set_posix.c new file mode 100644 index 0000000000..9dc9aff4a8 --- /dev/null +++ b/src/core/lib/iomgr/pollset_set_posix.c @@ -0,0 +1,202 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_SOCKET + +#include +#include + +#include +#include + +#include "src/core/iomgr/pollset_posix.h" +#include "src/core/iomgr/pollset_set_posix.h" + +struct grpc_pollset_set { + gpr_mu mu; + + size_t pollset_count; + size_t pollset_capacity; + grpc_pollset **pollsets; + + size_t pollset_set_count; + size_t pollset_set_capacity; + struct grpc_pollset_set **pollset_sets; + + size_t fd_count; + size_t fd_capacity; + grpc_fd **fds; +}; + +grpc_pollset_set *grpc_pollset_set_create(void) { + grpc_pollset_set *pollset_set = gpr_malloc(sizeof(*pollset_set)); + memset(pollset_set, 0, sizeof(*pollset_set)); + gpr_mu_init(&pollset_set->mu); + return pollset_set; +} + +void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set) { + size_t i; + gpr_mu_destroy(&pollset_set->mu); + for (i = 0; i < pollset_set->fd_count; i++) { + GRPC_FD_UNREF(pollset_set->fds[i], "pollset_set"); + } + gpr_free(pollset_set->pollsets); + gpr_free(pollset_set->pollset_sets); + gpr_free(pollset_set->fds); + gpr_free(pollset_set); +} + +void grpc_pollset_set_add_pollset(grpc_exec_ctx *exec_ctx, + grpc_pollset_set *pollset_set, + grpc_pollset *pollset) { + size_t i, j; + gpr_mu_lock(&pollset_set->mu); + if (pollset_set->pollset_count == pollset_set->pollset_capacity) { + pollset_set->pollset_capacity = + GPR_MAX(8, 2 * pollset_set->pollset_capacity); + pollset_set->pollsets = + gpr_realloc(pollset_set->pollsets, pollset_set->pollset_capacity * + sizeof(*pollset_set->pollsets)); + } + pollset_set->pollsets[pollset_set->pollset_count++] = pollset; + for (i = 0, j = 0; i < pollset_set->fd_count; i++) { + if (grpc_fd_is_orphaned(pollset_set->fds[i])) { + GRPC_FD_UNREF(pollset_set->fds[i], "pollset_set"); + } else { + grpc_pollset_add_fd(exec_ctx, pollset, pollset_set->fds[i]); + pollset_set->fds[j++] = pollset_set->fds[i]; + } + } + pollset_set->fd_count = j; + gpr_mu_unlock(&pollset_set->mu); +} + +void grpc_pollset_set_del_pollset(grpc_exec_ctx *exec_ctx, + grpc_pollset_set *pollset_set, + grpc_pollset *pollset) { + size_t i; + gpr_mu_lock(&pollset_set->mu); + for (i = 0; i < pollset_set->pollset_count; i++) { + if (pollset_set->pollsets[i] == pollset) { + pollset_set->pollset_count--; + GPR_SWAP(grpc_pollset *, pollset_set->pollsets[i], + pollset_set->pollsets[pollset_set->pollset_count]); + break; + } + } + gpr_mu_unlock(&pollset_set->mu); +} + +void grpc_pollset_set_add_pollset_set(grpc_exec_ctx *exec_ctx, + grpc_pollset_set *bag, + grpc_pollset_set *item) { + size_t i, j; + gpr_mu_lock(&bag->mu); + if (bag->pollset_set_count == bag->pollset_set_capacity) { + bag->pollset_set_capacity = GPR_MAX(8, 2 * bag->pollset_set_capacity); + bag->pollset_sets = + gpr_realloc(bag->pollset_sets, + bag->pollset_set_capacity * sizeof(*bag->pollset_sets)); + } + bag->pollset_sets[bag->pollset_set_count++] = item; + for (i = 0, j = 0; i < bag->fd_count; i++) { + if (grpc_fd_is_orphaned(bag->fds[i])) { + GRPC_FD_UNREF(bag->fds[i], "pollset_set"); + } else { + grpc_pollset_set_add_fd(exec_ctx, item, bag->fds[i]); + bag->fds[j++] = bag->fds[i]; + } + } + bag->fd_count = j; + gpr_mu_unlock(&bag->mu); +} + +void grpc_pollset_set_del_pollset_set(grpc_exec_ctx *exec_ctx, + grpc_pollset_set *bag, + grpc_pollset_set *item) { + size_t i; + gpr_mu_lock(&bag->mu); + for (i = 0; i < bag->pollset_set_count; i++) { + if (bag->pollset_sets[i] == item) { + bag->pollset_set_count--; + GPR_SWAP(grpc_pollset_set *, bag->pollset_sets[i], + bag->pollset_sets[bag->pollset_set_count]); + break; + } + } + gpr_mu_unlock(&bag->mu); +} + +void grpc_pollset_set_add_fd(grpc_exec_ctx *exec_ctx, + grpc_pollset_set *pollset_set, grpc_fd *fd) { + size_t i; + gpr_mu_lock(&pollset_set->mu); + if (pollset_set->fd_count == pollset_set->fd_capacity) { + pollset_set->fd_capacity = GPR_MAX(8, 2 * pollset_set->fd_capacity); + pollset_set->fds = gpr_realloc( + pollset_set->fds, pollset_set->fd_capacity * sizeof(*pollset_set->fds)); + } + GRPC_FD_REF(fd, "pollset_set"); + pollset_set->fds[pollset_set->fd_count++] = fd; + for (i = 0; i < pollset_set->pollset_count; i++) { + grpc_pollset_add_fd(exec_ctx, pollset_set->pollsets[i], fd); + } + for (i = 0; i < pollset_set->pollset_set_count; i++) { + grpc_pollset_set_add_fd(exec_ctx, pollset_set->pollset_sets[i], fd); + } + gpr_mu_unlock(&pollset_set->mu); +} + +void grpc_pollset_set_del_fd(grpc_exec_ctx *exec_ctx, + grpc_pollset_set *pollset_set, grpc_fd *fd) { + size_t i; + gpr_mu_lock(&pollset_set->mu); + for (i = 0; i < pollset_set->fd_count; i++) { + if (pollset_set->fds[i] == fd) { + pollset_set->fd_count--; + GPR_SWAP(grpc_fd *, pollset_set->fds[i], + pollset_set->fds[pollset_set->fd_count]); + GRPC_FD_UNREF(fd, "pollset_set"); + break; + } + } + for (i = 0; i < pollset_set->pollset_set_count; i++) { + grpc_pollset_set_del_fd(exec_ctx, pollset_set->pollset_sets[i], fd); + } + gpr_mu_unlock(&pollset_set->mu); +} + +#endif /* GPR_POSIX_SOCKET */ diff --git a/src/core/lib/iomgr/pollset_set_posix.h b/src/core/lib/iomgr/pollset_set_posix.h new file mode 100644 index 0000000000..80f487718e --- /dev/null +++ b/src/core/lib/iomgr/pollset_set_posix.h @@ -0,0 +1,45 @@ +/* + * + * Copyright 2015-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_IOMGR_POLLSET_SET_POSIX_H +#define GRPC_CORE_IOMGR_POLLSET_SET_POSIX_H + +#include "src/core/iomgr/fd_posix.h" +#include "src/core/iomgr/pollset_set.h" + +void grpc_pollset_set_add_fd(grpc_exec_ctx *exec_ctx, + grpc_pollset_set *pollset_set, grpc_fd *fd); +void grpc_pollset_set_del_fd(grpc_exec_ctx *exec_ctx, + grpc_pollset_set *pollset_set, grpc_fd *fd); + +#endif /* GRPC_CORE_IOMGR_POLLSET_SET_POSIX_H */ diff --git a/src/core/lib/iomgr/pollset_set_windows.c b/src/core/lib/iomgr/pollset_set_windows.c new file mode 100644 index 0000000000..3b8eca28e6 --- /dev/null +++ b/src/core/lib/iomgr/pollset_set_windows.c @@ -0,0 +1,60 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_WINSOCK_SOCKET + +#include "src/core/iomgr/pollset_set_windows.h" + +grpc_pollset_set* grpc_pollset_set_create(pollset_set) { return NULL; } + +void grpc_pollset_set_destroy(grpc_pollset_set* pollset_set) {} + +void grpc_pollset_set_add_pollset(grpc_exec_ctx* exec_ctx, + grpc_pollset_set* pollset_set, + grpc_pollset* pollset) {} + +void grpc_pollset_set_del_pollset(grpc_exec_ctx* exec_ctx, + grpc_pollset_set* pollset_set, + grpc_pollset* pollset) {} + +void grpc_pollset_set_add_pollset_set(grpc_exec_ctx* exec_ctx, + grpc_pollset_set* bag, + grpc_pollset_set* item) {} + +void grpc_pollset_set_del_pollset_set(grpc_exec_ctx* exec_ctx, + grpc_pollset_set* bag, + grpc_pollset_set* item) {} + +#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/pollset_set_windows.h b/src/core/lib/iomgr/pollset_set_windows.h new file mode 100644 index 0000000000..0f040fef82 --- /dev/null +++ b/src/core/lib/iomgr/pollset_set_windows.h @@ -0,0 +1,39 @@ +/* + * + * Copyright 2015-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_IOMGR_POLLSET_SET_WINDOWS_H +#define GRPC_CORE_IOMGR_POLLSET_SET_WINDOWS_H + +#include "src/core/iomgr/pollset_set.h" + +#endif /* GRPC_CORE_IOMGR_POLLSET_SET_WINDOWS_H */ diff --git a/src/core/lib/iomgr/pollset_windows.c b/src/core/lib/iomgr/pollset_windows.c new file mode 100644 index 0000000000..1a99224c80 --- /dev/null +++ b/src/core/lib/iomgr/pollset_windows.c @@ -0,0 +1,240 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_WINSOCK_SOCKET + +#include +#include + +#include "src/core/iomgr/iocp_windows.h" +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/pollset.h" +#include "src/core/iomgr/pollset_windows.h" + +gpr_mu grpc_polling_mu; +static grpc_pollset_worker *g_active_poller; +static grpc_pollset_worker g_global_root_worker; + +void grpc_pollset_global_init() { + gpr_mu_init(&grpc_polling_mu); + g_active_poller = NULL; + g_global_root_worker.links[GRPC_POLLSET_WORKER_LINK_GLOBAL].next = + g_global_root_worker.links[GRPC_POLLSET_WORKER_LINK_GLOBAL].prev = + &g_global_root_worker; +} + +void grpc_pollset_global_shutdown() { gpr_mu_destroy(&grpc_polling_mu); } + +static void remove_worker(grpc_pollset_worker *worker, + grpc_pollset_worker_link_type type) { + worker->links[type].prev->links[type].next = worker->links[type].next; + worker->links[type].next->links[type].prev = worker->links[type].prev; + worker->links[type].next = worker->links[type].prev = worker; +} + +static int has_workers(grpc_pollset_worker *root, + grpc_pollset_worker_link_type type) { + return root->links[type].next != root; +} + +static grpc_pollset_worker *pop_front_worker( + grpc_pollset_worker *root, grpc_pollset_worker_link_type type) { + if (has_workers(root, type)) { + grpc_pollset_worker *w = root->links[type].next; + remove_worker(w, type); + return w; + } else { + return NULL; + } +} + +static void push_front_worker(grpc_pollset_worker *root, + grpc_pollset_worker_link_type type, + grpc_pollset_worker *worker) { + worker->links[type].prev = root; + worker->links[type].next = worker->links[type].prev->links[type].next; + worker->links[type].prev->links[type].next = + worker->links[type].next->links[type].prev = worker; +} + +size_t grpc_pollset_size(void) { return sizeof(grpc_pollset); } + +/* There isn't really any such thing as a pollset under Windows, due to the + nature of the IO completion ports. We're still going to provide a minimal + set of features for the sake of the rest of grpc. But grpc_pollset_work + won't actually do any polling, and return as quickly as possible. */ + +void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) { + *mu = &grpc_polling_mu; + memset(pollset, 0, sizeof(*pollset)); + pollset->root_worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].next = + pollset->root_worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].prev = + &pollset->root_worker; +} + +void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, + grpc_closure *closure) { + pollset->shutting_down = 1; + grpc_pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST); + if (!pollset->is_iocp_worker) { + grpc_exec_ctx_enqueue(exec_ctx, closure, true, NULL); + } else { + pollset->on_shutdown = closure; + } +} + +void grpc_pollset_destroy(grpc_pollset *pollset) {} + +void grpc_pollset_reset(grpc_pollset *pollset) { + GPR_ASSERT(pollset->shutting_down); + GPR_ASSERT( + !has_workers(&pollset->root_worker, GRPC_POLLSET_WORKER_LINK_POLLSET)); + pollset->shutting_down = 0; + pollset->is_iocp_worker = 0; + pollset->kicked_without_pollers = 0; + pollset->on_shutdown = NULL; +} + +void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, + grpc_pollset_worker **worker_hdl, gpr_timespec now, + gpr_timespec deadline) { + grpc_pollset_worker worker; + *worker_hdl = &worker; + + int added_worker = 0; + worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].next = + worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].prev = + worker.links[GRPC_POLLSET_WORKER_LINK_GLOBAL].next = + worker.links[GRPC_POLLSET_WORKER_LINK_GLOBAL].prev = NULL; + worker.kicked = 0; + worker.pollset = pollset; + gpr_cv_init(&worker.cv); + if (!pollset->kicked_without_pollers && !pollset->shutting_down) { + if (g_active_poller == NULL) { + grpc_pollset_worker *next_worker; + /* become poller */ + pollset->is_iocp_worker = 1; + g_active_poller = &worker; + gpr_mu_unlock(&grpc_polling_mu); + grpc_iocp_work(exec_ctx, deadline); + grpc_exec_ctx_flush(exec_ctx); + gpr_mu_lock(&grpc_polling_mu); + pollset->is_iocp_worker = 0; + g_active_poller = NULL; + /* try to get a worker from this pollsets worker list */ + next_worker = pop_front_worker(&pollset->root_worker, + GRPC_POLLSET_WORKER_LINK_POLLSET); + if (next_worker == NULL) { + /* try to get a worker from the global list */ + next_worker = pop_front_worker(&g_global_root_worker, + GRPC_POLLSET_WORKER_LINK_GLOBAL); + } + if (next_worker != NULL) { + next_worker->kicked = 1; + gpr_cv_signal(&next_worker->cv); + } + + if (pollset->shutting_down && pollset->on_shutdown != NULL) { + grpc_exec_ctx_enqueue(exec_ctx, pollset->on_shutdown, true, NULL); + pollset->on_shutdown = NULL; + } + goto done; + } + push_front_worker(&g_global_root_worker, GRPC_POLLSET_WORKER_LINK_GLOBAL, + &worker); + push_front_worker(&pollset->root_worker, GRPC_POLLSET_WORKER_LINK_POLLSET, + &worker); + added_worker = 1; + while (!worker.kicked) { + if (gpr_cv_wait(&worker.cv, &grpc_polling_mu, deadline)) { + break; + } + } + } else { + pollset->kicked_without_pollers = 0; + } +done: + if (!grpc_closure_list_empty(exec_ctx->closure_list)) { + gpr_mu_unlock(&grpc_polling_mu); + grpc_exec_ctx_flush(exec_ctx); + gpr_mu_lock(&grpc_polling_mu); + } + if (added_worker) { + remove_worker(&worker, GRPC_POLLSET_WORKER_LINK_GLOBAL); + remove_worker(&worker, GRPC_POLLSET_WORKER_LINK_POLLSET); + } + gpr_cv_destroy(&worker.cv); + *worker_hdl = NULL; +} + +void grpc_pollset_kick(grpc_pollset *p, grpc_pollset_worker *specific_worker) { + if (specific_worker != NULL) { + if (specific_worker == GRPC_POLLSET_KICK_BROADCAST) { + for (specific_worker = + p->root_worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].next; + specific_worker != &p->root_worker; + specific_worker = + specific_worker->links[GRPC_POLLSET_WORKER_LINK_POLLSET].next) { + specific_worker->kicked = 1; + gpr_cv_signal(&specific_worker->cv); + } + p->kicked_without_pollers = 1; + if (p->is_iocp_worker) { + grpc_iocp_kick(); + } + } else { + if (p->is_iocp_worker && g_active_poller == specific_worker) { + grpc_iocp_kick(); + } else { + specific_worker->kicked = 1; + gpr_cv_signal(&specific_worker->cv); + } + } + } else { + specific_worker = + pop_front_worker(&p->root_worker, GRPC_POLLSET_WORKER_LINK_POLLSET); + if (specific_worker != NULL) { + grpc_pollset_kick(p, specific_worker); + } else if (p->is_iocp_worker) { + grpc_iocp_kick(); + } else { + p->kicked_without_pollers = 1; + } + } +} + +void grpc_kick_poller(void) { grpc_iocp_kick(); } + +#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/pollset_windows.h b/src/core/lib/iomgr/pollset_windows.h new file mode 100644 index 0000000000..f1d1585922 --- /dev/null +++ b/src/core/lib/iomgr/pollset_windows.h @@ -0,0 +1,75 @@ +/* + * + * Copyright 2015-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_IOMGR_POLLSET_WINDOWS_H +#define GRPC_CORE_IOMGR_POLLSET_WINDOWS_H + +#include + +#include "src/core/iomgr/socket_windows.h" + +/* There isn't really any such thing as a pollset under Windows, due to the + nature of the IO completion ports. A Windows "pollset" is merely a mutex + used to synchronize with the IOCP, and workers are condition variables + used to block threads until work is ready. */ + +typedef enum { + GRPC_POLLSET_WORKER_LINK_POLLSET = 0, + GRPC_POLLSET_WORKER_LINK_GLOBAL, + GRPC_POLLSET_WORKER_LINK_TYPES +} grpc_pollset_worker_link_type; + +typedef struct grpc_pollset_worker_link { + struct grpc_pollset_worker *next; + struct grpc_pollset_worker *prev; +} grpc_pollset_worker_link; + +struct grpc_pollset; +typedef struct grpc_pollset grpc_pollset; + +typedef struct grpc_pollset_worker { + gpr_cv cv; + int kicked; + struct grpc_pollset *pollset; + grpc_pollset_worker_link links[GRPC_POLLSET_WORKER_LINK_TYPES]; +} grpc_pollset_worker; + +struct grpc_pollset { + int shutting_down; + int kicked_without_pollers; + int is_iocp_worker; + grpc_pollset_worker root_worker; + grpc_closure *on_shutdown; +}; + +#endif /* GRPC_CORE_IOMGR_POLLSET_WINDOWS_H */ diff --git a/src/core/lib/iomgr/resolve_address.h b/src/core/lib/iomgr/resolve_address.h new file mode 100644 index 0000000000..aa0d7d194b --- /dev/null +++ b/src/core/lib/iomgr/resolve_address.h @@ -0,0 +1,72 @@ +/* + * + * Copyright 2015-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_IOMGR_RESOLVE_ADDRESS_H +#define GRPC_CORE_IOMGR_RESOLVE_ADDRESS_H + +#include +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/iomgr/iomgr.h" + +#define GRPC_MAX_SOCKADDR_SIZE 128 + +typedef struct { + char addr[GRPC_MAX_SOCKADDR_SIZE]; + size_t len; +} grpc_resolved_address; + +typedef struct { + size_t naddrs; + grpc_resolved_address *addrs; +} grpc_resolved_addresses; + +/* Async result callback: + On success: addresses is the result, and the callee must call + grpc_resolved_addresses_destroy when it's done with them + On failure: addresses is NULL */ +typedef void (*grpc_resolve_cb)(grpc_exec_ctx *exec_ctx, void *arg, + grpc_resolved_addresses *addresses); +/* Asynchronously resolve addr. Use default_port if a port isn't designated + in addr, otherwise use the port in addr. */ +/* TODO(ctiller): add a timeout here */ +void grpc_resolve_address(const char *addr, const char *default_port, + grpc_resolve_cb cb, void *arg); +/* Destroy resolved addresses */ +void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addresses); + +/* Resolve addr in a blocking fashion. Returns NULL on failure. On success, + result must be freed with grpc_resolved_addresses_destroy. */ +extern grpc_resolved_addresses *(*grpc_blocking_resolve_address)( + const char *name, const char *default_port); + +#endif /* GRPC_CORE_IOMGR_RESOLVE_ADDRESS_H */ diff --git a/src/core/lib/iomgr/resolve_address_posix.c b/src/core/lib/iomgr/resolve_address_posix.c new file mode 100644 index 0000000000..26b3aa8189 --- /dev/null +++ b/src/core/lib/iomgr/resolve_address_posix.c @@ -0,0 +1,178 @@ +/* + * + * Copyright 2015-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 +#ifdef GPR_POSIX_SOCKET + +#include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/sockaddr.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "src/core/iomgr/executor.h" +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/iomgr/unix_sockets_posix.h" +#include "src/core/support/block_annotate.h" +#include "src/core/support/string.h" + +typedef struct { + char *name; + char *default_port; + grpc_resolve_cb cb; + grpc_closure request_closure; + void *arg; +} request; + +static grpc_resolved_addresses *blocking_resolve_address_impl( + const char *name, const char *default_port) { + struct addrinfo hints; + struct addrinfo *result = NULL, *resp; + char *host; + char *port; + int s; + size_t i; + grpc_resolved_addresses *addrs = NULL; + + if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' && + name[4] == ':' && name[5] != 0) { + return grpc_resolve_unix_domain_address(name + 5); + } + + /* parse name, splitting it into host and port parts */ + gpr_split_host_port(name, &host, &port); + if (host == NULL) { + gpr_log(GPR_ERROR, "unparseable host:port: '%s'", name); + goto done; + } + if (port == NULL) { + if (default_port == NULL) { + gpr_log(GPR_ERROR, "no port in name '%s'", name); + goto done; + } + port = gpr_strdup(default_port); + } + + /* Call getaddrinfo */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */ + hints.ai_socktype = SOCK_STREAM; /* stream socket */ + hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ + + GRPC_SCHEDULING_START_BLOCKING_REGION; + s = getaddrinfo(host, port, &hints, &result); + GRPC_SCHEDULING_END_BLOCKING_REGION; + + if (s != 0) { + /* Retry if well-known service name is recognized */ + char *svc[][2] = {{"http", "80"}, {"https", "443"}}; + for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) { + if (strcmp(port, svc[i][0]) == 0) { + GRPC_SCHEDULING_START_BLOCKING_REGION; + s = getaddrinfo(host, svc[i][1], &hints, &result); + GRPC_SCHEDULING_END_BLOCKING_REGION; + break; + } + } + } + + if (s != 0) { + gpr_log(GPR_ERROR, "getaddrinfo: %s", gai_strerror(s)); + goto done; + } + + /* Success path: set addrs non-NULL, fill it in */ + addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); + addrs->naddrs = 0; + for (resp = result; resp != NULL; resp = resp->ai_next) { + addrs->naddrs++; + } + addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address) * addrs->naddrs); + i = 0; + for (resp = result; resp != NULL; resp = resp->ai_next) { + memcpy(&addrs->addrs[i].addr, resp->ai_addr, resp->ai_addrlen); + addrs->addrs[i].len = resp->ai_addrlen; + i++; + } + +done: + gpr_free(host); + gpr_free(port); + if (result) { + freeaddrinfo(result); + } + return addrs; +} + +grpc_resolved_addresses *(*grpc_blocking_resolve_address)( + const char *name, const char *default_port) = blocking_resolve_address_impl; + +/* Callback to be passed to grpc_executor to asynch-ify + * grpc_blocking_resolve_address */ +static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp, bool success) { + request *r = rp; + grpc_resolved_addresses *resolved = + grpc_blocking_resolve_address(r->name, r->default_port); + void *arg = r->arg; + grpc_resolve_cb cb = r->cb; + gpr_free(r->name); + gpr_free(r->default_port); + cb(exec_ctx, arg, resolved); + gpr_free(r); +} + +void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) { + gpr_free(addrs->addrs); + gpr_free(addrs); +} + +void grpc_resolve_address(const char *name, const char *default_port, + grpc_resolve_cb cb, void *arg) { + request *r = gpr_malloc(sizeof(request)); + grpc_closure_init(&r->request_closure, do_request_thread, r); + r->name = gpr_strdup(name); + r->default_port = gpr_strdup(default_port); + r->cb = cb; + r->arg = arg; + grpc_executor_enqueue(&r->request_closure, 1); +} + +#endif diff --git a/src/core/lib/iomgr/resolve_address_windows.c b/src/core/lib/iomgr/resolve_address_windows.c new file mode 100644 index 0000000000..472e797163 --- /dev/null +++ b/src/core/lib/iomgr/resolve_address_windows.c @@ -0,0 +1,169 @@ +/* + * + * Copyright 2015-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 +#ifdef GPR_WINSOCK_SOCKET + +#include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/sockaddr.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "src/core/iomgr/executor.h" +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/support/block_annotate.h" +#include "src/core/support/string.h" + +typedef struct { + char *name; + char *default_port; + grpc_resolve_cb cb; + grpc_closure request_closure; + void *arg; +} request; + +static grpc_resolved_addresses *blocking_resolve_address_impl( + const char *name, const char *default_port) { + struct addrinfo hints; + struct addrinfo *result = NULL, *resp; + char *host; + char *port; + int s; + size_t i; + grpc_resolved_addresses *addrs = NULL; + + /* parse name, splitting it into host and port parts */ + gpr_split_host_port(name, &host, &port); + if (host == NULL) { + gpr_log(GPR_ERROR, "unparseable host:port: '%s'", name); + goto done; + } + if (port == NULL) { + if (default_port == NULL) { + gpr_log(GPR_ERROR, "no port in name '%s'", name); + goto done; + } + port = gpr_strdup(default_port); + } + + /* Call getaddrinfo */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */ + hints.ai_socktype = SOCK_STREAM; /* stream socket */ + hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ + + GRPC_SCHEDULING_START_BLOCKING_REGION; + s = getaddrinfo(host, port, &hints, &result); + GRPC_SCHEDULING_END_BLOCKING_REGION; + if (s != 0) { + char *error_message = gpr_format_message(s); + gpr_log(GPR_ERROR, "getaddrinfo: %s", error_message); + gpr_free(error_message); + goto done; + } + + /* Success path: set addrs non-NULL, fill it in */ + addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); + addrs->naddrs = 0; + for (resp = result; resp != NULL; resp = resp->ai_next) { + addrs->naddrs++; + } + addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address) * addrs->naddrs); + i = 0; + for (resp = result; resp != NULL; resp = resp->ai_next) { + memcpy(&addrs->addrs[i].addr, resp->ai_addr, resp->ai_addrlen); + addrs->addrs[i].len = resp->ai_addrlen; + i++; + } + + { + for (i = 0; i < addrs->naddrs; i++) { + char *buf; + grpc_sockaddr_to_string(&buf, (struct sockaddr *)&addrs->addrs[i].addr, + 0); + gpr_free(buf); + } + } + +done: + gpr_free(host); + gpr_free(port); + if (result) { + freeaddrinfo(result); + } + return addrs; +} + +grpc_resolved_addresses *(*grpc_blocking_resolve_address)( + const char *name, const char *default_port) = blocking_resolve_address_impl; + +/* Callback to be passed to grpc_executor to asynch-ify + * grpc_blocking_resolve_address */ +static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp, bool success) { + request *r = rp; + grpc_resolved_addresses *resolved = + grpc_blocking_resolve_address(r->name, r->default_port); + void *arg = r->arg; + grpc_resolve_cb cb = r->cb; + gpr_free(r->name); + gpr_free(r->default_port); + cb(exec_ctx, arg, resolved); + gpr_free(r); +} + +void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) { + gpr_free(addrs->addrs); + gpr_free(addrs); +} + +void grpc_resolve_address(const char *name, const char *default_port, + grpc_resolve_cb cb, void *arg) { + request *r = gpr_malloc(sizeof(request)); + grpc_closure_init(&r->request_closure, do_request_thread, r); + r->name = gpr_strdup(name); + r->default_port = gpr_strdup(default_port); + r->cb = cb; + r->arg = arg; + grpc_executor_enqueue(&r->request_closure, 1); +} + +#endif diff --git a/src/core/lib/iomgr/sockaddr.h b/src/core/lib/iomgr/sockaddr.h new file mode 100644 index 0000000000..68241bdd55 --- /dev/null +++ b/src/core/lib/iomgr/sockaddr.h @@ -0,0 +1,47 @@ +/* + * + * Copyright 2015-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_IOMGR_SOCKADDR_H +#define GRPC_CORE_IOMGR_SOCKADDR_H + +#include + +#ifdef GPR_WIN32 +#include "src/core/iomgr/sockaddr_win32.h" +#endif + +#ifdef GPR_POSIX_SOCKETADDR +#include "src/core/iomgr/sockaddr_posix.h" +#endif + +#endif /* GRPC_CORE_IOMGR_SOCKADDR_H */ diff --git a/src/core/lib/iomgr/sockaddr_posix.h b/src/core/lib/iomgr/sockaddr_posix.h new file mode 100644 index 0000000000..a398096837 --- /dev/null +++ b/src/core/lib/iomgr/sockaddr_posix.h @@ -0,0 +1,44 @@ +/* + * + * Copyright 2015-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_IOMGR_SOCKADDR_POSIX_H +#define GRPC_CORE_IOMGR_SOCKADDR_POSIX_H + +#include +#include +#include +#include +#include +#include + +#endif /* GRPC_CORE_IOMGR_SOCKADDR_POSIX_H */ diff --git a/src/core/lib/iomgr/sockaddr_utils.c b/src/core/lib/iomgr/sockaddr_utils.c new file mode 100644 index 0000000000..a3c3a874c1 --- /dev/null +++ b/src/core/lib/iomgr/sockaddr_utils.c @@ -0,0 +1,227 @@ +/* + * + * 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/iomgr/sockaddr_utils.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "src/core/iomgr/unix_sockets_posix.h" +#include "src/core/support/string.h" + +static const uint8_t kV4MappedPrefix[] = {0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0xff, 0xff}; + +int grpc_sockaddr_is_v4mapped(const struct sockaddr *addr, + struct sockaddr_in *addr4_out) { + GPR_ASSERT(addr != (struct sockaddr *)addr4_out); + if (addr->sa_family == AF_INET6) { + const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; + if (memcmp(addr6->sin6_addr.s6_addr, kV4MappedPrefix, + sizeof(kV4MappedPrefix)) == 0) { + if (addr4_out != NULL) { + /* Normalize ::ffff:0.0.0.0/96 to IPv4. */ + memset(addr4_out, 0, sizeof(*addr4_out)); + addr4_out->sin_family = AF_INET; + /* s6_addr32 would be nice, but it's non-standard. */ + memcpy(&addr4_out->sin_addr, &addr6->sin6_addr.s6_addr[12], 4); + addr4_out->sin_port = addr6->sin6_port; + } + return 1; + } + } + return 0; +} + +int grpc_sockaddr_to_v4mapped(const struct sockaddr *addr, + struct sockaddr_in6 *addr6_out) { + GPR_ASSERT(addr != (struct sockaddr *)addr6_out); + if (addr->sa_family == AF_INET) { + const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr; + memset(addr6_out, 0, sizeof(*addr6_out)); + addr6_out->sin6_family = AF_INET6; + memcpy(&addr6_out->sin6_addr.s6_addr[0], kV4MappedPrefix, 12); + memcpy(&addr6_out->sin6_addr.s6_addr[12], &addr4->sin_addr, 4); + addr6_out->sin6_port = addr4->sin_port; + return 1; + } + return 0; +} + +int grpc_sockaddr_is_wildcard(const struct sockaddr *addr, int *port_out) { + struct sockaddr_in addr4_normalized; + if (grpc_sockaddr_is_v4mapped(addr, &addr4_normalized)) { + addr = (struct sockaddr *)&addr4_normalized; + } + if (addr->sa_family == AF_INET) { + /* Check for 0.0.0.0 */ + const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr; + if (addr4->sin_addr.s_addr != 0) { + return 0; + } + *port_out = ntohs(addr4->sin_port); + return 1; + } else if (addr->sa_family == AF_INET6) { + /* Check for :: */ + const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; + int i; + for (i = 0; i < 16; i++) { + if (addr6->sin6_addr.s6_addr[i] != 0) { + return 0; + } + } + *port_out = ntohs(addr6->sin6_port); + return 1; + } else { + return 0; + } +} + +void grpc_sockaddr_make_wildcards(int port, struct sockaddr_in *wild4_out, + struct sockaddr_in6 *wild6_out) { + grpc_sockaddr_make_wildcard4(port, wild4_out); + grpc_sockaddr_make_wildcard6(port, wild6_out); +} + +void grpc_sockaddr_make_wildcard4(int port, struct sockaddr_in *wild_out) { + GPR_ASSERT(port >= 0 && port < 65536); + memset(wild_out, 0, sizeof(*wild_out)); + wild_out->sin_family = AF_INET; + wild_out->sin_port = htons((uint16_t)port); +} + +void grpc_sockaddr_make_wildcard6(int port, struct sockaddr_in6 *wild_out) { + GPR_ASSERT(port >= 0 && port < 65536); + memset(wild_out, 0, sizeof(*wild_out)); + wild_out->sin6_family = AF_INET6; + wild_out->sin6_port = htons((uint16_t)port); +} + +int grpc_sockaddr_to_string(char **out, const struct sockaddr *addr, + int normalize) { + const int save_errno = errno; + struct sockaddr_in addr_normalized; + char ntop_buf[INET6_ADDRSTRLEN]; + const void *ip = NULL; + int port; + int ret; + + *out = NULL; + if (normalize && grpc_sockaddr_is_v4mapped(addr, &addr_normalized)) { + addr = (const struct sockaddr *)&addr_normalized; + } + if (addr->sa_family == AF_INET) { + const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr; + ip = &addr4->sin_addr; + port = ntohs(addr4->sin_port); + } else if (addr->sa_family == AF_INET6) { + const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; + ip = &addr6->sin6_addr; + port = ntohs(addr6->sin6_port); + } + /* Windows inet_ntop wants a mutable ip pointer */ + if (ip != NULL && + inet_ntop(addr->sa_family, (void *)ip, ntop_buf, sizeof(ntop_buf)) != + NULL) { + ret = gpr_join_host_port(out, ntop_buf, port); + } else { + ret = gpr_asprintf(out, "(sockaddr family=%d)", addr->sa_family); + } + /* This is probably redundant, but we wouldn't want to log the wrong error. */ + errno = save_errno; + return ret; +} + +char *grpc_sockaddr_to_uri(const struct sockaddr *addr) { + char *temp; + char *result; + struct sockaddr_in addr_normalized; + + if (grpc_sockaddr_is_v4mapped(addr, &addr_normalized)) { + addr = (const struct sockaddr *)&addr_normalized; + } + + switch (addr->sa_family) { + case AF_INET: + grpc_sockaddr_to_string(&temp, addr, 0); + gpr_asprintf(&result, "ipv4:%s", temp); + gpr_free(temp); + return result; + case AF_INET6: + grpc_sockaddr_to_string(&temp, addr, 0); + gpr_asprintf(&result, "ipv6:%s", temp); + gpr_free(temp); + return result; + default: + return grpc_sockaddr_to_uri_unix_if_possible(addr); + } +} + +int grpc_sockaddr_get_port(const struct sockaddr *addr) { + switch (addr->sa_family) { + case AF_INET: + return ntohs(((struct sockaddr_in *)addr)->sin_port); + case AF_INET6: + return ntohs(((struct sockaddr_in6 *)addr)->sin6_port); + default: + if (grpc_is_unix_socket(addr)) { + return 1; + } + gpr_log(GPR_ERROR, "Unknown socket family %d in grpc_sockaddr_get_port", + addr->sa_family); + return 0; + } +} + +int grpc_sockaddr_set_port(const struct sockaddr *addr, int port) { + switch (addr->sa_family) { + case AF_INET: + GPR_ASSERT(port >= 0 && port < 65536); + ((struct sockaddr_in *)addr)->sin_port = htons((uint16_t)port); + return 1; + case AF_INET6: + GPR_ASSERT(port >= 0 && port < 65536); + ((struct sockaddr_in6 *)addr)->sin6_port = htons((uint16_t)port); + return 1; + default: + gpr_log(GPR_ERROR, "Unknown socket family %d in grpc_sockaddr_set_port", + addr->sa_family); + return 0; + } +} diff --git a/src/core/lib/iomgr/sockaddr_utils.h b/src/core/lib/iomgr/sockaddr_utils.h new file mode 100644 index 0000000000..43dc7a45ec --- /dev/null +++ b/src/core/lib/iomgr/sockaddr_utils.h @@ -0,0 +1,89 @@ +/* + * + * Copyright 2015-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_IOMGR_SOCKADDR_UTILS_H +#define GRPC_CORE_IOMGR_SOCKADDR_UTILS_H + +#include "src/core/iomgr/sockaddr.h" + +/* Returns true if addr is an IPv4-mapped IPv6 address within the + ::ffff:0.0.0.0/96 range, or false otherwise. + + If addr4_out is non-NULL, the inner IPv4 address will be copied here when + returning true. */ +int grpc_sockaddr_is_v4mapped(const struct sockaddr *addr, + struct sockaddr_in *addr4_out); + +/* If addr is an AF_INET address, writes the corresponding ::ffff:0.0.0.0/96 + address to addr6_out and returns true. Otherwise returns false. */ +int grpc_sockaddr_to_v4mapped(const struct sockaddr *addr, + struct sockaddr_in6 *addr6_out); + +/* If addr is ::, 0.0.0.0, or ::ffff:0.0.0.0, writes the port number to + *port_out (if not NULL) and returns true, otherwise returns false. */ +int grpc_sockaddr_is_wildcard(const struct sockaddr *addr, int *port_out); + +/* Writes 0.0.0.0:port and [::]:port to separate sockaddrs. */ +void grpc_sockaddr_make_wildcards(int port, struct sockaddr_in *wild4_out, + struct sockaddr_in6 *wild6_out); + +/* Writes 0.0.0.0:port. */ +void grpc_sockaddr_make_wildcard4(int port, struct sockaddr_in *wild_out); + +/* Writes [::]:port. */ +void grpc_sockaddr_make_wildcard6(int port, struct sockaddr_in6 *wild_out); + +/* Return the IP port number of a sockaddr */ +int grpc_sockaddr_get_port(const struct sockaddr *addr); + +/* Set IP port number of a sockaddr */ +int grpc_sockaddr_set_port(const struct sockaddr *addr, int port); + +/* Converts a sockaddr into a newly-allocated human-readable string. + + Currently, only the AF_INET and AF_INET6 families are recognized. + If the normalize flag is enabled, ::ffff:0.0.0.0/96 IPv6 addresses are + displayed as plain IPv4. + + Usage is similar to gpr_asprintf: returns the number of bytes written + (excluding the final '\0'), and *out points to a string which must later be + destroyed using gpr_free(). + + In the unlikely event of an error, returns -1 and sets *out to NULL. + The existing value of errno is always preserved. */ +int grpc_sockaddr_to_string(char **out, const struct sockaddr *addr, + int normalize); + +char *grpc_sockaddr_to_uri(const struct sockaddr *addr); + +#endif /* GRPC_CORE_IOMGR_SOCKADDR_UTILS_H */ diff --git a/src/core/lib/iomgr/sockaddr_win32.h b/src/core/lib/iomgr/sockaddr_win32.h new file mode 100644 index 0000000000..ef306e3cc3 --- /dev/null +++ b/src/core/lib/iomgr/sockaddr_win32.h @@ -0,0 +1,43 @@ +/* + * + * Copyright 2015-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_IOMGR_SOCKADDR_WIN32_H +#define GRPC_CORE_IOMGR_SOCKADDR_WIN32_H + +#include +#include + +// must be included after the above +#include + +#endif /* GRPC_CORE_IOMGR_SOCKADDR_WIN32_H */ diff --git a/src/core/lib/iomgr/socket_utils_common_posix.c b/src/core/lib/iomgr/socket_utils_common_posix.c new file mode 100644 index 0000000000..570daccc9e --- /dev/null +++ b/src/core/lib/iomgr/socket_utils_common_posix.c @@ -0,0 +1,208 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_SOCKET + +#include "src/core/iomgr/socket_utils_posix.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/support/string.h" + +/* set a socket to non blocking mode */ +int grpc_set_socket_nonblocking(int fd, int non_blocking) { + int oldflags = fcntl(fd, F_GETFL, 0); + if (oldflags < 0) { + return 0; + } + + if (non_blocking) { + oldflags |= O_NONBLOCK; + } else { + oldflags &= ~O_NONBLOCK; + } + + if (fcntl(fd, F_SETFL, oldflags) != 0) { + return 0; + } + + return 1; +} + +int grpc_set_socket_no_sigpipe_if_possible(int fd) { +#ifdef GPR_HAVE_SO_NOSIGPIPE + int val = 1; + int newval; + socklen_t intlen = sizeof(newval); + return 0 == setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val)) && + 0 == getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &newval, &intlen) && + (newval != 0) == val; +#else + return 1; +#endif +} + +/* set a socket to close on exec */ +int grpc_set_socket_cloexec(int fd, int close_on_exec) { + int oldflags = fcntl(fd, F_GETFD, 0); + if (oldflags < 0) { + return 0; + } + + if (close_on_exec) { + oldflags |= FD_CLOEXEC; + } else { + oldflags &= ~FD_CLOEXEC; + } + + if (fcntl(fd, F_SETFD, oldflags) != 0) { + return 0; + } + + return 1; +} + +/* set a socket to reuse old addresses */ +int grpc_set_socket_reuse_addr(int fd, int reuse) { + int val = (reuse != 0); + int newval; + socklen_t intlen = sizeof(newval); + return 0 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) && + 0 == getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &newval, &intlen) && + (newval != 0) == val; +} + +/* disable nagle */ +int grpc_set_socket_low_latency(int fd, int low_latency) { + int val = (low_latency != 0); + int newval; + socklen_t intlen = sizeof(newval); + return 0 == setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) && + 0 == getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &newval, &intlen) && + (newval != 0) == val; +} + +static gpr_once g_probe_ipv6_once = GPR_ONCE_INIT; +static int g_ipv6_loopback_available; + +static void probe_ipv6_once(void) { + int fd = socket(AF_INET6, SOCK_STREAM, 0); + g_ipv6_loopback_available = 0; + if (fd < 0) { + gpr_log(GPR_INFO, "Disabling AF_INET6 sockets because socket() failed."); + } else { + struct sockaddr_in6 addr; + memset(&addr, 0, sizeof(addr)); + addr.sin6_family = AF_INET6; + addr.sin6_addr.s6_addr[15] = 1; /* [::1]:0 */ + if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == 0) { + g_ipv6_loopback_available = 1; + } else { + gpr_log(GPR_INFO, + "Disabling AF_INET6 sockets because ::1 is not available."); + } + close(fd); + } +} + +int grpc_ipv6_loopback_available(void) { + gpr_once_init(&g_probe_ipv6_once, probe_ipv6_once); + return g_ipv6_loopback_available; +} + +/* This should be 0 in production, but it may be enabled for testing or + debugging purposes, to simulate an environment where IPv6 sockets can't + also speak IPv4. */ +int grpc_forbid_dualstack_sockets_for_testing = 0; + +static int set_socket_dualstack(int fd) { + if (!grpc_forbid_dualstack_sockets_for_testing) { + const int off = 0; + return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off)); + } else { + /* Force an IPv6-only socket, for testing purposes. */ + const int on = 1; + setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); + return 0; + } +} + +int grpc_create_dualstack_socket(const struct sockaddr *addr, int type, + int protocol, grpc_dualstack_mode *dsmode) { + int family = addr->sa_family; + if (family == AF_INET6) { + int fd; + if (grpc_ipv6_loopback_available()) { + fd = socket(family, type, protocol); + } else { + fd = -1; + errno = EAFNOSUPPORT; + } + /* Check if we've got a valid dualstack socket. */ + if (fd >= 0 && set_socket_dualstack(fd)) { + *dsmode = GRPC_DSMODE_DUALSTACK; + return fd; + } + /* If this isn't an IPv4 address, then return whatever we've got. */ + if (!grpc_sockaddr_is_v4mapped(addr, NULL)) { + *dsmode = GRPC_DSMODE_IPV6; + return fd; + } + /* Fall back to AF_INET. */ + if (fd >= 0) { + close(fd); + } + family = AF_INET; + } + *dsmode = family == AF_INET ? GRPC_DSMODE_IPV4 : GRPC_DSMODE_NONE; + return socket(family, type, protocol); +} + +#endif diff --git a/src/core/lib/iomgr/socket_utils_linux.c b/src/core/lib/iomgr/socket_utils_linux.c new file mode 100644 index 0000000000..e16885f231 --- /dev/null +++ b/src/core/lib/iomgr/socket_utils_linux.c @@ -0,0 +1,51 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_LINUX_SOCKETUTILS + +#include "src/core/iomgr/socket_utils_posix.h" + +#include +#include + +int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, + int nonblock, int cloexec) { + int flags = 0; + flags |= nonblock ? SOCK_NONBLOCK : 0; + flags |= cloexec ? SOCK_CLOEXEC : 0; + return accept4(sockfd, addr, addrlen, flags); +} + +#endif diff --git a/src/core/lib/iomgr/socket_utils_posix.c b/src/core/lib/iomgr/socket_utils_posix.c new file mode 100644 index 0000000000..3c56b46744 --- /dev/null +++ b/src/core/lib/iomgr/socket_utils_posix.c @@ -0,0 +1,70 @@ +/* + * + * Copyright 2015, 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 + +#ifdef GPR_POSIX_SOCKETUTILS + +#include "src/core/iomgr/socket_utils_posix.h" + +#include +#include +#include + +#include + +int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, + int nonblock, int cloexec) { + int fd, flags; + + fd = accept(sockfd, addr, addrlen); + if (fd >= 0) { + if (nonblock) { + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) goto close_and_error; + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) goto close_and_error; + } + if (cloexec) { + flags = fcntl(fd, F_GETFD, 0); + if (flags < 0) goto close_and_error; + if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != 0) goto close_and_error; + } + } + return fd; + +close_and_error: + close(fd); + return -1; +} + +#endif /* GPR_POSIX_SOCKETUTILS */ diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h new file mode 100644 index 0000000000..3908550380 --- /dev/null +++ b/src/core/lib/iomgr/socket_utils_posix.h @@ -0,0 +1,113 @@ +/* + * + * Copyright 2015-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_IOMGR_SOCKET_UTILS_POSIX_H +#define GRPC_CORE_IOMGR_SOCKET_UTILS_POSIX_H + +#include +#include + +/* a wrapper for accept or accept4 */ +int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, + int nonblock, int cloexec); + +/* set a socket to non blocking mode */ +int grpc_set_socket_nonblocking(int fd, int non_blocking); + +/* set a socket to close on exec */ +int grpc_set_socket_cloexec(int fd, int close_on_exec); + +/* set a socket to reuse old addresses */ +int grpc_set_socket_reuse_addr(int fd, int reuse); + +/* disable nagle */ +int grpc_set_socket_low_latency(int fd, int low_latency); + +/* Returns true if this system can create AF_INET6 sockets bound to ::1. + The value is probed once, and cached for the life of the process. + + This is more restrictive than checking for socket(AF_INET6) to succeed, + because Linux with "net.ipv6.conf.all.disable_ipv6 = 1" is able to create + and bind IPv6 sockets, but cannot connect to a getsockname() of [::]:port + without a valid loopback interface. Rather than expose this half-broken + state to library users, we turn off IPv6 sockets. */ +int grpc_ipv6_loopback_available(void); + +/* Tries to set SO_NOSIGPIPE if available on this platform. + Returns 1 on success, 0 on failure. + If SO_NO_SIGPIPE is not available, returns 1. */ +int grpc_set_socket_no_sigpipe_if_possible(int fd); + +/* An enum to keep track of IPv4/IPv6 socket modes. + + Currently, this information is only used when a socket is first created, but + in the future we may wish to store it alongside the fd. This would let calls + like sendto() know which family to use without asking the kernel first. */ +typedef enum grpc_dualstack_mode { + /* Uninitialized, or a non-IP socket. */ + GRPC_DSMODE_NONE, + /* AF_INET only. */ + GRPC_DSMODE_IPV4, + /* AF_INET6 only, because IPV6_V6ONLY could not be cleared. */ + GRPC_DSMODE_IPV6, + /* AF_INET6, which also supports ::ffff-mapped IPv4 addresses. */ + GRPC_DSMODE_DUALSTACK +} grpc_dualstack_mode; + +/* Only tests should use this flag. */ +extern int grpc_forbid_dualstack_sockets_for_testing; + +/* Creates a new socket for connecting to (or listening on) an address. + + If addr is AF_INET6, this creates an IPv6 socket first. If that fails, + and addr is within ::ffff:0.0.0.0/96, then it automatically falls back to + an IPv4 socket. + + If addr is AF_INET, AF_UNIX, or anything else, then this is similar to + calling socket() directly. + + Returns an fd on success, otherwise returns -1 with errno set to the result + of a failed socket() call. + + The *dsmode output indicates which address family was actually created. + The recommended way to use this is: + - First convert to IPv6 using grpc_sockaddr_to_v4mapped(). + - Create the socket. + - If *dsmode is IPV4, use grpc_sockaddr_is_v4mapped() to convert back to + IPv4, so that bind() or connect() see the correct family. + Also, it's important to distinguish between DUALSTACK and IPV6 when + listening on the [::] wildcard address. */ +int grpc_create_dualstack_socket(const struct sockaddr *addr, int type, + int protocol, grpc_dualstack_mode *dsmode); + +#endif /* GRPC_CORE_IOMGR_SOCKET_UTILS_POSIX_H */ diff --git a/src/core/lib/iomgr/socket_windows.c b/src/core/lib/iomgr/socket_windows.c new file mode 100644 index 0000000000..c1f419e273 --- /dev/null +++ b/src/core/lib/iomgr/socket_windows.c @@ -0,0 +1,100 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_WINSOCK_SOCKET + +#include + +// must be included after winsock2.h +#include + +#include +#include +#include +#include + +#include "src/core/iomgr/iocp_windows.h" +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/iomgr/pollset.h" +#include "src/core/iomgr/pollset_windows.h" +#include "src/core/iomgr/socket_windows.h" + +grpc_winsocket *grpc_winsocket_create(SOCKET socket, const char *name) { + char *final_name; + grpc_winsocket *r = gpr_malloc(sizeof(grpc_winsocket)); + memset(r, 0, sizeof(grpc_winsocket)); + r->socket = socket; + gpr_mu_init(&r->state_mu); + gpr_asprintf(&final_name, "%s:socket=0x%p", name, r); + grpc_iomgr_register_object(&r->iomgr_object, final_name); + gpr_free(final_name); + grpc_iocp_add_socket(r); + return r; +} + +/* Schedule a shutdown of the socket operations. Will call the pending + operations to abort them. We need to do that this way because of the + various callsites of that function, which happens to be in various + mutex hold states, and that'd be unsafe to call them directly. */ +void grpc_winsocket_shutdown(grpc_winsocket *winsocket) { + /* Grab the function pointer for DisconnectEx for that specific socket. + It may change depending on the interface. */ + int status; + GUID guid = WSAID_DISCONNECTEX; + LPFN_DISCONNECTEX DisconnectEx; + DWORD ioctl_num_bytes; + + status = WSAIoctl(winsocket->socket, SIO_GET_EXTENSION_FUNCTION_POINTER, + &guid, sizeof(guid), &DisconnectEx, sizeof(DisconnectEx), + &ioctl_num_bytes, NULL, NULL); + + if (status == 0) { + DisconnectEx(winsocket->socket, NULL, 0, 0); + } else { + char *utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, "Unable to retrieve DisconnectEx pointer : %s", + utf8_message); + gpr_free(utf8_message); + } + closesocket(winsocket->socket); +} + +void grpc_winsocket_destroy(grpc_winsocket *winsocket) { + grpc_iomgr_unregister_object(&winsocket->iomgr_object); + gpr_mu_destroy(&winsocket->state_mu); + gpr_free(winsocket); +} + +#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h new file mode 100644 index 0000000000..6fe3c6e080 --- /dev/null +++ b/src/core/lib/iomgr/socket_windows.h @@ -0,0 +1,111 @@ +/* + * + * Copyright 2015-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_IOMGR_SOCKET_WINDOWS_H +#define GRPC_CORE_IOMGR_SOCKET_WINDOWS_H + +#include +#include + +#include +#include + +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/iomgr/iomgr_internal.h" + +/* This holds the data for an outstanding read or write on a socket. + The mutex to protect the concurrent access to that data is the one + inside the winsocket wrapper. */ +typedef struct grpc_winsocket_callback_info { + /* This is supposed to be a WSAOVERLAPPED, but in order to get that + definition, we need to include ws2tcpip.h, which needs to be included + from the top, otherwise it'll clash with a previous inclusion of + windows.h that in turns includes winsock.h. If anyone knows a way + to do it properly, feel free to send a patch. */ + OVERLAPPED overlapped; + /* The callback information for the pending operation. May be empty if the + caller hasn't registered a callback yet. */ + grpc_closure *closure; + /* A boolean to describe if the IO Completion Port got a notification for + that operation. This will happen if the operation completed before the + called had time to register a callback. We could avoid that behavior + altogether by forcing the caller to always register its callback before + proceeding queue an operation, but it is frequent for an IO Completion + Port to trigger quickly. This way we avoid a context switch for calling + the callback. We also simplify the read / write operations to avoid having + to hold a mutex for a long amount of time. */ + int has_pending_iocp; + /* The results of the overlapped operation. */ + DWORD bytes_transfered; + int wsa_error; +} grpc_winsocket_callback_info; + +/* This is a wrapper to a Windows socket. A socket can have one outstanding + read, and one outstanding write. Doing an asynchronous accept means waiting + for a read operation. Doing an asynchronous connect means waiting for a + write operation. These are completely arbitrary ties between the operation + and the kind of event, because we can have one overlapped per pending + operation, whichever its nature is. So we could have more dedicated pending + operation callbacks for connect and listen. But given the scope of listen + and accept, we don't need to go to that extent and waste memory. Also, this + is closer to what happens in posix world. */ +typedef struct grpc_winsocket { + SOCKET socket; + + grpc_winsocket_callback_info write_info; + grpc_winsocket_callback_info read_info; + + gpr_mu state_mu; + + /* You can't add the same socket twice to the same IO Completion Port. + This prevents that. */ + int added_to_iocp; + + grpc_closure shutdown_closure; + + /* A label for iomgr to track outstanding objects */ + grpc_iomgr_object iomgr_object; +} grpc_winsocket; + +/* Create a wrapped windows handle. This takes ownership of it, meaning that + it will be responsible for closing it. */ +grpc_winsocket *grpc_winsocket_create(SOCKET socket, const char *name); + +/* Initiate an asynchronous shutdown of the socket. Will call off any pending + operation to cancel them. */ +void grpc_winsocket_shutdown(grpc_winsocket *socket); + +/* Destroy a socket. Should only be called if there's no pending operation. */ +void grpc_winsocket_destroy(grpc_winsocket *socket); + +#endif /* GRPC_CORE_IOMGR_SOCKET_WINDOWS_H */ diff --git a/src/core/lib/iomgr/tcp_client.h b/src/core/lib/iomgr/tcp_client.h new file mode 100644 index 0000000000..c36f8de713 --- /dev/null +++ b/src/core/lib/iomgr/tcp_client.h @@ -0,0 +1,53 @@ +/* + * + * Copyright 2015-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_IOMGR_TCP_CLIENT_H +#define GRPC_CORE_IOMGR_TCP_CLIENT_H + +#include +#include "src/core/iomgr/endpoint.h" +#include "src/core/iomgr/pollset_set.h" +#include "src/core/iomgr/sockaddr.h" + +/* Asynchronously connect to an address (specified as (addr, len)), and call + cb with arg and the completed connection when done (or call cb with arg and + NULL on failure). + interested_parties points to a set of pollsets that would be interested + in this connection being established (in order to continue their work) */ +void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_connect, + grpc_endpoint **endpoint, + grpc_pollset_set *interested_parties, + const struct sockaddr *addr, size_t addr_len, + gpr_timespec deadline); + +#endif /* GRPC_CORE_IOMGR_TCP_CLIENT_H */ diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c new file mode 100644 index 0000000000..1d3f9b6555 --- /dev/null +++ b/src/core/lib/iomgr/tcp_client_posix.c @@ -0,0 +1,306 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_SOCKET + +#include "src/core/iomgr/tcp_client.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "src/core/iomgr/iomgr_posix.h" +#include "src/core/iomgr/pollset_posix.h" +#include "src/core/iomgr/pollset_set_posix.h" +#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/iomgr/tcp_posix.h" +#include "src/core/iomgr/timer.h" +#include "src/core/iomgr/unix_sockets_posix.h" +#include "src/core/support/string.h" + +extern int grpc_tcp_trace; + +typedef struct { + gpr_mu mu; + grpc_fd *fd; + gpr_timespec deadline; + grpc_timer alarm; + int refs; + grpc_closure write_closure; + grpc_pollset_set *interested_parties; + char *addr_str; + grpc_endpoint **ep; + grpc_closure *closure; +} async_connect; + +static int prepare_socket(const struct sockaddr *addr, int fd) { + if (fd < 0) { + goto error; + } + + if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || + (!grpc_is_unix_socket(addr) && !grpc_set_socket_low_latency(fd, 1)) || + !grpc_set_socket_no_sigpipe_if_possible(fd)) { + gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, + strerror(errno)); + goto error; + } + return 1; + +error: + if (fd >= 0) { + close(fd); + } + return 0; +} + +static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, bool success) { + int done; + async_connect *ac = acp; + if (grpc_tcp_trace) { + gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: success=%d", ac->addr_str, + success); + } + gpr_mu_lock(&ac->mu); + if (ac->fd != NULL) { + grpc_fd_shutdown(exec_ctx, ac->fd); + } + done = (--ac->refs == 0); + gpr_mu_unlock(&ac->mu); + if (done) { + gpr_mu_destroy(&ac->mu); + gpr_free(ac->addr_str); + gpr_free(ac); + } +} + +static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, bool success) { + async_connect *ac = acp; + int so_error = 0; + socklen_t so_error_size; + int err; + int done; + grpc_endpoint **ep = ac->ep; + grpc_closure *closure = ac->closure; + grpc_fd *fd; + + if (grpc_tcp_trace) { + gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_writable: success=%d", + ac->addr_str, success); + } + + gpr_mu_lock(&ac->mu); + GPR_ASSERT(ac->fd); + fd = ac->fd; + ac->fd = NULL; + gpr_mu_unlock(&ac->mu); + + grpc_timer_cancel(exec_ctx, &ac->alarm); + + gpr_mu_lock(&ac->mu); + if (success) { + do { + so_error_size = sizeof(so_error); + err = getsockopt(fd->fd, SOL_SOCKET, SO_ERROR, &so_error, &so_error_size); + } while (err < 0 && errno == EINTR); + if (err < 0) { + gpr_log(GPR_ERROR, "failed to connect to '%s': getsockopt(ERROR): %s", + ac->addr_str, strerror(errno)); + goto finish; + } else if (so_error != 0) { + if (so_error == ENOBUFS) { + /* We will get one of these errors if we have run out of + memory in the kernel for the data structures allocated + when you connect a socket. If this happens it is very + likely that if we wait a little bit then try again the + connection will work (since other programs or this + program will close their network connections and free up + memory). This does _not_ indicate that there is anything + wrong with the server we are connecting to, this is a + local problem. + + If you are looking at this code, then chances are that + your program or another program on the same computer + opened too many network connections. The "easy" fix: + don't do that! */ + gpr_log(GPR_ERROR, "kernel out of buffers"); + gpr_mu_unlock(&ac->mu); + grpc_fd_notify_on_write(exec_ctx, fd, &ac->write_closure); + return; + } else { + switch (so_error) { + case ECONNREFUSED: + gpr_log( + GPR_ERROR, + "failed to connect to '%s': socket error: connection refused", + ac->addr_str); + break; + default: + gpr_log(GPR_ERROR, "failed to connect to '%s': socket error: %d", + ac->addr_str, so_error); + break; + } + goto finish; + } + } else { + grpc_pollset_set_del_fd(exec_ctx, ac->interested_parties, fd); + *ep = grpc_tcp_create(fd, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, ac->addr_str); + fd = NULL; + goto finish; + } + } else { + gpr_log(GPR_ERROR, "failed to connect to '%s': timeout occurred", + ac->addr_str); + goto finish; + } + + GPR_UNREACHABLE_CODE(return ); + +finish: + if (fd != NULL) { + grpc_pollset_set_del_fd(exec_ctx, ac->interested_parties, fd); + grpc_fd_orphan(exec_ctx, fd, NULL, NULL, "tcp_client_orphan"); + fd = NULL; + } + done = (--ac->refs == 0); + gpr_mu_unlock(&ac->mu); + if (done) { + gpr_mu_destroy(&ac->mu); + gpr_free(ac->addr_str); + gpr_free(ac); + } + grpc_exec_ctx_enqueue(exec_ctx, closure, *ep != NULL, NULL); +} + +void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure, + grpc_endpoint **ep, + grpc_pollset_set *interested_parties, + const struct sockaddr *addr, size_t addr_len, + gpr_timespec deadline) { + int fd; + grpc_dualstack_mode dsmode; + int err; + async_connect *ac; + struct sockaddr_in6 addr6_v4mapped; + struct sockaddr_in addr4_copy; + grpc_fd *fdobj; + char *name; + char *addr_str; + + *ep = NULL; + + /* Use dualstack sockets where available. */ + if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { + addr = (const struct sockaddr *)&addr6_v4mapped; + addr_len = sizeof(addr6_v4mapped); + } + + fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode); + if (fd < 0) { + gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno)); + } + if (dsmode == GRPC_DSMODE_IPV4) { + /* If we got an AF_INET socket, map the address back to IPv4. */ + GPR_ASSERT(grpc_sockaddr_is_v4mapped(addr, &addr4_copy)); + addr = (struct sockaddr *)&addr4_copy; + addr_len = sizeof(addr4_copy); + } + if (!prepare_socket(addr, fd)) { + grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL); + return; + } + + do { + GPR_ASSERT(addr_len < ~(socklen_t)0); + err = connect(fd, addr, (socklen_t)addr_len); + } while (err < 0 && errno == EINTR); + + addr_str = grpc_sockaddr_to_uri(addr); + gpr_asprintf(&name, "tcp-client:%s", addr_str); + + fdobj = grpc_fd_create(fd, name); + + if (err >= 0) { + *ep = grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str); + grpc_exec_ctx_enqueue(exec_ctx, closure, true, NULL); + goto done; + } + + if (errno != EWOULDBLOCK && errno != EINPROGRESS) { + gpr_log(GPR_ERROR, "connect error to '%s': %s", addr_str, strerror(errno)); + grpc_fd_orphan(exec_ctx, fdobj, NULL, NULL, "tcp_client_connect_error"); + grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL); + goto done; + } + + grpc_pollset_set_add_fd(exec_ctx, interested_parties, fdobj); + + ac = gpr_malloc(sizeof(async_connect)); + ac->closure = closure; + ac->ep = ep; + ac->fd = fdobj; + ac->interested_parties = interested_parties; + ac->addr_str = addr_str; + addr_str = NULL; + gpr_mu_init(&ac->mu); + ac->refs = 2; + ac->write_closure.cb = on_writable; + ac->write_closure.cb_arg = ac; + + if (grpc_tcp_trace) { + gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: asynchronously connecting", + ac->addr_str); + } + + gpr_mu_lock(&ac->mu); + grpc_timer_init(exec_ctx, &ac->alarm, + gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC), + tc_on_alarm, ac, gpr_now(GPR_CLOCK_MONOTONIC)); + grpc_fd_notify_on_write(exec_ctx, ac->fd, &ac->write_closure); + gpr_mu_unlock(&ac->mu); + +done: + gpr_free(name); + gpr_free(addr_str); +} + +#endif diff --git a/src/core/lib/iomgr/tcp_client_windows.c b/src/core/lib/iomgr/tcp_client_windows.c new file mode 100644 index 0000000000..da83f7b79c --- /dev/null +++ b/src/core/lib/iomgr/tcp_client_windows.c @@ -0,0 +1,221 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_WINSOCK_SOCKET + +#include "src/core/iomgr/sockaddr_win32.h" + +#include +#include +#include +#include +#include + +#include "src/core/iomgr/iocp_windows.h" +#include "src/core/iomgr/sockaddr.h" +#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/iomgr/socket_windows.h" +#include "src/core/iomgr/tcp_client.h" +#include "src/core/iomgr/tcp_windows.h" +#include "src/core/iomgr/timer.h" + +typedef struct { + grpc_closure *on_done; + gpr_mu mu; + grpc_winsocket *socket; + gpr_timespec deadline; + grpc_timer alarm; + char *addr_name; + int refs; + grpc_closure on_connect; + grpc_endpoint **endpoint; +} async_connect; + +static void async_connect_unlock_and_cleanup(async_connect *ac) { + int done = (--ac->refs == 0); + gpr_mu_unlock(&ac->mu); + if (done) { + if (ac->socket != NULL) grpc_winsocket_destroy(ac->socket); + gpr_mu_destroy(&ac->mu); + gpr_free(ac->addr_name); + gpr_free(ac); + } +} + +static void on_alarm(grpc_exec_ctx *exec_ctx, void *acp, bool occured) { + async_connect *ac = acp; + gpr_mu_lock(&ac->mu); + /* If the alarm didn't occur, it got cancelled. */ + if (ac->socket != NULL && occured) { + grpc_winsocket_shutdown(ac->socket); + } + async_connect_unlock_and_cleanup(ac); +} + +static void on_connect(grpc_exec_ctx *exec_ctx, void *acp, bool from_iocp) { + async_connect *ac = acp; + SOCKET sock = ac->socket->socket; + grpc_endpoint **ep = ac->endpoint; + grpc_winsocket_callback_info *info = &ac->socket->write_info; + grpc_closure *on_done = ac->on_done; + + grpc_timer_cancel(exec_ctx, &ac->alarm); + + gpr_mu_lock(&ac->mu); + + if (from_iocp) { + DWORD transfered_bytes = 0; + DWORD flags; + BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped, + &transfered_bytes, FALSE, &flags); + GPR_ASSERT(transfered_bytes == 0); + if (!wsa_success) { + char *utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message); + gpr_free(utf8_message); + } else { + *ep = grpc_tcp_create(ac->socket, ac->addr_name); + ac->socket = NULL; + } + } + + async_connect_unlock_and_cleanup(ac); + /* If the connection was aborted, the callback was already called when + the deadline was met. */ + on_done->cb(exec_ctx, on_done->cb_arg, *ep != NULL); +} + +/* Tries to issue one async connection, then schedules both an IOCP + notification request for the connection, and one timeout alert. */ +void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done, + grpc_endpoint **endpoint, + grpc_pollset_set *interested_parties, + const struct sockaddr *addr, size_t addr_len, + gpr_timespec deadline) { + SOCKET sock = INVALID_SOCKET; + BOOL success; + int status; + struct sockaddr_in6 addr6_v4mapped; + struct sockaddr_in6 local_address; + async_connect *ac; + grpc_winsocket *socket = NULL; + LPFN_CONNECTEX ConnectEx; + GUID guid = WSAID_CONNECTEX; + DWORD ioctl_num_bytes; + const char *message = NULL; + char *utf8_message; + grpc_winsocket_callback_info *info; + + *endpoint = NULL; + + /* Use dualstack sockets where available. */ + if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { + addr = (const struct sockaddr *)&addr6_v4mapped; + addr_len = sizeof(addr6_v4mapped); + } + + sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED); + if (sock == INVALID_SOCKET) { + message = "Unable to create socket: %s"; + goto failure; + } + + if (!grpc_tcp_prepare_socket(sock)) { + message = "Unable to set socket options: %s"; + goto failure; + } + + /* Grab the function pointer for ConnectEx for that specific socket. + It may change depending on the interface. */ + status = + WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), + &ConnectEx, sizeof(ConnectEx), &ioctl_num_bytes, NULL, NULL); + + if (status != 0) { + message = "Unable to retrieve ConnectEx pointer: %s"; + goto failure; + } + + grpc_sockaddr_make_wildcard6(0, &local_address); + + status = bind(sock, (struct sockaddr *)&local_address, sizeof(local_address)); + if (status != 0) { + message = "Unable to bind socket: %s"; + goto failure; + } + + socket = grpc_winsocket_create(sock, "client"); + info = &socket->write_info; + success = + ConnectEx(sock, addr, (int)addr_len, NULL, 0, NULL, &info->overlapped); + + /* It wouldn't be unusual to get a success immediately. But we'll still get + an IOCP notification, so let's ignore it. */ + if (!success) { + int error = WSAGetLastError(); + if (error != ERROR_IO_PENDING) { + message = "ConnectEx failed: %s"; + goto failure; + } + } + + ac = gpr_malloc(sizeof(async_connect)); + ac->on_done = on_done; + ac->socket = socket; + gpr_mu_init(&ac->mu); + ac->refs = 2; + ac->addr_name = grpc_sockaddr_to_uri(addr); + ac->endpoint = endpoint; + grpc_closure_init(&ac->on_connect, on_connect, ac); + + grpc_timer_init(exec_ctx, &ac->alarm, deadline, on_alarm, ac, + gpr_now(GPR_CLOCK_MONOTONIC)); + grpc_socket_notify_on_write(exec_ctx, socket, &ac->on_connect); + return; + +failure: + utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, message, utf8_message); + gpr_free(utf8_message); + if (socket != NULL) { + grpc_winsocket_destroy(socket); + } else if (sock != INVALID_SOCKET) { + closesocket(sock); + } + grpc_exec_ctx_enqueue(exec_ctx, on_done, false, NULL); +} + +#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c new file mode 100644 index 0000000000..e8f73811ce --- /dev/null +++ b/src/core/lib/iomgr/tcp_posix.c @@ -0,0 +1,493 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_SOCKET + +#include "src/core/iomgr/tcp_posix.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "src/core/debug/trace.h" +#include "src/core/iomgr/pollset_posix.h" +#include "src/core/iomgr/pollset_set_posix.h" +#include "src/core/profiling/timers.h" +#include "src/core/support/string.h" + +#ifdef GPR_HAVE_MSG_NOSIGNAL +#define SENDMSG_FLAGS MSG_NOSIGNAL +#else +#define SENDMSG_FLAGS 0 +#endif + +#ifdef GPR_MSG_IOVLEN_TYPE +typedef GPR_MSG_IOVLEN_TYPE msg_iovlen_type; +#else +typedef size_t msg_iovlen_type; +#endif + +int grpc_tcp_trace = 0; + +typedef struct { + grpc_endpoint base; + grpc_fd *em_fd; + int fd; + int finished_edge; + msg_iovlen_type iov_size; /* Number of slices to allocate per read attempt */ + size_t slice_size; + gpr_refcount refcount; + + /* garbage after the last read */ + gpr_slice_buffer last_read_buffer; + + gpr_slice_buffer *incoming_buffer; + gpr_slice_buffer *outgoing_buffer; + /** slice within outgoing_buffer to write next */ + size_t outgoing_slice_idx; + /** byte within outgoing_buffer->slices[outgoing_slice_idx] to write next */ + size_t outgoing_byte_idx; + + grpc_closure *read_cb; + grpc_closure *write_cb; + grpc_closure *release_fd_cb; + int *release_fd; + + grpc_closure read_closure; + grpc_closure write_closure; + + char *peer_string; +} grpc_tcp; + +static void tcp_handle_read(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */, + bool success); +static void tcp_handle_write(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */, + bool success); + +static void tcp_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) { + grpc_tcp *tcp = (grpc_tcp *)ep; + grpc_fd_shutdown(exec_ctx, tcp->em_fd); +} + +static void tcp_free(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) { + grpc_fd_orphan(exec_ctx, tcp->em_fd, tcp->release_fd_cb, tcp->release_fd, + "tcp_unref_orphan"); + gpr_slice_buffer_destroy(&tcp->last_read_buffer); + gpr_free(tcp->peer_string); + gpr_free(tcp); +} + +/*#define GRPC_TCP_REFCOUNT_DEBUG*/ +#ifdef GRPC_TCP_REFCOUNT_DEBUG +#define TCP_UNREF(cl, tcp, reason) \ + tcp_unref((cl), (tcp), (reason), __FILE__, __LINE__) +#define TCP_REF(tcp, reason) tcp_ref((tcp), (reason), __FILE__, __LINE__) +static void tcp_unref(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp, + const char *reason, const char *file, int line) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "TCP unref %p : %s %d -> %d", tcp, + reason, tcp->refcount.count, tcp->refcount.count - 1); + if (gpr_unref(&tcp->refcount)) { + tcp_free(exec_ctx, tcp); + } +} + +static void tcp_ref(grpc_tcp *tcp, const char *reason, const char *file, + int line) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "TCP ref %p : %s %d -> %d", tcp, + reason, tcp->refcount.count, tcp->refcount.count + 1); + gpr_ref(&tcp->refcount); +} +#else +#define TCP_UNREF(cl, tcp, reason) tcp_unref((cl), (tcp)) +#define TCP_REF(tcp, reason) tcp_ref((tcp)) +static void tcp_unref(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) { + if (gpr_unref(&tcp->refcount)) { + tcp_free(exec_ctx, tcp); + } +} + +static void tcp_ref(grpc_tcp *tcp) { gpr_ref(&tcp->refcount); } +#endif + +static void tcp_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) { + grpc_tcp *tcp = (grpc_tcp *)ep; + TCP_UNREF(exec_ctx, tcp, "destroy"); +} + +static void call_read_cb(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp, int success) { + grpc_closure *cb = tcp->read_cb; + + if (grpc_tcp_trace) { + size_t i; + gpr_log(GPR_DEBUG, "read: success=%d", success); + for (i = 0; i < tcp->incoming_buffer->count; i++) { + char *dump = gpr_dump_slice(tcp->incoming_buffer->slices[i], + GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "READ %p: %s", tcp, dump); + gpr_free(dump); + } + } + + tcp->read_cb = NULL; + tcp->incoming_buffer = NULL; + cb->cb(exec_ctx, cb->cb_arg, success); +} + +#define MAX_READ_IOVEC 4 +static void tcp_continue_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) { + struct msghdr msg; + struct iovec iov[MAX_READ_IOVEC]; + ssize_t read_bytes; + size_t i; + + GPR_ASSERT(!tcp->finished_edge); + GPR_ASSERT(tcp->iov_size <= MAX_READ_IOVEC); + GPR_ASSERT(tcp->incoming_buffer->count <= MAX_READ_IOVEC); + GPR_TIMER_BEGIN("tcp_continue_read", 0); + + while (tcp->incoming_buffer->count < (size_t)tcp->iov_size) { + gpr_slice_buffer_add_indexed(tcp->incoming_buffer, + gpr_slice_malloc(tcp->slice_size)); + } + for (i = 0; i < tcp->incoming_buffer->count; i++) { + iov[i].iov_base = GPR_SLICE_START_PTR(tcp->incoming_buffer->slices[i]); + iov[i].iov_len = GPR_SLICE_LENGTH(tcp->incoming_buffer->slices[i]); + } + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = tcp->iov_size; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + GPR_TIMER_BEGIN("recvmsg", 1); + do { + read_bytes = recvmsg(tcp->fd, &msg, 0); + } while (read_bytes < 0 && errno == EINTR); + GPR_TIMER_END("recvmsg", 0); + + if (read_bytes < 0) { + /* NB: After calling call_read_cb a parallel call of the read handler may + * be running. */ + if (errno == EAGAIN) { + if (tcp->iov_size > 1) { + tcp->iov_size /= 2; + } + /* We've consumed the edge, request a new one */ + grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure); + } else { + /* TODO(klempner): Log interesting errors */ + gpr_slice_buffer_reset_and_unref(tcp->incoming_buffer); + call_read_cb(exec_ctx, tcp, 0); + TCP_UNREF(exec_ctx, tcp, "read"); + } + } else if (read_bytes == 0) { + /* 0 read size ==> end of stream */ + gpr_slice_buffer_reset_and_unref(tcp->incoming_buffer); + call_read_cb(exec_ctx, tcp, 0); + TCP_UNREF(exec_ctx, tcp, "read"); + } else { + GPR_ASSERT((size_t)read_bytes <= tcp->incoming_buffer->length); + if ((size_t)read_bytes < tcp->incoming_buffer->length) { + gpr_slice_buffer_trim_end( + tcp->incoming_buffer, + tcp->incoming_buffer->length - (size_t)read_bytes, + &tcp->last_read_buffer); + } else if (tcp->iov_size < MAX_READ_IOVEC) { + ++tcp->iov_size; + } + GPR_ASSERT((size_t)read_bytes == tcp->incoming_buffer->length); + call_read_cb(exec_ctx, tcp, 1); + TCP_UNREF(exec_ctx, tcp, "read"); + } + + GPR_TIMER_END("tcp_continue_read", 0); +} + +static void tcp_handle_read(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */, + bool success) { + grpc_tcp *tcp = (grpc_tcp *)arg; + GPR_ASSERT(!tcp->finished_edge); + + if (!success) { + gpr_slice_buffer_reset_and_unref(tcp->incoming_buffer); + call_read_cb(exec_ctx, tcp, 0); + TCP_UNREF(exec_ctx, tcp, "read"); + } else { + tcp_continue_read(exec_ctx, tcp); + } +} + +static void tcp_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + gpr_slice_buffer *incoming_buffer, grpc_closure *cb) { + grpc_tcp *tcp = (grpc_tcp *)ep; + GPR_ASSERT(tcp->read_cb == NULL); + tcp->read_cb = cb; + tcp->incoming_buffer = incoming_buffer; + gpr_slice_buffer_reset_and_unref(incoming_buffer); + gpr_slice_buffer_swap(incoming_buffer, &tcp->last_read_buffer); + TCP_REF(tcp, "read"); + if (tcp->finished_edge) { + tcp->finished_edge = 0; + grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure); + } else { + grpc_exec_ctx_enqueue(exec_ctx, &tcp->read_closure, true, NULL); + } +} + +typedef enum { FLUSH_DONE, FLUSH_PENDING, FLUSH_ERROR } flush_result; + +#define MAX_WRITE_IOVEC 16 +static flush_result tcp_flush(grpc_tcp *tcp) { + struct msghdr msg; + struct iovec iov[MAX_WRITE_IOVEC]; + msg_iovlen_type iov_size; + ssize_t sent_length; + size_t sending_length; + size_t trailing; + size_t unwind_slice_idx; + size_t unwind_byte_idx; + + for (;;) { + sending_length = 0; + unwind_slice_idx = tcp->outgoing_slice_idx; + unwind_byte_idx = tcp->outgoing_byte_idx; + for (iov_size = 0; tcp->outgoing_slice_idx != tcp->outgoing_buffer->count && + iov_size != MAX_WRITE_IOVEC; + iov_size++) { + iov[iov_size].iov_base = + GPR_SLICE_START_PTR( + tcp->outgoing_buffer->slices[tcp->outgoing_slice_idx]) + + tcp->outgoing_byte_idx; + iov[iov_size].iov_len = + GPR_SLICE_LENGTH( + tcp->outgoing_buffer->slices[tcp->outgoing_slice_idx]) - + tcp->outgoing_byte_idx; + sending_length += iov[iov_size].iov_len; + tcp->outgoing_slice_idx++; + tcp->outgoing_byte_idx = 0; + } + GPR_ASSERT(iov_size > 0); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = iov_size; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + GPR_TIMER_BEGIN("sendmsg", 1); + do { + /* TODO(klempner): Cork if this is a partial write */ + sent_length = sendmsg(tcp->fd, &msg, SENDMSG_FLAGS); + } while (sent_length < 0 && errno == EINTR); + GPR_TIMER_END("sendmsg", 0); + + if (sent_length < 0) { + if (errno == EAGAIN) { + tcp->outgoing_slice_idx = unwind_slice_idx; + tcp->outgoing_byte_idx = unwind_byte_idx; + return FLUSH_PENDING; + } else { + /* TODO(klempner): Log some of these */ + return FLUSH_ERROR; + } + } + + GPR_ASSERT(tcp->outgoing_byte_idx == 0); + trailing = sending_length - (size_t)sent_length; + while (trailing > 0) { + size_t slice_length; + + tcp->outgoing_slice_idx--; + slice_length = GPR_SLICE_LENGTH( + tcp->outgoing_buffer->slices[tcp->outgoing_slice_idx]); + if (slice_length > trailing) { + tcp->outgoing_byte_idx = slice_length - trailing; + break; + } else { + trailing -= slice_length; + } + } + + if (tcp->outgoing_slice_idx == tcp->outgoing_buffer->count) { + return FLUSH_DONE; + } + }; +} + +static void tcp_handle_write(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */, + bool success) { + grpc_tcp *tcp = (grpc_tcp *)arg; + flush_result status; + grpc_closure *cb; + + if (!success) { + cb = tcp->write_cb; + tcp->write_cb = NULL; + cb->cb(exec_ctx, cb->cb_arg, 0); + TCP_UNREF(exec_ctx, tcp, "write"); + return; + } + + status = tcp_flush(tcp); + if (status == FLUSH_PENDING) { + grpc_fd_notify_on_write(exec_ctx, tcp->em_fd, &tcp->write_closure); + } else { + cb = tcp->write_cb; + tcp->write_cb = NULL; + GPR_TIMER_BEGIN("tcp_handle_write.cb", 0); + cb->cb(exec_ctx, cb->cb_arg, status == FLUSH_DONE); + GPR_TIMER_END("tcp_handle_write.cb", 0); + TCP_UNREF(exec_ctx, tcp, "write"); + } +} + +static void tcp_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + gpr_slice_buffer *buf, grpc_closure *cb) { + grpc_tcp *tcp = (grpc_tcp *)ep; + flush_result status; + + if (grpc_tcp_trace) { + size_t i; + + for (i = 0; i < buf->count; i++) { + char *data = + gpr_dump_slice(buf->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "WRITE %p: %s", tcp, data); + gpr_free(data); + } + } + + GPR_TIMER_BEGIN("tcp_write", 0); + GPR_ASSERT(tcp->write_cb == NULL); + + if (buf->length == 0) { + GPR_TIMER_END("tcp_write", 0); + grpc_exec_ctx_enqueue(exec_ctx, cb, true, NULL); + return; + } + tcp->outgoing_buffer = buf; + tcp->outgoing_slice_idx = 0; + tcp->outgoing_byte_idx = 0; + + status = tcp_flush(tcp); + if (status == FLUSH_PENDING) { + TCP_REF(tcp, "write"); + tcp->write_cb = cb; + grpc_fd_notify_on_write(exec_ctx, tcp->em_fd, &tcp->write_closure); + } else { + grpc_exec_ctx_enqueue(exec_ctx, cb, status == FLUSH_DONE, NULL); + } + + GPR_TIMER_END("tcp_write", 0); +} + +static void tcp_add_to_pollset(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + grpc_pollset *pollset) { + grpc_tcp *tcp = (grpc_tcp *)ep; + grpc_pollset_add_fd(exec_ctx, pollset, tcp->em_fd); +} + +static void tcp_add_to_pollset_set(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + grpc_pollset_set *pollset_set) { + grpc_tcp *tcp = (grpc_tcp *)ep; + grpc_pollset_set_add_fd(exec_ctx, pollset_set, tcp->em_fd); +} + +static char *tcp_get_peer(grpc_endpoint *ep) { + grpc_tcp *tcp = (grpc_tcp *)ep; + return gpr_strdup(tcp->peer_string); +} + +static const grpc_endpoint_vtable vtable = { + tcp_read, tcp_write, tcp_add_to_pollset, tcp_add_to_pollset_set, + tcp_shutdown, tcp_destroy, tcp_get_peer}; + +grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size, + const char *peer_string) { + grpc_tcp *tcp = (grpc_tcp *)gpr_malloc(sizeof(grpc_tcp)); + tcp->base.vtable = &vtable; + tcp->peer_string = gpr_strdup(peer_string); + tcp->fd = em_fd->fd; + tcp->read_cb = NULL; + tcp->write_cb = NULL; + tcp->release_fd_cb = NULL; + tcp->release_fd = NULL; + tcp->incoming_buffer = NULL; + tcp->slice_size = slice_size; + tcp->iov_size = 1; + tcp->finished_edge = 1; + /* paired with unref in grpc_tcp_destroy */ + gpr_ref_init(&tcp->refcount, 1); + tcp->em_fd = em_fd; + tcp->read_closure.cb = tcp_handle_read; + tcp->read_closure.cb_arg = tcp; + tcp->write_closure.cb = tcp_handle_write; + tcp->write_closure.cb_arg = tcp; + gpr_slice_buffer_init(&tcp->last_read_buffer); + + return &tcp->base; +} + +int grpc_tcp_fd(grpc_endpoint *ep) { + grpc_tcp *tcp = (grpc_tcp *)ep; + GPR_ASSERT(ep->vtable == &vtable); + return grpc_fd_wrapped_fd(tcp->em_fd); +} + +void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + int *fd, grpc_closure *done) { + grpc_tcp *tcp = (grpc_tcp *)ep; + GPR_ASSERT(ep->vtable == &vtable); + tcp->release_fd = fd; + tcp->release_fd_cb = done; + TCP_UNREF(exec_ctx, tcp, "destroy"); +} + +#endif diff --git a/src/core/lib/iomgr/tcp_posix.h b/src/core/lib/iomgr/tcp_posix.h new file mode 100644 index 0000000000..d846ec570f --- /dev/null +++ b/src/core/lib/iomgr/tcp_posix.h @@ -0,0 +1,71 @@ +/* + * + * Copyright 2015-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_IOMGR_TCP_POSIX_H +#define GRPC_CORE_IOMGR_TCP_POSIX_H +/* + Low level TCP "bottom half" implementation, for use by transports built on + top of a TCP connection. + + Note that this file does not (yet) include APIs for creating the socket in + the first place. + + All calls passing slice transfer ownership of a slice refcount unless + otherwise specified. +*/ + +#include "src/core/iomgr/endpoint.h" +#include "src/core/iomgr/fd_posix.h" + +#define GRPC_TCP_DEFAULT_READ_SLICE_SIZE 8192 + +extern int grpc_tcp_trace; + +/* Create a tcp endpoint given a file desciptor and a read slice size. + Takes ownership of fd. */ +grpc_endpoint *grpc_tcp_create(grpc_fd *fd, size_t read_slice_size, + const char *peer_string); + +/* Return the tcp endpoint's fd, or -1 if this is not available. Does not + release the fd. + Requires: ep must be a tcp endpoint. + */ +int grpc_tcp_fd(grpc_endpoint *ep); + +/* Destroy the tcp endpoint without closing its fd. *fd will be set and done + * will be called when the endpoint is destroyed. + * Requires: ep must be a tcp endpoint and fd must not be NULL. */ +void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + int *fd, grpc_closure *done); + +#endif /* GRPC_CORE_IOMGR_TCP_POSIX_H */ diff --git a/src/core/lib/iomgr/tcp_server.h b/src/core/lib/iomgr/tcp_server.h new file mode 100644 index 0000000000..93247e9e4e --- /dev/null +++ b/src/core/lib/iomgr/tcp_server.h @@ -0,0 +1,103 @@ +/* + * + * Copyright 2015-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_IOMGR_TCP_SERVER_H +#define GRPC_CORE_IOMGR_TCP_SERVER_H + +#include "src/core/iomgr/closure.h" +#include "src/core/iomgr/endpoint.h" + +/* Forward decl of grpc_tcp_server */ +typedef struct grpc_tcp_server grpc_tcp_server; + +typedef struct grpc_tcp_server_acceptor { + /* grpc_tcp_server_cb functions share a ref on from_server that is valid + until the function returns. */ + grpc_tcp_server *from_server; + /* Indices that may be passed to grpc_tcp_server_port_fd(). */ + unsigned port_index; + unsigned fd_index; +} grpc_tcp_server_acceptor; + +/* Called for newly connected TCP connections. */ +typedef void (*grpc_tcp_server_cb)(grpc_exec_ctx *exec_ctx, void *arg, + grpc_endpoint *ep, + grpc_tcp_server_acceptor *acceptor); + +/* Create a server, initially not bound to any ports. The caller owns one ref. + If shutdown_complete is not NULL, it will be used by + grpc_tcp_server_unref() when the ref count reaches zero. */ +grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete); + +/* Start listening to bound ports */ +void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *server, + grpc_pollset **pollsets, size_t pollset_count, + grpc_tcp_server_cb on_accept_cb, void *cb_arg); + +/* Add a port to the server, returning the newly allocated port on success, or + -1 on failure. + + The :: and 0.0.0.0 wildcard addresses are treated identically, accepting + both IPv4 and IPv6 connections, but :: is the preferred style. This usually + creates one socket, but possibly two on systems which support IPv6, + but not dualstack sockets. */ +/* TODO(ctiller): deprecate this, and make grpc_tcp_server_add_ports to handle + all of the multiple socket port matching logic in one place */ +int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, + size_t addr_len); + +/* Number of fds at the given port_index, or 0 if port_index is out of + bounds. */ +unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s, unsigned port_index); + +/* Returns the file descriptor of the Mth (fd_index) listening socket of the Nth + (port_index) call to add_port() on this server, or -1 if the indices are out + of bounds. The file descriptor remains owned by the server, and will be + cleaned up when the ref count reaches zero. */ +int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index, + unsigned fd_index); + +/* Ref s and return s. */ +grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s); + +/* shutdown_starting is called when ref count has reached zero and the server is + about to be destroyed. The server will be deleted after it returns. Calling + grpc_tcp_server_ref() from it has no effect. */ +void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s, + grpc_closure *shutdown_starting); + +/* If the refcount drops to zero, delete s, and call (exec_ctx==NULL) or enqueue + a call (exec_ctx!=NULL) to shutdown_complete. */ +void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s); + +#endif /* GRPC_CORE_IOMGR_TCP_SERVER_H */ diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c new file mode 100644 index 0000000000..74ee68a6f1 --- /dev/null +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -0,0 +1,607 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* FIXME: "posix" files shouldn't be depending on _GNU_SOURCE */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include + +#ifdef GPR_POSIX_SOCKET + +#include "src/core/iomgr/tcp_server.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "src/core/iomgr/pollset_posix.h" +#include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/iomgr/tcp_posix.h" +#include "src/core/iomgr/unix_sockets_posix.h" +#include "src/core/support/string.h" + +#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100 + +static gpr_once s_init_max_accept_queue_size; +static int s_max_accept_queue_size; + +/* one listening port */ +typedef struct grpc_tcp_listener grpc_tcp_listener; +struct grpc_tcp_listener { + int fd; + grpc_fd *emfd; + grpc_tcp_server *server; + union { + uint8_t untyped[GRPC_MAX_SOCKADDR_SIZE]; + struct sockaddr sockaddr; + } addr; + size_t addr_len; + int port; + unsigned port_index; + unsigned fd_index; + grpc_closure read_closure; + grpc_closure destroyed_closure; + struct grpc_tcp_listener *next; + /* When we add a listener, more than one can be created, mainly because of + IPv6. A sibling will still be in the normal list, but will be flagged + as such. Any action, such as ref or unref, will affect all of the + siblings in the list. */ + struct grpc_tcp_listener *sibling; + int is_sibling; +}; + +/* the overall server */ +struct grpc_tcp_server { + gpr_refcount refs; + /* Called whenever accept() succeeds on a server port. */ + grpc_tcp_server_cb on_accept_cb; + void *on_accept_cb_arg; + + gpr_mu mu; + + /* active port count: how many ports are actually still listening */ + size_t active_ports; + /* destroyed port count: how many ports are completely destroyed */ + size_t destroyed_ports; + + /* is this server shutting down? (boolean) */ + int shutdown; + + /* linked list of server ports */ + grpc_tcp_listener *head; + grpc_tcp_listener *tail; + unsigned nports; + + /* List of closures passed to shutdown_starting_add(). */ + grpc_closure_list shutdown_starting; + + /* shutdown callback */ + grpc_closure *shutdown_complete; + + /* all pollsets interested in new connections */ + grpc_pollset **pollsets; + /* number of pollsets in the pollsets array */ + size_t pollset_count; +}; + +grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) { + grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server)); + gpr_ref_init(&s->refs, 1); + gpr_mu_init(&s->mu); + s->active_ports = 0; + s->destroyed_ports = 0; + s->shutdown = 0; + s->shutdown_starting.head = NULL; + s->shutdown_starting.tail = NULL; + s->shutdown_complete = shutdown_complete; + s->on_accept_cb = NULL; + s->on_accept_cb_arg = NULL; + s->head = NULL; + s->tail = NULL; + s->nports = 0; + return s; +} + +static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { + if (s->shutdown_complete != NULL) { + grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, true, NULL); + } + + gpr_mu_destroy(&s->mu); + + while (s->head) { + grpc_tcp_listener *sp = s->head; + s->head = sp->next; + gpr_free(sp); + } + + gpr_free(s); +} + +static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server, + bool success) { + grpc_tcp_server *s = server; + gpr_mu_lock(&s->mu); + s->destroyed_ports++; + if (s->destroyed_ports == s->nports) { + gpr_mu_unlock(&s->mu); + finish_shutdown(exec_ctx, s); + } else { + GPR_ASSERT(s->destroyed_ports < s->nports); + gpr_mu_unlock(&s->mu); + } +} + +/* called when all listening endpoints have been shutdown, so no further + events will be received on them - at this point it's safe to destroy + things */ +static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { + /* delete ALL the things */ + gpr_mu_lock(&s->mu); + + if (!s->shutdown) { + gpr_mu_unlock(&s->mu); + return; + } + + if (s->head) { + grpc_tcp_listener *sp; + for (sp = s->head; sp; sp = sp->next) { + grpc_unlink_if_unix_domain_socket(&sp->addr.sockaddr); + sp->destroyed_closure.cb = destroyed_port; + sp->destroyed_closure.cb_arg = s; + grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, + "tcp_listener_shutdown"); + } + gpr_mu_unlock(&s->mu); + } else { + gpr_mu_unlock(&s->mu); + finish_shutdown(exec_ctx, s); + } +} + +static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { + gpr_mu_lock(&s->mu); + + GPR_ASSERT(!s->shutdown); + s->shutdown = 1; + + /* shutdown all fd's */ + if (s->active_ports) { + grpc_tcp_listener *sp; + for (sp = s->head; sp; sp = sp->next) { + grpc_fd_shutdown(exec_ctx, sp->emfd); + } + gpr_mu_unlock(&s->mu); + } else { + gpr_mu_unlock(&s->mu); + deactivated_all_ports(exec_ctx, s); + } +} + +/* get max listen queue size on linux */ +static void init_max_accept_queue_size(void) { + int n = SOMAXCONN; + char buf[64]; + FILE *fp = fopen("/proc/sys/net/core/somaxconn", "r"); + if (fp == NULL) { + /* 2.4 kernel. */ + s_max_accept_queue_size = SOMAXCONN; + return; + } + if (fgets(buf, sizeof buf, fp)) { + char *end; + long i = strtol(buf, &end, 10); + if (i > 0 && i <= INT_MAX && end && *end == 0) { + n = (int)i; + } + } + fclose(fp); + s_max_accept_queue_size = n; + + if (s_max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) { + gpr_log(GPR_INFO, + "Suspiciously small accept queue (%d) will probably lead to " + "connection drops", + s_max_accept_queue_size); + } +} + +static int get_max_accept_queue_size(void) { + gpr_once_init(&s_init_max_accept_queue_size, init_max_accept_queue_size); + return s_max_accept_queue_size; +} + +/* Prepare a recently-created socket for listening. */ +static int prepare_socket(int fd, const struct sockaddr *addr, + size_t addr_len) { + struct sockaddr_storage sockname_temp; + socklen_t sockname_len; + + if (fd < 0) { + goto error; + } + + if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || + (!grpc_is_unix_socket(addr) && (!grpc_set_socket_low_latency(fd, 1) || + !grpc_set_socket_reuse_addr(fd, 1))) || + !grpc_set_socket_no_sigpipe_if_possible(fd)) { + gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, + strerror(errno)); + goto error; + } + + GPR_ASSERT(addr_len < ~(socklen_t)0); + if (bind(fd, addr, (socklen_t)addr_len) < 0) { + char *addr_str; + grpc_sockaddr_to_string(&addr_str, addr, 0); + gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno)); + gpr_free(addr_str); + goto error; + } + + if (listen(fd, get_max_accept_queue_size()) < 0) { + gpr_log(GPR_ERROR, "listen: %s", strerror(errno)); + goto error; + } + + sockname_len = sizeof(sockname_temp); + if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) { + goto error; + } + + return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); + +error: + if (fd >= 0) { + close(fd); + } + return -1; +} + +/* event manager callback when reads are ready */ +static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + grpc_tcp_listener *sp = arg; + grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index, + sp->fd_index}; + grpc_fd *fdobj; + size_t i; + + if (!success) { + goto error; + } + + /* loop until accept4 returns EAGAIN, and then re-arm notification */ + for (;;) { + struct sockaddr_storage addr; + socklen_t addrlen = sizeof(addr); + char *addr_str; + char *name; + /* Note: If we ever decide to return this address to the user, remember to + strip off the ::ffff:0.0.0.0/96 prefix first. */ + int fd = grpc_accept4(sp->fd, (struct sockaddr *)&addr, &addrlen, 1, 1); + if (fd < 0) { + switch (errno) { + case EINTR: + continue; + case EAGAIN: + grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure); + return; + default: + gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno)); + goto error; + } + } + + grpc_set_socket_no_sigpipe_if_possible(fd); + + addr_str = grpc_sockaddr_to_uri((struct sockaddr *)&addr); + gpr_asprintf(&name, "tcp-server-connection:%s", addr_str); + + if (grpc_tcp_trace) { + gpr_log(GPR_DEBUG, "SERVER_CONNECT: incoming connection: %s", addr_str); + } + + fdobj = grpc_fd_create(fd, name); + /* TODO(ctiller): revise this when we have server-side sharding + of channels -- we certainly should not be automatically adding every + incoming channel to every pollset owned by the server */ + for (i = 0; i < sp->server->pollset_count; i++) { + grpc_pollset_add_fd(exec_ctx, sp->server->pollsets[i], fdobj); + } + sp->server->on_accept_cb( + exec_ctx, sp->server->on_accept_cb_arg, + grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str), + &acceptor); + + gpr_free(name); + gpr_free(addr_str); + } + + GPR_UNREACHABLE_CODE(return ); + +error: + gpr_mu_lock(&sp->server->mu); + if (0 == --sp->server->active_ports) { + gpr_mu_unlock(&sp->server->mu); + deactivated_all_ports(exec_ctx, sp->server); + } else { + gpr_mu_unlock(&sp->server->mu); + } +} + +static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd, + const struct sockaddr *addr, + size_t addr_len, + unsigned port_index, + unsigned fd_index) { + grpc_tcp_listener *sp = NULL; + int port; + char *addr_str; + char *name; + + port = prepare_socket(fd, addr, addr_len); + if (port >= 0) { + grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1); + gpr_asprintf(&name, "tcp-server-listener:%s", addr_str); + gpr_mu_lock(&s->mu); + s->nports++; + GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server"); + sp = gpr_malloc(sizeof(grpc_tcp_listener)); + sp->next = NULL; + if (s->head == NULL) { + s->head = sp; + } else { + s->tail->next = sp; + } + s->tail = sp; + sp->server = s; + sp->fd = fd; + sp->emfd = grpc_fd_create(fd, name); + memcpy(sp->addr.untyped, addr, addr_len); + sp->addr_len = addr_len; + sp->port = port; + sp->port_index = port_index; + sp->fd_index = fd_index; + sp->is_sibling = 0; + sp->sibling = NULL; + GPR_ASSERT(sp->emfd); + gpr_mu_unlock(&s->mu); + gpr_free(addr_str); + gpr_free(name); + } + + return sp; +} + +int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, + size_t addr_len) { + grpc_tcp_listener *sp; + grpc_tcp_listener *sp2 = NULL; + int fd; + grpc_dualstack_mode dsmode; + struct sockaddr_in6 addr6_v4mapped; + struct sockaddr_in wild4; + struct sockaddr_in6 wild6; + struct sockaddr_in addr4_copy; + struct sockaddr *allocated_addr = NULL; + struct sockaddr_storage sockname_temp; + socklen_t sockname_len; + int port; + unsigned port_index = 0; + unsigned fd_index = 0; + if (s->tail != NULL) { + port_index = s->tail->port_index + 1; + } + grpc_unlink_if_unix_domain_socket((struct sockaddr *)addr); + + /* Check if this is a wildcard port, and if so, try to keep the port the same + as some previously created listener. */ + if (grpc_sockaddr_get_port(addr) == 0) { + for (sp = s->head; sp; sp = sp->next) { + sockname_len = sizeof(sockname_temp); + if (0 == getsockname(sp->fd, (struct sockaddr *)&sockname_temp, + &sockname_len)) { + port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); + if (port > 0) { + allocated_addr = malloc(addr_len); + memcpy(allocated_addr, addr, addr_len); + grpc_sockaddr_set_port(allocated_addr, port); + addr = allocated_addr; + break; + } + } + } + } + + sp = NULL; + + if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { + addr = (const struct sockaddr *)&addr6_v4mapped; + addr_len = sizeof(addr6_v4mapped); + } + + /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */ + if (grpc_sockaddr_is_wildcard(addr, &port)) { + grpc_sockaddr_make_wildcards(port, &wild4, &wild6); + + /* Try listening on IPv6 first. */ + addr = (struct sockaddr *)&wild6; + addr_len = sizeof(wild6); + fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode); + sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index); + if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) { + goto done; + } + if (sp != NULL) { + ++fd_index; + } + /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */ + if (port == 0 && sp != NULL) { + grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port); + } + addr = (struct sockaddr *)&wild4; + addr_len = sizeof(wild4); + } + + fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode); + if (fd < 0) { + gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno)); + } else { + if (dsmode == GRPC_DSMODE_IPV4 && + grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) { + addr = (struct sockaddr *)&addr4_copy; + addr_len = sizeof(addr4_copy); + } + sp2 = sp; + sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index); + if (sp2 != NULL && sp != NULL) { + sp2->sibling = sp; + sp->is_sibling = 1; + } + } + +done: + gpr_free(allocated_addr); + if (sp != NULL) { + return sp->port; + } else { + return -1; + } +} + +unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s, + unsigned port_index) { + unsigned num_fds = 0; + grpc_tcp_listener *sp; + for (sp = s->head; sp && port_index != 0; sp = sp->next) { + if (!sp->is_sibling) { + --port_index; + } + } + for (; sp; sp = sp->sibling, ++num_fds) + ; + return num_fds; +} + +int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index, + unsigned fd_index) { + grpc_tcp_listener *sp; + for (sp = s->head; sp && port_index != 0; sp = sp->next) { + if (!sp->is_sibling) { + --port_index; + } + } + for (; sp && fd_index != 0; sp = sp->sibling, --fd_index) + ; + if (sp) { + return sp->fd; + } else { + return -1; + } +} + +void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, + grpc_pollset **pollsets, size_t pollset_count, + grpc_tcp_server_cb on_accept_cb, + void *on_accept_cb_arg) { + size_t i; + grpc_tcp_listener *sp; + GPR_ASSERT(on_accept_cb); + gpr_mu_lock(&s->mu); + GPR_ASSERT(!s->on_accept_cb); + GPR_ASSERT(s->active_ports == 0); + s->on_accept_cb = on_accept_cb; + s->on_accept_cb_arg = on_accept_cb_arg; + s->pollsets = pollsets; + s->pollset_count = pollset_count; + for (sp = s->head; sp; sp = sp->next) { + for (i = 0; i < pollset_count; i++) { + grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd); + } + sp->read_closure.cb = on_read; + sp->read_closure.cb_arg = sp; + grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure); + s->active_ports++; + } + gpr_mu_unlock(&s->mu); +} + +grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) { + gpr_ref(&s->refs); + return s; +} + +void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s, + grpc_closure *shutdown_starting) { + gpr_mu_lock(&s->mu); + grpc_closure_list_add(&s->shutdown_starting, shutdown_starting, 1); + gpr_mu_unlock(&s->mu); +} + +void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { + if (gpr_unref(&s->refs)) { + /* Complete shutdown_starting work before destroying. */ + grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT; + gpr_mu_lock(&s->mu); + grpc_exec_ctx_enqueue_list(&local_exec_ctx, &s->shutdown_starting, NULL); + gpr_mu_unlock(&s->mu); + if (exec_ctx == NULL) { + grpc_exec_ctx_flush(&local_exec_ctx); + tcp_server_destroy(&local_exec_ctx, s); + grpc_exec_ctx_finish(&local_exec_ctx); + } else { + grpc_exec_ctx_finish(&local_exec_ctx); + tcp_server_destroy(exec_ctx, s); + } + } +} + +#endif diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c new file mode 100644 index 0000000000..a4abc5b974 --- /dev/null +++ b/src/core/lib/iomgr/tcp_server_windows.c @@ -0,0 +1,557 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_WINSOCK_SOCKET + +#include + +#include "src/core/iomgr/sockaddr_utils.h" + +#include +#include +#include +#include +#include +#include + +#include "src/core/iomgr/iocp_windows.h" +#include "src/core/iomgr/pollset_windows.h" +#include "src/core/iomgr/socket_windows.h" +#include "src/core/iomgr/tcp_server.h" +#include "src/core/iomgr/tcp_windows.h" + +#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100 + +/* one listening port */ +typedef struct grpc_tcp_listener grpc_tcp_listener; +struct grpc_tcp_listener { + /* This seemingly magic number comes from AcceptEx's documentation. each + address buffer needs to have at least 16 more bytes at their end. */ + uint8_t addresses[(sizeof(struct sockaddr_in6) + 16) * 2]; + /* This will hold the socket for the next accept. */ + SOCKET new_socket; + /* The listener winsocket. */ + grpc_winsocket *socket; + /* The actual TCP port number. */ + int port; + unsigned port_index; + grpc_tcp_server *server; + /* The cached AcceptEx for that port. */ + LPFN_ACCEPTEX AcceptEx; + int shutting_down; + /* closure for socket notification of accept being ready */ + grpc_closure on_accept; + /* linked list */ + struct grpc_tcp_listener *next; +}; + +/* the overall server */ +struct grpc_tcp_server { + gpr_refcount refs; + /* Called whenever accept() succeeds on a server port. */ + grpc_tcp_server_cb on_accept_cb; + void *on_accept_cb_arg; + + gpr_mu mu; + + /* active port count: how many ports are actually still listening */ + int active_ports; + + /* linked list of server ports */ + grpc_tcp_listener *head; + grpc_tcp_listener *tail; + + /* List of closures passed to shutdown_starting_add(). */ + grpc_closure_list shutdown_starting; + + /* shutdown callback */ + grpc_closure *shutdown_complete; +}; + +/* Public function. Allocates the proper data structures to hold a + grpc_tcp_server. */ +grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) { + grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server)); + gpr_ref_init(&s->refs, 1); + gpr_mu_init(&s->mu); + s->active_ports = 0; + s->on_accept_cb = NULL; + s->on_accept_cb_arg = NULL; + s->head = NULL; + s->tail = NULL; + s->shutdown_starting.head = NULL; + s->shutdown_starting.tail = NULL; + s->shutdown_complete = shutdown_complete; + return s; +} + +static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { + if (s->shutdown_complete != NULL) { + grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, true, NULL); + } + + /* Now that the accepts have been aborted, we can destroy the sockets. + The IOCP won't get notified on these, so we can flag them as already + closed by the system. */ + while (s->head) { + grpc_tcp_listener *sp = s->head; + s->head = sp->next; + sp->next = NULL; + grpc_winsocket_destroy(sp->socket); + gpr_free(sp); + } + gpr_free(s); +} + +grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) { + gpr_ref(&s->refs); + return s; +} + +void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s, + grpc_closure *shutdown_starting) { + gpr_mu_lock(&s->mu); + grpc_closure_list_add(&s->shutdown_starting, shutdown_starting, 1); + gpr_mu_unlock(&s->mu); +} + +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); + + /* First, shutdown all fd's. This will queue abortion calls for all + of the pending accepts due to the normal operation mechanism. */ + if (s->active_ports == 0) { + immediately_done = 1; + } + for (sp = s->head; sp; sp = sp->next) { + sp->shutting_down = 1; + grpc_winsocket_shutdown(sp->socket); + } + gpr_mu_unlock(&s->mu); + + if (immediately_done) { + finish_shutdown(exec_ctx, s); + } +} + +void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { + if (gpr_unref(&s->refs)) { + /* Complete shutdown_starting work before destroying. */ + grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT; + gpr_mu_lock(&s->mu); + grpc_exec_ctx_enqueue_list(&local_exec_ctx, &s->shutdown_starting, NULL); + gpr_mu_unlock(&s->mu); + if (exec_ctx == NULL) { + grpc_exec_ctx_flush(&local_exec_ctx); + tcp_server_destroy(&local_exec_ctx, s); + grpc_exec_ctx_finish(&local_exec_ctx); + } else { + grpc_exec_ctx_finish(&local_exec_ctx); + tcp_server_destroy(exec_ctx, s); + } + } +} + +/* Prepare (bind) a recently-created socket for listening. */ +static int prepare_socket(SOCKET sock, const struct sockaddr *addr, + size_t addr_len) { + struct sockaddr_storage sockname_temp; + socklen_t sockname_len; + + if (sock == INVALID_SOCKET) goto error; + + if (!grpc_tcp_prepare_socket(sock)) { + char *utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, "Unable to prepare socket: %s", utf8_message); + gpr_free(utf8_message); + goto error; + } + + if (bind(sock, addr, (int)addr_len) == SOCKET_ERROR) { + char *addr_str; + char *utf8_message = gpr_format_message(WSAGetLastError()); + grpc_sockaddr_to_string(&addr_str, addr, 0); + gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, utf8_message); + gpr_free(utf8_message); + gpr_free(addr_str); + goto error; + } + + if (listen(sock, SOMAXCONN) == SOCKET_ERROR) { + char *utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, "listen: %s", utf8_message); + gpr_free(utf8_message); + goto error; + } + + sockname_len = sizeof(sockname_temp); + if (getsockname(sock, (struct sockaddr *)&sockname_temp, &sockname_len) == + SOCKET_ERROR) { + char *utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, "getsockname: %s", utf8_message); + gpr_free(utf8_message); + goto error; + } + + return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); + +error: + if (sock != INVALID_SOCKET) closesocket(sock); + return -1; +} + +static void decrement_active_ports_and_notify(grpc_exec_ctx *exec_ctx, + grpc_tcp_listener *sp) { + int notify = 0; + sp->shutting_down = 0; + gpr_mu_lock(&sp->server->mu); + GPR_ASSERT(sp->server->active_ports > 0); + if (0 == --sp->server->active_ports) { + notify = 1; + } + gpr_mu_unlock(&sp->server->mu); + if (notify) { + finish_shutdown(exec_ctx, sp->server); + } +} + +/* In order to do an async accept, we need to create a socket first which + will be the one assigned to the new incoming connection. */ +static void start_accept(grpc_exec_ctx *exec_ctx, grpc_tcp_listener *port) { + SOCKET sock = INVALID_SOCKET; + char *message; + char *utf8_message; + BOOL success; + DWORD addrlen = sizeof(struct sockaddr_in6) + 16; + DWORD bytes_received = 0; + + sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED); + + if (sock == INVALID_SOCKET) { + message = "Unable to create socket: %s"; + goto failure; + } + + if (!grpc_tcp_prepare_socket(sock)) { + message = "Unable to prepare socket: %s"; + goto failure; + } + + /* Start the "accept" asynchronously. */ + success = port->AcceptEx(port->socket->socket, sock, port->addresses, 0, + addrlen, addrlen, &bytes_received, + &port->socket->read_info.overlapped); + + /* It is possible to get an accept immediately without delay. However, we + will still get an IOCP notification for it. So let's just ignore it. */ + if (!success) { + int error = WSAGetLastError(); + if (error != ERROR_IO_PENDING) { + message = "AcceptEx failed: %s"; + goto failure; + } + } + + /* We're ready to do the accept. Calling grpc_socket_notify_on_read may + immediately process an accept that happened in the meantime. */ + port->new_socket = sock; + grpc_socket_notify_on_read(exec_ctx, port->socket, &port->on_accept); + return; + +failure: + if (port->shutting_down) { + /* We are abandoning the listener port, take that into account to prevent + occasional hangs on shutdown. The hang happens when sp->shutting_down + change is not seen by on_accept and we proceed to trying new accept, + but we fail there because the listening port has been closed in the + meantime. */ + decrement_active_ports_and_notify(exec_ctx, port); + return; + } + utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, message, utf8_message); + gpr_free(utf8_message); + if (sock != INVALID_SOCKET) closesocket(sock); +} + +/* Event manager callback when reads are ready. */ +static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, bool from_iocp) { + grpc_tcp_listener *sp = arg; + grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index, 0}; + SOCKET sock = sp->new_socket; + grpc_winsocket_callback_info *info = &sp->socket->read_info; + grpc_endpoint *ep = NULL; + struct sockaddr_storage peer_name; + char *peer_name_string; + char *fd_name; + int peer_name_len = sizeof(peer_name); + DWORD transfered_bytes; + DWORD flags; + BOOL wsa_success; + int err; + + /* The general mechanism for shutting down is to queue abortion calls. While + this is necessary in the read/write case, it's useless for the accept + case. We only need to adjust the pending callback count */ + if (!from_iocp) { + return; + } + + /* The IOCP notified us of a completed operation. Let's grab the results, + and act accordingly. */ + transfered_bytes = 0; + wsa_success = WSAGetOverlappedResult(sock, &info->overlapped, + &transfered_bytes, FALSE, &flags); + if (!wsa_success) { + if (sp->shutting_down) { + /* During the shutdown case, we ARE expecting an error. So that's well, + and we can wake up the shutdown thread. */ + decrement_active_ports_and_notify(exec_ctx, sp); + return; + } else { + char *utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, "on_accept error: %s", utf8_message); + gpr_free(utf8_message); + closesocket(sock); + } + } else { + if (!sp->shutting_down) { + peer_name_string = NULL; + err = setsockopt(sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, + (char *)&sp->socket->socket, sizeof(sp->socket->socket)); + if (err) { + char *utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, "setsockopt error: %s", utf8_message); + gpr_free(utf8_message); + } + err = getpeername(sock, (struct sockaddr *)&peer_name, &peer_name_len); + if (!err) { + peer_name_string = grpc_sockaddr_to_uri((struct sockaddr *)&peer_name); + } else { + char *utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, "getpeername error: %s", utf8_message); + gpr_free(utf8_message); + } + gpr_asprintf(&fd_name, "tcp_server:%s", peer_name_string); + ep = grpc_tcp_create(grpc_winsocket_create(sock, fd_name), + peer_name_string); + gpr_free(fd_name); + gpr_free(peer_name_string); + } else { + closesocket(sock); + } + } + + /* The only time we should call our callback, is where we successfully + managed to accept a connection, and created an endpoint. */ + if (ep) + sp->server->on_accept_cb(exec_ctx, sp->server->on_accept_cb_arg, ep, + &acceptor); + /* As we were notified from the IOCP of one and exactly one accept, + the former socked we created has now either been destroy or assigned + to the new connection. We need to create a new one for the next + connection. */ + start_accept(exec_ctx, sp); +} + +static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, SOCKET sock, + const struct sockaddr *addr, + size_t addr_len, + unsigned port_index) { + grpc_tcp_listener *sp = NULL; + int port; + int status; + GUID guid = WSAID_ACCEPTEX; + DWORD ioctl_num_bytes; + LPFN_ACCEPTEX AcceptEx; + + if (sock == INVALID_SOCKET) return NULL; + + /* We need to grab the AcceptEx pointer for that port, as it may be + interface-dependent. We'll cache it to avoid doing that again. */ + status = + WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), + &AcceptEx, sizeof(AcceptEx), &ioctl_num_bytes, NULL, NULL); + + if (status != 0) { + char *utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message); + gpr_free(utf8_message); + closesocket(sock); + return NULL; + } + + port = prepare_socket(sock, addr, addr_len); + if (port >= 0) { + gpr_mu_lock(&s->mu); + GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server"); + sp = gpr_malloc(sizeof(grpc_tcp_listener)); + sp->next = NULL; + if (s->head == NULL) { + s->head = sp; + } else { + s->tail->next = sp; + } + s->tail = sp; + sp->server = s; + sp->socket = grpc_winsocket_create(sock, "listener"); + sp->shutting_down = 0; + sp->AcceptEx = AcceptEx; + sp->new_socket = INVALID_SOCKET; + sp->port = port; + sp->port_index = port_index; + grpc_closure_init(&sp->on_accept, on_accept, sp); + GPR_ASSERT(sp->socket); + gpr_mu_unlock(&s->mu); + } + + return sp; +} + +int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, + size_t addr_len) { + grpc_tcp_listener *sp; + SOCKET sock; + struct sockaddr_in6 addr6_v4mapped; + struct sockaddr_in6 wildcard; + struct sockaddr *allocated_addr = NULL; + struct sockaddr_storage sockname_temp; + socklen_t sockname_len; + int port; + unsigned port_index = 0; + if (s->tail != NULL) { + port_index = s->tail->port_index + 1; + } + + /* Check if this is a wildcard port, and if so, try to keep the port the same + as some previously created listener. */ + if (grpc_sockaddr_get_port(addr) == 0) { + for (sp = s->head; sp; sp = sp->next) { + sockname_len = sizeof(sockname_temp); + if (0 == getsockname(sp->socket->socket, + (struct sockaddr *)&sockname_temp, &sockname_len)) { + port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); + if (port > 0) { + allocated_addr = malloc(addr_len); + memcpy(allocated_addr, addr, addr_len); + grpc_sockaddr_set_port(allocated_addr, port); + addr = allocated_addr; + break; + } + } + } + } + + if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { + addr = (const struct sockaddr *)&addr6_v4mapped; + addr_len = sizeof(addr6_v4mapped); + } + + /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */ + if (grpc_sockaddr_is_wildcard(addr, &port)) { + grpc_sockaddr_make_wildcard6(port, &wildcard); + + addr = (struct sockaddr *)&wildcard; + addr_len = sizeof(wildcard); + } + + sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED); + if (sock == INVALID_SOCKET) { + char *utf8_message = gpr_format_message(WSAGetLastError()); + gpr_log(GPR_ERROR, "unable to create socket: %s", utf8_message); + gpr_free(utf8_message); + } + + sp = add_socket_to_server(s, sock, addr, addr_len, port_index); + gpr_free(allocated_addr); + + if (sp) { + return sp->port; + } else { + return -1; + } +} + +unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s, + unsigned port_index) { + grpc_tcp_listener *sp; + for (sp = s->head; sp && port_index != 0; sp = sp->next, --port_index) + ; + if (sp) { + return 1; + } else { + return 0; + } +} + +int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index, + unsigned fd_index) { + grpc_tcp_listener *sp; + if (fd_index != 0) { + /* Windows implementation has only one fd per port_index. */ + return -1; + } + for (sp = s->head; sp && port_index != 0; sp = sp->next, --port_index) + ; + if (sp) { + return _open_osfhandle((intptr_t)sp->socket->socket, 0); + } else { + return -1; + } +} + +void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, + grpc_pollset **pollset, size_t pollset_count, + grpc_tcp_server_cb on_accept_cb, + void *on_accept_cb_arg) { + grpc_tcp_listener *sp; + GPR_ASSERT(on_accept_cb); + gpr_mu_lock(&s->mu); + GPR_ASSERT(!s->on_accept_cb); + GPR_ASSERT(s->active_ports == 0); + s->on_accept_cb = on_accept_cb; + s->on_accept_cb_arg = on_accept_cb_arg; + for (sp = s->head; sp; sp = sp->next) { + start_accept(exec_ctx, sp); + s->active_ports++; + } + gpr_mu_unlock(&s->mu); +} + +#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c new file mode 100644 index 0000000000..9b1db5fa7e --- /dev/null +++ b/src/core/lib/iomgr/tcp_windows.c @@ -0,0 +1,402 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_WINSOCK_SOCKET + +#include "src/core/iomgr/sockaddr_win32.h" + +#include +#include +#include +#include +#include +#include + +#include "src/core/iomgr/iocp_windows.h" +#include "src/core/iomgr/sockaddr.h" +#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/iomgr/socket_windows.h" +#include "src/core/iomgr/tcp_client.h" +#include "src/core/iomgr/timer.h" + +static int set_non_block(SOCKET sock) { + int status; + unsigned long param = 1; + DWORD ret; + status = + WSAIoctl(sock, FIONBIO, ¶m, sizeof(param), NULL, 0, &ret, NULL, NULL); + return status == 0; +} + +static int set_dualstack(SOCKET sock) { + int status; + unsigned long param = 0; + status = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)¶m, + sizeof(param)); + return status == 0; +} + +int grpc_tcp_prepare_socket(SOCKET sock) { + if (!set_non_block(sock)) return 0; + if (!set_dualstack(sock)) return 0; + return 1; +} + +typedef struct grpc_tcp { + /* This is our C++ class derivation emulation. */ + grpc_endpoint base; + /* The one socket this endpoint is using. */ + grpc_winsocket *socket; + /* Refcounting how many operations are in progress. */ + gpr_refcount refcount; + + grpc_closure on_read; + grpc_closure on_write; + + grpc_closure *read_cb; + grpc_closure *write_cb; + gpr_slice read_slice; + gpr_slice_buffer *write_slices; + gpr_slice_buffer *read_slices; + + /* The IO Completion Port runs from another thread. We need some mechanism + to protect ourselves when requesting a shutdown. */ + gpr_mu mu; + int shutting_down; + + char *peer_string; +} grpc_tcp; + +static void tcp_free(grpc_tcp *tcp) { + grpc_winsocket_destroy(tcp->socket); + gpr_mu_destroy(&tcp->mu); + gpr_free(tcp->peer_string); + gpr_free(tcp); +} + +/*#define GRPC_TCP_REFCOUNT_DEBUG*/ +#ifdef GRPC_TCP_REFCOUNT_DEBUG +#define TCP_UNREF(tcp, reason) tcp_unref((tcp), (reason), __FILE__, __LINE__) +#define TCP_REF(tcp, reason) tcp_ref((tcp), (reason), __FILE__, __LINE__) +static void tcp_unref(grpc_tcp *tcp, const char *reason, const char *file, + int line) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "TCP unref %p : %s %d -> %d", tcp, + reason, tcp->refcount.count, tcp->refcount.count - 1); + if (gpr_unref(&tcp->refcount)) { + tcp_free(tcp); + } +} + +static void tcp_ref(grpc_tcp *tcp, const char *reason, const char *file, + int line) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "TCP ref %p : %s %d -> %d", tcp, + reason, tcp->refcount.count, tcp->refcount.count + 1); + gpr_ref(&tcp->refcount); +} +#else +#define TCP_UNREF(tcp, reason) tcp_unref((tcp)) +#define TCP_REF(tcp, reason) tcp_ref((tcp)) +static void tcp_unref(grpc_tcp *tcp) { + if (gpr_unref(&tcp->refcount)) { + tcp_free(tcp); + } +} + +static void tcp_ref(grpc_tcp *tcp) { gpr_ref(&tcp->refcount); } +#endif + +/* Asynchronous callback from the IOCP, or the background thread. */ +static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, bool success) { + grpc_tcp *tcp = tcpp; + grpc_closure *cb = tcp->read_cb; + grpc_winsocket *socket = tcp->socket; + gpr_slice sub; + grpc_winsocket_callback_info *info = &socket->read_info; + + if (success) { + if (info->wsa_error != 0 && !tcp->shutting_down) { + if (info->wsa_error != WSAECONNRESET) { + char *utf8_message = gpr_format_message(info->wsa_error); + gpr_log(GPR_ERROR, "ReadFile overlapped error: %s", utf8_message); + gpr_free(utf8_message); + } + success = 0; + gpr_slice_unref(tcp->read_slice); + } else { + if (info->bytes_transfered != 0 && !tcp->shutting_down) { + sub = gpr_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); + gpr_slice_buffer_add(tcp->read_slices, sub); + success = 1; + } else { + gpr_slice_unref(tcp->read_slice); + success = 0; + } + } + } + + tcp->read_cb = NULL; + TCP_UNREF(tcp, "read"); + if (cb) { + cb->cb(exec_ctx, cb->cb_arg, success); + } +} + +static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + gpr_slice_buffer *read_slices, grpc_closure *cb) { + grpc_tcp *tcp = (grpc_tcp *)ep; + grpc_winsocket *handle = tcp->socket; + grpc_winsocket_callback_info *info = &handle->read_info; + int status; + DWORD bytes_read = 0; + DWORD flags = 0; + WSABUF buffer; + + if (tcp->shutting_down) { + grpc_exec_ctx_enqueue(exec_ctx, cb, false, NULL); + return; + } + + tcp->read_cb = cb; + tcp->read_slices = read_slices; + gpr_slice_buffer_reset_and_unref(read_slices); + + tcp->read_slice = gpr_slice_malloc(8192); + + buffer.len = (ULONG)GPR_SLICE_LENGTH( + tcp->read_slice); // we know slice size fits in 32bit. + buffer.buf = (char *)GPR_SLICE_START_PTR(tcp->read_slice); + + TCP_REF(tcp, "read"); + + /* First let's try a synchronous, non-blocking read. */ + status = + WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, NULL, NULL); + info->wsa_error = status == 0 ? 0 : WSAGetLastError(); + + /* Did we get data immediately ? Yay. */ + if (info->wsa_error != WSAEWOULDBLOCK) { + info->bytes_transfered = bytes_read; + grpc_exec_ctx_enqueue(exec_ctx, &tcp->on_read, true, NULL); + return; + } + + /* Otherwise, let's retry, by queuing a read. */ + memset(&tcp->socket->read_info.overlapped, 0, sizeof(OVERLAPPED)); + status = WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, + &info->overlapped, NULL); + + if (status != 0) { + int wsa_error = WSAGetLastError(); + if (wsa_error != WSA_IO_PENDING) { + info->wsa_error = wsa_error; + grpc_exec_ctx_enqueue(exec_ctx, &tcp->on_read, false, NULL); + return; + } + } + + grpc_socket_notify_on_read(exec_ctx, tcp->socket, &tcp->on_read); +} + +/* Asynchronous callback from the IOCP, or the background thread. */ +static void on_write(grpc_exec_ctx *exec_ctx, void *tcpp, bool success) { + grpc_tcp *tcp = (grpc_tcp *)tcpp; + grpc_winsocket *handle = tcp->socket; + grpc_winsocket_callback_info *info = &handle->write_info; + grpc_closure *cb; + + gpr_mu_lock(&tcp->mu); + cb = tcp->write_cb; + tcp->write_cb = NULL; + gpr_mu_unlock(&tcp->mu); + + if (success) { + if (info->wsa_error != 0) { + if (info->wsa_error != WSAECONNRESET) { + char *utf8_message = gpr_format_message(info->wsa_error); + gpr_log(GPR_ERROR, "WSASend overlapped error: %s", utf8_message); + gpr_free(utf8_message); + } + success = 0; + } else { + GPR_ASSERT(info->bytes_transfered == tcp->write_slices->length); + } + } + + TCP_UNREF(tcp, "write"); + cb->cb(exec_ctx, cb->cb_arg, success); +} + +/* Initiates a write. */ +static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + gpr_slice_buffer *slices, grpc_closure *cb) { + grpc_tcp *tcp = (grpc_tcp *)ep; + grpc_winsocket *socket = tcp->socket; + grpc_winsocket_callback_info *info = &socket->write_info; + unsigned i; + DWORD bytes_sent; + int status; + WSABUF local_buffers[16]; + WSABUF *allocated = NULL; + WSABUF *buffers = local_buffers; + size_t len; + + if (tcp->shutting_down) { + grpc_exec_ctx_enqueue(exec_ctx, cb, false, NULL); + return; + } + + tcp->write_cb = cb; + tcp->write_slices = slices; + GPR_ASSERT(tcp->write_slices->count <= UINT_MAX); + if (tcp->write_slices->count > GPR_ARRAY_SIZE(local_buffers)) { + buffers = (WSABUF *)gpr_malloc(sizeof(WSABUF) * tcp->write_slices->count); + allocated = buffers; + } + + for (i = 0; i < tcp->write_slices->count; i++) { + len = GPR_SLICE_LENGTH(tcp->write_slices->slices[i]); + GPR_ASSERT(len <= ULONG_MAX); + buffers[i].len = (ULONG)len; + buffers[i].buf = (char *)GPR_SLICE_START_PTR(tcp->write_slices->slices[i]); + } + + /* First, let's try a synchronous, non-blocking write. */ + status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count, + &bytes_sent, 0, NULL, NULL); + info->wsa_error = status == 0 ? 0 : WSAGetLastError(); + + /* We would kind of expect to get a WSAEWOULDBLOCK here, especially on a busy + connection that has its send queue filled up. But if we don't, then we can + avoid doing an async write operation at all. */ + if (info->wsa_error != WSAEWOULDBLOCK) { + bool ok = false; + if (status == 0) { + ok = true; + GPR_ASSERT(bytes_sent == tcp->write_slices->length); + } else { + if (info->wsa_error != WSAECONNRESET) { + char *utf8_message = gpr_format_message(info->wsa_error); + gpr_log(GPR_ERROR, "WSASend error: %s", utf8_message); + gpr_free(utf8_message); + } + } + if (allocated) gpr_free(allocated); + grpc_exec_ctx_enqueue(exec_ctx, cb, ok, NULL); + return; + } + + TCP_REF(tcp, "write"); + + /* If we got a WSAEWOULDBLOCK earlier, then we need to re-do the same + operation, this time asynchronously. */ + memset(&socket->write_info.overlapped, 0, sizeof(OVERLAPPED)); + status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count, + &bytes_sent, 0, &socket->write_info.overlapped, NULL); + if (allocated) gpr_free(allocated); + + if (status != 0) { + int wsa_error = WSAGetLastError(); + if (wsa_error != WSA_IO_PENDING) { + TCP_UNREF(tcp, "write"); + grpc_exec_ctx_enqueue(exec_ctx, cb, false, NULL); + return; + } + } + + /* As all is now setup, we can now ask for the IOCP notification. It may + trigger the callback immediately however, but no matter. */ + grpc_socket_notify_on_write(exec_ctx, socket, &tcp->on_write); +} + +static void win_add_to_pollset(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + grpc_pollset *ps) { + grpc_tcp *tcp; + (void)ps; + tcp = (grpc_tcp *)ep; + grpc_iocp_add_socket(tcp->socket); +} + +static void win_add_to_pollset_set(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, + grpc_pollset_set *pss) { + grpc_tcp *tcp; + (void)pss; + tcp = (grpc_tcp *)ep; + grpc_iocp_add_socket(tcp->socket); +} + +/* Initiates a shutdown of the TCP endpoint. This will queue abort callbacks + for the potential read and write operations. It is up to the caller to + guarantee this isn't called in parallel to a read or write request, so + we're not going to protect against these. However the IO Completion Port + callback will happen from another thread, so we need to protect against + concurrent access of the data structure in that regard. */ +static void win_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) { + grpc_tcp *tcp = (grpc_tcp *)ep; + gpr_mu_lock(&tcp->mu); + /* At that point, what may happen is that we're already inside the IOCP + callback. See the comments in on_read and on_write. */ + tcp->shutting_down = 1; + grpc_winsocket_shutdown(tcp->socket); + gpr_mu_unlock(&tcp->mu); +} + +static void win_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) { + grpc_tcp *tcp = (grpc_tcp *)ep; + TCP_UNREF(tcp, "destroy"); +} + +static char *win_get_peer(grpc_endpoint *ep) { + grpc_tcp *tcp = (grpc_tcp *)ep; + return gpr_strdup(tcp->peer_string); +} + +static grpc_endpoint_vtable vtable = { + win_read, win_write, win_add_to_pollset, win_add_to_pollset_set, + win_shutdown, win_destroy, win_get_peer}; + +grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket, char *peer_string) { + grpc_tcp *tcp = (grpc_tcp *)gpr_malloc(sizeof(grpc_tcp)); + memset(tcp, 0, sizeof(grpc_tcp)); + tcp->base.vtable = &vtable; + tcp->socket = socket; + gpr_mu_init(&tcp->mu); + gpr_ref_init(&tcp->refcount, 1); + grpc_closure_init(&tcp->on_read, on_read, tcp); + grpc_closure_init(&tcp->on_write, on_write, tcp); + tcp->peer_string = gpr_strdup(peer_string); + return &tcp->base; +} + +#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/tcp_windows.h b/src/core/lib/iomgr/tcp_windows.h new file mode 100644 index 0000000000..78bc13389a --- /dev/null +++ b/src/core/lib/iomgr/tcp_windows.h @@ -0,0 +1,57 @@ +/* + * + * Copyright 2015-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_IOMGR_TCP_WINDOWS_H +#define GRPC_CORE_IOMGR_TCP_WINDOWS_H +/* + Low level TCP "bottom half" implementation, for use by transports built on + top of a TCP connection. + + Note that this file does not (yet) include APIs for creating the socket in + the first place. + + All calls passing slice transfer ownership of a slice refcount unless + otherwise specified. +*/ + +#include "src/core/iomgr/endpoint.h" +#include "src/core/iomgr/socket_windows.h" + +/* Create a tcp endpoint given a winsock handle. + * Takes ownership of the handle. + */ +grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket, char *peer_string); + +int grpc_tcp_prepare_socket(SOCKET sock); + +#endif /* GRPC_CORE_IOMGR_TCP_WINDOWS_H */ diff --git a/src/core/lib/iomgr/time_averaged_stats.c b/src/core/lib/iomgr/time_averaged_stats.c new file mode 100644 index 0000000000..e075db4373 --- /dev/null +++ b/src/core/lib/iomgr/time_averaged_stats.c @@ -0,0 +1,77 @@ +/* + * + * Copyright 2015, 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/iomgr/time_averaged_stats.h" + +void grpc_time_averaged_stats_init(grpc_time_averaged_stats* stats, + double init_avg, double regress_weight, + double persistence_factor) { + stats->init_avg = init_avg; + stats->regress_weight = regress_weight; + stats->persistence_factor = persistence_factor; + stats->batch_total_value = 0; + stats->batch_num_samples = 0; + stats->aggregate_total_weight = 0; + stats->aggregate_weighted_avg = init_avg; +} + +void grpc_time_averaged_stats_add_sample(grpc_time_averaged_stats* stats, + double value) { + stats->batch_total_value += value; + ++stats->batch_num_samples; +} + +double grpc_time_averaged_stats_update_average( + grpc_time_averaged_stats* stats) { + /* Start with the current batch: */ + double weighted_sum = stats->batch_total_value; + double total_weight = stats->batch_num_samples; + if (stats->regress_weight > 0) { + /* Add in the regression towards init_avg_: */ + weighted_sum += stats->regress_weight * stats->init_avg; + total_weight += stats->regress_weight; + } + if (stats->persistence_factor > 0) { + /* Add in the persistence: */ + const double prev_sample_weight = + stats->persistence_factor * stats->aggregate_total_weight; + weighted_sum += prev_sample_weight * stats->aggregate_weighted_avg; + total_weight += prev_sample_weight; + } + stats->aggregate_weighted_avg = + (total_weight > 0) ? (weighted_sum / total_weight) : stats->init_avg; + stats->aggregate_total_weight = total_weight; + stats->batch_num_samples = 0; + stats->batch_total_value = 0; + return stats->aggregate_weighted_avg; +} diff --git a/src/core/lib/iomgr/time_averaged_stats.h b/src/core/lib/iomgr/time_averaged_stats.h new file mode 100644 index 0000000000..048e244bcc --- /dev/null +++ b/src/core/lib/iomgr/time_averaged_stats.h @@ -0,0 +1,88 @@ +/* + * + * Copyright 2015-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_IOMGR_TIME_AVERAGED_STATS_H +#define GRPC_CORE_IOMGR_TIME_AVERAGED_STATS_H + +/* This tracks a time-decaying weighted average. It works by collecting + batches of samples and then mixing their average into a time-decaying + weighted mean. It is designed for batch operations where we do many adds + before updating the average. */ + +typedef struct { + /* The initial average value. This is the reported average until the first + grpc_time_averaged_stats_update_average call. If a positive regress_weight + is used, we also regress towards this value on each update. */ + double init_avg; + /* The sample weight of "init_avg" that is mixed in with each call to + grpc_time_averaged_stats_update_average. If the calls to + grpc_time_averaged_stats_add_sample stop, this will cause the average to + regress back to the mean. This should be non-negative. Set it to 0 to + disable the bias. A value of 1 has the effect of adding in 1 bonus sample + with value init_avg to each sample period. */ + double regress_weight; + /* This determines the rate of decay of the time-averaging from one period + to the next by scaling the aggregate_total_weight of samples from prior + periods when combining with the latest period. It should be in the range + [0,1]. A higher value adapts more slowly. With a value of 0.5, if the + batches each have k samples, the samples_in_avg_ will grow to 2 k, so the + weighting of the time average will eventually be 1/3 new batch and 2/3 + old average. */ + double persistence_factor; + + /* The total value of samples since the last UpdateAverage(). */ + double batch_total_value; + /* The number of samples since the last UpdateAverage(). */ + double batch_num_samples; + /* The time-decayed sum of batch_num_samples_ over previous batches. This is + the "weight" of the old aggregate_weighted_avg_ when updating the + average. */ + double aggregate_total_weight; + /* A time-decayed average of the (batch_total_value_ / batch_num_samples_), + computed by decaying the samples_in_avg_ weight in the weighted average. */ + double aggregate_weighted_avg; +} grpc_time_averaged_stats; + +/* See the comments on the members above for an explanation of init_avg, + regress_weight, and persistence_factor. */ +void grpc_time_averaged_stats_init(grpc_time_averaged_stats* stats, + double init_avg, double regress_weight, + double persistence_factor); +/* Add a sample to the current batch. */ +void grpc_time_averaged_stats_add_sample(grpc_time_averaged_stats* stats, + double value); +/* Complete a batch and compute the new estimate of the average sample + value. */ +double grpc_time_averaged_stats_update_average(grpc_time_averaged_stats* stats); + +#endif /* GRPC_CORE_IOMGR_TIME_AVERAGED_STATS_H */ diff --git a/src/core/lib/iomgr/timer.c b/src/core/lib/iomgr/timer.c new file mode 100644 index 0000000000..f444643428 --- /dev/null +++ b/src/core/lib/iomgr/timer.c @@ -0,0 +1,356 @@ +/* + * + * Copyright 2015-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/iomgr/timer.h" + +#include +#include +#include +#include "src/core/iomgr/time_averaged_stats.h" +#include "src/core/iomgr/timer_heap.h" + +#define INVALID_HEAP_INDEX 0xffffffffu + +#define LOG2_NUM_SHARDS 5 +#define NUM_SHARDS (1 << LOG2_NUM_SHARDS) +#define ADD_DEADLINE_SCALE 0.33 +#define MIN_QUEUE_WINDOW_DURATION 0.01 +#define MAX_QUEUE_WINDOW_DURATION 1 + +typedef struct { + gpr_mu mu; + grpc_time_averaged_stats stats; + /* All and only timers with deadlines <= this will be in the heap. */ + gpr_timespec queue_deadline_cap; + gpr_timespec min_deadline; + /* Index in the g_shard_queue */ + uint32_t shard_queue_index; + /* This holds all timers with deadlines < queue_deadline_cap. Timers in this + list have the top bit of their deadline set to 0. */ + grpc_timer_heap heap; + /* This holds timers whose deadline is >= queue_deadline_cap. */ + grpc_timer list; +} shard_type; + +/* Protects g_shard_queue */ +static gpr_mu g_mu; +/* Allow only one run_some_expired_timers at once */ +static gpr_mu g_checker_mu; +static gpr_clock_type g_clock_type; +static shard_type g_shards[NUM_SHARDS]; +/* Protected by g_mu */ +static shard_type *g_shard_queue[NUM_SHARDS]; + +static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now, + gpr_timespec *next, int success); + +static gpr_timespec compute_min_deadline(shard_type *shard) { + return grpc_timer_heap_is_empty(&shard->heap) + ? shard->queue_deadline_cap + : grpc_timer_heap_top(&shard->heap)->deadline; +} + +void grpc_timer_list_init(gpr_timespec now) { + uint32_t i; + + gpr_mu_init(&g_mu); + gpr_mu_init(&g_checker_mu); + g_clock_type = now.clock_type; + + for (i = 0; i < NUM_SHARDS; i++) { + shard_type *shard = &g_shards[i]; + gpr_mu_init(&shard->mu); + grpc_time_averaged_stats_init(&shard->stats, 1.0 / ADD_DEADLINE_SCALE, 0.1, + 0.5); + shard->queue_deadline_cap = now; + shard->shard_queue_index = i; + grpc_timer_heap_init(&shard->heap); + shard->list.next = shard->list.prev = &shard->list; + shard->min_deadline = compute_min_deadline(shard); + g_shard_queue[i] = shard; + } +} + +void grpc_timer_list_shutdown(grpc_exec_ctx *exec_ctx) { + int i; + run_some_expired_timers(exec_ctx, gpr_inf_future(g_clock_type), NULL, 0); + for (i = 0; i < NUM_SHARDS; i++) { + shard_type *shard = &g_shards[i]; + gpr_mu_destroy(&shard->mu); + grpc_timer_heap_destroy(&shard->heap); + } + gpr_mu_destroy(&g_mu); + gpr_mu_destroy(&g_checker_mu); +} + +/* This is a cheap, but good enough, pointer hash for sharding the tasks: */ +static size_t shard_idx(const grpc_timer *info) { + size_t x = (size_t)info; + return ((x >> 4) ^ (x >> 9) ^ (x >> 14)) & (NUM_SHARDS - 1); +} + +static double ts_to_dbl(gpr_timespec ts) { + return (double)ts.tv_sec + 1e-9 * ts.tv_nsec; +} + +static gpr_timespec dbl_to_ts(double d) { + gpr_timespec ts; + ts.tv_sec = (int64_t)d; + ts.tv_nsec = (int32_t)(1e9 * (d - (double)ts.tv_sec)); + ts.clock_type = GPR_TIMESPAN; + return ts; +} + +static void list_join(grpc_timer *head, grpc_timer *timer) { + timer->next = head; + timer->prev = head->prev; + timer->next->prev = timer->prev->next = timer; +} + +static void list_remove(grpc_timer *timer) { + timer->next->prev = timer->prev; + timer->prev->next = timer->next; +} + +static void swap_adjacent_shards_in_queue(uint32_t first_shard_queue_index) { + shard_type *temp; + temp = g_shard_queue[first_shard_queue_index]; + g_shard_queue[first_shard_queue_index] = + g_shard_queue[first_shard_queue_index + 1]; + g_shard_queue[first_shard_queue_index + 1] = temp; + g_shard_queue[first_shard_queue_index]->shard_queue_index = + first_shard_queue_index; + g_shard_queue[first_shard_queue_index + 1]->shard_queue_index = + first_shard_queue_index + 1; +} + +static void note_deadline_change(shard_type *shard) { + while (shard->shard_queue_index > 0 && + gpr_time_cmp( + shard->min_deadline, + g_shard_queue[shard->shard_queue_index - 1]->min_deadline) < 0) { + swap_adjacent_shards_in_queue(shard->shard_queue_index - 1); + } + while (shard->shard_queue_index < NUM_SHARDS - 1 && + gpr_time_cmp( + shard->min_deadline, + g_shard_queue[shard->shard_queue_index + 1]->min_deadline) > 0) { + swap_adjacent_shards_in_queue(shard->shard_queue_index); + } +} + +void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer, + gpr_timespec deadline, grpc_iomgr_cb_func timer_cb, + void *timer_cb_arg, gpr_timespec now) { + int is_first_timer = 0; + shard_type *shard = &g_shards[shard_idx(timer)]; + GPR_ASSERT(deadline.clock_type == g_clock_type); + GPR_ASSERT(now.clock_type == g_clock_type); + grpc_closure_init(&timer->closure, timer_cb, timer_cb_arg); + timer->deadline = deadline; + timer->triggered = 0; + + /* TODO(ctiller): check deadline expired */ + + gpr_mu_lock(&shard->mu); + grpc_time_averaged_stats_add_sample(&shard->stats, + ts_to_dbl(gpr_time_sub(deadline, now))); + if (gpr_time_cmp(deadline, shard->queue_deadline_cap) < 0) { + is_first_timer = grpc_timer_heap_add(&shard->heap, timer); + } else { + timer->heap_index = INVALID_HEAP_INDEX; + list_join(&shard->list, timer); + } + gpr_mu_unlock(&shard->mu); + + /* Deadline may have decreased, we need to adjust the master queue. Note + that there is a potential racy unlocked region here. There could be a + reordering of multiple grpc_timer_init calls, at this point, but the < test + below should ensure that we err on the side of caution. There could + also be a race with grpc_timer_check, which might beat us to the lock. In + that case, it is possible that the timer that we added will have already + run by the time we hold the lock, but that too is a safe error. + Finally, it's possible that the grpc_timer_check that intervened failed to + trigger the new timer because the min_deadline hadn't yet been reduced. + In that case, the timer will simply have to wait for the next + grpc_timer_check. */ + if (is_first_timer) { + gpr_mu_lock(&g_mu); + if (gpr_time_cmp(deadline, shard->min_deadline) < 0) { + gpr_timespec old_min_deadline = g_shard_queue[0]->min_deadline; + shard->min_deadline = deadline; + note_deadline_change(shard); + if (shard->shard_queue_index == 0 && + gpr_time_cmp(deadline, old_min_deadline) < 0) { + grpc_kick_poller(); + } + } + gpr_mu_unlock(&g_mu); + } +} + +void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) { + shard_type *shard = &g_shards[shard_idx(timer)]; + gpr_mu_lock(&shard->mu); + if (!timer->triggered) { + grpc_exec_ctx_enqueue(exec_ctx, &timer->closure, false, NULL); + timer->triggered = 1; + if (timer->heap_index == INVALID_HEAP_INDEX) { + list_remove(timer); + } else { + grpc_timer_heap_remove(&shard->heap, timer); + } + } + gpr_mu_unlock(&shard->mu); +} + +/* This is called when the queue is empty and "now" has reached the + queue_deadline_cap. We compute a new queue deadline and then scan the map + for timers that fall at or under it. Returns true if the queue is no + longer empty. + REQUIRES: shard->mu locked */ +static int refill_queue(shard_type *shard, gpr_timespec now) { + /* Compute the new queue window width and bound by the limits: */ + double computed_deadline_delta = + grpc_time_averaged_stats_update_average(&shard->stats) * + ADD_DEADLINE_SCALE; + double deadline_delta = + GPR_CLAMP(computed_deadline_delta, MIN_QUEUE_WINDOW_DURATION, + MAX_QUEUE_WINDOW_DURATION); + grpc_timer *timer, *next; + + /* Compute the new cap and put all timers under it into the queue: */ + shard->queue_deadline_cap = gpr_time_add( + gpr_time_max(now, shard->queue_deadline_cap), dbl_to_ts(deadline_delta)); + for (timer = shard->list.next; timer != &shard->list; timer = next) { + next = timer->next; + + if (gpr_time_cmp(timer->deadline, shard->queue_deadline_cap) < 0) { + list_remove(timer); + grpc_timer_heap_add(&shard->heap, timer); + } + } + return !grpc_timer_heap_is_empty(&shard->heap); +} + +/* This pops the next non-cancelled timer with deadline <= now from the queue, + or returns NULL if there isn't one. + REQUIRES: shard->mu locked */ +static grpc_timer *pop_one(shard_type *shard, gpr_timespec now) { + grpc_timer *timer; + for (;;) { + if (grpc_timer_heap_is_empty(&shard->heap)) { + if (gpr_time_cmp(now, shard->queue_deadline_cap) < 0) return NULL; + if (!refill_queue(shard, now)) return NULL; + } + timer = grpc_timer_heap_top(&shard->heap); + if (gpr_time_cmp(timer->deadline, now) > 0) return NULL; + timer->triggered = 1; + grpc_timer_heap_pop(&shard->heap); + return timer; + } +} + +/* REQUIRES: shard->mu unlocked */ +static size_t pop_timers(grpc_exec_ctx *exec_ctx, shard_type *shard, + gpr_timespec now, gpr_timespec *new_min_deadline, + int success) { + size_t n = 0; + grpc_timer *timer; + gpr_mu_lock(&shard->mu); + while ((timer = pop_one(shard, now))) { + grpc_exec_ctx_enqueue(exec_ctx, &timer->closure, success, NULL); + n++; + } + *new_min_deadline = compute_min_deadline(shard); + gpr_mu_unlock(&shard->mu); + return n; +} + +static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now, + gpr_timespec *next, int success) { + size_t n = 0; + + /* TODO(ctiller): verify that there are any timers (atomically) here */ + + if (gpr_mu_trylock(&g_checker_mu)) { + gpr_mu_lock(&g_mu); + + while (gpr_time_cmp(g_shard_queue[0]->min_deadline, now) < 0) { + gpr_timespec new_min_deadline; + + /* For efficiency, we pop as many available timers as we can from the + shard. This may violate perfect timer deadline ordering, but that + shouldn't be a big deal because we don't make ordering guarantees. */ + n += pop_timers(exec_ctx, g_shard_queue[0], now, &new_min_deadline, + success); + + /* An grpc_timer_init() on the shard could intervene here, adding a new + timer that is earlier than new_min_deadline. However, + grpc_timer_init() will block on the master_lock before it can call + set_min_deadline, so this one will complete first and then the Addtimer + will reduce the min_deadline (perhaps unnecessarily). */ + g_shard_queue[0]->min_deadline = new_min_deadline; + note_deadline_change(g_shard_queue[0]); + } + + if (next) { + *next = gpr_time_min(*next, g_shard_queue[0]->min_deadline); + } + + gpr_mu_unlock(&g_mu); + gpr_mu_unlock(&g_checker_mu); + } else if (next != NULL) { + /* TODO(ctiller): this forces calling code to do an short poll, and + then retry the timer check (because this time through the timer list was + contended). + + We could reduce the cost here dramatically by keeping a count of how many + currently active pollers got through the uncontended case above + successfully, and waking up other pollers IFF that count drops to zero. + + Once that count is in place, this entire else branch could disappear. */ + *next = gpr_time_min( + *next, gpr_time_add(now, gpr_time_from_millis(1, GPR_TIMESPAN))); + } + + return (int)n; +} + +bool grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now, + gpr_timespec *next) { + GPR_ASSERT(now.clock_type == g_clock_type); + return run_some_expired_timers( + exec_ctx, now, next, + gpr_time_cmp(now, gpr_inf_future(now.clock_type)) != 0); +} diff --git a/src/core/lib/iomgr/timer.h b/src/core/lib/iomgr/timer.h new file mode 100644 index 0000000000..1e2d1cbfbd --- /dev/null +++ b/src/core/lib/iomgr/timer.h @@ -0,0 +1,108 @@ +/* + * + * Copyright 2015-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_IOMGR_TIMER_H +#define GRPC_CORE_IOMGR_TIMER_H + +#include +#include +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/iomgr/iomgr.h" + +typedef struct grpc_timer { + gpr_timespec deadline; + uint32_t heap_index; /* INVALID_HEAP_INDEX if not in heap */ + int triggered; + struct grpc_timer *next; + struct grpc_timer *prev; + grpc_closure closure; +} grpc_timer; + +/* Initialize *timer. When expired or canceled, timer_cb will be called with + *timer_cb_arg and status to indicate if it expired (SUCCESS) or was + canceled (CANCELLED). timer_cb is guaranteed to be called exactly once, + and application code should check the status to determine how it was + invoked. The application callback is also responsible for maintaining + information about when to free up any user-level state. */ +void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer, + gpr_timespec deadline, grpc_iomgr_cb_func timer_cb, + void *timer_cb_arg, gpr_timespec now); + +/* Note that there is no timer destroy function. This is because the + timer is a one-time occurrence with a guarantee that the callback will + be called exactly once, either at expiration or cancellation. Thus, all + the internal timer event management state is destroyed just before + that callback is invoked. If the user has additional state associated with + the timer, the user is responsible for determining when it is safe to + destroy that state. */ + +/* Cancel an *timer. + There are three cases: + 1. We normally cancel the timer + 2. The timer has already run + 3. We can't cancel the timer because it is "in flight". + + In all of these cases, the cancellation is still considered successful. + They are essentially distinguished in that the timer_cb will be run + exactly once from either the cancellation (with status CANCELLED) + or from the activation (with status SUCCESS) + + Note carefully that the callback function MAY occur in the same callstack + as grpc_timer_cancel. It's expected that most timers will be cancelled (their + primary use is to implement deadlines), and so this code is optimized such + that cancellation costs as little as possible. Making callbacks run inline + matches this aim. + + Requires: cancel() must happen after add() on a given timer */ +void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer); + +/* iomgr internal api for dealing with timers */ + +/* Check for timers to be run, and run them. + Return true if timer callbacks were executed. + Drops drop_mu if it is non-null before executing callbacks. + If next is non-null, TRY to update *next with the next running timer + IF that timer occurs before *next current value. + *next is never guaranteed to be updated on any given execution; however, + with high probability at least one thread in the system will see an update + at any time slice. */ +bool grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now, + gpr_timespec *next); +void grpc_timer_list_init(gpr_timespec now); +void grpc_timer_list_shutdown(grpc_exec_ctx *exec_ctx); + +/* the following must be implemented by each iomgr implementation */ + +void grpc_kick_poller(void); + +#endif /* GRPC_CORE_IOMGR_TIMER_H */ diff --git a/src/core/lib/iomgr/timer_heap.c b/src/core/lib/iomgr/timer_heap.c new file mode 100644 index 0000000000..b5df566c45 --- /dev/null +++ b/src/core/lib/iomgr/timer_heap.c @@ -0,0 +1,146 @@ +/* + * + * Copyright 2015-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/iomgr/timer_heap.h" + +#include + +#include +#include + +/* Adjusts a heap so as to move a hole at position i closer to the root, + until a suitable position is found for element t. Then, copies t into that + position. This functor is called each time immediately after modifying a + value in the underlying container, with the offset of the modified element as + its argument. */ +static void adjust_upwards(grpc_timer **first, uint32_t i, grpc_timer *t) { + while (i > 0) { + uint32_t parent = (uint32_t)(((int)i - 1) / 2); + if (gpr_time_cmp(first[parent]->deadline, t->deadline) <= 0) break; + first[i] = first[parent]; + first[i]->heap_index = i; + i = parent; + } + first[i] = t; + t->heap_index = i; +} + +/* Adjusts a heap so as to move a hole at position i farther away from the root, + until a suitable position is found for element t. Then, copies t into that + position. */ +static void adjust_downwards(grpc_timer **first, uint32_t i, uint32_t length, + grpc_timer *t) { + for (;;) { + uint32_t left_child = 1u + 2u * i; + if (left_child >= length) break; + uint32_t right_child = left_child + 1; + uint32_t next_i = right_child < length && + gpr_time_cmp(first[left_child]->deadline, + first[right_child]->deadline) > 0 + ? right_child + : left_child; + if (gpr_time_cmp(t->deadline, first[next_i]->deadline) <= 0) break; + first[i] = first[next_i]; + first[i]->heap_index = i; + i = next_i; + } + first[i] = t; + t->heap_index = i; +} + +#define SHRINK_MIN_ELEMS 8 +#define SHRINK_FULLNESS_FACTOR 2 + +static void maybe_shrink(grpc_timer_heap *heap) { + if (heap->timer_count >= 8 && + heap->timer_count <= heap->timer_capacity / SHRINK_FULLNESS_FACTOR / 2) { + heap->timer_capacity = heap->timer_count * SHRINK_FULLNESS_FACTOR; + heap->timers = + gpr_realloc(heap->timers, heap->timer_capacity * sizeof(grpc_timer *)); + } +} + +static void note_changed_priority(grpc_timer_heap *heap, grpc_timer *timer) { + uint32_t i = timer->heap_index; + uint32_t parent = (uint32_t)(((int)i - 1) / 2); + if (gpr_time_cmp(heap->timers[parent]->deadline, timer->deadline) > 0) { + adjust_upwards(heap->timers, i, timer); + } else { + adjust_downwards(heap->timers, i, heap->timer_count, timer); + } +} + +void grpc_timer_heap_init(grpc_timer_heap *heap) { + memset(heap, 0, sizeof(*heap)); +} + +void grpc_timer_heap_destroy(grpc_timer_heap *heap) { gpr_free(heap->timers); } + +int grpc_timer_heap_add(grpc_timer_heap *heap, grpc_timer *timer) { + if (heap->timer_count == heap->timer_capacity) { + heap->timer_capacity = + GPR_MAX(heap->timer_capacity + 1, heap->timer_capacity * 3 / 2); + heap->timers = + gpr_realloc(heap->timers, heap->timer_capacity * sizeof(grpc_timer *)); + } + timer->heap_index = heap->timer_count; + adjust_upwards(heap->timers, heap->timer_count, timer); + heap->timer_count++; + return timer->heap_index == 0; +} + +void grpc_timer_heap_remove(grpc_timer_heap *heap, grpc_timer *timer) { + uint32_t i = timer->heap_index; + if (i == heap->timer_count - 1) { + heap->timer_count--; + maybe_shrink(heap); + return; + } + heap->timers[i] = heap->timers[heap->timer_count - 1]; + heap->timers[i]->heap_index = i; + heap->timer_count--; + maybe_shrink(heap); + note_changed_priority(heap, heap->timers[i]); +} + +int grpc_timer_heap_is_empty(grpc_timer_heap *heap) { + return heap->timer_count == 0; +} + +grpc_timer *grpc_timer_heap_top(grpc_timer_heap *heap) { + return heap->timers[0]; +} + +void grpc_timer_heap_pop(grpc_timer_heap *heap) { + grpc_timer_heap_remove(heap, grpc_timer_heap_top(heap)); +} diff --git a/src/core/lib/iomgr/timer_heap.h b/src/core/lib/iomgr/timer_heap.h new file mode 100644 index 0000000000..c2912ef45d --- /dev/null +++ b/src/core/lib/iomgr/timer_heap.h @@ -0,0 +1,57 @@ +/* + * + * Copyright 2015-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_IOMGR_TIMER_HEAP_H +#define GRPC_CORE_IOMGR_TIMER_HEAP_H + +#include "src/core/iomgr/timer.h" + +typedef struct { + grpc_timer **timers; + uint32_t timer_count; + uint32_t timer_capacity; +} grpc_timer_heap; + +/* return 1 if the new timer is the first timer in the heap */ +int grpc_timer_heap_add(grpc_timer_heap *heap, grpc_timer *timer); + +void grpc_timer_heap_init(grpc_timer_heap *heap); +void grpc_timer_heap_destroy(grpc_timer_heap *heap); + +void grpc_timer_heap_remove(grpc_timer_heap *heap, grpc_timer *timer); +grpc_timer *grpc_timer_heap_top(grpc_timer_heap *heap); +void grpc_timer_heap_pop(grpc_timer_heap *heap); + +int grpc_timer_heap_is_empty(grpc_timer_heap *heap); + +#endif /* GRPC_CORE_IOMGR_TIMER_HEAP_H */ diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c new file mode 100644 index 0000000000..174159170f --- /dev/null +++ b/src/core/lib/iomgr/udp_server.c @@ -0,0 +1,418 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* FIXME: "posix" files shouldn't be depending on _GNU_SOURCE */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include + +#ifdef GRPC_NEED_UDP +#ifdef GPR_POSIX_SOCKET + +#include "src/core/iomgr/udp_server.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "src/core/iomgr/fd_posix.h" +#include "src/core/iomgr/pollset_posix.h" +#include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/iomgr/unix_sockets_posix.h" +#include "src/core/support/string.h" + +#define INIT_PORT_CAP 2 + +/* one listening port */ +typedef struct { + int fd; + grpc_fd *emfd; + grpc_udp_server *server; + union { + uint8_t untyped[GRPC_MAX_SOCKADDR_SIZE]; + struct sockaddr sockaddr; + } addr; + size_t addr_len; + grpc_closure read_closure; + grpc_closure destroyed_closure; + grpc_udp_server_read_cb read_cb; +} server_port; + +/* the overall server */ +struct grpc_udp_server { + gpr_mu mu; + gpr_cv cv; + + /* active port count: how many ports are actually still listening */ + size_t active_ports; + /* destroyed port count: how many ports are completely destroyed */ + size_t destroyed_ports; + + /* is this server shutting down? (boolean) */ + int shutdown; + + /* all listening ports */ + server_port *ports; + size_t nports; + size_t port_capacity; + + /* shutdown callback */ + grpc_closure *shutdown_complete; + + /* all pollsets interested in new connections */ + grpc_pollset **pollsets; + /* number of pollsets in the pollsets array */ + size_t pollset_count; + /* The parent grpc server */ + grpc_server *grpc_server; +}; + +grpc_udp_server *grpc_udp_server_create(void) { + grpc_udp_server *s = gpr_malloc(sizeof(grpc_udp_server)); + gpr_mu_init(&s->mu); + gpr_cv_init(&s->cv); + s->active_ports = 0; + s->destroyed_ports = 0; + s->shutdown = 0; + s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP); + s->nports = 0; + s->port_capacity = INIT_PORT_CAP; + + return s; +} + +static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { + grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1, NULL); + + gpr_mu_destroy(&s->mu); + gpr_cv_destroy(&s->cv); + + gpr_free(s->ports); + gpr_free(s); +} + +static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server, + bool success) { + grpc_udp_server *s = server; + gpr_mu_lock(&s->mu); + s->destroyed_ports++; + if (s->destroyed_ports == s->nports) { + gpr_mu_unlock(&s->mu); + finish_shutdown(exec_ctx, s); + } else { + gpr_mu_unlock(&s->mu); + } +} + +/* called when all listening endpoints have been shutdown, so no further + events will be received on them - at this point it's safe to destroy + things */ +static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { + size_t i; + + /* delete ALL the things */ + gpr_mu_lock(&s->mu); + + if (!s->shutdown) { + gpr_mu_unlock(&s->mu); + return; + } + + if (s->nports) { + for (i = 0; i < s->nports; i++) { + server_port *sp = &s->ports[i]; + grpc_unlink_if_unix_domain_socket(&sp->addr.sockaddr); + sp->destroyed_closure.cb = destroyed_port; + sp->destroyed_closure.cb_arg = s; + grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL, + "udp_listener_shutdown"); + } + gpr_mu_unlock(&s->mu); + } else { + gpr_mu_unlock(&s->mu); + finish_shutdown(exec_ctx, s); + } +} + +void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *s, + grpc_closure *on_done) { + size_t i; + gpr_mu_lock(&s->mu); + + GPR_ASSERT(!s->shutdown); + s->shutdown = 1; + + s->shutdown_complete = on_done; + + /* shutdown all fd's */ + if (s->active_ports) { + for (i = 0; i < s->nports; i++) { + grpc_fd_shutdown(exec_ctx, s->ports[i].emfd); + } + gpr_mu_unlock(&s->mu); + } else { + gpr_mu_unlock(&s->mu); + deactivated_all_ports(exec_ctx, s); + } +} + +/* Prepare a recently-created socket for listening. */ +static int prepare_socket(int fd, const struct sockaddr *addr, + size_t addr_len) { + struct sockaddr_storage sockname_temp; + socklen_t sockname_len; + int get_local_ip; + int rc; + + if (fd < 0) { + goto error; + } + + if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1)) { + gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, + strerror(errno)); + } + + get_local_ip = 1; + rc = setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_local_ip, + sizeof(get_local_ip)); + if (rc == 0 && addr->sa_family == AF_INET6) { +#if !defined(__APPLE__) + rc = setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &get_local_ip, + sizeof(get_local_ip)); +#endif + } + + GPR_ASSERT(addr_len < ~(socklen_t)0); + if (bind(fd, addr, (socklen_t)addr_len) < 0) { + char *addr_str; + grpc_sockaddr_to_string(&addr_str, addr, 0); + gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno)); + gpr_free(addr_str); + goto error; + } + + sockname_len = sizeof(sockname_temp); + if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) { + goto error; + } + + return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); + +error: + if (fd >= 0) { + close(fd); + } + return -1; +} + +/* event manager callback when reads are ready */ +static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + server_port *sp = arg; + + if (!success) { + gpr_mu_lock(&sp->server->mu); + if (0 == --sp->server->active_ports) { + gpr_mu_unlock(&sp->server->mu); + deactivated_all_ports(exec_ctx, sp->server); + } else { + gpr_mu_unlock(&sp->server->mu); + } + return; + } + + /* Tell the registered callback that data is available to read. */ + GPR_ASSERT(sp->read_cb); + sp->read_cb(exec_ctx, sp->emfd, sp->server->grpc_server); + + /* Re-arm the notification event so we get another chance to read. */ + grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure); +} + +static int add_socket_to_server(grpc_udp_server *s, int fd, + const struct sockaddr *addr, size_t addr_len, + grpc_udp_server_read_cb read_cb) { + server_port *sp; + int port; + char *addr_str; + char *name; + + port = prepare_socket(fd, addr, addr_len); + if (port >= 0) { + grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1); + gpr_asprintf(&name, "udp-server-listener:%s", addr_str); + gpr_free(addr_str); + gpr_mu_lock(&s->mu); + /* append it to the list under a lock */ + if (s->nports == s->port_capacity) { + s->port_capacity *= 2; + s->ports = gpr_realloc(s->ports, sizeof(server_port) * s->port_capacity); + } + sp = &s->ports[s->nports++]; + sp->server = s; + sp->fd = fd; + sp->emfd = grpc_fd_create(fd, name); + memcpy(sp->addr.untyped, addr, addr_len); + sp->addr_len = addr_len; + sp->read_cb = read_cb; + GPR_ASSERT(sp->emfd); + gpr_mu_unlock(&s->mu); + gpr_free(name); + } + + return port; +} + +int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, + size_t addr_len, grpc_udp_server_read_cb read_cb) { + int allocated_port1 = -1; + int allocated_port2 = -1; + unsigned i; + int fd; + grpc_dualstack_mode dsmode; + struct sockaddr_in6 addr6_v4mapped; + struct sockaddr_in wild4; + struct sockaddr_in6 wild6; + struct sockaddr_in addr4_copy; + struct sockaddr *allocated_addr = NULL; + struct sockaddr_storage sockname_temp; + socklen_t sockname_len; + int port; + + grpc_unlink_if_unix_domain_socket((struct sockaddr *)addr); + + /* Check if this is a wildcard port, and if so, try to keep the port the same + as some previously created listener. */ + if (grpc_sockaddr_get_port(addr) == 0) { + for (i = 0; i < s->nports; i++) { + sockname_len = sizeof(sockname_temp); + if (0 == getsockname(s->ports[i].fd, (struct sockaddr *)&sockname_temp, + &sockname_len)) { + port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); + if (port > 0) { + allocated_addr = malloc(addr_len); + memcpy(allocated_addr, addr, addr_len); + grpc_sockaddr_set_port(allocated_addr, port); + addr = allocated_addr; + break; + } + } + } + } + + if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { + addr = (const struct sockaddr *)&addr6_v4mapped; + addr_len = sizeof(addr6_v4mapped); + } + + /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */ + if (grpc_sockaddr_is_wildcard(addr, &port)) { + grpc_sockaddr_make_wildcards(port, &wild4, &wild6); + + /* Try listening on IPv6 first. */ + addr = (struct sockaddr *)&wild6; + addr_len = sizeof(wild6); + fd = grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode); + allocated_port1 = add_socket_to_server(s, fd, addr, addr_len, read_cb); + if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) { + goto done; + } + + /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */ + if (port == 0 && allocated_port1 > 0) { + grpc_sockaddr_set_port((struct sockaddr *)&wild4, allocated_port1); + } + addr = (struct sockaddr *)&wild4; + addr_len = sizeof(wild4); + } + + fd = grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode); + if (fd < 0) { + gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno)); + } + if (dsmode == GRPC_DSMODE_IPV4 && + grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) { + addr = (struct sockaddr *)&addr4_copy; + addr_len = sizeof(addr4_copy); + } + allocated_port2 = add_socket_to_server(s, fd, addr, addr_len, read_cb); + +done: + gpr_free(allocated_addr); + return allocated_port1 >= 0 ? allocated_port1 : allocated_port2; +} + +int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned port_index) { + return (port_index < s->nports) ? s->ports[port_index].fd : -1; +} + +void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s, + grpc_pollset **pollsets, size_t pollset_count, + grpc_server *server) { + size_t i, j; + gpr_mu_lock(&s->mu); + GPR_ASSERT(s->active_ports == 0); + s->pollsets = pollsets; + s->grpc_server = server; + for (i = 0; i < s->nports; i++) { + for (j = 0; j < pollset_count; j++) { + grpc_pollset_add_fd(exec_ctx, pollsets[j], s->ports[i].emfd); + } + s->ports[i].read_closure.cb = on_read; + s->ports[i].read_closure.cb_arg = &s->ports[i]; + grpc_fd_notify_on_read(exec_ctx, s->ports[i].emfd, + &s->ports[i].read_closure); + s->active_ports++; + } + gpr_mu_unlock(&s->mu); +} + +#endif +#endif diff --git a/src/core/lib/iomgr/udp_server.h b/src/core/lib/iomgr/udp_server.h new file mode 100644 index 0000000000..148c04fa9b --- /dev/null +++ b/src/core/lib/iomgr/udp_server.h @@ -0,0 +1,77 @@ +/* + * + * Copyright 2015-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_IOMGR_UDP_SERVER_H +#define GRPC_CORE_IOMGR_UDP_SERVER_H + +#include "src/core/iomgr/endpoint.h" +#include "src/core/iomgr/fd_posix.h" + +/* Forward decl of struct grpc_server */ +/* This is not typedef'ed to avoid a typedef-redefinition error */ +struct grpc_server; + +/* Forward decl of grpc_udp_server */ +typedef struct grpc_udp_server grpc_udp_server; + +/* Called when data is available to read from the socket. */ +typedef void (*grpc_udp_server_read_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, + struct grpc_server *server); + +/* Create a server, initially not bound to any ports */ +grpc_udp_server *grpc_udp_server_create(void); + +/* Start listening to bound ports */ +void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *udp_server, + grpc_pollset **pollsets, size_t pollset_count, + struct grpc_server *server); + +int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned index); + +/* Add a port to the server, returning port number on success, or negative + on failure. + + The :: and 0.0.0.0 wildcard addresses are treated identically, accepting + both IPv4 and IPv6 connections, but :: is the preferred style. This usually + creates one socket, but possibly two on systems which support IPv6, + but not dualstack sockets. */ + +/* TODO(ctiller): deprecate this, and make grpc_udp_server_add_ports to handle + all of the multiple socket port matching logic in one place */ +int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, + size_t addr_len, grpc_udp_server_read_cb read_cb); + +void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *server, + grpc_closure *on_done); + +#endif /* GRPC_CORE_IOMGR_UDP_SERVER_H */ diff --git a/src/core/lib/iomgr/unix_sockets_posix.c b/src/core/lib/iomgr/unix_sockets_posix.c new file mode 100644 index 0000000000..174a7e7abf --- /dev/null +++ b/src/core/lib/iomgr/unix_sockets_posix.c @@ -0,0 +1,103 @@ +/* + * + * 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/iomgr/unix_sockets_posix.h" + +#ifdef GPR_HAVE_UNIX_SOCKET + +#include +#include +#include +#include + +#include + +void grpc_create_socketpair_if_unix(int sv[2]) { + GPR_ASSERT(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); +} + +grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char *name) { + struct sockaddr_un *un; + + grpc_resolved_addresses *addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); + addrs->naddrs = 1; + addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address)); + un = (struct sockaddr_un *)addrs->addrs->addr; + un->sun_family = AF_UNIX; + strcpy(un->sun_path, name); + addrs->addrs->len = strlen(un->sun_path) + sizeof(un->sun_family) + 1; + return addrs; +} + +int grpc_is_unix_socket(const struct sockaddr *addr) { + return addr->sa_family == AF_UNIX; +} + +void grpc_unlink_if_unix_domain_socket(const struct sockaddr *addr) { + if (addr->sa_family != AF_UNIX) { + return; + } + struct sockaddr_un *un = (struct sockaddr_un *)addr; + struct stat st; + + if (stat(un->sun_path, &st) == 0 && (st.st_mode & S_IFMT) == S_IFSOCK) { + unlink(un->sun_path); + } +} + +int grpc_parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { + struct sockaddr_un *un = (struct sockaddr_un *)addr; + + un->sun_family = AF_UNIX; + strcpy(un->sun_path, uri->path); + *len = strlen(un->sun_path) + sizeof(un->sun_family) + 1; + + return 1; +} + +char *grpc_unix_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) { + return gpr_strdup("localhost"); +} + +char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr) { + if (addr->sa_family != AF_UNIX) { + return NULL; + } + + char *result; + gpr_asprintf(&result, "unix:%s", ((struct sockaddr_un *)addr)->sun_path); + return result; +} + +#endif diff --git a/src/core/lib/iomgr/unix_sockets_posix.h b/src/core/lib/iomgr/unix_sockets_posix.h new file mode 100644 index 0000000000..e842ba3770 --- /dev/null +++ b/src/core/lib/iomgr/unix_sockets_posix.h @@ -0,0 +1,61 @@ +/* + * + * 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_IOMGR_UNIX_SOCKETS_POSIX_H +#define GRPC_CORE_IOMGR_UNIX_SOCKETS_POSIX_H + +#include + +#include + +#include "src/core/client_config/resolver_factory.h" +#include "src/core/client_config/uri_parser.h" +#include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/sockaddr.h" + +void grpc_create_socketpair_if_unix(int sv[2]); + +grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char *name); + +int grpc_is_unix_socket(const struct sockaddr *addr); + +void grpc_unlink_if_unix_domain_socket(const struct sockaddr *addr); + +int grpc_parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len); + +char *grpc_unix_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri); + +char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr); + +#endif /* GRPC_CORE_IOMGR_UNIX_SOCKETS_POSIX_H */ diff --git a/src/core/lib/iomgr/unix_sockets_posix_noop.c b/src/core/lib/iomgr/unix_sockets_posix_noop.c new file mode 100644 index 0000000000..045467bea4 --- /dev/null +++ b/src/core/lib/iomgr/unix_sockets_posix_noop.c @@ -0,0 +1,61 @@ +/* + * + * 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/iomgr/unix_sockets_posix.h" + +#ifndef GPR_HAVE_UNIX_SOCKET + +void grpc_create_socketpair_if_unix(int sv[2]) {} + +grpc_resolved_addresses *grpc_resolve_unix_domain_address(const char *name) { + return NULL; +} + +int grpc_is_unix_socket(const struct sockaddr *addr) { return false; } + +void grpc_unlink_if_unix_domain_socket(const struct sockaddr *addr) {} + +int grpc_parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) { + return 0; +} + +char *grpc_unix_get_default_authority(grpc_resolver_factory *factory, + grpc_uri *uri) { + return NULL; +} + +char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr) { + return NULL; +} + +#endif diff --git a/src/core/lib/iomgr/wakeup_fd_eventfd.c b/src/core/lib/iomgr/wakeup_fd_eventfd.c new file mode 100644 index 0000000000..f67379e4fc --- /dev/null +++ b/src/core/lib/iomgr/wakeup_fd_eventfd.c @@ -0,0 +1,85 @@ +/* + * + * Copyright 2015, 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 + +#ifdef GPR_LINUX_EVENTFD + +#include +#include +#include + +#include + +#include "src/core/iomgr/wakeup_fd_posix.h" +#include "src/core/profiling/timers.h" + +static void eventfd_create(grpc_wakeup_fd* fd_info) { + int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); + /* TODO(klempner): Handle failure more gracefully */ + GPR_ASSERT(efd >= 0); + fd_info->read_fd = efd; + fd_info->write_fd = -1; +} + +static void eventfd_consume(grpc_wakeup_fd* fd_info) { + eventfd_t value; + int err; + do { + err = eventfd_read(fd_info->read_fd, &value); + } while (err < 0 && errno == EINTR); +} + +static void eventfd_wakeup(grpc_wakeup_fd* fd_info) { + int err; + GPR_TIMER_BEGIN("eventfd_wakeup", 0); + do { + err = eventfd_write(fd_info->read_fd, 1); + } while (err < 0 && errno == EINTR); + GPR_TIMER_END("eventfd_wakeup", 0); +} + +static void eventfd_destroy(grpc_wakeup_fd* fd_info) { + if (fd_info->read_fd != 0) close(fd_info->read_fd); +} + +static int eventfd_check_availability(void) { + /* TODO(klempner): Actually check if eventfd is available */ + return 1; +} + +const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable = { + eventfd_create, eventfd_consume, eventfd_wakeup, eventfd_destroy, + eventfd_check_availability}; + +#endif /* GPR_LINUX_EVENTFD */ diff --git a/src/core/lib/iomgr/wakeup_fd_nospecial.c b/src/core/lib/iomgr/wakeup_fd_nospecial.c new file mode 100644 index 0000000000..7b2be9ed52 --- /dev/null +++ b/src/core/lib/iomgr/wakeup_fd_nospecial.c @@ -0,0 +1,51 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* + * This is a dummy file to provide an invalid specialized_wakeup_fd_vtable on + * systems without anything better than pipe. + */ + +#include + +#ifdef GPR_POSIX_NO_SPECIAL_WAKEUP_FD + +#include +#include "src/core/iomgr/wakeup_fd_posix.h" + +static int check_availability_invalid(void) { return 0; } + +const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable = { + NULL, NULL, NULL, NULL, check_availability_invalid}; + +#endif /* GPR_POSIX_NO_SPECIAL_WAKEUP_FD */ diff --git a/src/core/lib/iomgr/wakeup_fd_pipe.c b/src/core/lib/iomgr/wakeup_fd_pipe.c new file mode 100644 index 0000000000..dd2fd1f057 --- /dev/null +++ b/src/core/lib/iomgr/wakeup_fd_pipe.c @@ -0,0 +1,102 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_WAKEUP_FD + +#include "src/core/iomgr/wakeup_fd_posix.h" + +#include +#include +#include + +#include + +#include "src/core/iomgr/socket_utils_posix.h" + +static void pipe_init(grpc_wakeup_fd* fd_info) { + int pipefd[2]; + /* TODO(klempner): Make this nonfatal */ + int r = pipe(pipefd); + if (0 != r) { + gpr_log(GPR_ERROR, "pipe creation failed (%d): %s", errno, strerror(errno)); + abort(); + } + GPR_ASSERT(grpc_set_socket_nonblocking(pipefd[0], 1)); + GPR_ASSERT(grpc_set_socket_nonblocking(pipefd[1], 1)); + fd_info->read_fd = pipefd[0]; + fd_info->write_fd = pipefd[1]; +} + +static void pipe_consume(grpc_wakeup_fd* fd_info) { + char buf[128]; + ssize_t r; + + for (;;) { + r = read(fd_info->read_fd, buf, sizeof(buf)); + if (r > 0) continue; + if (r == 0) return; + switch (errno) { + case EAGAIN: + return; + case EINTR: + continue; + default: + gpr_log(GPR_ERROR, "error reading pipe: %s", strerror(errno)); + return; + } + } +} + +static void pipe_wakeup(grpc_wakeup_fd* fd_info) { + char c = 0; + while (write(fd_info->write_fd, &c, 1) != 1 && errno == EINTR) + ; +} + +static void pipe_destroy(grpc_wakeup_fd* fd_info) { + if (fd_info->read_fd != 0) close(fd_info->read_fd); + if (fd_info->write_fd != 0) close(fd_info->write_fd); +} + +static int pipe_check_availability(void) { + /* Assume that pipes are always available. */ + return 1; +} + +const grpc_wakeup_fd_vtable grpc_pipe_wakeup_fd_vtable = { + pipe_init, pipe_consume, pipe_wakeup, pipe_destroy, + pipe_check_availability}; + +#endif /* GPR_POSIX_WAKUP_FD */ diff --git a/src/core/lib/iomgr/wakeup_fd_pipe.h b/src/core/lib/iomgr/wakeup_fd_pipe.h new file mode 100644 index 0000000000..eb3e02b482 --- /dev/null +++ b/src/core/lib/iomgr/wakeup_fd_pipe.h @@ -0,0 +1,41 @@ +/* + * + * Copyright 2015-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_IOMGR_WAKEUP_FD_PIPE_H +#define GRPC_CORE_IOMGR_WAKEUP_FD_PIPE_H + +#include "src/core/iomgr/wakeup_fd_posix.h" + +extern grpc_wakeup_fd_vtable grpc_pipe_wakeup_fd_vtable; + +#endif /* GRPC_CORE_IOMGR_WAKEUP_FD_PIPE_H */ diff --git a/src/core/lib/iomgr/wakeup_fd_posix.c b/src/core/lib/iomgr/wakeup_fd_posix.c new file mode 100644 index 0000000000..07778c408e --- /dev/null +++ b/src/core/lib/iomgr/wakeup_fd_posix.c @@ -0,0 +1,72 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_WAKEUP_FD + +#include +#include "src/core/iomgr/wakeup_fd_pipe.h" +#include "src/core/iomgr/wakeup_fd_posix.h" + +static const grpc_wakeup_fd_vtable *wakeup_fd_vtable = NULL; +int grpc_allow_specialized_wakeup_fd = 1; + +void grpc_wakeup_fd_global_init(void) { + if (grpc_allow_specialized_wakeup_fd && + grpc_specialized_wakeup_fd_vtable.check_availability()) { + wakeup_fd_vtable = &grpc_specialized_wakeup_fd_vtable; + } else { + wakeup_fd_vtable = &grpc_pipe_wakeup_fd_vtable; + } +} + +void grpc_wakeup_fd_global_destroy(void) { wakeup_fd_vtable = NULL; } + +void grpc_wakeup_fd_init(grpc_wakeup_fd *fd_info) { + wakeup_fd_vtable->init(fd_info); +} + +void grpc_wakeup_fd_consume_wakeup(grpc_wakeup_fd *fd_info) { + wakeup_fd_vtable->consume(fd_info); +} + +void grpc_wakeup_fd_wakeup(grpc_wakeup_fd *fd_info) { + wakeup_fd_vtable->wakeup(fd_info); +} + +void grpc_wakeup_fd_destroy(grpc_wakeup_fd *fd_info) { + wakeup_fd_vtable->destroy(fd_info); +} + +#endif /* GPR_POSIX_WAKEUP_FD */ diff --git a/src/core/lib/iomgr/wakeup_fd_posix.h b/src/core/lib/iomgr/wakeup_fd_posix.h new file mode 100644 index 0000000000..d7e3cf4673 --- /dev/null +++ b/src/core/lib/iomgr/wakeup_fd_posix.h @@ -0,0 +1,101 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* + * wakeup_fd abstracts the concept of a file descriptor for the purpose of + * waking up a thread in select()/poll()/epoll_wait()/etc. + + * The poll() family of system calls provide a way for a thread to block until + * there is activity on one (or more) of a set of file descriptors. An + * application may wish to wake up this thread to do non file related work. The + * typical way to do this is to add a pipe to the set of file descriptors, then + * write to the pipe to wake up the thread in poll(). + * + * Linux has a lighter weight eventfd specifically designed for this purpose. + * wakeup_fd abstracts the difference between the two. + * + * Setup: + * 1. Before calling anything, call global_init() at least once. + * 1. Call grpc_wakeup_fd_create() to get a wakeup_fd. + * 2. Add the result of GRPC_WAKEUP_FD_FD to the set of monitored file + * descriptors for the poll() style API you are using. Monitor the file + * descriptor for readability. + * 3. To tear down, call grpc_wakeup_fd_destroy(). This closes the underlying + * file descriptor. + * + * Usage: + * 1. To wake up a polling thread, call grpc_wakeup_fd_wakeup() on a wakeup_fd + * it is monitoring. + * 2. If the polling thread was awakened by a wakeup_fd event, call + * grpc_wakeup_fd_consume_wakeup() on it. + */ +#ifndef GRPC_CORE_IOMGR_WAKEUP_FD_POSIX_H +#define GRPC_CORE_IOMGR_WAKEUP_FD_POSIX_H + +void grpc_wakeup_fd_global_init(void); +void grpc_wakeup_fd_global_destroy(void); + +/* Force using the fallback implementation. This is intended for testing + * purposes only.*/ +void grpc_wakeup_fd_global_init_force_fallback(void); + +typedef struct grpc_wakeup_fd grpc_wakeup_fd; + +typedef struct grpc_wakeup_fd_vtable { + void (*init)(grpc_wakeup_fd* fd_info); + void (*consume)(grpc_wakeup_fd* fd_info); + void (*wakeup)(grpc_wakeup_fd* fd_info); + void (*destroy)(grpc_wakeup_fd* fd_info); + /* Must be called before calling any other functions */ + int (*check_availability)(void); +} grpc_wakeup_fd_vtable; + +struct grpc_wakeup_fd { + int read_fd; + int write_fd; +}; + +extern int grpc_allow_specialized_wakeup_fd; + +#define GRPC_WAKEUP_FD_GET_READ_FD(fd_info) ((fd_info)->read_fd) + +void grpc_wakeup_fd_init(grpc_wakeup_fd* fd_info); +void grpc_wakeup_fd_consume_wakeup(grpc_wakeup_fd* fd_info); +void grpc_wakeup_fd_wakeup(grpc_wakeup_fd* fd_info); +void grpc_wakeup_fd_destroy(grpc_wakeup_fd* fd_info); + +/* Defined in some specialized implementation's .c file, or by + * wakeup_fd_nospecial.c if no such implementation exists. */ +extern const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable; + +#endif /* GRPC_CORE_IOMGR_WAKEUP_FD_POSIX_H */ diff --git a/src/core/lib/iomgr/workqueue.h b/src/core/lib/iomgr/workqueue.h new file mode 100644 index 0000000000..2b923ba152 --- /dev/null +++ b/src/core/lib/iomgr/workqueue.h @@ -0,0 +1,83 @@ +/* + * + * Copyright 2015-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_IOMGR_WORKQUEUE_H +#define GRPC_CORE_IOMGR_WORKQUEUE_H + +#include "src/core/iomgr/closure.h" +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/iomgr/iomgr.h" +#include "src/core/iomgr/pollset.h" + +#ifdef GPR_POSIX_SOCKET +#include "src/core/iomgr/workqueue_posix.h" +#endif + +#ifdef GPR_WIN32 +#include "src/core/iomgr/workqueue_windows.h" +#endif + +/* grpc_workqueue is forward declared in exec_ctx.h */ + +/** Create a work queue */ +grpc_workqueue *grpc_workqueue_create(grpc_exec_ctx *exec_ctx); + +void grpc_workqueue_flush(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue); + +#define GRPC_WORKQUEUE_REFCOUNT_DEBUG +#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG +#define GRPC_WORKQUEUE_REF(p, r) \ + grpc_workqueue_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_WORKQUEUE_UNREF(cl, p, r) \ + grpc_workqueue_unref((cl), (p), __FILE__, __LINE__, (r)) +void grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, int line, + const char *reason); +void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, + const char *file, int line, const char *reason); +#else +#define GRPC_WORKQUEUE_REF(p, r) grpc_workqueue_ref((p)) +#define GRPC_WORKQUEUE_UNREF(cl, p, r) grpc_workqueue_unref((cl), (p)) +void grpc_workqueue_ref(grpc_workqueue *workqueue); +void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue); +#endif + +/** Bind this workqueue to a pollset */ +void grpc_workqueue_add_to_pollset(grpc_exec_ctx *exec_ctx, + grpc_workqueue *workqueue, + grpc_pollset *pollset); + +/** Add a work item to a workqueue */ +void grpc_workqueue_push(grpc_workqueue *workqueue, grpc_closure *closure, + int success); + +#endif /* GRPC_CORE_IOMGR_WORKQUEUE_H */ diff --git a/src/core/lib/iomgr/workqueue_posix.c b/src/core/lib/iomgr/workqueue_posix.c new file mode 100644 index 0000000000..2b42e6d4fb --- /dev/null +++ b/src/core/lib/iomgr/workqueue_posix.c @@ -0,0 +1,144 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_SOCKET + +#include "src/core/iomgr/workqueue.h" + +#include + +#include +#include +#include + +#include "src/core/iomgr/fd_posix.h" +#include "src/core/iomgr/pollset_posix.h" + +static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, bool success); + +grpc_workqueue *grpc_workqueue_create(grpc_exec_ctx *exec_ctx) { + char name[32]; + grpc_workqueue *workqueue = gpr_malloc(sizeof(grpc_workqueue)); + gpr_ref_init(&workqueue->refs, 1); + gpr_mu_init(&workqueue->mu); + workqueue->closure_list.head = workqueue->closure_list.tail = NULL; + grpc_wakeup_fd_init(&workqueue->wakeup_fd); + sprintf(name, "workqueue:%p", (void *)workqueue); + workqueue->wakeup_read_fd = + grpc_fd_create(GRPC_WAKEUP_FD_GET_READ_FD(&workqueue->wakeup_fd), name); + grpc_closure_init(&workqueue->read_closure, on_readable, workqueue); + grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, + &workqueue->read_closure); + return workqueue; +} + +static void workqueue_destroy(grpc_exec_ctx *exec_ctx, + grpc_workqueue *workqueue) { + GPR_ASSERT(grpc_closure_list_empty(workqueue->closure_list)); + grpc_fd_shutdown(exec_ctx, workqueue->wakeup_read_fd); +} + +#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG +void grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file, int line, + const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "WORKQUEUE:%p ref %d -> %d %s", + workqueue, (int)workqueue->refs.count, (int)workqueue->refs.count + 1, + reason); +#else +void grpc_workqueue_ref(grpc_workqueue *workqueue) { +#endif + gpr_ref(&workqueue->refs); +} + +#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG +void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue, + const char *file, int line, const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "WORKQUEUE:%p unref %d -> %d %s", + workqueue, (int)workqueue->refs.count, (int)workqueue->refs.count - 1, + reason); +#else +void grpc_workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) { +#endif + if (gpr_unref(&workqueue->refs)) { + workqueue_destroy(exec_ctx, workqueue); + } +} + +void grpc_workqueue_add_to_pollset(grpc_exec_ctx *exec_ctx, + grpc_workqueue *workqueue, + grpc_pollset *pollset) { + grpc_pollset_add_fd(exec_ctx, pollset, workqueue->wakeup_read_fd); +} + +void grpc_workqueue_flush(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) { + gpr_mu_lock(&workqueue->mu); + if (grpc_closure_list_empty(workqueue->closure_list)) { + grpc_wakeup_fd_wakeup(&workqueue->wakeup_fd); + } + grpc_exec_ctx_enqueue_list(exec_ctx, &workqueue->closure_list, NULL); + gpr_mu_unlock(&workqueue->mu); +} + +static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + grpc_workqueue *workqueue = arg; + + if (!success) { + gpr_mu_destroy(&workqueue->mu); + /* HACK: let wakeup_fd code know that we stole the fd */ + workqueue->wakeup_fd.read_fd = 0; + grpc_wakeup_fd_destroy(&workqueue->wakeup_fd); + grpc_fd_orphan(exec_ctx, workqueue->wakeup_read_fd, NULL, NULL, "destroy"); + gpr_free(workqueue); + } else { + gpr_mu_lock(&workqueue->mu); + grpc_exec_ctx_enqueue_list(exec_ctx, &workqueue->closure_list, NULL); + grpc_wakeup_fd_consume_wakeup(&workqueue->wakeup_fd); + gpr_mu_unlock(&workqueue->mu); + grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, + &workqueue->read_closure); + } +} + +void grpc_workqueue_push(grpc_workqueue *workqueue, grpc_closure *closure, + int success) { + gpr_mu_lock(&workqueue->mu); + if (grpc_closure_list_empty(workqueue->closure_list)) { + grpc_wakeup_fd_wakeup(&workqueue->wakeup_fd); + } + grpc_closure_list_add(&workqueue->closure_list, closure, success); + gpr_mu_unlock(&workqueue->mu); +} + +#endif /* GPR_POSIX_SOCKET */ diff --git a/src/core/lib/iomgr/workqueue_posix.h b/src/core/lib/iomgr/workqueue_posix.h new file mode 100644 index 0000000000..89937b1ea8 --- /dev/null +++ b/src/core/lib/iomgr/workqueue_posix.h @@ -0,0 +1,53 @@ +/* + * + * Copyright 2015-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_IOMGR_WORKQUEUE_POSIX_H +#define GRPC_CORE_IOMGR_WORKQUEUE_POSIX_H + +#include "src/core/iomgr/wakeup_fd_posix.h" + +struct grpc_fd; + +struct grpc_workqueue { + gpr_refcount refs; + + gpr_mu mu; + grpc_closure_list closure_list; + + grpc_wakeup_fd wakeup_fd; + struct grpc_fd *wakeup_read_fd; + + grpc_closure read_closure; +}; + +#endif /* GRPC_CORE_IOMGR_WORKQUEUE_POSIX_H */ diff --git a/src/core/lib/iomgr/workqueue_windows.c b/src/core/lib/iomgr/workqueue_windows.c new file mode 100644 index 0000000000..f9ca57557b --- /dev/null +++ b/src/core/lib/iomgr/workqueue_windows.c @@ -0,0 +1,40 @@ +/* + * + * Copyright 2015, 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 + +#ifdef GPR_WIN32 + +#include "src/core/iomgr/workqueue.h" + +#endif /* GPR_WIN32 */ diff --git a/src/core/lib/iomgr/workqueue_windows.h b/src/core/lib/iomgr/workqueue_windows.h new file mode 100644 index 0000000000..7e8186921e --- /dev/null +++ b/src/core/lib/iomgr/workqueue_windows.h @@ -0,0 +1,37 @@ +/* + * + * Copyright 2015-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_IOMGR_WORKQUEUE_WINDOWS_H +#define GRPC_CORE_IOMGR_WORKQUEUE_WINDOWS_H + +#endif /* GRPC_CORE_IOMGR_WORKQUEUE_WINDOWS_H */ diff --git a/src/core/lib/json/json.c b/src/core/lib/json/json.c new file mode 100644 index 0000000000..96e11eebb1 --- /dev/null +++ b/src/core/lib/json/json.c @@ -0,0 +1,64 @@ +/* + * + * Copyright 2015, 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 + +#include + +#include "src/core/json/json.h" + +grpc_json *grpc_json_create(grpc_json_type type) { + grpc_json *json = gpr_malloc(sizeof(*json)); + memset(json, 0, sizeof(*json)); + json->type = type; + + return json; +} + +void grpc_json_destroy(grpc_json *json) { + while (json->child) { + grpc_json_destroy(json->child); + } + + if (json->next) { + json->next->prev = json->prev; + } + + if (json->prev) { + json->prev->next = json->next; + } else if (json->parent) { + json->parent->child = json->next; + } + + gpr_free(json); +} diff --git a/src/core/lib/json/json.h b/src/core/lib/json/json.h new file mode 100644 index 0000000000..aea9d5dadb --- /dev/null +++ b/src/core/lib/json/json.h @@ -0,0 +1,88 @@ +/* + * + * Copyright 2015-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_JSON_JSON_H +#define GRPC_CORE_JSON_JSON_H + +#include + +#include "src/core/json/json_common.h" + +/* A tree-like structure to hold json values. The key and value pointers + * are not owned by it. + */ +typedef struct grpc_json { + struct grpc_json *next; + struct grpc_json *prev; + struct grpc_json *child; + struct grpc_json *parent; + + grpc_json_type type; + const char *key; + const char *value; +} grpc_json; + +/* The next two functions are going to parse the input string, and + * modify it in the process, in order to use its space to store + * all of the keys and values for the returned object tree. + * + * They assume UTF-8 input stream, and will output UTF-8 encoded + * strings in the tree. The input stream's UTF-8 isn't validated, + * as in, what you input is what you get as an output. + * + * All the keys and values in the grpc_json objects will be strings + * pointing at your input buffer. + * + * Delete the allocated tree afterward using grpc_json_destroy(). + */ +grpc_json *grpc_json_parse_string_with_len(char *input, size_t size); +grpc_json *grpc_json_parse_string(char *input); + +/* This function will create a new string using gpr_realloc, and will + * deserialize the grpc_json tree into it. It'll be zero-terminated, + * but will be allocated in chunks of 256 bytes. + * + * The indent parameter controls the way the output is formatted. + * If indent is 0, then newlines will be suppressed as well, and the + * output will be condensed at its maximum. + */ +char *grpc_json_dump_to_string(grpc_json *json, int indent); + +/* Use these to create or delete a grpc_json object. + * Deletion is recursive. We will not attempt to free any of the strings + * in any of the objects of that tree. + */ +grpc_json *grpc_json_create(grpc_json_type type); +void grpc_json_destroy(grpc_json *json); + +#endif /* GRPC_CORE_JSON_JSON_H */ diff --git a/src/core/lib/json/json_common.h b/src/core/lib/json/json_common.h new file mode 100644 index 0000000000..7205a94685 --- /dev/null +++ b/src/core/lib/json/json_common.h @@ -0,0 +1,49 @@ +/* + * + * Copyright 2015-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_JSON_JSON_COMMON_H +#define GRPC_CORE_JSON_JSON_COMMON_H + +/* The various json types. */ +typedef enum { + GRPC_JSON_OBJECT, + GRPC_JSON_ARRAY, + GRPC_JSON_STRING, + GRPC_JSON_NUMBER, + GRPC_JSON_TRUE, + GRPC_JSON_FALSE, + GRPC_JSON_NULL, + GRPC_JSON_TOP_LEVEL +} grpc_json_type; + +#endif /* GRPC_CORE_JSON_JSON_COMMON_H */ diff --git a/src/core/lib/json/json_reader.c b/src/core/lib/json/json_reader.c new file mode 100644 index 0000000000..30da6f28f3 --- /dev/null +++ b/src/core/lib/json/json_reader.c @@ -0,0 +1,659 @@ +/* + * + * Copyright 2015, 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 + +#include + +#include + +#include "src/core/json/json_reader.h" + +static void json_reader_string_clear(grpc_json_reader *reader) { + reader->vtable->string_clear(reader->userdata); +} + +static void json_reader_string_add_char(grpc_json_reader *reader, uint32_t c) { + reader->vtable->string_add_char(reader->userdata, c); +} + +static void json_reader_string_add_utf32(grpc_json_reader *reader, + uint32_t utf32) { + reader->vtable->string_add_utf32(reader->userdata, utf32); +} + +static uint32_t grpc_json_reader_read_char(grpc_json_reader *reader) { + return reader->vtable->read_char(reader->userdata); +} + +static void json_reader_container_begins(grpc_json_reader *reader, + grpc_json_type type) { + reader->vtable->container_begins(reader->userdata, type); +} + +static grpc_json_type grpc_json_reader_container_ends( + grpc_json_reader *reader) { + return reader->vtable->container_ends(reader->userdata); +} + +static void json_reader_set_key(grpc_json_reader *reader) { + reader->vtable->set_key(reader->userdata); +} + +static void json_reader_set_string(grpc_json_reader *reader) { + reader->vtable->set_string(reader->userdata); +} + +static int json_reader_set_number(grpc_json_reader *reader) { + return reader->vtable->set_number(reader->userdata); +} + +static void json_reader_set_true(grpc_json_reader *reader) { + reader->vtable->set_true(reader->userdata); +} + +static void json_reader_set_false(grpc_json_reader *reader) { + reader->vtable->set_false(reader->userdata); +} + +static void json_reader_set_null(grpc_json_reader *reader) { + reader->vtable->set_null(reader->userdata); +} + +/* Call this function to initialize the reader structure. */ +void grpc_json_reader_init(grpc_json_reader *reader, + grpc_json_reader_vtable *vtable, void *userdata) { + memset(reader, 0, sizeof(*reader)); + reader->vtable = vtable; + reader->userdata = userdata; + json_reader_string_clear(reader); + reader->state = GRPC_JSON_STATE_VALUE_BEGIN; +} + +int grpc_json_reader_is_complete(grpc_json_reader *reader) { + return ((reader->depth == 0) && + ((reader->state == GRPC_JSON_STATE_END) || + (reader->state == GRPC_JSON_STATE_VALUE_END))); +} + +grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) { + uint32_t c, success; + + /* This state-machine is a strict implementation of ECMA-404 */ + for (;;) { + c = grpc_json_reader_read_char(reader); + switch (c) { + /* Let's process the error cases first. */ + case GRPC_JSON_READ_CHAR_ERROR: + return GRPC_JSON_READ_ERROR; + + case GRPC_JSON_READ_CHAR_EAGAIN: + return GRPC_JSON_EAGAIN; + + case GRPC_JSON_READ_CHAR_EOF: + if (grpc_json_reader_is_complete(reader)) { + return GRPC_JSON_DONE; + } else { + return GRPC_JSON_PARSE_ERROR; + } + break; + + /* Processing whitespaces. */ + case ' ': + case '\t': + case '\n': + case '\r': + switch (reader->state) { + case GRPC_JSON_STATE_OBJECT_KEY_BEGIN: + case GRPC_JSON_STATE_OBJECT_KEY_END: + case GRPC_JSON_STATE_VALUE_BEGIN: + case GRPC_JSON_STATE_VALUE_END: + case GRPC_JSON_STATE_END: + break; + + case GRPC_JSON_STATE_OBJECT_KEY_STRING: + case GRPC_JSON_STATE_VALUE_STRING: + if (c != ' ') return GRPC_JSON_PARSE_ERROR; + if (reader->unicode_high_surrogate != 0) + return GRPC_JSON_PARSE_ERROR; + json_reader_string_add_char(reader, c); + break; + + case GRPC_JSON_STATE_VALUE_NUMBER: + case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL: + case GRPC_JSON_STATE_VALUE_NUMBER_ZERO: + case GRPC_JSON_STATE_VALUE_NUMBER_EPM: + success = (uint32_t)json_reader_set_number(reader); + if (!success) return GRPC_JSON_PARSE_ERROR; + json_reader_string_clear(reader); + reader->state = GRPC_JSON_STATE_VALUE_END; + break; + + default: + return GRPC_JSON_PARSE_ERROR; + } + break; + + /* Value, object or array terminations. */ + case ',': + case '}': + case ']': + switch (reader->state) { + case GRPC_JSON_STATE_OBJECT_KEY_STRING: + case GRPC_JSON_STATE_VALUE_STRING: + if (reader->unicode_high_surrogate != 0) + return GRPC_JSON_PARSE_ERROR; + json_reader_string_add_char(reader, c); + break; + + case GRPC_JSON_STATE_VALUE_NUMBER: + case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL: + case GRPC_JSON_STATE_VALUE_NUMBER_ZERO: + case GRPC_JSON_STATE_VALUE_NUMBER_EPM: + success = (uint32_t)json_reader_set_number(reader); + if (!success) return GRPC_JSON_PARSE_ERROR; + json_reader_string_clear(reader); + reader->state = GRPC_JSON_STATE_VALUE_END; + /* The missing break here is intentional. */ + + case GRPC_JSON_STATE_VALUE_END: + case GRPC_JSON_STATE_OBJECT_KEY_BEGIN: + case GRPC_JSON_STATE_VALUE_BEGIN: + if (c == ',') { + if (reader->state != GRPC_JSON_STATE_VALUE_END) { + return GRPC_JSON_PARSE_ERROR; + } + if (reader->in_object) { + reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN; + } else { + reader->state = GRPC_JSON_STATE_VALUE_BEGIN; + } + } else { + if (reader->depth-- == 0) return GRPC_JSON_PARSE_ERROR; + if ((c == '}') && !reader->in_object) { + return GRPC_JSON_PARSE_ERROR; + } + if ((c == '}') && + (reader->state == GRPC_JSON_STATE_OBJECT_KEY_BEGIN) && + !reader->container_just_begun) { + return GRPC_JSON_PARSE_ERROR; + } + if ((c == ']') && !reader->in_array) return GRPC_JSON_PARSE_ERROR; + if ((c == ']') && + (reader->state == GRPC_JSON_STATE_VALUE_BEGIN) && + !reader->container_just_begun) { + return GRPC_JSON_PARSE_ERROR; + } + reader->state = GRPC_JSON_STATE_VALUE_END; + switch (grpc_json_reader_container_ends(reader)) { + case GRPC_JSON_OBJECT: + reader->in_object = 1; + reader->in_array = 0; + break; + case GRPC_JSON_ARRAY: + reader->in_object = 0; + reader->in_array = 1; + break; + case GRPC_JSON_TOP_LEVEL: + GPR_ASSERT(reader->depth == 0); + reader->in_object = 0; + reader->in_array = 0; + reader->state = GRPC_JSON_STATE_END; + break; + default: + GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR); + } + } + break; + + default: + return GRPC_JSON_PARSE_ERROR; + } + break; + + /* In-string escaping. */ + case '\\': + switch (reader->state) { + case GRPC_JSON_STATE_OBJECT_KEY_STRING: + reader->escaped_string_was_key = 1; + reader->state = GRPC_JSON_STATE_STRING_ESCAPE; + break; + + case GRPC_JSON_STATE_VALUE_STRING: + reader->escaped_string_was_key = 0; + reader->state = GRPC_JSON_STATE_STRING_ESCAPE; + break; + + /* This is the \\ case. */ + case GRPC_JSON_STATE_STRING_ESCAPE: + if (reader->unicode_high_surrogate != 0) + return GRPC_JSON_PARSE_ERROR; + json_reader_string_add_char(reader, '\\'); + if (reader->escaped_string_was_key) { + reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; + } else { + reader->state = GRPC_JSON_STATE_VALUE_STRING; + } + break; + + default: + return GRPC_JSON_PARSE_ERROR; + } + break; + + default: + reader->container_just_begun = 0; + switch (reader->state) { + case GRPC_JSON_STATE_OBJECT_KEY_BEGIN: + if (c != '"') return GRPC_JSON_PARSE_ERROR; + reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; + break; + + case GRPC_JSON_STATE_OBJECT_KEY_STRING: + GPR_ASSERT(reader->unicode_high_surrogate == 0); + if (c == '"') { + reader->state = GRPC_JSON_STATE_OBJECT_KEY_END; + json_reader_set_key(reader); + json_reader_string_clear(reader); + } else { + if (c <= 0x001f) return GRPC_JSON_PARSE_ERROR; + json_reader_string_add_char(reader, c); + } + break; + + case GRPC_JSON_STATE_VALUE_STRING: + if (reader->unicode_high_surrogate != 0) + return GRPC_JSON_PARSE_ERROR; + if (c == '"') { + reader->state = GRPC_JSON_STATE_VALUE_END; + json_reader_set_string(reader); + json_reader_string_clear(reader); + } else { + if (c < 32) return GRPC_JSON_PARSE_ERROR; + json_reader_string_add_char(reader, c); + } + break; + + case GRPC_JSON_STATE_OBJECT_KEY_END: + if (c != ':') return GRPC_JSON_PARSE_ERROR; + reader->state = GRPC_JSON_STATE_VALUE_BEGIN; + break; + + case GRPC_JSON_STATE_VALUE_BEGIN: + switch (c) { + case 't': + reader->state = GRPC_JSON_STATE_VALUE_TRUE_R; + break; + + case 'f': + reader->state = GRPC_JSON_STATE_VALUE_FALSE_A; + break; + + case 'n': + reader->state = GRPC_JSON_STATE_VALUE_NULL_U; + break; + + case '"': + reader->state = GRPC_JSON_STATE_VALUE_STRING; + break; + + case '0': + json_reader_string_add_char(reader, c); + reader->state = GRPC_JSON_STATE_VALUE_NUMBER_ZERO; + break; + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + json_reader_string_add_char(reader, c); + reader->state = GRPC_JSON_STATE_VALUE_NUMBER; + break; + + case '{': + reader->container_just_begun = 1; + json_reader_container_begins(reader, GRPC_JSON_OBJECT); + reader->depth++; + reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN; + reader->in_object = 1; + reader->in_array = 0; + break; + + case '[': + reader->container_just_begun = 1; + json_reader_container_begins(reader, GRPC_JSON_ARRAY); + reader->depth++; + reader->in_object = 0; + reader->in_array = 1; + break; + } + break; + + case GRPC_JSON_STATE_STRING_ESCAPE: + if (reader->escaped_string_was_key) { + reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; + } else { + reader->state = GRPC_JSON_STATE_VALUE_STRING; + } + if (reader->unicode_high_surrogate && c != 'u') + return GRPC_JSON_PARSE_ERROR; + switch (c) { + case '"': + case '/': + json_reader_string_add_char(reader, c); + break; + case 'b': + json_reader_string_add_char(reader, '\b'); + break; + case 'f': + json_reader_string_add_char(reader, '\f'); + break; + case 'n': + json_reader_string_add_char(reader, '\n'); + break; + case 'r': + json_reader_string_add_char(reader, '\r'); + break; + case 't': + json_reader_string_add_char(reader, '\t'); + break; + case 'u': + reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U1; + reader->unicode_char = 0; + break; + default: + return GRPC_JSON_PARSE_ERROR; + } + break; + + case GRPC_JSON_STATE_STRING_ESCAPE_U1: + case GRPC_JSON_STATE_STRING_ESCAPE_U2: + case GRPC_JSON_STATE_STRING_ESCAPE_U3: + case GRPC_JSON_STATE_STRING_ESCAPE_U4: + if ((c >= '0') && (c <= '9')) { + c -= '0'; + } else if ((c >= 'A') && (c <= 'F')) { + c -= 'A' - 10; + } else if ((c >= 'a') && (c <= 'f')) { + c -= 'a' - 10; + } else { + return GRPC_JSON_PARSE_ERROR; + } + reader->unicode_char = (uint16_t)(reader->unicode_char << 4); + reader->unicode_char = (uint16_t)(reader->unicode_char | c); + + switch (reader->state) { + case GRPC_JSON_STATE_STRING_ESCAPE_U1: + reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U2; + break; + case GRPC_JSON_STATE_STRING_ESCAPE_U2: + reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U3; + break; + case GRPC_JSON_STATE_STRING_ESCAPE_U3: + reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U4; + break; + case GRPC_JSON_STATE_STRING_ESCAPE_U4: + /* See grpc_json_writer_escape_string to have a description + * of what's going on here. + */ + if ((reader->unicode_char & 0xfc00) == 0xd800) { + /* high surrogate utf-16 */ + if (reader->unicode_high_surrogate != 0) + return GRPC_JSON_PARSE_ERROR; + reader->unicode_high_surrogate = reader->unicode_char; + } else if ((reader->unicode_char & 0xfc00) == 0xdc00) { + /* low surrogate utf-16 */ + uint32_t utf32; + if (reader->unicode_high_surrogate == 0) + return GRPC_JSON_PARSE_ERROR; + utf32 = 0x10000; + utf32 += (uint32_t)( + (reader->unicode_high_surrogate - 0xd800) * 0x400); + utf32 += (uint32_t)(reader->unicode_char - 0xdc00); + json_reader_string_add_utf32(reader, utf32); + reader->unicode_high_surrogate = 0; + } else { + /* anything else */ + if (reader->unicode_high_surrogate != 0) + return GRPC_JSON_PARSE_ERROR; + json_reader_string_add_utf32(reader, reader->unicode_char); + } + if (reader->escaped_string_was_key) { + reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; + } else { + reader->state = GRPC_JSON_STATE_VALUE_STRING; + } + break; + default: + GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR); + } + break; + + case GRPC_JSON_STATE_VALUE_NUMBER: + json_reader_string_add_char(reader, c); + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + break; + case 'e': + case 'E': + reader->state = GRPC_JSON_STATE_VALUE_NUMBER_E; + break; + case '.': + reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT; + break; + default: + return GRPC_JSON_PARSE_ERROR; + } + break; + + case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL: + json_reader_string_add_char(reader, c); + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + break; + case 'e': + case 'E': + reader->state = GRPC_JSON_STATE_VALUE_NUMBER_E; + break; + default: + return GRPC_JSON_PARSE_ERROR; + } + break; + + case GRPC_JSON_STATE_VALUE_NUMBER_ZERO: + if (c != '.') return GRPC_JSON_PARSE_ERROR; + json_reader_string_add_char(reader, c); + reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT; + break; + + case GRPC_JSON_STATE_VALUE_NUMBER_DOT: + json_reader_string_add_char(reader, c); + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + reader->state = GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL; + break; + default: + return GRPC_JSON_PARSE_ERROR; + } + break; + + case GRPC_JSON_STATE_VALUE_NUMBER_E: + json_reader_string_add_char(reader, c); + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + reader->state = GRPC_JSON_STATE_VALUE_NUMBER_EPM; + break; + default: + return GRPC_JSON_PARSE_ERROR; + } + break; + + case GRPC_JSON_STATE_VALUE_NUMBER_EPM: + json_reader_string_add_char(reader, c); + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + break; + default: + return GRPC_JSON_PARSE_ERROR; + } + break; + + case GRPC_JSON_STATE_VALUE_TRUE_R: + if (c != 'r') return GRPC_JSON_PARSE_ERROR; + reader->state = GRPC_JSON_STATE_VALUE_TRUE_U; + break; + + case GRPC_JSON_STATE_VALUE_TRUE_U: + if (c != 'u') return GRPC_JSON_PARSE_ERROR; + reader->state = GRPC_JSON_STATE_VALUE_TRUE_E; + break; + + case GRPC_JSON_STATE_VALUE_TRUE_E: + if (c != 'e') return GRPC_JSON_PARSE_ERROR; + json_reader_set_true(reader); + reader->state = GRPC_JSON_STATE_VALUE_END; + break; + + case GRPC_JSON_STATE_VALUE_FALSE_A: + if (c != 'a') return GRPC_JSON_PARSE_ERROR; + reader->state = GRPC_JSON_STATE_VALUE_FALSE_L; + break; + + case GRPC_JSON_STATE_VALUE_FALSE_L: + if (c != 'l') return GRPC_JSON_PARSE_ERROR; + reader->state = GRPC_JSON_STATE_VALUE_FALSE_S; + break; + + case GRPC_JSON_STATE_VALUE_FALSE_S: + if (c != 's') return GRPC_JSON_PARSE_ERROR; + reader->state = GRPC_JSON_STATE_VALUE_FALSE_E; + break; + + case GRPC_JSON_STATE_VALUE_FALSE_E: + if (c != 'e') return GRPC_JSON_PARSE_ERROR; + json_reader_set_false(reader); + reader->state = GRPC_JSON_STATE_VALUE_END; + break; + + case GRPC_JSON_STATE_VALUE_NULL_U: + if (c != 'u') return GRPC_JSON_PARSE_ERROR; + reader->state = GRPC_JSON_STATE_VALUE_NULL_L1; + break; + + case GRPC_JSON_STATE_VALUE_NULL_L1: + if (c != 'l') return GRPC_JSON_PARSE_ERROR; + reader->state = GRPC_JSON_STATE_VALUE_NULL_L2; + break; + + case GRPC_JSON_STATE_VALUE_NULL_L2: + if (c != 'l') return GRPC_JSON_PARSE_ERROR; + json_reader_set_null(reader); + reader->state = GRPC_JSON_STATE_VALUE_END; + break; + + /* All of the VALUE_END cases are handled in the specialized case + * above. */ + case GRPC_JSON_STATE_VALUE_END: + switch (c) { + case ',': + case '}': + case ']': + GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR); + break; + + default: + return GRPC_JSON_PARSE_ERROR; + } + break; + + case GRPC_JSON_STATE_END: + return GRPC_JSON_PARSE_ERROR; + } + } + } + + GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR); +} diff --git a/src/core/lib/json/json_reader.h b/src/core/lib/json/json_reader.h new file mode 100644 index 0000000000..f25f44b2ef --- /dev/null +++ b/src/core/lib/json/json_reader.h @@ -0,0 +1,160 @@ +/* + * + * Copyright 2015-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_JSON_JSON_READER_H +#define GRPC_CORE_JSON_JSON_READER_H + +#include +#include "src/core/json/json_common.h" + +typedef enum { + GRPC_JSON_STATE_OBJECT_KEY_BEGIN, + GRPC_JSON_STATE_OBJECT_KEY_STRING, + GRPC_JSON_STATE_OBJECT_KEY_END, + GRPC_JSON_STATE_VALUE_BEGIN, + GRPC_JSON_STATE_VALUE_STRING, + GRPC_JSON_STATE_STRING_ESCAPE, + GRPC_JSON_STATE_STRING_ESCAPE_U1, + GRPC_JSON_STATE_STRING_ESCAPE_U2, + GRPC_JSON_STATE_STRING_ESCAPE_U3, + GRPC_JSON_STATE_STRING_ESCAPE_U4, + GRPC_JSON_STATE_VALUE_NUMBER, + GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL, + GRPC_JSON_STATE_VALUE_NUMBER_ZERO, + GRPC_JSON_STATE_VALUE_NUMBER_DOT, + GRPC_JSON_STATE_VALUE_NUMBER_E, + GRPC_JSON_STATE_VALUE_NUMBER_EPM, + GRPC_JSON_STATE_VALUE_TRUE_R, + GRPC_JSON_STATE_VALUE_TRUE_U, + GRPC_JSON_STATE_VALUE_TRUE_E, + GRPC_JSON_STATE_VALUE_FALSE_A, + GRPC_JSON_STATE_VALUE_FALSE_L, + GRPC_JSON_STATE_VALUE_FALSE_S, + GRPC_JSON_STATE_VALUE_FALSE_E, + GRPC_JSON_STATE_VALUE_NULL_U, + GRPC_JSON_STATE_VALUE_NULL_L1, + GRPC_JSON_STATE_VALUE_NULL_L2, + GRPC_JSON_STATE_VALUE_END, + GRPC_JSON_STATE_END +} grpc_json_reader_state; + +enum { + /* The first non-unicode value is 0x110000. But let's pick + * a value high enough to start our error codes from. These + * values are safe to return from the read_char function. + */ + GRPC_JSON_READ_CHAR_EOF = 0x7ffffff0, + GRPC_JSON_READ_CHAR_EAGAIN, + GRPC_JSON_READ_CHAR_ERROR +}; + +struct grpc_json_reader; + +typedef struct grpc_json_reader_vtable { + /* Clears your internal string scratchpad. */ + void (*string_clear)(void *userdata); + /* Adds a char to the string scratchpad. */ + void (*string_add_char)(void *userdata, uint32_t c); + /* Adds a utf32 char to the string scratchpad. */ + void (*string_add_utf32)(void *userdata, uint32_t c); + /* Reads a character from your input. May be utf-8, 16 or 32. */ + uint32_t (*read_char)(void *userdata); + /* Starts a container of type GRPC_JSON_ARRAY or GRPC_JSON_OBJECT. */ + void (*container_begins)(void *userdata, grpc_json_type type); + /* Ends the current container. Must return the type of its parent. */ + grpc_json_type (*container_ends)(void *userdata); + /* Your internal string scratchpad is an object's key. */ + void (*set_key)(void *userdata); + /* Your internal string scratchpad is a string value. */ + void (*set_string)(void *userdata); + /* Your internal string scratchpad is a numerical value. Return 1 if valid. */ + int (*set_number)(void *userdata); + /* Sets the values true, false or null. */ + void (*set_true)(void *userdata); + void (*set_false)(void *userdata); + void (*set_null)(void *userdata); +} grpc_json_reader_vtable; + +typedef struct grpc_json_reader { + /* That structure is fully private, and initialized by grpc_json_reader_init. + * The definition is public so you can put it on your stack. + */ + + void *userdata; + grpc_json_reader_vtable *vtable; + int depth; + int in_object; + int in_array; + int escaped_string_was_key; + int container_just_begun; + uint16_t unicode_char, unicode_high_surrogate; + grpc_json_reader_state state; +} grpc_json_reader; + +/* The return type of the parser. */ +typedef enum { + GRPC_JSON_DONE, /* The parser finished successfully. */ + GRPC_JSON_EAGAIN, /* The parser yields to get more data. */ + GRPC_JSON_READ_ERROR, /* The parser passes through a read error. */ + GRPC_JSON_PARSE_ERROR, /* The parser found an error in the json stream. */ + GRPC_JSON_INTERNAL_ERROR /* The parser got an internal error. */ +} grpc_json_reader_status; + +/* Call this function to start parsing the input. It will return the following: + * . GRPC_JSON_DONE if the input got eof, and the parsing finished + * successfully. + * . GRPC_JSON_EAGAIN if the read_char function returned again. Call the + * parser again as needed. It is okay to call the parser in polling mode, + * although a bit dull. + * . GRPC_JSON_READ_ERROR if the read_char function returned an error. The + * state isn't broken however, and the function can be called again if the + * error has been corrected. But please use the EAGAIN feature instead for + * consistency. + * . GRPC_JSON_PARSE_ERROR if the input was somehow invalid. + * . GRPC_JSON_INTERNAL_ERROR if the parser somehow ended into an invalid + * internal state. + */ +grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader); + +/* Call this function to initialize the reader structure. */ +void grpc_json_reader_init(grpc_json_reader *reader, + grpc_json_reader_vtable *vtable, void *userdata); + +/* You may call this from the read_char callback if you don't know where is the + * end of your input stream, and you'd like the json reader to hint you that it + * has completed reading its input, so you can return an EOF to it. Note that + * there might still be trailing whitespaces after that point. + */ +int grpc_json_reader_is_complete(grpc_json_reader *reader); + +#endif /* GRPC_CORE_JSON_JSON_READER_H */ diff --git a/src/core/lib/json/json_string.c b/src/core/lib/json/json_string.c new file mode 100644 index 0000000000..d4ebce18e1 --- /dev/null +++ b/src/core/lib/json/json_string.c @@ -0,0 +1,379 @@ +/* + * + * Copyright 2015-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 +#include + +#include +#include + +#include "src/core/json/json.h" +#include "src/core/json/json_reader.h" +#include "src/core/json/json_writer.h" + +/* The json reader will construct a bunch of grpc_json objects and + * link them all up together in a tree-like structure that will represent + * the json data in memory. + * + * It also uses its own input as a scratchpad to store all of the decoded, + * unescaped strings. So we need to keep track of all these pointers in + * that opaque structure the reader will carry for us. + * + * Note that this works because the act of parsing json always reduces its + * input size, and never expands it. + */ +typedef struct { + grpc_json *top; + grpc_json *current_container; + grpc_json *current_value; + uint8_t *input; + uint8_t *key; + uint8_t *string; + uint8_t *string_ptr; + size_t remaining_input; +} json_reader_userdata; + +/* This json writer will put everything in a big string. + * The point is that we allocate that string in chunks of 256 bytes. + */ +typedef struct { + char *output; + size_t free_space; + size_t string_len; + size_t allocated; +} json_writer_userdata; + +/* This function checks if there's enough space left in the output buffer, + * and will enlarge it if necessary. We're only allocating chunks of 256 + * bytes at a time (or multiples thereof). + */ +static void json_writer_output_check(void *userdata, size_t needed) { + json_writer_userdata *state = userdata; + if (state->free_space >= needed) return; + needed -= state->free_space; + /* Round up by 256 bytes. */ + needed = (needed + 0xff) & ~0xffU; + state->output = gpr_realloc(state->output, state->allocated + needed); + state->free_space += needed; + state->allocated += needed; +} + +/* These are needed by the writer's implementation. */ +static void json_writer_output_char(void *userdata, char c) { + json_writer_userdata *state = userdata; + json_writer_output_check(userdata, 1); + state->output[state->string_len++] = c; + state->free_space--; +} + +static void json_writer_output_string_with_len(void *userdata, const char *str, + size_t len) { + json_writer_userdata *state = userdata; + json_writer_output_check(userdata, len); + memcpy(state->output + state->string_len, str, len); + state->string_len += len; + state->free_space -= len; +} + +static void json_writer_output_string(void *userdata, const char *str) { + size_t len = strlen(str); + json_writer_output_string_with_len(userdata, str, len); +} + +/* The reader asks us to clear our scratchpad. In our case, we'll simply mark + * the end of the current string, and advance our output pointer. + */ +static void json_reader_string_clear(void *userdata) { + json_reader_userdata *state = userdata; + if (state->string) { + GPR_ASSERT(state->string_ptr < state->input); + *state->string_ptr++ = 0; + } + state->string = state->string_ptr; +} + +static void json_reader_string_add_char(void *userdata, uint32_t c) { + json_reader_userdata *state = userdata; + GPR_ASSERT(state->string_ptr < state->input); + GPR_ASSERT(c <= 0xff); + *state->string_ptr++ = (uint8_t)c; +} + +/* We are converting a UTF-32 character into UTF-8 here, + * as described by RFC3629. + */ +static void json_reader_string_add_utf32(void *userdata, uint32_t c) { + if (c <= 0x7f) { + json_reader_string_add_char(userdata, c); + } else if (c <= 0x7ff) { + uint32_t b1 = 0xc0 | ((c >> 6) & 0x1f); + uint32_t b2 = 0x80 | (c & 0x3f); + json_reader_string_add_char(userdata, b1); + json_reader_string_add_char(userdata, b2); + } else if (c <= 0xffff) { + uint32_t b1 = 0xe0 | ((c >> 12) & 0x0f); + uint32_t b2 = 0x80 | ((c >> 6) & 0x3f); + uint32_t b3 = 0x80 | (c & 0x3f); + json_reader_string_add_char(userdata, b1); + json_reader_string_add_char(userdata, b2); + json_reader_string_add_char(userdata, b3); + } else if (c <= 0x1fffff) { + uint32_t b1 = 0xf0 | ((c >> 18) & 0x07); + uint32_t b2 = 0x80 | ((c >> 12) & 0x3f); + uint32_t b3 = 0x80 | ((c >> 6) & 0x3f); + uint32_t b4 = 0x80 | (c & 0x3f); + json_reader_string_add_char(userdata, b1); + json_reader_string_add_char(userdata, b2); + json_reader_string_add_char(userdata, b3); + json_reader_string_add_char(userdata, b4); + } +} + +/* We consider that the input may be a zero-terminated string. So we + * can end up hitting eof before the end of the alleged string length. + */ +static uint32_t json_reader_read_char(void *userdata) { + uint32_t r; + json_reader_userdata *state = userdata; + + if (state->remaining_input == 0) return GRPC_JSON_READ_CHAR_EOF; + + r = *state->input++; + state->remaining_input--; + + if (r == 0) { + state->remaining_input = 0; + return GRPC_JSON_READ_CHAR_EOF; + } + + return r; +} + +/* Helper function to create a new grpc_json object and link it into + * our tree-in-progress inside our opaque structure. + */ +static grpc_json *json_create_and_link(void *userdata, grpc_json_type type) { + json_reader_userdata *state = userdata; + grpc_json *json = grpc_json_create(type); + + json->parent = state->current_container; + json->prev = state->current_value; + state->current_value = json; + + if (json->prev) { + json->prev->next = json; + } + if (json->parent) { + if (!json->parent->child) { + json->parent->child = json; + } + if (json->parent->type == GRPC_JSON_OBJECT) { + json->key = (char *)state->key; + } + } + if (!state->top) { + state->top = json; + } + + return json; +} + +static void json_reader_container_begins(void *userdata, grpc_json_type type) { + json_reader_userdata *state = userdata; + grpc_json *container; + + GPR_ASSERT(type == GRPC_JSON_ARRAY || type == GRPC_JSON_OBJECT); + + container = json_create_and_link(userdata, type); + state->current_container = container; + state->current_value = NULL; +} + +/* It's important to remember that the reader is mostly stateless, so it + * isn't trying to remember what the container was prior the one that just + * ends. Since we're keeping track of these for our own purpose, we are + * able to return that information back, which is useful for it to validate + * the input json stream. + * + * Also note that if we're at the top of the tree, and the last container + * ends, we have to return GRPC_JSON_TOP_LEVEL. + */ +static grpc_json_type json_reader_container_ends(void *userdata) { + grpc_json_type container_type = GRPC_JSON_TOP_LEVEL; + json_reader_userdata *state = userdata; + + GPR_ASSERT(state->current_container); + + state->current_value = state->current_container; + state->current_container = state->current_container->parent; + + if (state->current_container) { + container_type = state->current_container->type; + } + + return container_type; +} + +/* The next 3 functions basically are the reader asking us to use our string + * scratchpad for one of these 3 purposes. + * + * Note that in the set_number case, we're not going to try interpreting it. + * We'll keep it as a string, and leave it to the caller to evaluate it. + */ +static void json_reader_set_key(void *userdata) { + json_reader_userdata *state = userdata; + state->key = state->string; +} + +static void json_reader_set_string(void *userdata) { + json_reader_userdata *state = userdata; + grpc_json *json = json_create_and_link(userdata, GRPC_JSON_STRING); + json->value = (char *)state->string; +} + +static int json_reader_set_number(void *userdata) { + json_reader_userdata *state = userdata; + grpc_json *json = json_create_and_link(userdata, GRPC_JSON_NUMBER); + json->value = (char *)state->string; + return 1; +} + +/* The object types true, false and null are self-sufficient, and don't need + * any more information beside their type. + */ +static void json_reader_set_true(void *userdata) { + json_create_and_link(userdata, GRPC_JSON_TRUE); +} + +static void json_reader_set_false(void *userdata) { + json_create_and_link(userdata, GRPC_JSON_FALSE); +} + +static void json_reader_set_null(void *userdata) { + json_create_and_link(userdata, GRPC_JSON_NULL); +} + +static grpc_json_reader_vtable reader_vtable = { + json_reader_string_clear, json_reader_string_add_char, + json_reader_string_add_utf32, json_reader_read_char, + json_reader_container_begins, json_reader_container_ends, + json_reader_set_key, json_reader_set_string, + json_reader_set_number, json_reader_set_true, + json_reader_set_false, json_reader_set_null}; + +/* And finally, let's define our public API. */ +grpc_json *grpc_json_parse_string_with_len(char *input, size_t size) { + grpc_json_reader reader; + json_reader_userdata state; + grpc_json *json = NULL; + grpc_json_reader_status status; + + if (!input) return NULL; + + state.top = state.current_container = state.current_value = NULL; + state.string = state.key = NULL; + state.string_ptr = state.input = (uint8_t *)input; + state.remaining_input = size; + grpc_json_reader_init(&reader, &reader_vtable, &state); + + status = grpc_json_reader_run(&reader); + json = state.top; + + if ((status != GRPC_JSON_DONE) && json) { + grpc_json_destroy(json); + json = NULL; + } + + return json; +} + +#define UNBOUND_JSON_STRING_LENGTH 0x7fffffff + +grpc_json *grpc_json_parse_string(char *input) { + return grpc_json_parse_string_with_len(input, UNBOUND_JSON_STRING_LENGTH); +} + +static void json_dump_recursive(grpc_json_writer *writer, grpc_json *json, + int in_object) { + while (json) { + if (in_object) grpc_json_writer_object_key(writer, json->key); + + switch (json->type) { + case GRPC_JSON_OBJECT: + case GRPC_JSON_ARRAY: + grpc_json_writer_container_begins(writer, json->type); + if (json->child) + json_dump_recursive(writer, json->child, + json->type == GRPC_JSON_OBJECT); + grpc_json_writer_container_ends(writer, json->type); + break; + case GRPC_JSON_STRING: + grpc_json_writer_value_string(writer, json->value); + break; + case GRPC_JSON_NUMBER: + grpc_json_writer_value_raw(writer, json->value); + break; + case GRPC_JSON_TRUE: + grpc_json_writer_value_raw_with_len(writer, "true", 4); + break; + case GRPC_JSON_FALSE: + grpc_json_writer_value_raw_with_len(writer, "false", 5); + break; + case GRPC_JSON_NULL: + grpc_json_writer_value_raw_with_len(writer, "null", 4); + break; + default: + GPR_UNREACHABLE_CODE(abort()); + } + json = json->next; + } +} + +static grpc_json_writer_vtable writer_vtable = { + json_writer_output_char, json_writer_output_string, + json_writer_output_string_with_len}; + +char *grpc_json_dump_to_string(grpc_json *json, int indent) { + grpc_json_writer writer; + json_writer_userdata state; + + state.output = NULL; + state.free_space = state.string_len = state.allocated = 0; + grpc_json_writer_init(&writer, indent, &writer_vtable, &state); + + json_dump_recursive(&writer, json, 0); + + json_writer_output_char(&state, 0); + + return state.output; +} diff --git a/src/core/lib/json/json_writer.c b/src/core/lib/json/json_writer.c new file mode 100644 index 0000000000..326ec2d431 --- /dev/null +++ b/src/core/lib/json/json_writer.c @@ -0,0 +1,258 @@ +/* + * + * Copyright 2015, 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 + +#include + +#include "src/core/json/json_writer.h" + +static void json_writer_output_char(grpc_json_writer *writer, char c) { + writer->vtable->output_char(writer->userdata, c); +} + +static void json_writer_output_string(grpc_json_writer *writer, + const char *str) { + writer->vtable->output_string(writer->userdata, str); +} + +static void json_writer_output_string_with_len(grpc_json_writer *writer, + const char *str, size_t len) { + writer->vtable->output_string_with_len(writer->userdata, str, len); +} + +void grpc_json_writer_init(grpc_json_writer *writer, int indent, + grpc_json_writer_vtable *vtable, void *userdata) { + memset(writer, 0, sizeof(*writer)); + writer->container_empty = 1; + writer->indent = indent; + writer->vtable = vtable; + writer->userdata = userdata; +} + +static void json_writer_output_indent(grpc_json_writer *writer) { + static const char spacesstr[] = + " " + " " + " " + " "; + + unsigned spaces = (unsigned)(writer->depth * writer->indent); + + if (writer->indent == 0) return; + + if (writer->got_key) { + json_writer_output_char(writer, ' '); + return; + } + + while (spaces >= (sizeof(spacesstr) - 1)) { + json_writer_output_string_with_len(writer, spacesstr, + sizeof(spacesstr) - 1); + spaces -= (unsigned)(sizeof(spacesstr) - 1); + } + + if (spaces == 0) return; + + json_writer_output_string_with_len( + writer, spacesstr + sizeof(spacesstr) - 1 - spaces, spaces); +} + +static void json_writer_value_end(grpc_json_writer *writer) { + if (writer->container_empty) { + writer->container_empty = 0; + if ((writer->indent == 0) || (writer->depth == 0)) return; + json_writer_output_char(writer, '\n'); + } else { + json_writer_output_char(writer, ','); + if (writer->indent == 0) return; + json_writer_output_char(writer, '\n'); + } +} + +static void json_writer_escape_utf16(grpc_json_writer *writer, uint16_t utf16) { + static const char hex[] = "0123456789abcdef"; + + json_writer_output_string_with_len(writer, "\\u", 2); + json_writer_output_char(writer, hex[(utf16 >> 12) & 0x0f]); + json_writer_output_char(writer, hex[(utf16 >> 8) & 0x0f]); + json_writer_output_char(writer, hex[(utf16 >> 4) & 0x0f]); + json_writer_output_char(writer, hex[(utf16)&0x0f]); +} + +static void json_writer_escape_string(grpc_json_writer *writer, + const char *string) { + json_writer_output_char(writer, '"'); + + for (;;) { + uint8_t c = (uint8_t)*string++; + if (c == 0) { + break; + } else if ((c >= 32) && (c <= 126)) { + if ((c == '\\') || (c == '"')) json_writer_output_char(writer, '\\'); + json_writer_output_char(writer, (char)c); + } else if ((c < 32) || (c == 127)) { + switch (c) { + case '\b': + json_writer_output_string_with_len(writer, "\\b", 2); + break; + case '\f': + json_writer_output_string_with_len(writer, "\\f", 2); + break; + case '\n': + json_writer_output_string_with_len(writer, "\\n", 2); + break; + case '\r': + json_writer_output_string_with_len(writer, "\\r", 2); + break; + case '\t': + json_writer_output_string_with_len(writer, "\\t", 2); + break; + default: + json_writer_escape_utf16(writer, c); + break; + } + } else { + uint32_t utf32 = 0; + int extra = 0; + int i; + int valid = 1; + if ((c & 0xe0) == 0xc0) { + utf32 = c & 0x1f; + extra = 1; + } else if ((c & 0xf0) == 0xe0) { + utf32 = c & 0x0f; + extra = 2; + } else if ((c & 0xf8) == 0xf0) { + utf32 = c & 0x07; + extra = 3; + } else { + break; + } + for (i = 0; i < extra; i++) { + utf32 <<= 6; + c = (uint8_t)(*string++); + /* Breaks out and bail on any invalid UTF-8 sequence, including \0. */ + if ((c & 0xc0) != 0x80) { + valid = 0; + break; + } + utf32 |= c & 0x3f; + } + if (!valid) break; + /* The range 0xd800 - 0xdfff is reserved by the surrogates ad vitam. + * Any other range is technically reserved for future usage, so if we + * don't want the software to break in the future, we have to allow + * anything else. The first non-unicode character is 0x110000. */ + if (((utf32 >= 0xd800) && (utf32 <= 0xdfff)) || (utf32 >= 0x110000)) + break; + if (utf32 >= 0x10000) { + /* If utf32 contains a character that is above 0xffff, it needs to be + * broken down into a utf-16 surrogate pair. A surrogate pair is first + * a high surrogate, followed by a low surrogate. Each surrogate holds + * 10 bits of usable data, thus allowing a total of 20 bits of data. + * The high surrogate marker is 0xd800, while the low surrogate marker + * is 0xdc00. The low 10 bits of each will be the usable data. + * + * After re-combining the 20 bits of data, one has to add 0x10000 to + * the resulting value, in order to obtain the original character. + * This is obviously because the range 0x0000 - 0xffff can be written + * without any special trick. + * + * Since 0x10ffff is the highest allowed character, we're working in + * the range 0x00000 - 0xfffff after we decrement it by 0x10000. + * That range is exactly 20 bits. + */ + utf32 -= 0x10000; + json_writer_escape_utf16(writer, (uint16_t)(0xd800 | (utf32 >> 10))); + json_writer_escape_utf16(writer, (uint16_t)(0xdc00 | (utf32 & 0x3ff))); + } else { + json_writer_escape_utf16(writer, (uint16_t)utf32); + } + } + } + + json_writer_output_char(writer, '"'); +} + +void grpc_json_writer_container_begins(grpc_json_writer *writer, + grpc_json_type type) { + if (!writer->got_key) json_writer_value_end(writer); + json_writer_output_indent(writer); + json_writer_output_char(writer, type == GRPC_JSON_OBJECT ? '{' : '['); + writer->container_empty = 1; + writer->got_key = 0; + writer->depth++; +} + +void grpc_json_writer_container_ends(grpc_json_writer *writer, + grpc_json_type type) { + if (writer->indent && !writer->container_empty) + json_writer_output_char(writer, '\n'); + writer->depth--; + if (!writer->container_empty) json_writer_output_indent(writer); + json_writer_output_char(writer, type == GRPC_JSON_OBJECT ? '}' : ']'); + writer->container_empty = 0; + writer->got_key = 0; +} + +void grpc_json_writer_object_key(grpc_json_writer *writer, const char *string) { + json_writer_value_end(writer); + json_writer_output_indent(writer); + json_writer_escape_string(writer, string); + json_writer_output_char(writer, ':'); + writer->got_key = 1; +} + +void grpc_json_writer_value_raw(grpc_json_writer *writer, const char *string) { + if (!writer->got_key) json_writer_value_end(writer); + json_writer_output_indent(writer); + json_writer_output_string(writer, string); + writer->got_key = 0; +} + +void grpc_json_writer_value_raw_with_len(grpc_json_writer *writer, + const char *string, size_t len) { + if (!writer->got_key) json_writer_value_end(writer); + json_writer_output_indent(writer); + json_writer_output_string_with_len(writer, string, len); + writer->got_key = 0; +} + +void grpc_json_writer_value_string(grpc_json_writer *writer, + const char *string) { + if (!writer->got_key) json_writer_value_end(writer); + json_writer_output_indent(writer); + json_writer_escape_string(writer, string); + writer->got_key = 0; +} diff --git a/src/core/lib/json/json_writer.h b/src/core/lib/json/json_writer.h new file mode 100644 index 0000000000..c392126950 --- /dev/null +++ b/src/core/lib/json/json_writer.h @@ -0,0 +1,97 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* The idea of the writer is basically symmetrical of the reader. While the + * reader emits various calls to your code, the writer takes basically the + * same calls and emit json out of it. It doesn't try to make any check on + * the order of the calls you do on it. Meaning you can theorically force + * it to generate invalid json. + * + * Also, unlike the reader, the writer expects UTF-8 encoded input strings. + * These strings will be UTF-8 validated, and any invalid character will + * cut the conversion short, before any invalid UTF-8 sequence, thus forming + * a valid UTF-8 string overall. + */ + +#ifndef GRPC_CORE_JSON_JSON_WRITER_H +#define GRPC_CORE_JSON_JSON_WRITER_H + +#include + +#include "src/core/json/json_common.h" + +typedef struct grpc_json_writer_vtable { + /* Adds a character to the output stream. */ + void (*output_char)(void *userdata, char); + /* Adds a zero-terminated string to the output stream. */ + void (*output_string)(void *userdata, const char *str); + /* Adds a fixed-length string to the output stream. */ + void (*output_string_with_len)(void *userdata, const char *str, size_t len); + +} grpc_json_writer_vtable; + +typedef struct grpc_json_writer { + void *userdata; + grpc_json_writer_vtable *vtable; + int indent; + int depth; + int container_empty; + int got_key; +} grpc_json_writer; + +/* Call this to initialize your writer structure. The indent parameter is + * specifying the number of spaces to use for indenting the output. If you + * use indent=0, then the output will not have any newlines either, thus + * emitting a condensed json output. + */ +void grpc_json_writer_init(grpc_json_writer *writer, int indent, + grpc_json_writer_vtable *vtable, void *userdata); + +/* Signals the beginning of a container. */ +void grpc_json_writer_container_begins(grpc_json_writer *writer, + grpc_json_type type); +/* Signals the end of a container. */ +void grpc_json_writer_container_ends(grpc_json_writer *writer, + grpc_json_type type); +/* Writes down an object key for the next value. */ +void grpc_json_writer_object_key(grpc_json_writer *writer, const char *string); +/* Sets a raw value. Useful for numbers. */ +void grpc_json_writer_value_raw(grpc_json_writer *writer, const char *string); +/* Sets a raw value with its length. Useful for values like true or false. */ +void grpc_json_writer_value_raw_with_len(grpc_json_writer *writer, + const char *string, size_t len); +/* Sets a string value. It'll be escaped, and utf-8 validated. */ +void grpc_json_writer_value_string(grpc_json_writer *writer, + const char *string); + +#endif /* GRPC_CORE_JSON_JSON_WRITER_H */ diff --git a/src/core/lib/profiling/basic_timers.c b/src/core/lib/profiling/basic_timers.c new file mode 100644 index 0000000000..3067f52c21 --- /dev/null +++ b/src/core/lib/profiling/basic_timers.c @@ -0,0 +1,274 @@ +/* + * + * Copyright 2015-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 + +#ifdef GRPC_BASIC_PROFILER + +#include "src/core/profiling/timers.h" + +#include +#include +#include +#include +#include +#include + +typedef enum { BEGIN = '{', END = '}', MARK = '.' } marker_type; + +typedef struct gpr_timer_entry { + gpr_timespec tm; + const char *tagstr; + const char *file; + short line; + char type; + uint8_t important; + int thd; +} gpr_timer_entry; + +#define MAX_COUNT 1000000 + +typedef struct gpr_timer_log { + size_t num_entries; + struct gpr_timer_log *next; + struct gpr_timer_log *prev; + gpr_timer_entry log[MAX_COUNT]; +} gpr_timer_log; + +typedef struct gpr_timer_log_list { + gpr_timer_log *head; + /* valid iff head!=NULL */ + gpr_timer_log *tail; +} gpr_timer_log_list; + +static __thread gpr_timer_log *g_thread_log; +static gpr_once g_once_init = GPR_ONCE_INIT; +static FILE *output_file; +static const char *output_filename = "latency_trace.txt"; +static pthread_mutex_t g_mu; +static pthread_cond_t g_cv; +static gpr_timer_log_list g_in_progress_logs; +static gpr_timer_log_list g_done_logs; +static int g_shutdown; +static gpr_thd_id g_writing_thread; +static __thread int g_thread_id; +static int g_next_thread_id; + +static int timer_log_push_back(gpr_timer_log_list *list, gpr_timer_log *log) { + if (list->head == NULL) { + list->head = list->tail = log; + log->next = log->prev = NULL; + return 1; + } else { + log->prev = list->tail; + log->next = NULL; + list->tail->next = log; + list->tail = log; + return 0; + } +} + +static gpr_timer_log *timer_log_pop_front(gpr_timer_log_list *list) { + gpr_timer_log *out = list->head; + if (out != NULL) { + list->head = out->next; + if (list->head != NULL) { + list->head->prev = NULL; + } else { + list->tail = NULL; + } + } + return out; +} + +static void timer_log_remove(gpr_timer_log_list *list, gpr_timer_log *log) { + if (log->prev == NULL) { + list->head = log->next; + if (list->head != NULL) { + list->head->prev = NULL; + } + } else { + log->prev->next = log->next; + } + if (log->next == NULL) { + list->tail = log->prev; + if (list->tail != NULL) { + list->tail->next = NULL; + } + } else { + log->next->prev = log->prev; + } +} + +static void write_log(gpr_timer_log *log) { + size_t i; + if (output_file == NULL) { + output_file = fopen(output_filename, "w"); + } + for (i = 0; i < log->num_entries; i++) { + gpr_timer_entry *entry = &(log->log[i]); + if (gpr_time_cmp(entry->tm, gpr_time_0(entry->tm.clock_type)) < 0) { + entry->tm = gpr_time_0(entry->tm.clock_type); + } + fprintf(output_file, + "{\"t\": %lld.%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": " + "\"%s\", \"file\": \"%s\", \"line\": %d, \"imp\": %d}\n", + (long long)entry->tm.tv_sec, (int)entry->tm.tv_nsec, entry->thd, + entry->type, entry->tagstr, entry->file, entry->line, + entry->important); + } +} + +static void writing_thread(void *unused) { + gpr_timer_log *log; + pthread_mutex_lock(&g_mu); + for (;;) { + while ((log = timer_log_pop_front(&g_done_logs)) == NULL && !g_shutdown) { + pthread_cond_wait(&g_cv, &g_mu); + } + if (log != NULL) { + pthread_mutex_unlock(&g_mu); + write_log(log); + free(log); + pthread_mutex_lock(&g_mu); + } + if (g_shutdown) { + pthread_mutex_unlock(&g_mu); + return; + } + } +} + +static void flush_logs(gpr_timer_log_list *list) { + gpr_timer_log *log; + while ((log = timer_log_pop_front(list)) != NULL) { + write_log(log); + free(log); + } +} + +static void finish_writing() { + pthread_mutex_lock(&g_mu); + g_shutdown = 1; + pthread_cond_signal(&g_cv); + pthread_mutex_unlock(&g_mu); + gpr_thd_join(g_writing_thread); + + gpr_log(GPR_INFO, "flushing logs"); + + pthread_mutex_lock(&g_mu); + flush_logs(&g_done_logs); + flush_logs(&g_in_progress_logs); + pthread_mutex_unlock(&g_mu); + + if (output_file) { + fclose(output_file); + } +} + +void gpr_timers_set_log_filename(const char *filename) { + output_filename = filename; +} + +static void init_output() { + gpr_thd_options options = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&options); + gpr_thd_new(&g_writing_thread, writing_thread, NULL, &options); + atexit(finish_writing); +} + +static void rotate_log() { + gpr_timer_log *new = malloc(sizeof(*new)); + gpr_once_init(&g_once_init, init_output); + new->num_entries = 0; + pthread_mutex_lock(&g_mu); + if (g_thread_log != NULL) { + timer_log_remove(&g_in_progress_logs, g_thread_log); + if (timer_log_push_back(&g_done_logs, g_thread_log)) { + pthread_cond_signal(&g_cv); + } + } else { + g_thread_id = g_next_thread_id++; + } + timer_log_push_back(&g_in_progress_logs, new); + pthread_mutex_unlock(&g_mu); + g_thread_log = new; +} + +static void gpr_timers_log_add(const char *tagstr, marker_type type, + int important, const char *file, int line) { + gpr_timer_entry *entry; + + if (g_thread_log == NULL || g_thread_log->num_entries == MAX_COUNT) { + rotate_log(); + } + + entry = &g_thread_log->log[g_thread_log->num_entries++]; + + entry->tm = gpr_now(GPR_CLOCK_PRECISE); + entry->tagstr = tagstr; + entry->type = type; + entry->file = file; + entry->line = (short)line; + entry->important = important != 0; + entry->thd = g_thread_id; +} + +/* Latency profiler API implementation. */ +void gpr_timer_add_mark(const char *tagstr, int important, const char *file, + int line) { + gpr_timers_log_add(tagstr, MARK, important, file, line); +} + +void gpr_timer_begin(const char *tagstr, int important, const char *file, + int line) { + gpr_timers_log_add(tagstr, BEGIN, important, file, line); +} + +void gpr_timer_end(const char *tagstr, int important, const char *file, + int line) { + gpr_timers_log_add(tagstr, END, important, file, line); +} + +/* Basic profiler specific API functions. */ +void gpr_timers_global_init(void) {} + +void gpr_timers_global_destroy(void) {} + +#else /* !GRPC_BASIC_PROFILER */ +void gpr_timers_global_init(void) {} + +void gpr_timers_global_destroy(void) {} + +void gpr_timers_set_log_filename(const char *filename) {} +#endif /* GRPC_BASIC_PROFILER */ diff --git a/src/core/lib/profiling/stap_probes.d b/src/core/lib/profiling/stap_probes.d new file mode 100644 index 0000000000..153de91752 --- /dev/null +++ b/src/core/lib/profiling/stap_probes.d @@ -0,0 +1,7 @@ +provider _stap { + probe add_mark(int tag); + probe add_important_mark(int tag); + probe timing_ns_begin(int tag); + probe timing_ns_end(int tag); +}; + diff --git a/src/core/lib/profiling/stap_timers.c b/src/core/lib/profiling/stap_timers.c new file mode 100644 index 0000000000..efcd1af4a1 --- /dev/null +++ b/src/core/lib/profiling/stap_timers.c @@ -0,0 +1,65 @@ +/* + * + * Copyright 2015, 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 + +#ifdef GRPC_STAP_PROFILER + +#include "src/core/profiling/timers.h" + +#include +/* Generated from src/core/profiling/stap_probes.d */ +#include "src/core/profiling/stap_probes.h" + +/* Latency profiler API implementation. */ +void gpr_timer_add_mark(int tag, const char *tagstr, void *id, const char *file, + int line) { + _STAP_ADD_MARK(tag); +} + +void gpr_timer_add_important_mark(int tag, const char *tagstr, void *id, + const char *file, int line) { + _STAP_ADD_IMPORTANT_MARK(tag); +} + +void gpr_timer_begin(int tag, const char *tagstr, void *id, const char *file, + int line) { + _STAP_TIMING_NS_BEGIN(tag); +} + +void gpr_timer_end(int tag, const char *tagstr, void *id, const char *file, + int line) { + _STAP_TIMING_NS_END(tag); +} + +#endif /* GRPC_STAP_PROFILER */ diff --git a/src/core/lib/profiling/timers.h b/src/core/lib/profiling/timers.h new file mode 100644 index 0000000000..6a188dc566 --- /dev/null +++ b/src/core/lib/profiling/timers.h @@ -0,0 +1,119 @@ +/* + * + * Copyright 2015, 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_PROFILING_TIMERS_H +#define GRPC_CORE_PROFILING_TIMERS_H + +#ifdef __cplusplus +extern "C" { +#endif + +void gpr_timers_global_init(void); +void gpr_timers_global_destroy(void); + +void gpr_timer_add_mark(const char *tagstr, int important, const char *file, + int line); +void gpr_timer_begin(const char *tagstr, int important, const char *file, + int line); +void gpr_timer_end(const char *tagstr, int important, const char *file, + int line); + +void gpr_timers_set_log_filename(const char *filename); + +#if !(defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER)) +/* No profiling. No-op all the things. */ +#define GPR_TIMER_MARK(tag, important) \ + do { \ + } while (0) + +#define GPR_TIMER_BEGIN(tag, important) \ + do { \ + } while (0) + +#define GPR_TIMER_END(tag, important) \ + do { \ + } while (0) + +#else /* at least one profiler requested... */ +/* ... hopefully only one. */ +#if defined(GRPC_STAP_PROFILER) && defined(GRPC_BASIC_PROFILER) +#error "GRPC_STAP_PROFILER and GRPC_BASIC_PROFILER are mutually exclusive." +#endif + +/* Generic profiling interface. */ +#define GPR_TIMER_MARK(tag, important) \ + gpr_timer_add_mark(tag, important, __FILE__, __LINE__); + +#define GPR_TIMER_BEGIN(tag, important) \ + gpr_timer_begin(tag, important, __FILE__, __LINE__); + +#define GPR_TIMER_END(tag, important) \ + gpr_timer_end(tag, important, __FILE__, __LINE__); + +#ifdef GRPC_STAP_PROFILER +/* Empty placeholder for now. */ +#endif /* GRPC_STAP_PROFILER */ + +#ifdef GRPC_BASIC_PROFILER +/* Empty placeholder for now. */ +#endif /* GRPC_BASIC_PROFILER */ + +#endif /* at least one profiler requested. */ + +#ifdef __cplusplus +} + +#if (defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER)) +namespace grpc { +class ProfileScope { + public: + ProfileScope(const char *desc, bool important) : desc_(desc) { + GPR_TIMER_BEGIN(desc_, important ? 1 : 0); + } + ~ProfileScope() { GPR_TIMER_END(desc_, 0); } + + private: + const char *const desc_; +}; +} + +#define GPR_TIMER_SCOPE(tag, important) \ + ::grpc::ProfileScope _profile_scope_##__LINE__((tag), (important)) +#else +#define GPR_TIMER_SCOPE(tag, important) \ + do { \ + } while (false) +#endif +#endif + +#endif /* GRPC_CORE_PROFILING_TIMERS_H */ diff --git a/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c b/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c new file mode 100644 index 0000000000..59aae30cff --- /dev/null +++ b/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c @@ -0,0 +1,119 @@ +/* + * + * 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. + * + */ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.5-dev */ + +#include "src/core/proto/grpc/lb/v0/load_balancer.pb.h" + +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t grpc_lb_v0_Duration_fields[3] = { + PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, grpc_lb_v0_Duration, seconds, seconds, 0), + PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, grpc_lb_v0_Duration, nanos, seconds, 0), + PB_LAST_FIELD +}; + +const pb_field_t grpc_lb_v0_LoadBalanceRequest_fields[3] = { + PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, grpc_lb_v0_LoadBalanceRequest, initial_request, initial_request, &grpc_lb_v0_InitialLoadBalanceRequest_fields), + PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v0_LoadBalanceRequest, client_stats, initial_request, &grpc_lb_v0_ClientStats_fields), + PB_LAST_FIELD +}; + +const pb_field_t grpc_lb_v0_InitialLoadBalanceRequest_fields[2] = { + PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, grpc_lb_v0_InitialLoadBalanceRequest, name, name, 0), + PB_LAST_FIELD +}; + +const pb_field_t grpc_lb_v0_ClientStats_fields[4] = { + PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, grpc_lb_v0_ClientStats, total_requests, total_requests, 0), + PB_FIELD( 2, INT64 , OPTIONAL, STATIC , OTHER, grpc_lb_v0_ClientStats, client_rpc_errors, total_requests, 0), + PB_FIELD( 3, INT64 , OPTIONAL, STATIC , OTHER, grpc_lb_v0_ClientStats, dropped_requests, client_rpc_errors, 0), + PB_LAST_FIELD +}; + +const pb_field_t grpc_lb_v0_LoadBalanceResponse_fields[3] = { + PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, grpc_lb_v0_LoadBalanceResponse, initial_response, initial_response, &grpc_lb_v0_InitialLoadBalanceResponse_fields), + PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v0_LoadBalanceResponse, server_list, initial_response, &grpc_lb_v0_ServerList_fields), + PB_LAST_FIELD +}; + +const pb_field_t grpc_lb_v0_InitialLoadBalanceResponse_fields[4] = { + PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, grpc_lb_v0_InitialLoadBalanceResponse, client_config, client_config, 0), + PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, grpc_lb_v0_InitialLoadBalanceResponse, load_balancer_delegate, client_config, 0), + PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v0_InitialLoadBalanceResponse, client_stats_report_interval, load_balancer_delegate, &grpc_lb_v0_Duration_fields), + PB_LAST_FIELD +}; + +const pb_field_t grpc_lb_v0_ServerList_fields[3] = { + PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, grpc_lb_v0_ServerList, servers, servers, &grpc_lb_v0_Server_fields), + PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v0_ServerList, expiration_interval, servers, &grpc_lb_v0_Duration_fields), + PB_LAST_FIELD +}; + +const pb_field_t grpc_lb_v0_Server_fields[5] = { + PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, grpc_lb_v0_Server, ip_address, ip_address, 0), + PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, grpc_lb_v0_Server, port, ip_address, 0), + PB_FIELD( 3, BYTES , OPTIONAL, STATIC , OTHER, grpc_lb_v0_Server, load_balance_token, port, 0), + PB_FIELD( 4, BOOL , OPTIONAL, STATIC , OTHER, grpc_lb_v0_Server, drop_request, load_balance_token, 0), + PB_LAST_FIELD +}; + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(grpc_lb_v0_LoadBalanceRequest, initial_request) < 65536 && pb_membersize(grpc_lb_v0_LoadBalanceRequest, client_stats) < 65536 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, initial_response) < 65536 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, server_list) < 65536 && pb_membersize(grpc_lb_v0_InitialLoadBalanceResponse, client_stats_report_interval) < 65536 && pb_membersize(grpc_lb_v0_ServerList, servers) < 65536 && pb_membersize(grpc_lb_v0_ServerList, expiration_interval) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v0_Duration_grpc_lb_v0_LoadBalanceRequest_grpc_lb_v0_InitialLoadBalanceRequest_grpc_lb_v0_ClientStats_grpc_lb_v0_LoadBalanceResponse_grpc_lb_v0_InitialLoadBalanceResponse_grpc_lb_v0_ServerList_grpc_lb_v0_Server) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(grpc_lb_v0_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v0_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v0_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v0_ServerList, servers) < 256 && pb_membersize(grpc_lb_v0_ServerList, expiration_interval) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v0_Duration_grpc_lb_v0_LoadBalanceRequest_grpc_lb_v0_InitialLoadBalanceRequest_grpc_lb_v0_ClientStats_grpc_lb_v0_LoadBalanceResponse_grpc_lb_v0_InitialLoadBalanceResponse_grpc_lb_v0_ServerList_grpc_lb_v0_Server) +#endif + + diff --git a/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h b/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h new file mode 100644 index 0000000000..3599f881bb --- /dev/null +++ b/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h @@ -0,0 +1,182 @@ +/* + * + * 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. + * + */ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.5-dev */ + +#ifndef PB_LOAD_BALANCER_PB_H_INCLUDED +#define PB_LOAD_BALANCER_PB_H_INCLUDED +#include "third_party/nanopb/pb.h" +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Struct definitions */ +typedef struct _grpc_lb_v0_ClientStats { + bool has_total_requests; + int64_t total_requests; + bool has_client_rpc_errors; + int64_t client_rpc_errors; + bool has_dropped_requests; + int64_t dropped_requests; +} grpc_lb_v0_ClientStats; + +typedef struct _grpc_lb_v0_Duration { + bool has_seconds; + int64_t seconds; + bool has_nanos; + int32_t nanos; +} grpc_lb_v0_Duration; + +typedef struct _grpc_lb_v0_InitialLoadBalanceRequest { + bool has_name; + char name[128]; +} grpc_lb_v0_InitialLoadBalanceRequest; + +typedef PB_BYTES_ARRAY_T(64) grpc_lb_v0_Server_load_balance_token_t; +typedef struct _grpc_lb_v0_Server { + bool has_ip_address; + char ip_address[46]; + bool has_port; + int32_t port; + bool has_load_balance_token; + grpc_lb_v0_Server_load_balance_token_t load_balance_token; + bool has_drop_request; + bool drop_request; +} grpc_lb_v0_Server; + +typedef struct _grpc_lb_v0_InitialLoadBalanceResponse { + bool has_client_config; + char client_config[64]; + bool has_load_balancer_delegate; + char load_balancer_delegate[64]; + bool has_client_stats_report_interval; + grpc_lb_v0_Duration client_stats_report_interval; +} grpc_lb_v0_InitialLoadBalanceResponse; + +typedef struct _grpc_lb_v0_LoadBalanceRequest { + bool has_initial_request; + grpc_lb_v0_InitialLoadBalanceRequest initial_request; + bool has_client_stats; + grpc_lb_v0_ClientStats client_stats; +} grpc_lb_v0_LoadBalanceRequest; + +typedef struct _grpc_lb_v0_ServerList { + pb_callback_t servers; + bool has_expiration_interval; + grpc_lb_v0_Duration expiration_interval; +} grpc_lb_v0_ServerList; + +typedef struct _grpc_lb_v0_LoadBalanceResponse { + bool has_initial_response; + grpc_lb_v0_InitialLoadBalanceResponse initial_response; + bool has_server_list; + grpc_lb_v0_ServerList server_list; +} grpc_lb_v0_LoadBalanceResponse; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define grpc_lb_v0_Duration_init_default {false, 0, false, 0} +#define grpc_lb_v0_LoadBalanceRequest_init_default {false, grpc_lb_v0_InitialLoadBalanceRequest_init_default, false, grpc_lb_v0_ClientStats_init_default} +#define grpc_lb_v0_InitialLoadBalanceRequest_init_default {false, ""} +#define grpc_lb_v0_ClientStats_init_default {false, 0, false, 0, false, 0} +#define grpc_lb_v0_LoadBalanceResponse_init_default {false, grpc_lb_v0_InitialLoadBalanceResponse_init_default, false, grpc_lb_v0_ServerList_init_default} +#define grpc_lb_v0_InitialLoadBalanceResponse_init_default {false, "", false, "", false, grpc_lb_v0_Duration_init_default} +#define grpc_lb_v0_ServerList_init_default {{{NULL}, NULL}, false, grpc_lb_v0_Duration_init_default} +#define grpc_lb_v0_Server_init_default {false, "", false, 0, false, {0, {0}}, false, 0} +#define grpc_lb_v0_Duration_init_zero {false, 0, false, 0} +#define grpc_lb_v0_LoadBalanceRequest_init_zero {false, grpc_lb_v0_InitialLoadBalanceRequest_init_zero, false, grpc_lb_v0_ClientStats_init_zero} +#define grpc_lb_v0_InitialLoadBalanceRequest_init_zero {false, ""} +#define grpc_lb_v0_ClientStats_init_zero {false, 0, false, 0, false, 0} +#define grpc_lb_v0_LoadBalanceResponse_init_zero {false, grpc_lb_v0_InitialLoadBalanceResponse_init_zero, false, grpc_lb_v0_ServerList_init_zero} +#define grpc_lb_v0_InitialLoadBalanceResponse_init_zero {false, "", false, "", false, grpc_lb_v0_Duration_init_zero} +#define grpc_lb_v0_ServerList_init_zero {{{NULL}, NULL}, false, grpc_lb_v0_Duration_init_zero} +#define grpc_lb_v0_Server_init_zero {false, "", false, 0, false, {0, {0}}, false, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define grpc_lb_v0_ClientStats_total_requests_tag 1 +#define grpc_lb_v0_ClientStats_client_rpc_errors_tag 2 +#define grpc_lb_v0_ClientStats_dropped_requests_tag 3 +#define grpc_lb_v0_Duration_seconds_tag 1 +#define grpc_lb_v0_Duration_nanos_tag 2 +#define grpc_lb_v0_InitialLoadBalanceRequest_name_tag 1 +#define grpc_lb_v0_Server_ip_address_tag 1 +#define grpc_lb_v0_Server_port_tag 2 +#define grpc_lb_v0_Server_load_balance_token_tag 3 +#define grpc_lb_v0_Server_drop_request_tag 4 +#define grpc_lb_v0_InitialLoadBalanceResponse_client_config_tag 1 +#define grpc_lb_v0_InitialLoadBalanceResponse_load_balancer_delegate_tag 2 +#define grpc_lb_v0_InitialLoadBalanceResponse_client_stats_report_interval_tag 3 +#define grpc_lb_v0_LoadBalanceRequest_initial_request_tag 1 +#define grpc_lb_v0_LoadBalanceRequest_client_stats_tag 2 +#define grpc_lb_v0_ServerList_servers_tag 1 +#define grpc_lb_v0_ServerList_expiration_interval_tag 3 +#define grpc_lb_v0_LoadBalanceResponse_initial_response_tag 1 +#define grpc_lb_v0_LoadBalanceResponse_server_list_tag 2 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t grpc_lb_v0_Duration_fields[3]; +extern const pb_field_t grpc_lb_v0_LoadBalanceRequest_fields[3]; +extern const pb_field_t grpc_lb_v0_InitialLoadBalanceRequest_fields[2]; +extern const pb_field_t grpc_lb_v0_ClientStats_fields[4]; +extern const pb_field_t grpc_lb_v0_LoadBalanceResponse_fields[3]; +extern const pb_field_t grpc_lb_v0_InitialLoadBalanceResponse_fields[4]; +extern const pb_field_t grpc_lb_v0_ServerList_fields[3]; +extern const pb_field_t grpc_lb_v0_Server_fields[5]; + +/* Maximum encoded size of messages (where known) */ +#define grpc_lb_v0_Duration_size 22 +#define grpc_lb_v0_LoadBalanceRequest_size 169 +#define grpc_lb_v0_InitialLoadBalanceRequest_size 131 +#define grpc_lb_v0_ClientStats_size 33 +#define grpc_lb_v0_LoadBalanceResponse_size (165 + grpc_lb_v0_ServerList_size) +#define grpc_lb_v0_InitialLoadBalanceResponse_size 156 +#define grpc_lb_v0_Server_size 127 + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define LOAD_BALANCER_MESSAGES \ + + +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/core/lib/security/auth_filters.h b/src/core/lib/security/auth_filters.h new file mode 100644 index 0000000000..1154a1d914 --- /dev/null +++ b/src/core/lib/security/auth_filters.h @@ -0,0 +1,42 @@ +/* + * + * Copyright 2015-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_SECURITY_AUTH_FILTERS_H +#define GRPC_CORE_SECURITY_AUTH_FILTERS_H + +#include "src/core/channel/channel_stack.h" + +extern const grpc_channel_filter grpc_client_auth_filter; +extern const grpc_channel_filter grpc_server_auth_filter; + +#endif /* GRPC_CORE_SECURITY_AUTH_FILTERS_H */ diff --git a/src/core/lib/security/b64.c b/src/core/lib/security/b64.c new file mode 100644 index 0000000000..c40b528e2f --- /dev/null +++ b/src/core/lib/security/b64.c @@ -0,0 +1,233 @@ +/* + * + * Copyright 2015-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/security/b64.h" + +#include +#include + +#include +#include +#include + +/* --- Constants. --- */ + +static const int8_t base64_bytes[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 0x3E, -1, -1, -1, 0x3F, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, -1, -1, + -1, 0x7F, -1, -1, -1, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, -1, -1, -1, -1, -1, + -1, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, -1, -1, -1, -1, -1}; + +static const char base64_url_unsafe_chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char base64_url_safe_chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + +#define GRPC_BASE64_PAD_CHAR '=' +#define GRPC_BASE64_PAD_BYTE 0x7F +#define GRPC_BASE64_MULTILINE_LINE_LEN 76 +#define GRPC_BASE64_MULTILINE_NUM_BLOCKS (GRPC_BASE64_MULTILINE_LINE_LEN / 4) + +/* --- base64 functions. --- */ + +char *grpc_base64_encode(const void *vdata, size_t data_size, int url_safe, + int multiline) { + const unsigned char *data = vdata; + const char *base64_chars = + url_safe ? base64_url_safe_chars : base64_url_unsafe_chars; + size_t result_projected_size = + 4 * ((data_size + 3) / 3) + + 2 * (multiline ? (data_size / (3 * GRPC_BASE64_MULTILINE_NUM_BLOCKS)) + : 0) + + 1; + char *result = gpr_malloc(result_projected_size); + char *current = result; + size_t num_blocks = 0; + size_t i = 0; + + /* Encode each block. */ + while (data_size >= 3) { + *current++ = base64_chars[(data[i] >> 2) & 0x3F]; + *current++ = + base64_chars[((data[i] & 0x03) << 4) | ((data[i + 1] >> 4) & 0x0F)]; + *current++ = + base64_chars[((data[i + 1] & 0x0F) << 2) | ((data[i + 2] >> 6) & 0x03)]; + *current++ = base64_chars[data[i + 2] & 0x3F]; + + data_size -= 3; + i += 3; + if (multiline && (++num_blocks == GRPC_BASE64_MULTILINE_NUM_BLOCKS)) { + *current++ = '\r'; + *current++ = '\n'; + num_blocks = 0; + } + } + + /* Take care of the tail. */ + if (data_size == 2) { + *current++ = base64_chars[(data[i] >> 2) & 0x3F]; + *current++ = + base64_chars[((data[i] & 0x03) << 4) | ((data[i + 1] >> 4) & 0x0F)]; + *current++ = base64_chars[(data[i + 1] & 0x0F) << 2]; + *current++ = GRPC_BASE64_PAD_CHAR; + } else if (data_size == 1) { + *current++ = base64_chars[(data[i] >> 2) & 0x3F]; + *current++ = base64_chars[(data[i] & 0x03) << 4]; + *current++ = GRPC_BASE64_PAD_CHAR; + *current++ = GRPC_BASE64_PAD_CHAR; + } + + GPR_ASSERT(current >= result); + GPR_ASSERT((uintptr_t)(current - result) < result_projected_size); + result[current - result] = '\0'; + return result; +} + +gpr_slice grpc_base64_decode(const char *b64, int url_safe) { + return grpc_base64_decode_with_len(b64, strlen(b64), url_safe); +} + +static void decode_one_char(const unsigned char *codes, unsigned char *result, + size_t *result_offset) { + uint32_t packed = ((uint32_t)codes[0] << 2) | ((uint32_t)codes[1] >> 4); + result[(*result_offset)++] = (unsigned char)packed; +} + +static void decode_two_chars(const unsigned char *codes, unsigned char *result, + size_t *result_offset) { + uint32_t packed = ((uint32_t)codes[0] << 10) | ((uint32_t)codes[1] << 4) | + ((uint32_t)codes[2] >> 2); + result[(*result_offset)++] = (unsigned char)(packed >> 8); + result[(*result_offset)++] = (unsigned char)(packed); +} + +static int decode_group(const unsigned char *codes, size_t num_codes, + unsigned char *result, size_t *result_offset) { + GPR_ASSERT(num_codes <= 4); + + /* Short end groups that may not have padding. */ + if (num_codes == 1) { + gpr_log(GPR_ERROR, "Invalid group. Must be at least 2 bytes."); + return 0; + } + if (num_codes == 2) { + decode_one_char(codes, result, result_offset); + return 1; + } + if (num_codes == 3) { + decode_two_chars(codes, result, result_offset); + return 1; + } + + /* Regular 4 byte groups with padding or not. */ + GPR_ASSERT(num_codes == 4); + if (codes[0] == GRPC_BASE64_PAD_BYTE || codes[1] == GRPC_BASE64_PAD_BYTE) { + gpr_log(GPR_ERROR, "Invalid padding detected."); + return 0; + } + if (codes[2] == GRPC_BASE64_PAD_BYTE) { + if (codes[3] == GRPC_BASE64_PAD_BYTE) { + decode_one_char(codes, result, result_offset); + } else { + gpr_log(GPR_ERROR, "Invalid padding detected."); + return 0; + } + } else if (codes[3] == GRPC_BASE64_PAD_BYTE) { + decode_two_chars(codes, result, result_offset); + } else { + /* No padding. */ + uint32_t packed = ((uint32_t)codes[0] << 18) | ((uint32_t)codes[1] << 12) | + ((uint32_t)codes[2] << 6) | codes[3]; + result[(*result_offset)++] = (unsigned char)(packed >> 16); + result[(*result_offset)++] = (unsigned char)(packed >> 8); + result[(*result_offset)++] = (unsigned char)(packed); + } + return 1; +} + +gpr_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len, + int url_safe) { + gpr_slice result = gpr_slice_malloc(b64_len); + unsigned char *current = GPR_SLICE_START_PTR(result); + size_t result_size = 0; + unsigned char codes[4]; + size_t num_codes = 0; + + while (b64_len--) { + unsigned char c = (unsigned char)(*b64++); + signed char code; + if (c >= GPR_ARRAY_SIZE(base64_bytes)) continue; + if (url_safe) { + if (c == '+' || c == '/') { + gpr_log(GPR_ERROR, "Invalid character for url safe base64 %c", c); + goto fail; + } + if (c == '-') { + c = '+'; + } else if (c == '_') { + c = '/'; + } + } + code = base64_bytes[c]; + if (code == -1) { + if (c != '\r' && c != '\n') { + gpr_log(GPR_ERROR, "Invalid character %c", c); + goto fail; + } + } else { + codes[num_codes++] = (unsigned char)code; + if (num_codes == 4) { + if (!decode_group(codes, num_codes, current, &result_size)) goto fail; + num_codes = 0; + } + } + } + + if (num_codes != 0 && + !decode_group(codes, num_codes, current, &result_size)) { + goto fail; + } + GPR_SLICE_SET_LENGTH(result, result_size); + return result; + +fail: + gpr_slice_unref(result); + return gpr_empty_slice(); +} diff --git a/src/core/lib/security/b64.h b/src/core/lib/security/b64.h new file mode 100644 index 0000000000..d18f69563d --- /dev/null +++ b/src/core/lib/security/b64.h @@ -0,0 +1,52 @@ +/* + * + * Copyright 2015-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_SECURITY_B64_H +#define GRPC_CORE_SECURITY_B64_H + +#include + +/* Encodes data using base64. It is the caller's responsability to free + the returned char * using gpr_free. Returns NULL on NULL input. */ +char *grpc_base64_encode(const void *data, size_t data_size, int url_safe, + int multiline); + +/* Decodes data according to the base64 specification. Returns an empty + slice in case of failure. */ +gpr_slice grpc_base64_decode(const char *b64, int url_safe); + +/* Same as above except that the length is provided by the caller. */ +gpr_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len, + int url_safe); + +#endif /* GRPC_CORE_SECURITY_B64_H */ diff --git a/src/core/lib/security/client_auth_filter.c b/src/core/lib/security/client_auth_filter.c new file mode 100644 index 0000000000..e2c23ef98d --- /dev/null +++ b/src/core/lib/security/client_auth_filter.c @@ -0,0 +1,336 @@ +/* + * + * Copyright 2015-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/security/auth_filters.h" + +#include + +#include +#include +#include + +#include "src/core/channel/channel_stack.h" +#include "src/core/security/credentials.h" +#include "src/core/security/security_connector.h" +#include "src/core/security/security_context.h" +#include "src/core/support/string.h" +#include "src/core/surface/call.h" +#include "src/core/transport/static_metadata.h" + +#define MAX_CREDENTIALS_METADATA_COUNT 4 + +/* We can have a per-call credentials. */ +typedef struct { + grpc_call_credentials *creds; + grpc_mdstr *host; + grpc_mdstr *method; + /* pollset bound to this call; if we need to make external + network requests, they should be done under this pollset + so that work can progress when this call wants work to + progress */ + grpc_pollset *pollset; + grpc_transport_stream_op op; + uint8_t security_context_set; + grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT]; + grpc_auth_metadata_context auth_md_context; +} call_data; + +/* We can have a per-channel credentials. */ +typedef struct { + grpc_channel_security_connector *security_connector; + grpc_auth_context *auth_context; +} channel_data; + +static void reset_auth_metadata_context( + grpc_auth_metadata_context *auth_md_context) { + if (auth_md_context->service_url != NULL) { + gpr_free((char *)auth_md_context->service_url); + auth_md_context->service_url = NULL; + } + if (auth_md_context->method_name != NULL) { + gpr_free((char *)auth_md_context->method_name); + auth_md_context->method_name = NULL; + } + GRPC_AUTH_CONTEXT_UNREF( + (grpc_auth_context *)auth_md_context->channel_auth_context, + "grpc_auth_metadata_context"); + auth_md_context->channel_auth_context = NULL; +} + +static void bubble_up_error(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_status_code status, const char *error_msg) { + call_data *calld = elem->call_data; + gpr_log(GPR_ERROR, "Client side authentication failure: %s", error_msg); + grpc_transport_stream_op_add_cancellation(&calld->op, status); + grpc_call_next_op(exec_ctx, elem, &calld->op); +} + +static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_credentials_md *md_elems, + size_t num_md, + grpc_credentials_status status) { + grpc_call_element *elem = (grpc_call_element *)user_data; + call_data *calld = elem->call_data; + grpc_transport_stream_op *op = &calld->op; + grpc_metadata_batch *mdb; + size_t i; + reset_auth_metadata_context(&calld->auth_md_context); + if (status != GRPC_CREDENTIALS_OK) { + bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED, + "Credentials failed to get metadata."); + return; + } + GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT); + GPR_ASSERT(op->send_initial_metadata != NULL); + mdb = op->send_initial_metadata; + for (i = 0; i < num_md; i++) { + grpc_metadata_batch_add_tail( + mdb, &calld->md_links[i], + grpc_mdelem_from_slices(gpr_slice_ref(md_elems[i].key), + gpr_slice_ref(md_elems[i].value))); + } + grpc_call_next_op(exec_ctx, elem, op); +} + +void build_auth_metadata_context(grpc_security_connector *sc, + grpc_auth_context *auth_context, + call_data *calld) { + char *service = gpr_strdup(grpc_mdstr_as_c_string(calld->method)); + char *last_slash = strrchr(service, '/'); + char *method_name = NULL; + char *service_url = NULL; + reset_auth_metadata_context(&calld->auth_md_context); + if (last_slash == NULL) { + gpr_log(GPR_ERROR, "No '/' found in fully qualified method name"); + service[0] = '\0'; + } else if (last_slash == service) { + /* No service part in fully qualified method name: will just be "/". */ + service[1] = '\0'; + } else { + *last_slash = '\0'; + method_name = gpr_strdup(last_slash + 1); + } + if (method_name == NULL) method_name = gpr_strdup(""); + gpr_asprintf(&service_url, "%s://%s%s", + sc->url_scheme == NULL ? "" : sc->url_scheme, + grpc_mdstr_as_c_string(calld->host), service); + calld->auth_md_context.service_url = service_url; + calld->auth_md_context.method_name = method_name; + calld->auth_md_context.channel_auth_context = + GRPC_AUTH_CONTEXT_REF(auth_context, "grpc_auth_metadata_context"); + gpr_free(service); +} + +static void send_security_metadata(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + grpc_client_security_context *ctx = + (grpc_client_security_context *)op->context[GRPC_CONTEXT_SECURITY].value; + grpc_call_credentials *channel_call_creds = + chand->security_connector->request_metadata_creds; + int call_creds_has_md = (ctx != NULL) && (ctx->creds != NULL); + + if (channel_call_creds == NULL && !call_creds_has_md) { + /* Skip sending metadata altogether. */ + grpc_call_next_op(exec_ctx, elem, op); + return; + } + + if (channel_call_creds != NULL && call_creds_has_md) { + calld->creds = grpc_composite_call_credentials_create(channel_call_creds, + ctx->creds, NULL); + if (calld->creds == NULL) { + bubble_up_error(exec_ctx, elem, GRPC_STATUS_INVALID_ARGUMENT, + "Incompatible credentials set on channel and call."); + return; + } + } else { + calld->creds = grpc_call_credentials_ref( + call_creds_has_md ? ctx->creds : channel_call_creds); + } + + build_auth_metadata_context(&chand->security_connector->base, + chand->auth_context, calld); + calld->op = *op; /* Copy op (originates from the caller's stack). */ + GPR_ASSERT(calld->pollset); + grpc_call_credentials_get_request_metadata( + exec_ctx, calld->creds, calld->pollset, calld->auth_md_context, + on_credentials_metadata, elem); +} + +static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_security_status status) { + grpc_call_element *elem = (grpc_call_element *)user_data; + call_data *calld = elem->call_data; + + if (status == GRPC_SECURITY_OK) { + send_security_metadata(exec_ctx, elem, &calld->op); + } else { + char *error_msg; + gpr_asprintf(&error_msg, "Invalid host %s set in :authority metadata.", + grpc_mdstr_as_c_string(calld->host)); + bubble_up_error(exec_ctx, elem, GRPC_STATUS_INVALID_ARGUMENT, error_msg); + gpr_free(error_msg); + } +} + +/* Called either: + - in response to an API call (or similar) from above, to send something + - a network event (or similar) from below, to receive something + op contains type and call direction information, in addition to the data + that is being sent or received. */ +static void auth_start_transport_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + /* grab pointers to our data from the call element */ + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + grpc_linked_mdelem *l; + grpc_client_security_context *sec_ctx = NULL; + + if (calld->security_context_set == 0 && + op->cancel_with_status == GRPC_STATUS_OK) { + calld->security_context_set = 1; + GPR_ASSERT(op->context); + if (op->context[GRPC_CONTEXT_SECURITY].value == NULL) { + op->context[GRPC_CONTEXT_SECURITY].value = + grpc_client_security_context_create(); + op->context[GRPC_CONTEXT_SECURITY].destroy = + grpc_client_security_context_destroy; + } + sec_ctx = op->context[GRPC_CONTEXT_SECURITY].value; + GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter"); + sec_ctx->auth_context = + GRPC_AUTH_CONTEXT_REF(chand->auth_context, "client_auth_filter"); + } + + if (op->send_initial_metadata != NULL) { + for (l = op->send_initial_metadata->list.head; l != NULL; l = l->next) { + grpc_mdelem *md = l->md; + /* Pointer comparison is OK for md_elems created from the same context. + */ + if (md->key == GRPC_MDSTR_AUTHORITY) { + if (calld->host != NULL) GRPC_MDSTR_UNREF(calld->host); + calld->host = GRPC_MDSTR_REF(md->value); + } else if (md->key == GRPC_MDSTR_PATH) { + if (calld->method != NULL) GRPC_MDSTR_UNREF(calld->method); + calld->method = GRPC_MDSTR_REF(md->value); + } + } + if (calld->host != NULL) { + const char *call_host = grpc_mdstr_as_c_string(calld->host); + calld->op = *op; /* Copy op (originates from the caller's stack). */ + grpc_channel_security_connector_check_call_host( + exec_ctx, chand->security_connector, call_host, chand->auth_context, + on_host_checked, elem); + return; /* early exit */ + } + } + + /* pass control down the stack */ + grpc_call_next_op(exec_ctx, elem, op); +} + +/* Constructor for call_data */ +static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args) { + call_data *calld = elem->call_data; + memset(calld, 0, sizeof(*calld)); +} + +static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_pollset *pollset) { + call_data *calld = elem->call_data; + calld->pollset = pollset; +} + +/* Destructor for call_data */ +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + call_data *calld = elem->call_data; + grpc_call_credentials_unref(calld->creds); + if (calld->host != NULL) { + GRPC_MDSTR_UNREF(calld->host); + } + if (calld->method != NULL) { + GRPC_MDSTR_UNREF(calld->method); + } + reset_auth_metadata_context(&calld->auth_md_context); +} + +/* Constructor for channel_data */ +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + grpc_security_connector *sc = + grpc_find_security_connector_in_args(args->channel_args); + grpc_auth_context *auth_context = + grpc_find_auth_context_in_args(args->channel_args); + + /* grab pointers to our data from the channel element */ + channel_data *chand = elem->channel_data; + + /* The first and the last filters tend to be implemented differently to + handle the case that there's no 'next' filter to call on the up or down + path */ + GPR_ASSERT(!args->is_last); + GPR_ASSERT(sc != NULL); + GPR_ASSERT(auth_context != NULL); + + /* initialize members */ + chand->security_connector = + (grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF( + sc, "client_auth_filter"); + chand->auth_context = + GRPC_AUTH_CONTEXT_REF(auth_context, "client_auth_filter"); +} + +/* Destructor for channel data */ +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) { + /* grab pointers to our data from the channel element */ + channel_data *chand = elem->channel_data; + grpc_channel_security_connector *sc = chand->security_connector; + if (sc != NULL) { + GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "client_auth_filter"); + } + GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter"); +} + +const grpc_channel_filter grpc_client_auth_filter = { + auth_start_transport_op, grpc_channel_next_op, sizeof(call_data), + init_call_elem, set_pollset, destroy_call_elem, + sizeof(channel_data), init_channel_elem, destroy_channel_elem, + grpc_call_next_get_peer, "client-auth"}; diff --git a/src/core/lib/security/credentials.c b/src/core/lib/security/credentials.c new file mode 100644 index 0000000000..c8348bc12c --- /dev/null +++ b/src/core/lib/security/credentials.c @@ -0,0 +1,1281 @@ +/* + * + * Copyright 2015-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/security/credentials.h" + +#include +#include + +#include "src/core/channel/channel_args.h" +#include "src/core/channel/http_client_filter.h" +#include "src/core/http/httpcli.h" +#include "src/core/http/parser.h" +#include "src/core/iomgr/executor.h" +#include "src/core/json/json.h" +#include "src/core/support/string.h" +#include "src/core/surface/api_trace.h" + +#include +#include +#include +#include +#include + +/* -- Common. -- */ + +struct grpc_credentials_metadata_request { + grpc_call_credentials *creds; + grpc_credentials_metadata_cb cb; + void *user_data; +}; + +static grpc_credentials_metadata_request * +grpc_credentials_metadata_request_create(grpc_call_credentials *creds, + grpc_credentials_metadata_cb cb, + void *user_data) { + grpc_credentials_metadata_request *r = + gpr_malloc(sizeof(grpc_credentials_metadata_request)); + r->creds = grpc_call_credentials_ref(creds); + r->cb = cb; + r->user_data = user_data; + return r; +} + +static void grpc_credentials_metadata_request_destroy( + grpc_credentials_metadata_request *r) { + grpc_call_credentials_unref(r->creds); + gpr_free(r); +} + +grpc_channel_credentials *grpc_channel_credentials_ref( + grpc_channel_credentials *creds) { + if (creds == NULL) return NULL; + gpr_ref(&creds->refcount); + return creds; +} + +void grpc_channel_credentials_unref(grpc_channel_credentials *creds) { + if (creds == NULL) return; + if (gpr_unref(&creds->refcount)) { + if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds); + gpr_free(creds); + } +} + +void grpc_channel_credentials_release(grpc_channel_credentials *creds) { + GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds)); + grpc_channel_credentials_unref(creds); +} + +grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds) { + if (creds == NULL) return NULL; + gpr_ref(&creds->refcount); + return creds; +} + +void grpc_call_credentials_unref(grpc_call_credentials *creds) { + if (creds == NULL) return; + if (gpr_unref(&creds->refcount)) { + if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds); + gpr_free(creds); + } +} + +void grpc_call_credentials_release(grpc_call_credentials *creds) { + GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds)); + grpc_call_credentials_unref(creds); +} + +void grpc_call_credentials_get_request_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, void *user_data) { + if (creds == NULL || creds->vtable->get_request_metadata == NULL) { + if (cb != NULL) { + cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK); + } + return; + } + creds->vtable->get_request_metadata(exec_ctx, creds, pollset, context, cb, + user_data); +} + +grpc_security_status grpc_channel_credentials_create_security_connector( + grpc_channel_credentials *channel_creds, const char *target, + const grpc_channel_args *args, grpc_channel_security_connector **sc, + grpc_channel_args **new_args) { + *new_args = NULL; + if (channel_creds == NULL) { + return GRPC_SECURITY_ERROR; + } + GPR_ASSERT(channel_creds->vtable->create_security_connector != NULL); + return channel_creds->vtable->create_security_connector( + channel_creds, NULL, target, args, sc, new_args); +} + +grpc_server_credentials *grpc_server_credentials_ref( + grpc_server_credentials *creds) { + if (creds == NULL) return NULL; + gpr_ref(&creds->refcount); + return creds; +} + +void grpc_server_credentials_unref(grpc_server_credentials *creds) { + if (creds == NULL) return; + if (gpr_unref(&creds->refcount)) { + if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds); + if (creds->processor.destroy != NULL && creds->processor.state != NULL) { + creds->processor.destroy(creds->processor.state); + } + gpr_free(creds); + } +} + +void grpc_server_credentials_release(grpc_server_credentials *creds) { + GRPC_API_TRACE("grpc_server_credentials_release(creds=%p)", 1, (creds)); + grpc_server_credentials_unref(creds); +} + +grpc_security_status grpc_server_credentials_create_security_connector( + grpc_server_credentials *creds, grpc_server_security_connector **sc) { + if (creds == NULL || creds->vtable->create_security_connector == NULL) { + gpr_log(GPR_ERROR, "Server credentials cannot create security context."); + return GRPC_SECURITY_ERROR; + } + return creds->vtable->create_security_connector(creds, sc); +} + +void grpc_server_credentials_set_auth_metadata_processor( + grpc_server_credentials *creds, grpc_auth_metadata_processor processor) { + GRPC_API_TRACE( + "grpc_server_credentials_set_auth_metadata_processor(" + "creds=%p, " + "processor=grpc_auth_metadata_processor { process: %p, state: %p })", + 3, (creds, (void *)(intptr_t)processor.process, processor.state)); + if (creds == NULL) return; + if (creds->processor.destroy != NULL && creds->processor.state != NULL) { + creds->processor.destroy(creds->processor.state); + } + creds->processor = processor; +} + +static void server_credentials_pointer_arg_destroy(void *p) { + grpc_server_credentials_unref(p); +} + +static void *server_credentials_pointer_arg_copy(void *p) { + return grpc_server_credentials_ref(p); +} + +static int server_credentials_pointer_cmp(void *a, void *b) { + return GPR_ICMP(a, b); +} + +static const grpc_arg_pointer_vtable cred_ptr_vtable = { + server_credentials_pointer_arg_copy, server_credentials_pointer_arg_destroy, + server_credentials_pointer_cmp}; + +grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *p) { + grpc_arg arg; + memset(&arg, 0, sizeof(grpc_arg)); + arg.type = GRPC_ARG_POINTER; + arg.key = GRPC_SERVER_CREDENTIALS_ARG; + arg.value.pointer.p = p; + arg.value.pointer.vtable = &cred_ptr_vtable; + return arg; +} + +grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg) { + if (strcmp(arg->key, GRPC_SERVER_CREDENTIALS_ARG) != 0) return NULL; + if (arg->type != GRPC_ARG_POINTER) { + gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, + GRPC_SERVER_CREDENTIALS_ARG); + return NULL; + } + return arg->value.pointer.p; +} + +grpc_server_credentials *grpc_find_server_credentials_in_args( + const grpc_channel_args *args) { + size_t i; + if (args == NULL) return NULL; + for (i = 0; i < args->num_args; i++) { + grpc_server_credentials *p = + grpc_server_credentials_from_arg(&args->args[i]); + if (p != NULL) return p; + } + return NULL; +} + +/* -- Ssl credentials. -- */ + +static void ssl_destruct(grpc_channel_credentials *creds) { + grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds; + if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs); + if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key); + if (c->config.pem_cert_chain != NULL) gpr_free(c->config.pem_cert_chain); +} + +static void ssl_server_destruct(grpc_server_credentials *creds) { + grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds; + size_t i; + for (i = 0; i < c->config.num_key_cert_pairs; i++) { + if (c->config.pem_private_keys[i] != NULL) { + gpr_free(c->config.pem_private_keys[i]); + } + if (c->config.pem_cert_chains[i] != NULL) { + gpr_free(c->config.pem_cert_chains[i]); + } + } + if (c->config.pem_private_keys != NULL) gpr_free(c->config.pem_private_keys); + if (c->config.pem_private_keys_sizes != NULL) { + gpr_free(c->config.pem_private_keys_sizes); + } + if (c->config.pem_cert_chains != NULL) gpr_free(c->config.pem_cert_chains); + if (c->config.pem_cert_chains_sizes != NULL) { + gpr_free(c->config.pem_cert_chains_sizes); + } + if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs); +} + +static grpc_security_status ssl_create_security_connector( + grpc_channel_credentials *creds, grpc_call_credentials *call_creds, + const char *target, const grpc_channel_args *args, + grpc_channel_security_connector **sc, grpc_channel_args **new_args) { + grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds; + grpc_security_status status = GRPC_SECURITY_OK; + size_t i = 0; + const char *overridden_target_name = NULL; + grpc_arg new_arg; + + for (i = 0; args && i < args->num_args; i++) { + grpc_arg *arg = &args->args[i]; + if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 && + arg->type == GRPC_ARG_STRING) { + overridden_target_name = arg->value.string; + break; + } + } + status = grpc_ssl_channel_security_connector_create( + call_creds, &c->config, target, overridden_target_name, sc); + if (status != GRPC_SECURITY_OK) { + return status; + } + new_arg.type = GRPC_ARG_STRING; + new_arg.key = GRPC_ARG_HTTP2_SCHEME; + new_arg.value.string = "https"; + *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1); + return status; +} + +static grpc_security_status ssl_server_create_security_connector( + grpc_server_credentials *creds, grpc_server_security_connector **sc) { + grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds; + return grpc_ssl_server_security_connector_create(&c->config, sc); +} + +static grpc_channel_credentials_vtable ssl_vtable = { + ssl_destruct, ssl_create_security_connector}; + +static grpc_server_credentials_vtable ssl_server_vtable = { + ssl_server_destruct, ssl_server_create_security_connector}; + +static void ssl_copy_key_material(const char *input, unsigned char **output, + size_t *output_size) { + *output_size = strlen(input); + *output = gpr_malloc(*output_size); + memcpy(*output, input, *output_size); +} + +static void ssl_build_config(const char *pem_root_certs, + grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, + grpc_ssl_config *config) { + if (pem_root_certs != NULL) { + ssl_copy_key_material(pem_root_certs, &config->pem_root_certs, + &config->pem_root_certs_size); + } + if (pem_key_cert_pair != NULL) { + GPR_ASSERT(pem_key_cert_pair->private_key != NULL); + GPR_ASSERT(pem_key_cert_pair->cert_chain != NULL); + ssl_copy_key_material(pem_key_cert_pair->private_key, + &config->pem_private_key, + &config->pem_private_key_size); + ssl_copy_key_material(pem_key_cert_pair->cert_chain, + &config->pem_cert_chain, + &config->pem_cert_chain_size); + } +} + +static void ssl_build_server_config( + const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, + size_t num_key_cert_pairs, int force_client_auth, + grpc_ssl_server_config *config) { + size_t i; + config->force_client_auth = force_client_auth; + if (pem_root_certs != NULL) { + ssl_copy_key_material(pem_root_certs, &config->pem_root_certs, + &config->pem_root_certs_size); + } + if (num_key_cert_pairs > 0) { + GPR_ASSERT(pem_key_cert_pairs != NULL); + config->pem_private_keys = + gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *)); + config->pem_cert_chains = + gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *)); + config->pem_private_keys_sizes = + gpr_malloc(num_key_cert_pairs * sizeof(size_t)); + config->pem_cert_chains_sizes = + gpr_malloc(num_key_cert_pairs * sizeof(size_t)); + } + config->num_key_cert_pairs = num_key_cert_pairs; + for (i = 0; i < num_key_cert_pairs; i++) { + GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL); + GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL); + ssl_copy_key_material(pem_key_cert_pairs[i].private_key, + &config->pem_private_keys[i], + &config->pem_private_keys_sizes[i]); + ssl_copy_key_material(pem_key_cert_pairs[i].cert_chain, + &config->pem_cert_chains[i], + &config->pem_cert_chains_sizes[i]); + } +} + +grpc_channel_credentials *grpc_ssl_credentials_create( + const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, + void *reserved) { + grpc_ssl_credentials *c = gpr_malloc(sizeof(grpc_ssl_credentials)); + GRPC_API_TRACE( + "grpc_ssl_credentials_create(pem_root_certs=%s, " + "pem_key_cert_pair=%p, " + "reserved=%p)", + 3, (pem_root_certs, pem_key_cert_pair, reserved)); + GPR_ASSERT(reserved == NULL); + memset(c, 0, sizeof(grpc_ssl_credentials)); + c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; + c->base.vtable = &ssl_vtable; + gpr_ref_init(&c->base.refcount, 1); + ssl_build_config(pem_root_certs, pem_key_cert_pair, &c->config); + return &c->base; +} + +grpc_server_credentials *grpc_ssl_server_credentials_create( + const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, + size_t num_key_cert_pairs, int force_client_auth, void *reserved) { + grpc_ssl_server_credentials *c = + gpr_malloc(sizeof(grpc_ssl_server_credentials)); + GRPC_API_TRACE( + "grpc_ssl_server_credentials_create(" + "pem_root_certs=%s, pem_key_cert_pairs=%p, num_key_cert_pairs=%lu, " + "force_client_auth=%d, reserved=%p)", + 5, (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs, + force_client_auth, reserved)); + GPR_ASSERT(reserved == NULL); + memset(c, 0, sizeof(grpc_ssl_server_credentials)); + c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; + gpr_ref_init(&c->base.refcount, 1); + c->base.vtable = &ssl_server_vtable; + ssl_build_server_config(pem_root_certs, pem_key_cert_pairs, + num_key_cert_pairs, force_client_auth, &c->config); + return &c->base; +} + +/* -- Jwt credentials -- */ + +static void jwt_reset_cache(grpc_service_account_jwt_access_credentials *c) { + if (c->cached.jwt_md != NULL) { + grpc_credentials_md_store_unref(c->cached.jwt_md); + c->cached.jwt_md = NULL; + } + if (c->cached.service_url != NULL) { + gpr_free(c->cached.service_url); + c->cached.service_url = NULL; + } + c->cached.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); +} + +static void jwt_destruct(grpc_call_credentials *creds) { + grpc_service_account_jwt_access_credentials *c = + (grpc_service_account_jwt_access_credentials *)creds; + grpc_auth_json_key_destruct(&c->key); + jwt_reset_cache(c); + gpr_mu_destroy(&c->cache_mu); +} + +static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx, + grpc_call_credentials *creds, + grpc_pollset *pollset, + grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, + void *user_data) { + grpc_service_account_jwt_access_credentials *c = + (grpc_service_account_jwt_access_credentials *)creds; + gpr_timespec refresh_threshold = gpr_time_from_seconds( + GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN); + + /* See if we can return a cached jwt. */ + grpc_credentials_md_store *jwt_md = NULL; + { + gpr_mu_lock(&c->cache_mu); + if (c->cached.service_url != NULL && + strcmp(c->cached.service_url, context.service_url) == 0 && + c->cached.jwt_md != NULL && + (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, + gpr_now(GPR_CLOCK_REALTIME)), + refresh_threshold) > 0)) { + jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md); + } + gpr_mu_unlock(&c->cache_mu); + } + + if (jwt_md == NULL) { + char *jwt = NULL; + /* Generate a new jwt. */ + gpr_mu_lock(&c->cache_mu); + jwt_reset_cache(c); + jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url, + c->jwt_lifetime, NULL); + if (jwt != NULL) { + char *md_value; + gpr_asprintf(&md_value, "Bearer %s", jwt); + gpr_free(jwt); + c->cached.jwt_expiration = + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime); + c->cached.service_url = gpr_strdup(context.service_url); + c->cached.jwt_md = grpc_credentials_md_store_create(1); + grpc_credentials_md_store_add_cstrings( + c->cached.jwt_md, GRPC_AUTHORIZATION_METADATA_KEY, md_value); + gpr_free(md_value); + jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md); + } + gpr_mu_unlock(&c->cache_mu); + } + + if (jwt_md != NULL) { + cb(exec_ctx, user_data, jwt_md->entries, jwt_md->num_entries, + GRPC_CREDENTIALS_OK); + grpc_credentials_md_store_unref(jwt_md); + } else { + cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_ERROR); + } +} + +static grpc_call_credentials_vtable jwt_vtable = {jwt_destruct, + jwt_get_request_metadata}; + +grpc_call_credentials * +grpc_service_account_jwt_access_credentials_create_from_auth_json_key( + grpc_auth_json_key key, gpr_timespec token_lifetime) { + grpc_service_account_jwt_access_credentials *c; + if (!grpc_auth_json_key_is_valid(&key)) { + gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation"); + return NULL; + } + c = gpr_malloc(sizeof(grpc_service_account_jwt_access_credentials)); + memset(c, 0, sizeof(grpc_service_account_jwt_access_credentials)); + c->base.type = GRPC_CALL_CREDENTIALS_TYPE_JWT; + gpr_ref_init(&c->base.refcount, 1); + c->base.vtable = &jwt_vtable; + c->key = key; + c->jwt_lifetime = token_lifetime; + gpr_mu_init(&c->cache_mu); + jwt_reset_cache(c); + return &c->base; +} + +grpc_call_credentials *grpc_service_account_jwt_access_credentials_create( + const char *json_key, gpr_timespec token_lifetime, void *reserved) { + GRPC_API_TRACE( + "grpc_service_account_jwt_access_credentials_create(" + "json_key=%s, " + "token_lifetime=" + "gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " + "reserved=%p)", + 5, + (json_key, (long long)token_lifetime.tv_sec, (int)token_lifetime.tv_nsec, + (int)token_lifetime.clock_type, reserved)); + GPR_ASSERT(reserved == NULL); + return grpc_service_account_jwt_access_credentials_create_from_auth_json_key( + grpc_auth_json_key_create_from_string(json_key), token_lifetime); +} + +/* -- Oauth2TokenFetcher credentials -- */ + +static void oauth2_token_fetcher_destruct(grpc_call_credentials *creds) { + grpc_oauth2_token_fetcher_credentials *c = + (grpc_oauth2_token_fetcher_credentials *)creds; + grpc_credentials_md_store_unref(c->access_token_md); + gpr_mu_destroy(&c->mu); + grpc_httpcli_context_destroy(&c->httpcli_context); +} + +grpc_credentials_status +grpc_oauth2_token_fetcher_credentials_parse_server_response( + const grpc_http_response *response, grpc_credentials_md_store **token_md, + gpr_timespec *token_lifetime) { + char *null_terminated_body = NULL; + char *new_access_token = NULL; + grpc_credentials_status status = GRPC_CREDENTIALS_OK; + grpc_json *json = NULL; + + if (response == NULL) { + gpr_log(GPR_ERROR, "Received NULL response."); + status = GRPC_CREDENTIALS_ERROR; + goto end; + } + + if (response->body_length > 0) { + null_terminated_body = gpr_malloc(response->body_length + 1); + null_terminated_body[response->body_length] = '\0'; + memcpy(null_terminated_body, response->body, response->body_length); + } + + if (response->status != 200) { + gpr_log(GPR_ERROR, "Call to http server ended with error %d [%s].", + response->status, + null_terminated_body != NULL ? null_terminated_body : ""); + status = GRPC_CREDENTIALS_ERROR; + goto end; + } else { + grpc_json *access_token = NULL; + grpc_json *token_type = NULL; + grpc_json *expires_in = NULL; + grpc_json *ptr; + json = grpc_json_parse_string(null_terminated_body); + if (json == NULL) { + gpr_log(GPR_ERROR, "Could not parse JSON from %s", null_terminated_body); + status = GRPC_CREDENTIALS_ERROR; + goto end; + } + if (json->type != GRPC_JSON_OBJECT) { + gpr_log(GPR_ERROR, "Response should be a JSON object"); + status = GRPC_CREDENTIALS_ERROR; + goto end; + } + for (ptr = json->child; ptr; ptr = ptr->next) { + if (strcmp(ptr->key, "access_token") == 0) { + access_token = ptr; + } else if (strcmp(ptr->key, "token_type") == 0) { + token_type = ptr; + } else if (strcmp(ptr->key, "expires_in") == 0) { + expires_in = ptr; + } + } + if (access_token == NULL || access_token->type != GRPC_JSON_STRING) { + gpr_log(GPR_ERROR, "Missing or invalid access_token in JSON."); + status = GRPC_CREDENTIALS_ERROR; + goto end; + } + if (token_type == NULL || token_type->type != GRPC_JSON_STRING) { + gpr_log(GPR_ERROR, "Missing or invalid token_type in JSON."); + status = GRPC_CREDENTIALS_ERROR; + goto end; + } + if (expires_in == NULL || expires_in->type != GRPC_JSON_NUMBER) { + gpr_log(GPR_ERROR, "Missing or invalid expires_in in JSON."); + status = GRPC_CREDENTIALS_ERROR; + goto end; + } + gpr_asprintf(&new_access_token, "%s %s", token_type->value, + access_token->value); + token_lifetime->tv_sec = strtol(expires_in->value, NULL, 10); + token_lifetime->tv_nsec = 0; + token_lifetime->clock_type = GPR_TIMESPAN; + if (*token_md != NULL) grpc_credentials_md_store_unref(*token_md); + *token_md = grpc_credentials_md_store_create(1); + grpc_credentials_md_store_add_cstrings( + *token_md, GRPC_AUTHORIZATION_METADATA_KEY, new_access_token); + status = GRPC_CREDENTIALS_OK; + } + +end: + if (status != GRPC_CREDENTIALS_OK && (*token_md != NULL)) { + grpc_credentials_md_store_unref(*token_md); + *token_md = NULL; + } + if (null_terminated_body != NULL) gpr_free(null_terminated_body); + if (new_access_token != NULL) gpr_free(new_access_token); + if (json != NULL) grpc_json_destroy(json); + return status; +} + +static void on_oauth2_token_fetcher_http_response( + grpc_exec_ctx *exec_ctx, void *user_data, + const grpc_http_response *response) { + grpc_credentials_metadata_request *r = + (grpc_credentials_metadata_request *)user_data; + grpc_oauth2_token_fetcher_credentials *c = + (grpc_oauth2_token_fetcher_credentials *)r->creds; + gpr_timespec token_lifetime; + grpc_credentials_status status; + + gpr_mu_lock(&c->mu); + status = grpc_oauth2_token_fetcher_credentials_parse_server_response( + response, &c->access_token_md, &token_lifetime); + if (status == GRPC_CREDENTIALS_OK) { + c->token_expiration = + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), token_lifetime); + r->cb(exec_ctx, r->user_data, c->access_token_md->entries, + c->access_token_md->num_entries, status); + } else { + c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); + r->cb(exec_ctx, r->user_data, NULL, 0, status); + } + gpr_mu_unlock(&c->mu); + grpc_credentials_metadata_request_destroy(r); +} + +static void oauth2_token_fetcher_get_request_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, void *user_data) { + grpc_oauth2_token_fetcher_credentials *c = + (grpc_oauth2_token_fetcher_credentials *)creds; + gpr_timespec refresh_threshold = gpr_time_from_seconds( + GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN); + grpc_credentials_md_store *cached_access_token_md = NULL; + { + gpr_mu_lock(&c->mu); + if (c->access_token_md != NULL && + (gpr_time_cmp( + gpr_time_sub(c->token_expiration, gpr_now(GPR_CLOCK_REALTIME)), + refresh_threshold) > 0)) { + cached_access_token_md = + grpc_credentials_md_store_ref(c->access_token_md); + } + gpr_mu_unlock(&c->mu); + } + if (cached_access_token_md != NULL) { + cb(exec_ctx, user_data, cached_access_token_md->entries, + cached_access_token_md->num_entries, GRPC_CREDENTIALS_OK); + grpc_credentials_md_store_unref(cached_access_token_md); + } else { + c->fetch_func( + exec_ctx, + grpc_credentials_metadata_request_create(creds, cb, user_data), + &c->httpcli_context, pollset, on_oauth2_token_fetcher_http_response, + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), refresh_threshold)); + } +} + +static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials *c, + grpc_fetch_oauth2_func fetch_func) { + memset(c, 0, sizeof(grpc_oauth2_token_fetcher_credentials)); + c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; + gpr_ref_init(&c->base.refcount, 1); + gpr_mu_init(&c->mu); + c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); + c->fetch_func = fetch_func; + grpc_httpcli_context_init(&c->httpcli_context); +} + +/* -- GoogleComputeEngine credentials. -- */ + +static grpc_call_credentials_vtable compute_engine_vtable = { + oauth2_token_fetcher_destruct, oauth2_token_fetcher_get_request_metadata}; + +static void compute_engine_fetch_oauth2( + grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req, + grpc_httpcli_context *httpcli_context, grpc_pollset *pollset, + grpc_httpcli_response_cb response_cb, gpr_timespec deadline) { + grpc_http_header header = {"Metadata-Flavor", "Google"}; + grpc_httpcli_request request; + memset(&request, 0, sizeof(grpc_httpcli_request)); + request.host = GRPC_COMPUTE_ENGINE_METADATA_HOST; + request.http.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH; + request.http.hdr_count = 1; + request.http.hdrs = &header; + grpc_httpcli_get(exec_ctx, httpcli_context, pollset, &request, deadline, + response_cb, metadata_req); +} + +grpc_call_credentials *grpc_google_compute_engine_credentials_create( + void *reserved) { + grpc_oauth2_token_fetcher_credentials *c = + gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials)); + GRPC_API_TRACE("grpc_compute_engine_credentials_create(reserved=%p)", 1, + (reserved)); + GPR_ASSERT(reserved == NULL); + init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2); + c->base.vtable = &compute_engine_vtable; + return &c->base; +} + +/* -- GoogleRefreshToken credentials. -- */ + +static void refresh_token_destruct(grpc_call_credentials *creds) { + grpc_google_refresh_token_credentials *c = + (grpc_google_refresh_token_credentials *)creds; + grpc_auth_refresh_token_destruct(&c->refresh_token); + oauth2_token_fetcher_destruct(&c->base.base); +} + +static grpc_call_credentials_vtable refresh_token_vtable = { + refresh_token_destruct, oauth2_token_fetcher_get_request_metadata}; + +static void refresh_token_fetch_oauth2( + grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req, + grpc_httpcli_context *httpcli_context, grpc_pollset *pollset, + grpc_httpcli_response_cb response_cb, gpr_timespec deadline) { + grpc_google_refresh_token_credentials *c = + (grpc_google_refresh_token_credentials *)metadata_req->creds; + grpc_http_header header = {"Content-Type", + "application/x-www-form-urlencoded"}; + grpc_httpcli_request request; + char *body = NULL; + gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING, + c->refresh_token.client_id, c->refresh_token.client_secret, + c->refresh_token.refresh_token); + memset(&request, 0, sizeof(grpc_httpcli_request)); + request.host = GRPC_GOOGLE_OAUTH2_SERVICE_HOST; + request.http.path = GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH; + request.http.hdr_count = 1; + request.http.hdrs = &header; + request.handshaker = &grpc_httpcli_ssl; + grpc_httpcli_post(exec_ctx, httpcli_context, pollset, &request, body, + strlen(body), deadline, response_cb, metadata_req); + gpr_free(body); +} + +grpc_call_credentials * +grpc_refresh_token_credentials_create_from_auth_refresh_token( + grpc_auth_refresh_token refresh_token) { + grpc_google_refresh_token_credentials *c; + if (!grpc_auth_refresh_token_is_valid(&refresh_token)) { + gpr_log(GPR_ERROR, "Invalid input for refresh token credentials creation"); + return NULL; + } + c = gpr_malloc(sizeof(grpc_google_refresh_token_credentials)); + memset(c, 0, sizeof(grpc_google_refresh_token_credentials)); + init_oauth2_token_fetcher(&c->base, refresh_token_fetch_oauth2); + c->base.base.vtable = &refresh_token_vtable; + c->refresh_token = refresh_token; + return &c->base.base; +} + +grpc_call_credentials *grpc_google_refresh_token_credentials_create( + const char *json_refresh_token, void *reserved) { + GRPC_API_TRACE( + "grpc_refresh_token_credentials_create(json_refresh_token=%s, " + "reserved=%p)", + 2, (json_refresh_token, reserved)); + GPR_ASSERT(reserved == NULL); + return grpc_refresh_token_credentials_create_from_auth_refresh_token( + grpc_auth_refresh_token_create_from_string(json_refresh_token)); +} + +/* -- Metadata-only credentials. -- */ + +static void md_only_test_destruct(grpc_call_credentials *creds) { + grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds; + grpc_credentials_md_store_unref(c->md_store); +} + +static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx, + void *user_data, bool success) { + grpc_credentials_metadata_request *r = + (grpc_credentials_metadata_request *)user_data; + grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)r->creds; + r->cb(exec_ctx, r->user_data, c->md_store->entries, c->md_store->num_entries, + GRPC_CREDENTIALS_OK); + grpc_credentials_metadata_request_destroy(r); +} + +static void md_only_test_get_request_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, void *user_data) { + grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds; + + if (c->is_async) { + grpc_credentials_metadata_request *cb_arg = + grpc_credentials_metadata_request_create(creds, cb, user_data); + grpc_executor_enqueue( + grpc_closure_create(on_simulated_token_fetch_done, cb_arg), true); + } else { + cb(exec_ctx, user_data, c->md_store->entries, 1, GRPC_CREDENTIALS_OK); + } +} + +static grpc_call_credentials_vtable md_only_test_vtable = { + md_only_test_destruct, md_only_test_get_request_metadata}; + +grpc_call_credentials *grpc_md_only_test_credentials_create( + const char *md_key, const char *md_value, int is_async) { + grpc_md_only_test_credentials *c = + gpr_malloc(sizeof(grpc_md_only_test_credentials)); + memset(c, 0, sizeof(grpc_md_only_test_credentials)); + c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; + c->base.vtable = &md_only_test_vtable; + gpr_ref_init(&c->base.refcount, 1); + c->md_store = grpc_credentials_md_store_create(1); + grpc_credentials_md_store_add_cstrings(c->md_store, md_key, md_value); + c->is_async = is_async; + return &c->base; +} + +/* -- Oauth2 Access Token credentials. -- */ + +static void access_token_destruct(grpc_call_credentials *creds) { + grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds; + grpc_credentials_md_store_unref(c->access_token_md); +} + +static void access_token_get_request_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, void *user_data) { + grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds; + cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK); +} + +static grpc_call_credentials_vtable access_token_vtable = { + access_token_destruct, access_token_get_request_metadata}; + +grpc_call_credentials *grpc_access_token_credentials_create( + const char *access_token, void *reserved) { + grpc_access_token_credentials *c = + gpr_malloc(sizeof(grpc_access_token_credentials)); + char *token_md_value; + GRPC_API_TRACE( + "grpc_access_token_credentials_create(access_token=%s, " + "reserved=%p)", + 2, (access_token, reserved)); + GPR_ASSERT(reserved == NULL); + memset(c, 0, sizeof(grpc_access_token_credentials)); + c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; + c->base.vtable = &access_token_vtable; + gpr_ref_init(&c->base.refcount, 1); + c->access_token_md = grpc_credentials_md_store_create(1); + gpr_asprintf(&token_md_value, "Bearer %s", access_token); + grpc_credentials_md_store_add_cstrings( + c->access_token_md, GRPC_AUTHORIZATION_METADATA_KEY, token_md_value); + gpr_free(token_md_value); + return &c->base; +} + +/* -- Fake transport security credentials. -- */ + +static grpc_security_status fake_transport_security_create_security_connector( + grpc_channel_credentials *c, grpc_call_credentials *call_creds, + const char *target, const grpc_channel_args *args, + grpc_channel_security_connector **sc, grpc_channel_args **new_args) { + *sc = grpc_fake_channel_security_connector_create(call_creds); + return GRPC_SECURITY_OK; +} + +static grpc_security_status +fake_transport_security_server_create_security_connector( + grpc_server_credentials *c, grpc_server_security_connector **sc) { + *sc = grpc_fake_server_security_connector_create(); + return GRPC_SECURITY_OK; +} + +static grpc_channel_credentials_vtable + fake_transport_security_credentials_vtable = { + NULL, fake_transport_security_create_security_connector}; + +static grpc_server_credentials_vtable + fake_transport_security_server_credentials_vtable = { + NULL, fake_transport_security_server_create_security_connector}; + +grpc_channel_credentials *grpc_fake_transport_security_credentials_create( + void) { + grpc_channel_credentials *c = gpr_malloc(sizeof(grpc_channel_credentials)); + memset(c, 0, sizeof(grpc_channel_credentials)); + c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY; + c->vtable = &fake_transport_security_credentials_vtable; + gpr_ref_init(&c->refcount, 1); + return c; +} + +grpc_server_credentials *grpc_fake_transport_security_server_credentials_create( + void) { + grpc_server_credentials *c = gpr_malloc(sizeof(grpc_server_credentials)); + memset(c, 0, sizeof(grpc_server_credentials)); + c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY; + gpr_ref_init(&c->refcount, 1); + c->vtable = &fake_transport_security_server_credentials_vtable; + return c; +} + +/* -- Composite call credentials. -- */ + +typedef struct { + grpc_composite_call_credentials *composite_creds; + size_t creds_index; + grpc_credentials_md_store *md_elems; + grpc_auth_metadata_context auth_md_context; + void *user_data; + grpc_pollset *pollset; + grpc_credentials_metadata_cb cb; +} grpc_composite_call_credentials_metadata_context; + +static void composite_call_destruct(grpc_call_credentials *creds) { + grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds; + size_t i; + for (i = 0; i < c->inner.num_creds; i++) { + grpc_call_credentials_unref(c->inner.creds_array[i]); + } + gpr_free(c->inner.creds_array); +} + +static void composite_call_md_context_destroy( + grpc_composite_call_credentials_metadata_context *ctx) { + grpc_credentials_md_store_unref(ctx->md_elems); + gpr_free(ctx); +} + +static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_credentials_md *md_elems, + size_t num_md, + grpc_credentials_status status) { + grpc_composite_call_credentials_metadata_context *ctx = + (grpc_composite_call_credentials_metadata_context *)user_data; + if (status != GRPC_CREDENTIALS_OK) { + ctx->cb(exec_ctx, ctx->user_data, NULL, 0, status); + return; + } + + /* Copy the metadata in the context. */ + if (num_md > 0) { + size_t i; + for (i = 0; i < num_md; i++) { + grpc_credentials_md_store_add(ctx->md_elems, md_elems[i].key, + md_elems[i].value); + } + } + + /* See if we need to get some more metadata. */ + if (ctx->creds_index < ctx->composite_creds->inner.num_creds) { + grpc_call_credentials *inner_creds = + ctx->composite_creds->inner.creds_array[ctx->creds_index++]; + grpc_call_credentials_get_request_metadata( + exec_ctx, inner_creds, ctx->pollset, ctx->auth_md_context, + composite_call_metadata_cb, ctx); + return; + } + + /* We're done!. */ + ctx->cb(exec_ctx, ctx->user_data, ctx->md_elems->entries, + ctx->md_elems->num_entries, GRPC_CREDENTIALS_OK); + composite_call_md_context_destroy(ctx); +} + +static void composite_call_get_request_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context auth_md_context, + grpc_credentials_metadata_cb cb, void *user_data) { + grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds; + grpc_composite_call_credentials_metadata_context *ctx; + + ctx = gpr_malloc(sizeof(grpc_composite_call_credentials_metadata_context)); + memset(ctx, 0, sizeof(grpc_composite_call_credentials_metadata_context)); + ctx->auth_md_context = auth_md_context; + ctx->user_data = user_data; + ctx->cb = cb; + ctx->composite_creds = c; + ctx->pollset = pollset; + ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds); + grpc_call_credentials_get_request_metadata( + exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset, + auth_md_context, composite_call_metadata_cb, ctx); +} + +static grpc_call_credentials_vtable composite_call_credentials_vtable = { + composite_call_destruct, composite_call_get_request_metadata}; + +static grpc_call_credentials_array get_creds_array( + grpc_call_credentials **creds_addr) { + grpc_call_credentials_array result; + grpc_call_credentials *creds = *creds_addr; + result.creds_array = creds_addr; + result.num_creds = 1; + if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) { + result = *grpc_composite_call_credentials_get_credentials(creds); + } + return result; +} + +grpc_call_credentials *grpc_composite_call_credentials_create( + grpc_call_credentials *creds1, grpc_call_credentials *creds2, + void *reserved) { + size_t i; + size_t creds_array_byte_size; + grpc_call_credentials_array creds1_array; + grpc_call_credentials_array creds2_array; + grpc_composite_call_credentials *c; + GRPC_API_TRACE( + "grpc_composite_call_credentials_create(creds1=%p, creds2=%p, " + "reserved=%p)", + 3, (creds1, creds2, reserved)); + GPR_ASSERT(reserved == NULL); + GPR_ASSERT(creds1 != NULL); + GPR_ASSERT(creds2 != NULL); + c = gpr_malloc(sizeof(grpc_composite_call_credentials)); + memset(c, 0, sizeof(grpc_composite_call_credentials)); + c->base.type = GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE; + c->base.vtable = &composite_call_credentials_vtable; + gpr_ref_init(&c->base.refcount, 1); + creds1_array = get_creds_array(&creds1); + creds2_array = get_creds_array(&creds2); + c->inner.num_creds = creds1_array.num_creds + creds2_array.num_creds; + creds_array_byte_size = c->inner.num_creds * sizeof(grpc_call_credentials *); + c->inner.creds_array = gpr_malloc(creds_array_byte_size); + memset(c->inner.creds_array, 0, creds_array_byte_size); + for (i = 0; i < creds1_array.num_creds; i++) { + grpc_call_credentials *cur_creds = creds1_array.creds_array[i]; + c->inner.creds_array[i] = grpc_call_credentials_ref(cur_creds); + } + for (i = 0; i < creds2_array.num_creds; i++) { + grpc_call_credentials *cur_creds = creds2_array.creds_array[i]; + c->inner.creds_array[i + creds1_array.num_creds] = + grpc_call_credentials_ref(cur_creds); + } + return &c->base; +} + +const grpc_call_credentials_array * +grpc_composite_call_credentials_get_credentials(grpc_call_credentials *creds) { + const grpc_composite_call_credentials *c = + (const grpc_composite_call_credentials *)creds; + GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); + return &c->inner; +} + +grpc_call_credentials *grpc_credentials_contains_type( + grpc_call_credentials *creds, const char *type, + grpc_call_credentials **composite_creds) { + size_t i; + if (strcmp(creds->type, type) == 0) { + if (composite_creds != NULL) *composite_creds = NULL; + return creds; + } else if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) { + const grpc_call_credentials_array *inner_creds_array = + grpc_composite_call_credentials_get_credentials(creds); + for (i = 0; i < inner_creds_array->num_creds; i++) { + if (strcmp(type, inner_creds_array->creds_array[i]->type) == 0) { + if (composite_creds != NULL) *composite_creds = creds; + return inner_creds_array->creds_array[i]; + } + } + } + return NULL; +} + +/* -- IAM credentials. -- */ + +static void iam_destruct(grpc_call_credentials *creds) { + grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds; + grpc_credentials_md_store_unref(c->iam_md); +} + +static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx, + grpc_call_credentials *creds, + grpc_pollset *pollset, + grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, + void *user_data) { + grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds; + cb(exec_ctx, user_data, c->iam_md->entries, c->iam_md->num_entries, + GRPC_CREDENTIALS_OK); +} + +static grpc_call_credentials_vtable iam_vtable = {iam_destruct, + iam_get_request_metadata}; + +grpc_call_credentials *grpc_google_iam_credentials_create( + const char *token, const char *authority_selector, void *reserved) { + grpc_google_iam_credentials *c; + GRPC_API_TRACE( + "grpc_iam_credentials_create(token=%s, authority_selector=%s, " + "reserved=%p)", + 3, (token, authority_selector, reserved)); + GPR_ASSERT(reserved == NULL); + GPR_ASSERT(token != NULL); + GPR_ASSERT(authority_selector != NULL); + c = gpr_malloc(sizeof(grpc_google_iam_credentials)); + memset(c, 0, sizeof(grpc_google_iam_credentials)); + c->base.type = GRPC_CALL_CREDENTIALS_TYPE_IAM; + c->base.vtable = &iam_vtable; + gpr_ref_init(&c->base.refcount, 1); + c->iam_md = grpc_credentials_md_store_create(2); + grpc_credentials_md_store_add_cstrings( + c->iam_md, GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, token); + grpc_credentials_md_store_add_cstrings( + c->iam_md, GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, authority_selector); + return &c->base; +} + +/* -- Plugin credentials. -- */ + +typedef struct { + void *user_data; + grpc_credentials_metadata_cb cb; +} grpc_metadata_plugin_request; + +static void plugin_destruct(grpc_call_credentials *creds) { + grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds; + if (c->plugin.state != NULL && c->plugin.destroy != NULL) { + c->plugin.destroy(c->plugin.state); + } +} + +static void plugin_md_request_metadata_ready(void *request, + const grpc_metadata *md, + size_t num_md, + grpc_status_code status, + const char *error_details) { + /* called from application code */ + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_metadata_plugin_request *r = (grpc_metadata_plugin_request *)request; + if (status != GRPC_STATUS_OK) { + if (error_details != NULL) { + gpr_log(GPR_ERROR, "Getting metadata from plugin failed with error: %s", + error_details); + } + r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR); + } else { + size_t i; + grpc_credentials_md *md_array = NULL; + if (num_md > 0) { + md_array = gpr_malloc(num_md * sizeof(grpc_credentials_md)); + for (i = 0; i < num_md; i++) { + md_array[i].key = gpr_slice_from_copied_string(md[i].key); + md_array[i].value = + gpr_slice_from_copied_buffer(md[i].value, md[i].value_length); + } + } + r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK); + if (md_array != NULL) { + for (i = 0; i < num_md; i++) { + gpr_slice_unref(md_array[i].key); + gpr_slice_unref(md_array[i].value); + } + gpr_free(md_array); + } + } + gpr_free(r); + grpc_exec_ctx_finish(&exec_ctx); +} + +static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx, + grpc_call_credentials *creds, + grpc_pollset *pollset, + grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, + void *user_data) { + grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds; + if (c->plugin.get_metadata != NULL) { + grpc_metadata_plugin_request *request = gpr_malloc(sizeof(*request)); + memset(request, 0, sizeof(*request)); + request->user_data = user_data; + request->cb = cb; + c->plugin.get_metadata(c->plugin.state, context, + plugin_md_request_metadata_ready, request); + } else { + cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK); + } +} + +static grpc_call_credentials_vtable plugin_vtable = { + plugin_destruct, plugin_get_request_metadata}; + +grpc_call_credentials *grpc_metadata_credentials_create_from_plugin( + grpc_metadata_credentials_plugin plugin, void *reserved) { + grpc_plugin_credentials *c = gpr_malloc(sizeof(*c)); + GRPC_API_TRACE("grpc_metadata_credentials_create_from_plugin(reserved=%p)", 1, + (reserved)); + GPR_ASSERT(reserved == NULL); + memset(c, 0, sizeof(*c)); + c->base.type = plugin.type; + c->base.vtable = &plugin_vtable; + gpr_ref_init(&c->base.refcount, 1); + c->plugin = plugin; + return &c->base; +} + +/* -- Composite channel credentials. -- */ + +static void composite_channel_destruct(grpc_channel_credentials *creds) { + grpc_composite_channel_credentials *c = + (grpc_composite_channel_credentials *)creds; + grpc_channel_credentials_unref(c->inner_creds); + grpc_call_credentials_unref(c->call_creds); +} + +static grpc_security_status composite_channel_create_security_connector( + grpc_channel_credentials *creds, grpc_call_credentials *call_creds, + const char *target, const grpc_channel_args *args, + grpc_channel_security_connector **sc, grpc_channel_args **new_args) { + grpc_composite_channel_credentials *c = + (grpc_composite_channel_credentials *)creds; + grpc_security_status status = GRPC_SECURITY_ERROR; + + GPR_ASSERT(c->inner_creds != NULL && c->call_creds != NULL && + c->inner_creds->vtable != NULL && + c->inner_creds->vtable->create_security_connector != NULL); + /* If we are passed a call_creds, create a call composite to pass it + downstream. */ + if (call_creds != NULL) { + grpc_call_credentials *composite_call_creds = + grpc_composite_call_credentials_create(c->call_creds, call_creds, NULL); + status = c->inner_creds->vtable->create_security_connector( + c->inner_creds, composite_call_creds, target, args, sc, new_args); + grpc_call_credentials_unref(composite_call_creds); + } else { + status = c->inner_creds->vtable->create_security_connector( + c->inner_creds, c->call_creds, target, args, sc, new_args); + } + return status; +} + +static grpc_channel_credentials_vtable composite_channel_credentials_vtable = { + composite_channel_destruct, composite_channel_create_security_connector}; + +grpc_channel_credentials *grpc_composite_channel_credentials_create( + grpc_channel_credentials *channel_creds, grpc_call_credentials *call_creds, + void *reserved) { + grpc_composite_channel_credentials *c = gpr_malloc(sizeof(*c)); + memset(c, 0, sizeof(*c)); + GPR_ASSERT(channel_creds != NULL && call_creds != NULL && reserved == NULL); + GRPC_API_TRACE( + "grpc_composite_channel_credentials_create(channel_creds=%p, " + "call_creds=%p, reserved=%p)", + 3, (channel_creds, call_creds, reserved)); + c->base.type = channel_creds->type; + c->base.vtable = &composite_channel_credentials_vtable; + gpr_ref_init(&c->base.refcount, 1); + c->inner_creds = grpc_channel_credentials_ref(channel_creds); + c->call_creds = grpc_call_credentials_ref(call_creds); + return &c->base; +} diff --git a/src/core/lib/security/credentials.h b/src/core/lib/security/credentials.h new file mode 100644 index 0000000000..bfa7cc71bd --- /dev/null +++ b/src/core/lib/security/credentials.h @@ -0,0 +1,377 @@ +/* + * + * Copyright 2015-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_SECURITY_CREDENTIALS_H +#define GRPC_CORE_SECURITY_CREDENTIALS_H + +#include +#include +#include +#include "src/core/transport/metadata_batch.h" + +#include "src/core/http/httpcli.h" +#include "src/core/http/parser.h" +#include "src/core/security/json_token.h" +#include "src/core/security/security_connector.h" + +struct grpc_http_response; + +/* --- Constants. --- */ + +typedef enum { + GRPC_CREDENTIALS_OK = 0, + GRPC_CREDENTIALS_ERROR +} grpc_credentials_status; + +#define GRPC_FAKE_TRANSPORT_SECURITY_TYPE "fake" + +#define GRPC_CHANNEL_CREDENTIALS_TYPE_SSL "Ssl" +#define GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY \ + "FakeTransportSecurity" + +#define GRPC_CALL_CREDENTIALS_TYPE_OAUTH2 "Oauth2" +#define GRPC_CALL_CREDENTIALS_TYPE_JWT "Jwt" +#define GRPC_CALL_CREDENTIALS_TYPE_IAM "Iam" +#define GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE "Composite" + +#define GRPC_AUTHORIZATION_METADATA_KEY "authorization" +#define GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY \ + "x-goog-iam-authorization-token" +#define GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY "x-goog-iam-authority-selector" + +#define GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY "gcloud" +#define GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE \ + "application_default_credentials.json" + +#define GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS 60 + +#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata" +#define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \ + "/computeMetadata/v1/instance/service-accounts/default/token" + +#define GRPC_GOOGLE_OAUTH2_SERVICE_HOST "www.googleapis.com" +#define GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH "/oauth2/v3/token" + +#define GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX \ + "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" \ + "assertion=" + +#define GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING \ + "client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token" + +/* --- Google utils --- */ + +/* It is the caller's responsibility to gpr_free the result if not NULL. */ +char *grpc_get_well_known_google_credentials_file_path(void); + +/* Implementation function for the different platforms. */ +char *grpc_get_well_known_google_credentials_file_path_impl(void); + +/* Override for testing only. Not thread-safe */ +typedef char *(*grpc_well_known_credentials_path_getter)(void); +void grpc_override_well_known_credentials_path_getter( + grpc_well_known_credentials_path_getter getter); + +/* --- grpc_channel_credentials. --- */ + +typedef struct { + void (*destruct)(grpc_channel_credentials *c); + + grpc_security_status (*create_security_connector)( + grpc_channel_credentials *c, grpc_call_credentials *call_creds, + const char *target, const grpc_channel_args *args, + grpc_channel_security_connector **sc, grpc_channel_args **new_args); +} grpc_channel_credentials_vtable; + +struct grpc_channel_credentials { + const grpc_channel_credentials_vtable *vtable; + const char *type; + gpr_refcount refcount; +}; + +grpc_channel_credentials *grpc_channel_credentials_ref( + grpc_channel_credentials *creds); +void grpc_channel_credentials_unref(grpc_channel_credentials *creds); + +/* Creates a security connector for the channel. May also create new channel + args for the channel to be used in place of the passed in const args if + returned non NULL. In that case the caller is responsible for destroying + new_args after channel creation. */ +grpc_security_status grpc_channel_credentials_create_security_connector( + grpc_channel_credentials *creds, const char *target, + const grpc_channel_args *args, grpc_channel_security_connector **sc, + grpc_channel_args **new_args); + +/* --- grpc_credentials_md. --- */ + +typedef struct { + gpr_slice key; + gpr_slice value; +} grpc_credentials_md; + +typedef struct { + grpc_credentials_md *entries; + size_t num_entries; + size_t allocated; + gpr_refcount refcount; +} grpc_credentials_md_store; + +grpc_credentials_md_store *grpc_credentials_md_store_create( + size_t initial_capacity); + +/* Will ref key and value. */ +void grpc_credentials_md_store_add(grpc_credentials_md_store *store, + gpr_slice key, gpr_slice value); +void grpc_credentials_md_store_add_cstrings(grpc_credentials_md_store *store, + const char *key, const char *value); +grpc_credentials_md_store *grpc_credentials_md_store_ref( + grpc_credentials_md_store *store); +void grpc_credentials_md_store_unref(grpc_credentials_md_store *store); + +/* --- grpc_call_credentials. --- */ + +typedef void (*grpc_credentials_metadata_cb)(grpc_exec_ctx *exec_ctx, + void *user_data, + grpc_credentials_md *md_elems, + size_t num_md, + grpc_credentials_status status); + +typedef struct { + void (*destruct)(grpc_call_credentials *c); + void (*get_request_metadata)(grpc_exec_ctx *exec_ctx, + grpc_call_credentials *c, grpc_pollset *pollset, + grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, + void *user_data); +} grpc_call_credentials_vtable; + +struct grpc_call_credentials { + const grpc_call_credentials_vtable *vtable; + const char *type; + gpr_refcount refcount; +}; + +grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds); +void grpc_call_credentials_unref(grpc_call_credentials *creds); +void grpc_call_credentials_get_request_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, void *user_data); + +typedef struct { + grpc_call_credentials **creds_array; + size_t num_creds; +} grpc_call_credentials_array; + +const grpc_call_credentials_array * +grpc_composite_call_credentials_get_credentials( + grpc_call_credentials *composite_creds); + +/* Returns creds if creds is of the specified type or the inner creds of the + specified type (if found), if the creds is of type COMPOSITE. + If composite_creds is not NULL, *composite_creds will point to creds if of + type COMPOSITE in case of success. */ +grpc_call_credentials *grpc_credentials_contains_type( + grpc_call_credentials *creds, const char *type, + grpc_call_credentials **composite_creds); + +/* Exposed for testing only. */ +grpc_credentials_status +grpc_oauth2_token_fetcher_credentials_parse_server_response( + const struct grpc_http_response *response, + grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime); + +void grpc_flush_cached_google_default_credentials(void); + +/* Metadata-only credentials with the specified key and value where + asynchronicity can be simulated for testing. */ +grpc_call_credentials *grpc_md_only_test_credentials_create( + const char *md_key, const char *md_value, int is_async); + +/* Private constructor for jwt credentials from an already parsed json key. + Takes ownership of the key. */ +grpc_call_credentials * +grpc_service_account_jwt_access_credentials_create_from_auth_json_key( + grpc_auth_json_key key, gpr_timespec token_lifetime); + +/* Private constructor for refresh token credentials from an already parsed + refresh token. Takes ownership of the refresh token. */ +grpc_call_credentials * +grpc_refresh_token_credentials_create_from_auth_refresh_token( + grpc_auth_refresh_token token); + +/* --- grpc_server_credentials. --- */ + +typedef struct { + void (*destruct)(grpc_server_credentials *c); + grpc_security_status (*create_security_connector)( + grpc_server_credentials *c, grpc_server_security_connector **sc); +} grpc_server_credentials_vtable; + +struct grpc_server_credentials { + const grpc_server_credentials_vtable *vtable; + const char *type; + gpr_refcount refcount; + grpc_auth_metadata_processor processor; +}; + +grpc_security_status grpc_server_credentials_create_security_connector( + grpc_server_credentials *creds, grpc_server_security_connector **sc); + +grpc_server_credentials *grpc_server_credentials_ref( + grpc_server_credentials *creds); + +void grpc_server_credentials_unref(grpc_server_credentials *creds); + +#define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials" + +grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *c); +grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg); +grpc_server_credentials *grpc_find_server_credentials_in_args( + const grpc_channel_args *args); + +/* -- Fake transport security credentials. -- */ + +/* Creates a fake transport security credentials object for testing. */ +grpc_channel_credentials *grpc_fake_transport_security_credentials_create(void); +/* Creates a fake server transport security credentials object for testing. */ +grpc_server_credentials *grpc_fake_transport_security_server_credentials_create( + void); + +/* -- Ssl credentials. -- */ + +typedef struct { + grpc_channel_credentials base; + grpc_ssl_config config; +} grpc_ssl_credentials; + +typedef struct { + grpc_server_credentials base; + grpc_ssl_server_config config; +} grpc_ssl_server_credentials; + +/* -- Channel composite credentials. -- */ + +typedef struct { + grpc_channel_credentials base; + grpc_channel_credentials *inner_creds; + grpc_call_credentials *call_creds; +} grpc_composite_channel_credentials; + +/* -- Jwt credentials -- */ + +typedef struct { + grpc_call_credentials base; + + /* Have a simple cache for now with just 1 entry. We could have a map based on + the service_url for a more sophisticated one. */ + gpr_mu cache_mu; + struct { + grpc_credentials_md_store *jwt_md; + char *service_url; + gpr_timespec jwt_expiration; + } cached; + + grpc_auth_json_key key; + gpr_timespec jwt_lifetime; +} grpc_service_account_jwt_access_credentials; + +/* -- Oauth2TokenFetcher credentials -- + + This object is a base for credentials that need to acquire an oauth2 token + from an http service. */ + +typedef struct grpc_credentials_metadata_request + grpc_credentials_metadata_request; + +typedef void (*grpc_fetch_oauth2_func)(grpc_exec_ctx *exec_ctx, + grpc_credentials_metadata_request *req, + grpc_httpcli_context *http_context, + grpc_pollset *pollset, + grpc_httpcli_response_cb response_cb, + gpr_timespec deadline); + +typedef struct { + grpc_call_credentials base; + gpr_mu mu; + grpc_credentials_md_store *access_token_md; + gpr_timespec token_expiration; + grpc_httpcli_context httpcli_context; + grpc_fetch_oauth2_func fetch_func; +} grpc_oauth2_token_fetcher_credentials; + +/* -- GoogleRefreshToken credentials. -- */ + +typedef struct { + grpc_oauth2_token_fetcher_credentials base; + grpc_auth_refresh_token refresh_token; +} grpc_google_refresh_token_credentials; + +/* -- Oauth2 Access Token credentials. -- */ + +typedef struct { + grpc_call_credentials base; + grpc_credentials_md_store *access_token_md; +} grpc_access_token_credentials; + +/* -- Metadata-only Test credentials. -- */ + +typedef struct { + grpc_call_credentials base; + grpc_credentials_md_store *md_store; + int is_async; +} grpc_md_only_test_credentials; + +/* -- GoogleIAM credentials. -- */ + +typedef struct { + grpc_call_credentials base; + grpc_credentials_md_store *iam_md; +} grpc_google_iam_credentials; + +/* -- Composite credentials. -- */ + +typedef struct { + grpc_call_credentials base; + grpc_call_credentials_array inner; +} grpc_composite_call_credentials; + +/* -- Plugin credentials. -- */ + +typedef struct { + grpc_call_credentials base; + grpc_metadata_credentials_plugin plugin; + grpc_credentials_md_store *plugin_md; +} grpc_plugin_credentials; + +#endif /* GRPC_CORE_SECURITY_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials_metadata.c b/src/core/lib/security/credentials_metadata.c new file mode 100644 index 0000000000..b8a132f1ea --- /dev/null +++ b/src/core/lib/security/credentials_metadata.c @@ -0,0 +1,101 @@ +/* + * + * Copyright 2015, 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/security/credentials.h" + +#include + +#include + +static void store_ensure_capacity(grpc_credentials_md_store *store) { + if (store->num_entries == store->allocated) { + store->allocated = (store->allocated == 0) ? 1 : store->allocated * 2; + store->entries = gpr_realloc( + store->entries, store->allocated * sizeof(grpc_credentials_md)); + } +} + +grpc_credentials_md_store *grpc_credentials_md_store_create( + size_t initial_capacity) { + grpc_credentials_md_store *store = + gpr_malloc(sizeof(grpc_credentials_md_store)); + memset(store, 0, sizeof(grpc_credentials_md_store)); + if (initial_capacity > 0) { + store->entries = gpr_malloc(initial_capacity * sizeof(grpc_credentials_md)); + store->allocated = initial_capacity; + } + gpr_ref_init(&store->refcount, 1); + return store; +} + +void grpc_credentials_md_store_add(grpc_credentials_md_store *store, + gpr_slice key, gpr_slice value) { + if (store == NULL) return; + store_ensure_capacity(store); + store->entries[store->num_entries].key = gpr_slice_ref(key); + store->entries[store->num_entries].value = gpr_slice_ref(value); + store->num_entries++; +} + +void grpc_credentials_md_store_add_cstrings(grpc_credentials_md_store *store, + const char *key, + const char *value) { + if (store == NULL) return; + store_ensure_capacity(store); + store->entries[store->num_entries].key = gpr_slice_from_copied_string(key); + store->entries[store->num_entries].value = + gpr_slice_from_copied_string(value); + store->num_entries++; +} + +grpc_credentials_md_store *grpc_credentials_md_store_ref( + grpc_credentials_md_store *store) { + if (store == NULL) return NULL; + gpr_ref(&store->refcount); + return store; +} + +void grpc_credentials_md_store_unref(grpc_credentials_md_store *store) { + if (store == NULL) return; + if (gpr_unref(&store->refcount)) { + if (store->entries != NULL) { + size_t i; + for (i = 0; i < store->num_entries; i++) { + gpr_slice_unref(store->entries[i].key); + gpr_slice_unref(store->entries[i].value); + } + gpr_free(store->entries); + } + gpr_free(store); + } +} diff --git a/src/core/lib/security/credentials_posix.c b/src/core/lib/security/credentials_posix.c new file mode 100644 index 0000000000..0c92bd4a96 --- /dev/null +++ b/src/core/lib/security/credentials_posix.c @@ -0,0 +1,61 @@ +/* + * + * Copyright 2015, 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 + +#ifdef GPR_POSIX_FILE + +#include "src/core/security/credentials.h" + +#include +#include +#include + +#include "src/core/support/env.h" +#include "src/core/support/string.h" + +char *grpc_get_well_known_google_credentials_file_path_impl(void) { + char *result = NULL; + char *home = gpr_getenv("HOME"); + if (home == NULL) { + gpr_log(GPR_ERROR, "Could not get HOME environment variable."); + return NULL; + } + gpr_asprintf(&result, "%s/.config/%s/%s", home, + GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY, + GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE); + gpr_free(home); + return result; +} + +#endif /* GPR_POSIX_FILE */ diff --git a/src/core/lib/security/credentials_win32.c b/src/core/lib/security/credentials_win32.c new file mode 100644 index 0000000000..8ee9f706a1 --- /dev/null +++ b/src/core/lib/security/credentials_win32.c @@ -0,0 +1,61 @@ +/* + * + * Copyright 2015, 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 + +#ifdef GPR_WIN32 + +#include "src/core/security/credentials.h" + +#include +#include +#include + +#include "src/core/support/env.h" +#include "src/core/support/string.h" + +char *grpc_get_well_known_google_credentials_file_path_impl(void) { + char *result = NULL; + char *appdata_path = gpr_getenv("APPDATA"); + if (appdata_path == NULL) { + gpr_log(GPR_ERROR, "Could not get APPDATA environment variable."); + return NULL; + } + gpr_asprintf(&result, "%s/%s/%s", appdata_path, + GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY, + GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE); + gpr_free(appdata_path); + return result; +} + +#endif /* GPR_WIN32 */ diff --git a/src/core/lib/security/google_default_credentials.c b/src/core/lib/security/google_default_credentials.c new file mode 100644 index 0000000000..3872e86993 --- /dev/null +++ b/src/core/lib/security/google_default_credentials.c @@ -0,0 +1,266 @@ +/* + * + * Copyright 2015-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/security/credentials.h" + +#include + +#include +#include +#include + +#include "src/core/http/httpcli.h" +#include "src/core/http/parser.h" +#include "src/core/support/env.h" +#include "src/core/support/load_file.h" +#include "src/core/surface/api_trace.h" + +/* -- Constants. -- */ + +#define GRPC_COMPUTE_ENGINE_DETECTION_HOST "metadata.google.internal" + +/* -- Default credentials. -- */ + +static grpc_channel_credentials *default_credentials = NULL; +static int compute_engine_detection_done = 0; +static gpr_mu g_state_mu; +static gpr_mu *g_polling_mu; +static gpr_once g_once = GPR_ONCE_INIT; + +static void init_default_credentials(void) { gpr_mu_init(&g_state_mu); } + +typedef struct { + grpc_pollset *pollset; + int is_done; + int success; +} compute_engine_detector; + +static void on_compute_engine_detection_http_response( + grpc_exec_ctx *exec_ctx, void *user_data, + const grpc_http_response *response) { + compute_engine_detector *detector = (compute_engine_detector *)user_data; + if (response != NULL && response->status == 200 && response->hdr_count > 0) { + /* Internet providers can return a generic response to all requests, so + it is necessary to check that metadata header is present also. */ + size_t i; + for (i = 0; i < response->hdr_count; i++) { + grpc_http_header *header = &response->hdrs[i]; + if (strcmp(header->key, "Metadata-Flavor") == 0 && + strcmp(header->value, "Google") == 0) { + detector->success = 1; + break; + } + } + } + gpr_mu_lock(g_polling_mu); + detector->is_done = 1; + grpc_pollset_kick(detector->pollset, NULL); + gpr_mu_unlock(g_polling_mu); +} + +static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool s) { + grpc_pollset_destroy(p); +} + +static int is_stack_running_on_compute_engine(void) { + compute_engine_detector detector; + grpc_httpcli_request request; + grpc_httpcli_context context; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_closure destroy_closure; + + /* The http call is local. If it takes more than one sec, it is for sure not + on compute engine. */ + gpr_timespec max_detection_delay = gpr_time_from_seconds(1, GPR_TIMESPAN); + + detector.pollset = gpr_malloc(grpc_pollset_size()); + grpc_pollset_init(detector.pollset, &g_polling_mu); + detector.is_done = 0; + detector.success = 0; + + memset(&request, 0, sizeof(grpc_httpcli_request)); + request.host = GRPC_COMPUTE_ENGINE_DETECTION_HOST; + request.http.path = "/"; + + grpc_httpcli_context_init(&context); + + grpc_httpcli_get( + &exec_ctx, &context, detector.pollset, &request, + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay), + on_compute_engine_detection_http_response, &detector); + + grpc_exec_ctx_finish(&exec_ctx); + + /* Block until we get the response. This is not ideal but this should only be + called once for the lifetime of the process by the default credentials. */ + gpr_mu_lock(g_polling_mu); + while (!detector.is_done) { + grpc_pollset_worker *worker = NULL; + grpc_pollset_work(&exec_ctx, detector.pollset, &worker, + gpr_now(GPR_CLOCK_MONOTONIC), + gpr_inf_future(GPR_CLOCK_MONOTONIC)); + } + gpr_mu_unlock(g_polling_mu); + + grpc_httpcli_context_destroy(&context); + grpc_closure_init(&destroy_closure, destroy_pollset, detector.pollset); + grpc_pollset_shutdown(&exec_ctx, detector.pollset, &destroy_closure); + grpc_exec_ctx_finish(&exec_ctx); + g_polling_mu = NULL; + + gpr_free(detector.pollset); + + return detector.success; +} + +/* Takes ownership of creds_path if not NULL. */ +static grpc_call_credentials *create_default_creds_from_path(char *creds_path) { + grpc_json *json = NULL; + grpc_auth_json_key key; + grpc_auth_refresh_token token; + grpc_call_credentials *result = NULL; + gpr_slice creds_data = gpr_empty_slice(); + int file_ok = 0; + if (creds_path == NULL) goto end; + creds_data = gpr_load_file(creds_path, 0, &file_ok); + if (!file_ok) goto end; + json = grpc_json_parse_string_with_len( + (char *)GPR_SLICE_START_PTR(creds_data), GPR_SLICE_LENGTH(creds_data)); + if (json == NULL) goto end; + + /* First, try an auth json key. */ + key = grpc_auth_json_key_create_from_json(json); + if (grpc_auth_json_key_is_valid(&key)) { + result = + grpc_service_account_jwt_access_credentials_create_from_auth_json_key( + key, grpc_max_auth_token_lifetime()); + goto end; + } + + /* Then try a refresh token if the auth json key was invalid. */ + token = grpc_auth_refresh_token_create_from_json(json); + if (grpc_auth_refresh_token_is_valid(&token)) { + result = + grpc_refresh_token_credentials_create_from_auth_refresh_token(token); + goto end; + } + +end: + if (creds_path != NULL) gpr_free(creds_path); + gpr_slice_unref(creds_data); + if (json != NULL) grpc_json_destroy(json); + return result; +} + +grpc_channel_credentials *grpc_google_default_credentials_create(void) { + grpc_channel_credentials *result = NULL; + grpc_call_credentials *call_creds = NULL; + + GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ()); + + gpr_once_init(&g_once, init_default_credentials); + + gpr_mu_lock(&g_state_mu); + + if (default_credentials != NULL) { + result = grpc_channel_credentials_ref(default_credentials); + goto end; + } + + /* First, try the environment variable. */ + call_creds = create_default_creds_from_path( + gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR)); + if (call_creds != NULL) goto end; + + /* Then the well-known file. */ + call_creds = create_default_creds_from_path( + grpc_get_well_known_google_credentials_file_path()); + if (call_creds != NULL) goto end; + + /* At last try to see if we're on compute engine (do the detection only once + since it requires a network test). */ + if (!compute_engine_detection_done) { + int need_compute_engine_creds = is_stack_running_on_compute_engine(); + compute_engine_detection_done = 1; + if (need_compute_engine_creds) { + call_creds = grpc_google_compute_engine_credentials_create(NULL); + } + } + +end: + if (result == NULL) { + if (call_creds != NULL) { + /* Blend with default ssl credentials and add a global reference so that + it + can be cached and re-served. */ + grpc_channel_credentials *ssl_creds = + grpc_ssl_credentials_create(NULL, NULL, NULL); + default_credentials = grpc_channel_credentials_ref( + grpc_composite_channel_credentials_create(ssl_creds, call_creds, + NULL)); + GPR_ASSERT(default_credentials != NULL); + grpc_channel_credentials_unref(ssl_creds); + grpc_call_credentials_unref(call_creds); + result = default_credentials; + } else { + gpr_log(GPR_ERROR, "Could not create google default credentials."); + } + } + gpr_mu_unlock(&g_state_mu); + return result; +} + +void grpc_flush_cached_google_default_credentials(void) { + gpr_once_init(&g_once, init_default_credentials); + gpr_mu_lock(&g_state_mu); + if (default_credentials != NULL) { + grpc_channel_credentials_unref(default_credentials); + default_credentials = NULL; + } + compute_engine_detection_done = 0; + gpr_mu_unlock(&g_state_mu); +} + +/* -- Well known credentials path. -- */ + +static grpc_well_known_credentials_path_getter creds_path_getter = NULL; + +char *grpc_get_well_known_google_credentials_file_path(void) { + if (creds_path_getter != NULL) return creds_path_getter(); + return grpc_get_well_known_google_credentials_file_path_impl(); +} + +void grpc_override_well_known_credentials_path_getter( + grpc_well_known_credentials_path_getter getter) { + creds_path_getter = getter; +} diff --git a/src/core/lib/security/handshake.c b/src/core/lib/security/handshake.c new file mode 100644 index 0000000000..9fb10a0ecb --- /dev/null +++ b/src/core/lib/security/handshake.c @@ -0,0 +1,336 @@ +/* + * + * Copyright 2015-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/security/handshake.h" + +#include +#include + +#include +#include +#include +#include "src/core/security/secure_endpoint.h" +#include "src/core/security/security_context.h" + +#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256 + +typedef struct { + grpc_security_connector *connector; + tsi_handshaker *handshaker; + bool is_client_side; + unsigned char *handshake_buffer; + size_t handshake_buffer_size; + grpc_endpoint *wrapped_endpoint; + grpc_endpoint *secure_endpoint; + gpr_slice_buffer left_overs; + gpr_slice_buffer incoming; + gpr_slice_buffer outgoing; + grpc_security_handshake_done_cb cb; + void *user_data; + grpc_closure on_handshake_data_sent_to_peer; + grpc_closure on_handshake_data_received_from_peer; + grpc_auth_context *auth_context; +} grpc_security_handshake; + +static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx, + void *setup, bool success); + +static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *setup, + bool success); + +static void security_connector_remove_handshake(grpc_security_handshake *h) { + GPR_ASSERT(!h->is_client_side); + grpc_security_connector_handshake_list *node; + grpc_security_connector_handshake_list *tmp; + grpc_server_security_connector *sc = + (grpc_server_security_connector *)h->connector; + gpr_mu_lock(&sc->mu); + node = sc->handshaking_handshakes; + if (node && node->handshake == h) { + sc->handshaking_handshakes = node->next; + gpr_free(node); + gpr_mu_unlock(&sc->mu); + return; + } + while (node) { + if (node->next->handshake == h) { + tmp = node->next; + node->next = node->next->next; + gpr_free(tmp); + gpr_mu_unlock(&sc->mu); + return; + } + node = node->next; + } + gpr_mu_unlock(&sc->mu); +} + +static void security_handshake_done(grpc_exec_ctx *exec_ctx, + grpc_security_handshake *h, + int is_success) { + if (!h->is_client_side) { + security_connector_remove_handshake(h); + } + if (is_success) { + h->cb(exec_ctx, h->user_data, GRPC_SECURITY_OK, h->secure_endpoint, + h->auth_context); + } else { + if (h->secure_endpoint != NULL) { + grpc_endpoint_shutdown(exec_ctx, h->secure_endpoint); + grpc_endpoint_destroy(exec_ctx, h->secure_endpoint); + } else { + grpc_endpoint_destroy(exec_ctx, h->wrapped_endpoint); + } + h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, NULL, NULL); + } + if (h->handshaker != NULL) tsi_handshaker_destroy(h->handshaker); + if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer); + gpr_slice_buffer_destroy(&h->left_overs); + gpr_slice_buffer_destroy(&h->outgoing); + gpr_slice_buffer_destroy(&h->incoming); + GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake"); + GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake"); + gpr_free(h); +} + +static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_security_status status, + grpc_auth_context *auth_context) { + grpc_security_handshake *h = user_data; + tsi_frame_protector *protector; + tsi_result result; + if (status != GRPC_SECURITY_OK) { + gpr_log(GPR_ERROR, "Error checking peer."); + security_handshake_done(exec_ctx, h, 0); + return; + } + h->auth_context = GRPC_AUTH_CONTEXT_REF(auth_context, "handshake"); + result = + tsi_handshaker_create_frame_protector(h->handshaker, NULL, &protector); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Frame protector creation failed with error %s.", + tsi_result_to_string(result)); + security_handshake_done(exec_ctx, h, 0); + return; + } + h->secure_endpoint = + grpc_secure_endpoint_create(protector, h->wrapped_endpoint, + h->left_overs.slices, h->left_overs.count); + h->left_overs.count = 0; + h->left_overs.length = 0; + security_handshake_done(exec_ctx, h, 1); + return; +} + +static void check_peer(grpc_exec_ctx *exec_ctx, grpc_security_handshake *h) { + tsi_peer peer; + tsi_result result = tsi_handshaker_extract_peer(h->handshaker, &peer); + + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Peer extraction failed with error %s", + tsi_result_to_string(result)); + security_handshake_done(exec_ctx, h, 0); + return; + } + grpc_security_connector_check_peer(exec_ctx, h->connector, peer, + on_peer_checked, h); +} + +static void send_handshake_bytes_to_peer(grpc_exec_ctx *exec_ctx, + grpc_security_handshake *h) { + size_t offset = 0; + tsi_result result = TSI_OK; + gpr_slice to_send; + + do { + size_t to_send_size = h->handshake_buffer_size - offset; + result = tsi_handshaker_get_bytes_to_send_to_peer( + h->handshaker, h->handshake_buffer + offset, &to_send_size); + offset += to_send_size; + if (result == TSI_INCOMPLETE_DATA) { + h->handshake_buffer_size *= 2; + h->handshake_buffer = + gpr_realloc(h->handshake_buffer, h->handshake_buffer_size); + } + } while (result == TSI_INCOMPLETE_DATA); + + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshake failed with error %s", + tsi_result_to_string(result)); + security_handshake_done(exec_ctx, h, 0); + return; + } + + to_send = + gpr_slice_from_copied_buffer((const char *)h->handshake_buffer, offset); + gpr_slice_buffer_reset_and_unref(&h->outgoing); + gpr_slice_buffer_add(&h->outgoing, to_send); + /* TODO(klempner,jboeuf): This should probably use the client setup + deadline */ + grpc_endpoint_write(exec_ctx, h->wrapped_endpoint, &h->outgoing, + &h->on_handshake_data_sent_to_peer); +} + +static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx, + void *handshake, + bool success) { + grpc_security_handshake *h = handshake; + size_t consumed_slice_size = 0; + tsi_result result = TSI_OK; + size_t i; + size_t num_left_overs; + int has_left_overs_in_current_slice = 0; + + if (!success) { + gpr_log(GPR_ERROR, "Read failed."); + security_handshake_done(exec_ctx, h, 0); + return; + } + + for (i = 0; i < h->incoming.count; i++) { + consumed_slice_size = GPR_SLICE_LENGTH(h->incoming.slices[i]); + result = tsi_handshaker_process_bytes_from_peer( + h->handshaker, GPR_SLICE_START_PTR(h->incoming.slices[i]), + &consumed_slice_size); + if (!tsi_handshaker_is_in_progress(h->handshaker)) break; + } + + if (tsi_handshaker_is_in_progress(h->handshaker)) { + /* We may need more data. */ + if (result == TSI_INCOMPLETE_DATA) { + grpc_endpoint_read(exec_ctx, h->wrapped_endpoint, &h->incoming, + &h->on_handshake_data_received_from_peer); + return; + } else { + send_handshake_bytes_to_peer(exec_ctx, h); + return; + } + } + + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshake failed with error %s", + tsi_result_to_string(result)); + security_handshake_done(exec_ctx, h, 0); + return; + } + + /* Handshake is done and successful this point. */ + has_left_overs_in_current_slice = + (consumed_slice_size < GPR_SLICE_LENGTH(h->incoming.slices[i])); + num_left_overs = + (has_left_overs_in_current_slice ? 1 : 0) + h->incoming.count - i - 1; + if (num_left_overs == 0) { + check_peer(exec_ctx, h); + return; + } + + /* Put the leftovers in our buffer (ownership transfered). */ + if (has_left_overs_in_current_slice) { + gpr_slice_buffer_add( + &h->left_overs, + gpr_slice_split_tail(&h->incoming.slices[i], consumed_slice_size)); + gpr_slice_unref( + h->incoming.slices[i]); /* split_tail above increments refcount. */ + } + gpr_slice_buffer_addn( + &h->left_overs, &h->incoming.slices[i + 1], + num_left_overs - (size_t)has_left_overs_in_current_slice); + check_peer(exec_ctx, h); +} + +/* If handshake is NULL, the handshake is done. */ +static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, + void *handshake, bool success) { + grpc_security_handshake *h = handshake; + + /* Make sure that write is OK. */ + if (!success) { + gpr_log(GPR_ERROR, "Write failed."); + if (handshake != NULL) security_handshake_done(exec_ctx, h, 0); + return; + } + + /* We may be done. */ + if (tsi_handshaker_is_in_progress(h->handshaker)) { + /* TODO(klempner,jboeuf): This should probably use the client setup + deadline */ + grpc_endpoint_read(exec_ctx, h->wrapped_endpoint, &h->incoming, + &h->on_handshake_data_received_from_peer); + } else { + check_peer(exec_ctx, h); + } +} + +void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx, + tsi_handshaker *handshaker, + grpc_security_connector *connector, + bool is_client_side, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *user_data) { + grpc_security_connector_handshake_list *handshake_node; + grpc_security_handshake *h = gpr_malloc(sizeof(grpc_security_handshake)); + memset(h, 0, sizeof(grpc_security_handshake)); + h->handshaker = handshaker; + h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake"); + h->is_client_side = is_client_side; + h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE; + h->handshake_buffer = gpr_malloc(h->handshake_buffer_size); + h->wrapped_endpoint = nonsecure_endpoint; + h->user_data = user_data; + h->cb = cb; + grpc_closure_init(&h->on_handshake_data_sent_to_peer, + on_handshake_data_sent_to_peer, h); + grpc_closure_init(&h->on_handshake_data_received_from_peer, + on_handshake_data_received_from_peer, h); + gpr_slice_buffer_init(&h->left_overs); + gpr_slice_buffer_init(&h->outgoing); + gpr_slice_buffer_init(&h->incoming); + if (!is_client_side) { + grpc_server_security_connector *server_connector = + (grpc_server_security_connector *)connector; + handshake_node = gpr_malloc(sizeof(grpc_security_connector_handshake_list)); + handshake_node->handshake = h; + gpr_mu_lock(&server_connector->mu); + handshake_node->next = server_connector->handshaking_handshakes; + server_connector->handshaking_handshakes = handshake_node; + gpr_mu_unlock(&server_connector->mu); + } + send_handshake_bytes_to_peer(exec_ctx, h); +} + +void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, + void *handshake) { + grpc_security_handshake *h = handshake; + grpc_endpoint_shutdown(exec_ctx, h->wrapped_endpoint); +} diff --git a/src/core/lib/security/handshake.h b/src/core/lib/security/handshake.h new file mode 100644 index 0000000000..4872045874 --- /dev/null +++ b/src/core/lib/security/handshake.h @@ -0,0 +1,51 @@ +/* + * + * Copyright 2015-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_SECURITY_HANDSHAKE_H +#define GRPC_CORE_SECURITY_HANDSHAKE_H + +#include "src/core/iomgr/endpoint.h" +#include "src/core/security/security_connector.h" + +/* Calls the callback upon completion. Takes owership of handshaker. */ +void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx, + tsi_handshaker *handshaker, + grpc_security_connector *connector, + bool is_client_side, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *user_data); + +void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake); + +#endif /* GRPC_CORE_SECURITY_HANDSHAKE_H */ diff --git a/src/core/lib/security/json_token.c b/src/core/lib/security/json_token.c new file mode 100644 index 0000000000..372e5bfc5a --- /dev/null +++ b/src/core/lib/security/json_token.c @@ -0,0 +1,411 @@ +/* + * + * Copyright 2015-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/security/json_token.h" + +#include + +#include +#include +#include + +#include "src/core/security/b64.h" +#include "src/core/support/string.h" + +#include +#include +#include + +/* --- Constants. --- */ + +/* 1 hour max. */ +gpr_timespec grpc_max_auth_token_lifetime() { + gpr_timespec out; + out.tv_sec = 3600; + out.tv_nsec = 0; + out.clock_type = GPR_TIMESPAN; + return out; +} + +#define GRPC_JWT_RSA_SHA256_ALGORITHM "RS256" +#define GRPC_JWT_TYPE "JWT" + +/* --- Override for testing. --- */ + +static grpc_jwt_encode_and_sign_override g_jwt_encode_and_sign_override = NULL; + +/* --- grpc_auth_json_key. --- */ + +static const char *json_get_string_property(const grpc_json *json, + const char *prop_name) { + grpc_json *child; + for (child = json->child; child != NULL; child = child->next) { + if (strcmp(child->key, prop_name) == 0) break; + } + if (child == NULL || child->type != GRPC_JSON_STRING) { + gpr_log(GPR_ERROR, "Invalid or missing %s property.", prop_name); + return NULL; + } + return child->value; +} + +static int set_json_key_string_property(const grpc_json *json, + const char *prop_name, + char **json_key_field) { + const char *prop_value = json_get_string_property(json, prop_name); + if (prop_value == NULL) return 0; + *json_key_field = gpr_strdup(prop_value); + return 1; +} + +int grpc_auth_json_key_is_valid(const grpc_auth_json_key *json_key) { + return (json_key != NULL) && + strcmp(json_key->type, GRPC_AUTH_JSON_TYPE_INVALID); +} + +grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json *json) { + grpc_auth_json_key result; + BIO *bio = NULL; + const char *prop_value; + int success = 0; + + memset(&result, 0, sizeof(grpc_auth_json_key)); + result.type = GRPC_AUTH_JSON_TYPE_INVALID; + if (json == NULL) { + gpr_log(GPR_ERROR, "Invalid json."); + goto end; + } + + prop_value = json_get_string_property(json, "type"); + if (prop_value == NULL || + strcmp(prop_value, GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT)) { + goto end; + } + result.type = GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT; + + if (!set_json_key_string_property(json, "private_key_id", + &result.private_key_id) || + !set_json_key_string_property(json, "client_id", &result.client_id) || + !set_json_key_string_property(json, "client_email", + &result.client_email)) { + goto end; + } + + prop_value = json_get_string_property(json, "private_key"); + if (prop_value == NULL) { + goto end; + } + bio = BIO_new(BIO_s_mem()); + success = BIO_puts(bio, prop_value); + if ((success < 0) || ((size_t)success != strlen(prop_value))) { + gpr_log(GPR_ERROR, "Could not write into openssl BIO."); + goto end; + } + result.private_key = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, ""); + if (result.private_key == NULL) { + gpr_log(GPR_ERROR, "Could not deserialize private key."); + goto end; + } + success = 1; + +end: + if (bio != NULL) BIO_free(bio); + if (!success) grpc_auth_json_key_destruct(&result); + return result; +} + +grpc_auth_json_key grpc_auth_json_key_create_from_string( + const char *json_string) { + char *scratchpad = gpr_strdup(json_string); + grpc_json *json = grpc_json_parse_string(scratchpad); + grpc_auth_json_key result = grpc_auth_json_key_create_from_json(json); + if (json != NULL) grpc_json_destroy(json); + gpr_free(scratchpad); + return result; +} + +void grpc_auth_json_key_destruct(grpc_auth_json_key *json_key) { + if (json_key == NULL) return; + json_key->type = GRPC_AUTH_JSON_TYPE_INVALID; + if (json_key->client_id != NULL) { + gpr_free(json_key->client_id); + json_key->client_id = NULL; + } + if (json_key->private_key_id != NULL) { + gpr_free(json_key->private_key_id); + json_key->private_key_id = NULL; + } + if (json_key->client_email != NULL) { + gpr_free(json_key->client_email); + json_key->client_email = NULL; + } + if (json_key->private_key != NULL) { + RSA_free(json_key->private_key); + json_key->private_key = NULL; + } +} + +/* --- jwt encoding and signature. --- */ + +static grpc_json *create_child(grpc_json *brother, grpc_json *parent, + const char *key, const char *value, + grpc_json_type type) { + grpc_json *child = grpc_json_create(type); + if (brother) brother->next = child; + if (!parent->child) parent->child = child; + child->parent = parent; + child->value = value; + child->key = key; + return child; +} + +static char *encoded_jwt_header(const char *key_id, const char *algorithm) { + grpc_json *json = grpc_json_create(GRPC_JSON_OBJECT); + grpc_json *child = NULL; + char *json_str = NULL; + char *result = NULL; + + child = create_child(NULL, json, "alg", algorithm, GRPC_JSON_STRING); + child = create_child(child, json, "typ", GRPC_JWT_TYPE, GRPC_JSON_STRING); + create_child(child, json, "kid", key_id, GRPC_JSON_STRING); + + json_str = grpc_json_dump_to_string(json, 0); + result = grpc_base64_encode(json_str, strlen(json_str), 1, 0); + gpr_free(json_str); + grpc_json_destroy(json); + return result; +} + +static char *encoded_jwt_claim(const grpc_auth_json_key *json_key, + const char *audience, + gpr_timespec token_lifetime, const char *scope) { + grpc_json *json = grpc_json_create(GRPC_JSON_OBJECT); + grpc_json *child = NULL; + char *json_str = NULL; + char *result = NULL; + gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); + gpr_timespec expiration = gpr_time_add(now, token_lifetime); + char now_str[GPR_LTOA_MIN_BUFSIZE]; + char expiration_str[GPR_LTOA_MIN_BUFSIZE]; + if (gpr_time_cmp(token_lifetime, grpc_max_auth_token_lifetime()) > 0) { + gpr_log(GPR_INFO, "Cropping token lifetime to maximum allowed value."); + expiration = gpr_time_add(now, grpc_max_auth_token_lifetime()); + } + int64_ttoa(now.tv_sec, now_str); + int64_ttoa(expiration.tv_sec, expiration_str); + + child = + create_child(NULL, json, "iss", json_key->client_email, GRPC_JSON_STRING); + if (scope != NULL) { + child = create_child(child, json, "scope", scope, GRPC_JSON_STRING); + } else { + /* Unscoped JWTs need a sub field. */ + child = create_child(child, json, "sub", json_key->client_email, + GRPC_JSON_STRING); + } + + child = create_child(child, json, "aud", audience, GRPC_JSON_STRING); + child = create_child(child, json, "iat", now_str, GRPC_JSON_NUMBER); + create_child(child, json, "exp", expiration_str, GRPC_JSON_NUMBER); + + json_str = grpc_json_dump_to_string(json, 0); + result = grpc_base64_encode(json_str, strlen(json_str), 1, 0); + gpr_free(json_str); + grpc_json_destroy(json); + return result; +} + +static char *dot_concat_and_free_strings(char *str1, char *str2) { + size_t str1_len = strlen(str1); + size_t str2_len = strlen(str2); + size_t result_len = str1_len + 1 /* dot */ + str2_len; + char *result = gpr_malloc(result_len + 1 /* NULL terminated */); + char *current = result; + memcpy(current, str1, str1_len); + current += str1_len; + *(current++) = '.'; + memcpy(current, str2, str2_len); + current += str2_len; + GPR_ASSERT(current >= result); + GPR_ASSERT((uintptr_t)(current - result) == result_len); + *current = '\0'; + gpr_free(str1); + gpr_free(str2); + return result; +} + +const EVP_MD *openssl_digest_from_algorithm(const char *algorithm) { + if (strcmp(algorithm, GRPC_JWT_RSA_SHA256_ALGORITHM) == 0) { + return EVP_sha256(); + } else { + gpr_log(GPR_ERROR, "Unknown algorithm %s.", algorithm); + return NULL; + } +} + +char *compute_and_encode_signature(const grpc_auth_json_key *json_key, + const char *signature_algorithm, + const char *to_sign) { + const EVP_MD *md = openssl_digest_from_algorithm(signature_algorithm); + EVP_MD_CTX *md_ctx = NULL; + EVP_PKEY *key = EVP_PKEY_new(); + size_t sig_len = 0; + unsigned char *sig = NULL; + char *result = NULL; + if (md == NULL) return NULL; + md_ctx = EVP_MD_CTX_create(); + if (md_ctx == NULL) { + gpr_log(GPR_ERROR, "Could not create MD_CTX"); + goto end; + } + EVP_PKEY_set1_RSA(key, json_key->private_key); + if (EVP_DigestSignInit(md_ctx, NULL, md, NULL, key) != 1) { + gpr_log(GPR_ERROR, "DigestInit failed."); + goto end; + } + if (EVP_DigestSignUpdate(md_ctx, to_sign, strlen(to_sign)) != 1) { + gpr_log(GPR_ERROR, "DigestUpdate failed."); + goto end; + } + if (EVP_DigestSignFinal(md_ctx, NULL, &sig_len) != 1) { + gpr_log(GPR_ERROR, "DigestFinal (get signature length) failed."); + goto end; + } + sig = gpr_malloc(sig_len); + if (EVP_DigestSignFinal(md_ctx, sig, &sig_len) != 1) { + gpr_log(GPR_ERROR, "DigestFinal (signature compute) failed."); + goto end; + } + result = grpc_base64_encode(sig, sig_len, 1, 0); + +end: + if (key != NULL) EVP_PKEY_free(key); + if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx); + if (sig != NULL) gpr_free(sig); + return result; +} + +char *grpc_jwt_encode_and_sign(const grpc_auth_json_key *json_key, + const char *audience, + gpr_timespec token_lifetime, const char *scope) { + if (g_jwt_encode_and_sign_override != NULL) { + return g_jwt_encode_and_sign_override(json_key, audience, token_lifetime, + scope); + } else { + const char *sig_algo = GRPC_JWT_RSA_SHA256_ALGORITHM; + char *to_sign = dot_concat_and_free_strings( + encoded_jwt_header(json_key->private_key_id, sig_algo), + encoded_jwt_claim(json_key, audience, token_lifetime, scope)); + char *sig = compute_and_encode_signature(json_key, sig_algo, to_sign); + if (sig == NULL) { + gpr_free(to_sign); + return NULL; + } + return dot_concat_and_free_strings(to_sign, sig); + } +} + +void grpc_jwt_encode_and_sign_set_override( + grpc_jwt_encode_and_sign_override func) { + g_jwt_encode_and_sign_override = func; +} + +/* --- grpc_auth_refresh_token --- */ + +int grpc_auth_refresh_token_is_valid( + const grpc_auth_refresh_token *refresh_token) { + return (refresh_token != NULL) && + strcmp(refresh_token->type, GRPC_AUTH_JSON_TYPE_INVALID); +} + +grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json( + const grpc_json *json) { + grpc_auth_refresh_token result; + const char *prop_value; + int success = 0; + + memset(&result, 0, sizeof(grpc_auth_refresh_token)); + result.type = GRPC_AUTH_JSON_TYPE_INVALID; + if (json == NULL) { + gpr_log(GPR_ERROR, "Invalid json."); + goto end; + } + + prop_value = json_get_string_property(json, "type"); + if (prop_value == NULL || + strcmp(prop_value, GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER)) { + goto end; + } + result.type = GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER; + + if (!set_json_key_string_property(json, "client_secret", + &result.client_secret) || + !set_json_key_string_property(json, "client_id", &result.client_id) || + !set_json_key_string_property(json, "refresh_token", + &result.refresh_token)) { + goto end; + } + success = 1; + +end: + if (!success) grpc_auth_refresh_token_destruct(&result); + return result; +} + +grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string( + const char *json_string) { + char *scratchpad = gpr_strdup(json_string); + grpc_json *json = grpc_json_parse_string(scratchpad); + grpc_auth_refresh_token result = + grpc_auth_refresh_token_create_from_json(json); + if (json != NULL) grpc_json_destroy(json); + gpr_free(scratchpad); + return result; +} + +void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token) { + if (refresh_token == NULL) return; + refresh_token->type = GRPC_AUTH_JSON_TYPE_INVALID; + if (refresh_token->client_id != NULL) { + gpr_free(refresh_token->client_id); + refresh_token->client_id = NULL; + } + if (refresh_token->client_secret != NULL) { + gpr_free(refresh_token->client_secret); + refresh_token->client_secret = NULL; + } + if (refresh_token->refresh_token != NULL) { + gpr_free(refresh_token->refresh_token); + refresh_token->refresh_token = NULL; + } +} diff --git a/src/core/lib/security/json_token.h b/src/core/lib/security/json_token.h new file mode 100644 index 0000000000..d183f9b3a3 --- /dev/null +++ b/src/core/lib/security/json_token.h @@ -0,0 +1,118 @@ +/* + * + * Copyright 2015-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_SECURITY_JSON_TOKEN_H +#define GRPC_CORE_SECURITY_JSON_TOKEN_H + +#include +#include + +#include "src/core/json/json.h" + +/* --- Constants. --- */ + +#define GRPC_JWT_OAUTH2_AUDIENCE "https://www.googleapis.com/oauth2/v3/token" + +#define GRPC_AUTH_JSON_TYPE_INVALID "invalid" +#define GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT "service_account" +#define GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER "authorized_user" + +/* --- auth_json_key parsing. --- */ + +typedef struct { + const char *type; + char *private_key_id; + char *client_id; + char *client_email; + RSA *private_key; +} grpc_auth_json_key; + +/* Returns 1 if the object is valid, 0 otherwise. */ +int grpc_auth_json_key_is_valid(const grpc_auth_json_key *json_key); + +/* Creates a json_key object from string. Returns an invalid object if a parsing + error has been encountered. */ +grpc_auth_json_key grpc_auth_json_key_create_from_string( + const char *json_string); + +/* Creates a json_key object from parsed json. Returns an invalid object if a + parsing error has been encountered. */ +grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json *json); + +/* Destructs the object. */ +void grpc_auth_json_key_destruct(grpc_auth_json_key *json_key); + +/* --- json token encoding and signing. --- */ + +/* Caller is responsible for calling gpr_free on the returned value. May return + NULL on invalid input. The scope parameter may be NULL. */ +char *grpc_jwt_encode_and_sign(const grpc_auth_json_key *json_key, + const char *audience, + gpr_timespec token_lifetime, const char *scope); + +/* Override encode_and_sign function for testing. */ +typedef char *(*grpc_jwt_encode_and_sign_override)( + const grpc_auth_json_key *json_key, const char *audience, + gpr_timespec token_lifetime, const char *scope); + +/* Set a custom encode_and_sign override for testing. */ +void grpc_jwt_encode_and_sign_set_override( + grpc_jwt_encode_and_sign_override func); + +/* --- auth_refresh_token parsing. --- */ + +typedef struct { + const char *type; + char *client_id; + char *client_secret; + char *refresh_token; +} grpc_auth_refresh_token; + +/* Returns 1 if the object is valid, 0 otherwise. */ +int grpc_auth_refresh_token_is_valid( + const grpc_auth_refresh_token *refresh_token); + +/* Creates a refresh token object from string. Returns an invalid object if a + parsing error has been encountered. */ +grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string( + const char *json_string); + +/* Creates a refresh token object from parsed json. Returns an invalid object if + a parsing error has been encountered. */ +grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json( + const grpc_json *json); + +/* Destructs the object. */ +void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token); + +#endif /* GRPC_CORE_SECURITY_JSON_TOKEN_H */ diff --git a/src/core/lib/security/jwt_verifier.c b/src/core/lib/security/jwt_verifier.c new file mode 100644 index 0000000000..0bb8e05306 --- /dev/null +++ b/src/core/lib/security/jwt_verifier.c @@ -0,0 +1,843 @@ +/* + * + * Copyright 2015-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/security/jwt_verifier.h" + +#include +#include + +#include "src/core/http/httpcli.h" +#include "src/core/security/b64.h" +#include "src/core/tsi/ssl_types.h" + +#include +#include +#include +#include +#include + +/* --- Utils. --- */ + +const char *grpc_jwt_verifier_status_to_string( + grpc_jwt_verifier_status status) { + switch (status) { + case GRPC_JWT_VERIFIER_OK: + return "OK"; + case GRPC_JWT_VERIFIER_BAD_SIGNATURE: + return "BAD_SIGNATURE"; + case GRPC_JWT_VERIFIER_BAD_FORMAT: + return "BAD_FORMAT"; + case GRPC_JWT_VERIFIER_BAD_AUDIENCE: + return "BAD_AUDIENCE"; + case GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR: + return "KEY_RETRIEVAL_ERROR"; + case GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE: + return "TIME_CONSTRAINT_FAILURE"; + case GRPC_JWT_VERIFIER_GENERIC_ERROR: + return "GENERIC_ERROR"; + default: + return "UNKNOWN"; + } +} + +static const EVP_MD *evp_md_from_alg(const char *alg) { + if (strcmp(alg, "RS256") == 0) { + return EVP_sha256(); + } else if (strcmp(alg, "RS384") == 0) { + return EVP_sha384(); + } else if (strcmp(alg, "RS512") == 0) { + return EVP_sha512(); + } else { + return NULL; + } +} + +static grpc_json *parse_json_part_from_jwt(const char *str, size_t len, + gpr_slice *buffer) { + grpc_json *json; + + *buffer = grpc_base64_decode_with_len(str, len, 1); + if (GPR_SLICE_IS_EMPTY(*buffer)) { + gpr_log(GPR_ERROR, "Invalid base64."); + return NULL; + } + json = grpc_json_parse_string_with_len((char *)GPR_SLICE_START_PTR(*buffer), + GPR_SLICE_LENGTH(*buffer)); + if (json == NULL) { + gpr_slice_unref(*buffer); + gpr_log(GPR_ERROR, "JSON parsing error."); + } + return json; +} + +static const char *validate_string_field(const grpc_json *json, + const char *key) { + if (json->type != GRPC_JSON_STRING) { + gpr_log(GPR_ERROR, "Invalid %s field [%s]", key, json->value); + return NULL; + } + return json->value; +} + +static gpr_timespec validate_time_field(const grpc_json *json, + const char *key) { + gpr_timespec result = gpr_time_0(GPR_CLOCK_REALTIME); + if (json->type != GRPC_JSON_NUMBER) { + gpr_log(GPR_ERROR, "Invalid %s field [%s]", key, json->value); + return result; + } + result.tv_sec = strtol(json->value, NULL, 10); + return result; +} + +/* --- JOSE header. see http://tools.ietf.org/html/rfc7515#section-4 --- */ + +typedef struct { + const char *alg; + const char *kid; + const char *typ; + /* TODO(jboeuf): Add others as needed (jku, jwk, x5u, x5c and so on...). */ + gpr_slice buffer; +} jose_header; + +static void jose_header_destroy(jose_header *h) { + gpr_slice_unref(h->buffer); + gpr_free(h); +} + +/* Takes ownership of json and buffer. */ +static jose_header *jose_header_from_json(grpc_json *json, gpr_slice buffer) { + grpc_json *cur; + jose_header *h = gpr_malloc(sizeof(jose_header)); + memset(h, 0, sizeof(jose_header)); + h->buffer = buffer; + for (cur = json->child; cur != NULL; cur = cur->next) { + if (strcmp(cur->key, "alg") == 0) { + /* We only support RSA-1.5 signatures for now. + Beware of this if we add HMAC support: + https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/ + */ + if (cur->type != GRPC_JSON_STRING || strncmp(cur->value, "RS", 2) || + evp_md_from_alg(cur->value) == NULL) { + gpr_log(GPR_ERROR, "Invalid alg field [%s]", cur->value); + goto error; + } + h->alg = cur->value; + } else if (strcmp(cur->key, "typ") == 0) { + h->typ = validate_string_field(cur, "typ"); + if (h->typ == NULL) goto error; + } else if (strcmp(cur->key, "kid") == 0) { + h->kid = validate_string_field(cur, "kid"); + if (h->kid == NULL) goto error; + } + } + if (h->alg == NULL) { + gpr_log(GPR_ERROR, "Missing alg field."); + goto error; + } + grpc_json_destroy(json); + h->buffer = buffer; + return h; + +error: + grpc_json_destroy(json); + jose_header_destroy(h); + return NULL; +} + +/* --- JWT claims. see http://tools.ietf.org/html/rfc7519#section-4.1 */ + +struct grpc_jwt_claims { + /* Well known properties already parsed. */ + const char *sub; + const char *iss; + const char *aud; + const char *jti; + gpr_timespec iat; + gpr_timespec exp; + gpr_timespec nbf; + + grpc_json *json; + gpr_slice buffer; +}; + +void grpc_jwt_claims_destroy(grpc_jwt_claims *claims) { + grpc_json_destroy(claims->json); + gpr_slice_unref(claims->buffer); + gpr_free(claims); +} + +const grpc_json *grpc_jwt_claims_json(const grpc_jwt_claims *claims) { + if (claims == NULL) return NULL; + return claims->json; +} + +const char *grpc_jwt_claims_subject(const grpc_jwt_claims *claims) { + if (claims == NULL) return NULL; + return claims->sub; +} + +const char *grpc_jwt_claims_issuer(const grpc_jwt_claims *claims) { + if (claims == NULL) return NULL; + return claims->iss; +} + +const char *grpc_jwt_claims_id(const grpc_jwt_claims *claims) { + if (claims == NULL) return NULL; + return claims->jti; +} + +const char *grpc_jwt_claims_audience(const grpc_jwt_claims *claims) { + if (claims == NULL) return NULL; + return claims->aud; +} + +gpr_timespec grpc_jwt_claims_issued_at(const grpc_jwt_claims *claims) { + if (claims == NULL) return gpr_inf_past(GPR_CLOCK_REALTIME); + return claims->iat; +} + +gpr_timespec grpc_jwt_claims_expires_at(const grpc_jwt_claims *claims) { + if (claims == NULL) return gpr_inf_future(GPR_CLOCK_REALTIME); + return claims->exp; +} + +gpr_timespec grpc_jwt_claims_not_before(const grpc_jwt_claims *claims) { + if (claims == NULL) return gpr_inf_past(GPR_CLOCK_REALTIME); + return claims->nbf; +} + +/* Takes ownership of json and buffer even in case of failure. */ +grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, gpr_slice buffer) { + grpc_json *cur; + grpc_jwt_claims *claims = gpr_malloc(sizeof(grpc_jwt_claims)); + memset(claims, 0, sizeof(grpc_jwt_claims)); + claims->json = json; + claims->buffer = buffer; + claims->iat = gpr_inf_past(GPR_CLOCK_REALTIME); + claims->nbf = gpr_inf_past(GPR_CLOCK_REALTIME); + claims->exp = gpr_inf_future(GPR_CLOCK_REALTIME); + + /* Per the spec, all fields are optional. */ + for (cur = json->child; cur != NULL; cur = cur->next) { + if (strcmp(cur->key, "sub") == 0) { + claims->sub = validate_string_field(cur, "sub"); + if (claims->sub == NULL) goto error; + } else if (strcmp(cur->key, "iss") == 0) { + claims->iss = validate_string_field(cur, "iss"); + if (claims->iss == NULL) goto error; + } else if (strcmp(cur->key, "aud") == 0) { + claims->aud = validate_string_field(cur, "aud"); + if (claims->aud == NULL) goto error; + } else if (strcmp(cur->key, "jti") == 0) { + claims->jti = validate_string_field(cur, "jti"); + if (claims->jti == NULL) goto error; + } else if (strcmp(cur->key, "iat") == 0) { + claims->iat = validate_time_field(cur, "iat"); + if (gpr_time_cmp(claims->iat, gpr_time_0(GPR_CLOCK_REALTIME)) == 0) + goto error; + } else if (strcmp(cur->key, "exp") == 0) { + claims->exp = validate_time_field(cur, "exp"); + if (gpr_time_cmp(claims->exp, gpr_time_0(GPR_CLOCK_REALTIME)) == 0) + goto error; + } else if (strcmp(cur->key, "nbf") == 0) { + claims->nbf = validate_time_field(cur, "nbf"); + if (gpr_time_cmp(claims->nbf, gpr_time_0(GPR_CLOCK_REALTIME)) == 0) + goto error; + } + } + return claims; + +error: + grpc_jwt_claims_destroy(claims); + return NULL; +} + +grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims, + const char *audience) { + gpr_timespec skewed_now; + int audience_ok; + + GPR_ASSERT(claims != NULL); + + skewed_now = + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_clock_skew); + if (gpr_time_cmp(skewed_now, claims->nbf) < 0) { + gpr_log(GPR_ERROR, "JWT is not valid yet."); + return GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE; + } + skewed_now = + gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_clock_skew); + if (gpr_time_cmp(skewed_now, claims->exp) > 0) { + gpr_log(GPR_ERROR, "JWT is expired."); + return GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE; + } + + if (audience == NULL) { + audience_ok = claims->aud == NULL; + } else { + audience_ok = claims->aud != NULL && strcmp(audience, claims->aud) == 0; + } + if (!audience_ok) { + gpr_log(GPR_ERROR, "Audience mismatch: expected %s and found %s.", + audience == NULL ? "NULL" : audience, + claims->aud == NULL ? "NULL" : claims->aud); + return GRPC_JWT_VERIFIER_BAD_AUDIENCE; + } + return GRPC_JWT_VERIFIER_OK; +} + +/* --- verifier_cb_ctx object. --- */ + +typedef struct { + grpc_jwt_verifier *verifier; + grpc_pollset *pollset; + jose_header *header; + grpc_jwt_claims *claims; + char *audience; + gpr_slice signature; + gpr_slice signed_data; + void *user_data; + grpc_jwt_verification_done_cb user_cb; +} verifier_cb_ctx; + +/* Takes ownership of the header, claims and signature. */ +static verifier_cb_ctx *verifier_cb_ctx_create( + grpc_jwt_verifier *verifier, grpc_pollset *pollset, jose_header *header, + grpc_jwt_claims *claims, const char *audience, gpr_slice signature, + const char *signed_jwt, size_t signed_jwt_len, void *user_data, + grpc_jwt_verification_done_cb cb) { + verifier_cb_ctx *ctx = gpr_malloc(sizeof(verifier_cb_ctx)); + memset(ctx, 0, sizeof(verifier_cb_ctx)); + ctx->verifier = verifier; + ctx->pollset = pollset; + ctx->header = header; + ctx->audience = gpr_strdup(audience); + ctx->claims = claims; + ctx->signature = signature; + ctx->signed_data = gpr_slice_from_copied_buffer(signed_jwt, signed_jwt_len); + ctx->user_data = user_data; + ctx->user_cb = cb; + return ctx; +} + +void verifier_cb_ctx_destroy(verifier_cb_ctx *ctx) { + if (ctx->audience != NULL) gpr_free(ctx->audience); + if (ctx->claims != NULL) grpc_jwt_claims_destroy(ctx->claims); + gpr_slice_unref(ctx->signature); + gpr_slice_unref(ctx->signed_data); + jose_header_destroy(ctx->header); + /* TODO: see what to do with claims... */ + gpr_free(ctx); +} + +/* --- grpc_jwt_verifier object. --- */ + +/* Clock skew defaults to one minute. */ +gpr_timespec grpc_jwt_verifier_clock_skew = {60, 0, GPR_TIMESPAN}; + +/* Max delay defaults to one minute. */ +gpr_timespec grpc_jwt_verifier_max_delay = {60, 0, GPR_TIMESPAN}; + +typedef struct { + char *email_domain; + char *key_url_prefix; +} email_key_mapping; + +struct grpc_jwt_verifier { + email_key_mapping *mappings; + size_t num_mappings; /* Should be very few, linear search ok. */ + size_t allocated_mappings; + grpc_httpcli_context http_ctx; +}; + +static grpc_json *json_from_http(const grpc_httpcli_response *response) { + grpc_json *json = NULL; + + if (response == NULL) { + gpr_log(GPR_ERROR, "HTTP response is NULL."); + return NULL; + } + if (response->status != 200) { + gpr_log(GPR_ERROR, "Call to http server failed with error %d.", + response->status); + return NULL; + } + + json = grpc_json_parse_string_with_len(response->body, response->body_length); + if (json == NULL) { + gpr_log(GPR_ERROR, "Invalid JSON found in response."); + } + return json; +} + +static const grpc_json *find_property_by_name(const grpc_json *json, + const char *name) { + const grpc_json *cur; + for (cur = json->child; cur != NULL; cur = cur->next) { + if (strcmp(cur->key, name) == 0) return cur; + } + return NULL; +} + +static EVP_PKEY *extract_pkey_from_x509(const char *x509_str) { + X509 *x509 = NULL; + EVP_PKEY *result = NULL; + BIO *bio = BIO_new(BIO_s_mem()); + size_t len = strlen(x509_str); + GPR_ASSERT(len < INT_MAX); + BIO_write(bio, x509_str, (int)len); + x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); + if (x509 == NULL) { + gpr_log(GPR_ERROR, "Unable to parse x509 cert."); + goto end; + } + result = X509_get_pubkey(x509); + if (result == NULL) { + gpr_log(GPR_ERROR, "Cannot find public key in X509 cert."); + } + +end: + BIO_free(bio); + if (x509 != NULL) X509_free(x509); + return result; +} + +static BIGNUM *bignum_from_base64(const char *b64) { + BIGNUM *result = NULL; + gpr_slice bin; + + if (b64 == NULL) return NULL; + bin = grpc_base64_decode(b64, 1); + if (GPR_SLICE_IS_EMPTY(bin)) { + gpr_log(GPR_ERROR, "Invalid base64 for big num."); + return NULL; + } + result = BN_bin2bn(GPR_SLICE_START_PTR(bin), + TSI_SIZE_AS_SIZE(GPR_SLICE_LENGTH(bin)), NULL); + gpr_slice_unref(bin); + return result; +} + +static EVP_PKEY *pkey_from_jwk(const grpc_json *json, const char *kty) { + const grpc_json *key_prop; + RSA *rsa = NULL; + EVP_PKEY *result = NULL; + + GPR_ASSERT(kty != NULL && json != NULL); + if (strcmp(kty, "RSA") != 0) { + gpr_log(GPR_ERROR, "Unsupported key type %s.", kty); + goto end; + } + rsa = RSA_new(); + if (rsa == NULL) { + gpr_log(GPR_ERROR, "Could not create rsa key."); + goto end; + } + for (key_prop = json->child; key_prop != NULL; key_prop = key_prop->next) { + if (strcmp(key_prop->key, "n") == 0) { + rsa->n = bignum_from_base64(validate_string_field(key_prop, "n")); + if (rsa->n == NULL) goto end; + } else if (strcmp(key_prop->key, "e") == 0) { + rsa->e = bignum_from_base64(validate_string_field(key_prop, "e")); + if (rsa->e == NULL) goto end; + } + } + if (rsa->e == NULL || rsa->n == NULL) { + gpr_log(GPR_ERROR, "Missing RSA public key field."); + goto end; + } + result = EVP_PKEY_new(); + EVP_PKEY_set1_RSA(result, rsa); /* uprefs rsa. */ + +end: + if (rsa != NULL) RSA_free(rsa); + return result; +} + +static EVP_PKEY *find_verification_key(const grpc_json *json, + const char *header_alg, + const char *header_kid) { + const grpc_json *jkey; + const grpc_json *jwk_keys; + /* Try to parse the json as a JWK set: + https://tools.ietf.org/html/rfc7517#section-5. */ + jwk_keys = find_property_by_name(json, "keys"); + if (jwk_keys == NULL) { + /* Use the google proprietary format which is: + { : , : , ... } */ + const grpc_json *cur = find_property_by_name(json, header_kid); + if (cur == NULL) return NULL; + return extract_pkey_from_x509(cur->value); + } + + if (jwk_keys->type != GRPC_JSON_ARRAY) { + gpr_log(GPR_ERROR, + "Unexpected value type of keys property in jwks key set."); + return NULL; + } + /* Key format is specified in: + https://tools.ietf.org/html/rfc7518#section-6. */ + for (jkey = jwk_keys->child; jkey != NULL; jkey = jkey->next) { + grpc_json *key_prop; + const char *alg = NULL; + const char *kid = NULL; + const char *kty = NULL; + + if (jkey->type != GRPC_JSON_OBJECT) continue; + for (key_prop = jkey->child; key_prop != NULL; key_prop = key_prop->next) { + if (strcmp(key_prop->key, "alg") == 0 && + key_prop->type == GRPC_JSON_STRING) { + alg = key_prop->value; + } else if (strcmp(key_prop->key, "kid") == 0 && + key_prop->type == GRPC_JSON_STRING) { + kid = key_prop->value; + } else if (strcmp(key_prop->key, "kty") == 0 && + key_prop->type == GRPC_JSON_STRING) { + kty = key_prop->value; + } + } + if (alg != NULL && kid != NULL && kty != NULL && + strcmp(kid, header_kid) == 0 && strcmp(alg, header_alg) == 0) { + return pkey_from_jwk(jkey, kty); + } + } + gpr_log(GPR_ERROR, + "Could not find matching key in key set for kid=%s and alg=%s", + header_kid, header_alg); + return NULL; +} + +static int verify_jwt_signature(EVP_PKEY *key, const char *alg, + gpr_slice signature, gpr_slice signed_data) { + EVP_MD_CTX *md_ctx = EVP_MD_CTX_create(); + const EVP_MD *md = evp_md_from_alg(alg); + int result = 0; + + GPR_ASSERT(md != NULL); /* Checked before. */ + if (md_ctx == NULL) { + gpr_log(GPR_ERROR, "Could not create EVP_MD_CTX."); + goto end; + } + if (EVP_DigestVerifyInit(md_ctx, NULL, md, NULL, key) != 1) { + gpr_log(GPR_ERROR, "EVP_DigestVerifyInit failed."); + goto end; + } + if (EVP_DigestVerifyUpdate(md_ctx, GPR_SLICE_START_PTR(signed_data), + GPR_SLICE_LENGTH(signed_data)) != 1) { + gpr_log(GPR_ERROR, "EVP_DigestVerifyUpdate failed."); + goto end; + } + if (EVP_DigestVerifyFinal(md_ctx, GPR_SLICE_START_PTR(signature), + GPR_SLICE_LENGTH(signature)) != 1) { + gpr_log(GPR_ERROR, "JWT signature verification failed."); + goto end; + } + result = 1; + +end: + if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx); + return result; +} + +static void on_keys_retrieved(grpc_exec_ctx *exec_ctx, void *user_data, + const grpc_httpcli_response *response) { + grpc_json *json = json_from_http(response); + verifier_cb_ctx *ctx = (verifier_cb_ctx *)user_data; + EVP_PKEY *verification_key = NULL; + grpc_jwt_verifier_status status = GRPC_JWT_VERIFIER_GENERIC_ERROR; + grpc_jwt_claims *claims = NULL; + + if (json == NULL) { + status = GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR; + goto end; + } + verification_key = + find_verification_key(json, ctx->header->alg, ctx->header->kid); + if (verification_key == NULL) { + gpr_log(GPR_ERROR, "Could not find verification key with kid %s.", + ctx->header->kid); + status = GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR; + goto end; + } + + if (!verify_jwt_signature(verification_key, ctx->header->alg, ctx->signature, + ctx->signed_data)) { + status = GRPC_JWT_VERIFIER_BAD_SIGNATURE; + goto end; + } + + status = grpc_jwt_claims_check(ctx->claims, ctx->audience); + if (status == GRPC_JWT_VERIFIER_OK) { + /* Pass ownership. */ + claims = ctx->claims; + ctx->claims = NULL; + } + +end: + if (json != NULL) grpc_json_destroy(json); + if (verification_key != NULL) EVP_PKEY_free(verification_key); + ctx->user_cb(ctx->user_data, status, claims); + verifier_cb_ctx_destroy(ctx); +} + +static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data, + const grpc_httpcli_response *response) { + const grpc_json *cur; + grpc_json *json = json_from_http(response); + verifier_cb_ctx *ctx = (verifier_cb_ctx *)user_data; + grpc_httpcli_request req; + const char *jwks_uri; + + /* TODO(jboeuf): Cache the jwks_uri in order to avoid this hop next time. */ + if (json == NULL) goto error; + cur = find_property_by_name(json, "jwks_uri"); + if (cur == NULL) { + gpr_log(GPR_ERROR, "Could not find jwks_uri in openid config."); + goto error; + } + jwks_uri = validate_string_field(cur, "jwks_uri"); + if (jwks_uri == NULL) goto error; + if (strstr(jwks_uri, "https://") != jwks_uri) { + gpr_log(GPR_ERROR, "Invalid non https jwks_uri: %s.", jwks_uri); + goto error; + } + jwks_uri += 8; + req.handshaker = &grpc_httpcli_ssl; + req.host = gpr_strdup(jwks_uri); + req.http.path = strchr(jwks_uri, '/'); + if (req.http.path == NULL) { + req.http.path = ""; + } else { + *(req.host + (req.http.path - jwks_uri)) = '\0'; + } + grpc_httpcli_get( + exec_ctx, &ctx->verifier->http_ctx, ctx->pollset, &req, + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay), + on_keys_retrieved, ctx); + grpc_json_destroy(json); + gpr_free(req.host); + return; + +error: + if (json != NULL) grpc_json_destroy(json); + ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL); + verifier_cb_ctx_destroy(ctx); +} + +static email_key_mapping *verifier_get_mapping(grpc_jwt_verifier *v, + const char *email_domain) { + size_t i; + if (v->mappings == NULL) return NULL; + for (i = 0; i < v->num_mappings; i++) { + if (strcmp(email_domain, v->mappings[i].email_domain) == 0) { + return &v->mappings[i]; + } + } + return NULL; +} + +static void verifier_put_mapping(grpc_jwt_verifier *v, const char *email_domain, + const char *key_url_prefix) { + email_key_mapping *mapping = verifier_get_mapping(v, email_domain); + GPR_ASSERT(v->num_mappings < v->allocated_mappings); + if (mapping != NULL) { + gpr_free(mapping->key_url_prefix); + mapping->key_url_prefix = gpr_strdup(key_url_prefix); + return; + } + v->mappings[v->num_mappings].email_domain = gpr_strdup(email_domain); + v->mappings[v->num_mappings].key_url_prefix = gpr_strdup(key_url_prefix); + v->num_mappings++; + GPR_ASSERT(v->num_mappings <= v->allocated_mappings); +} + +/* Takes ownership of ctx. */ +static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx, + verifier_cb_ctx *ctx) { + const char *at_sign; + grpc_httpcli_response_cb http_cb; + char *path_prefix = NULL; + const char *iss; + grpc_httpcli_request req; + memset(&req, 0, sizeof(grpc_httpcli_request)); + req.handshaker = &grpc_httpcli_ssl; + + GPR_ASSERT(ctx != NULL && ctx->header != NULL && ctx->claims != NULL); + iss = ctx->claims->iss; + if (ctx->header->kid == NULL) { + gpr_log(GPR_ERROR, "Missing kid in jose header."); + goto error; + } + if (iss == NULL) { + gpr_log(GPR_ERROR, "Missing iss in claims."); + goto error; + } + + /* This code relies on: + https://openid.net/specs/openid-connect-discovery-1_0.html + Nobody seems to implement the account/email/webfinger part 2. of the spec + so we will rely instead on email/url mappings if we detect such an issuer. + Part 4, on the other hand is implemented by both google and salesforce. */ + + /* Very non-sophisticated way to detect an email address. Should be good + enough for now... */ + at_sign = strchr(iss, '@'); + if (at_sign != NULL) { + email_key_mapping *mapping; + const char *email_domain = at_sign + 1; + GPR_ASSERT(ctx->verifier != NULL); + mapping = verifier_get_mapping(ctx->verifier, email_domain); + if (mapping == NULL) { + gpr_log(GPR_ERROR, "Missing mapping for issuer email."); + goto error; + } + req.host = gpr_strdup(mapping->key_url_prefix); + path_prefix = strchr(req.host, '/'); + if (path_prefix == NULL) { + gpr_asprintf(&req.http.path, "/%s", iss); + } else { + *(path_prefix++) = '\0'; + gpr_asprintf(&req.http.path, "/%s/%s", path_prefix, iss); + } + http_cb = on_keys_retrieved; + } else { + req.host = gpr_strdup(strstr(iss, "https://") == iss ? iss + 8 : iss); + path_prefix = strchr(req.host, '/'); + if (path_prefix == NULL) { + req.http.path = gpr_strdup(GRPC_OPENID_CONFIG_URL_SUFFIX); + } else { + *(path_prefix++) = 0; + gpr_asprintf(&req.http.path, "/%s%s", path_prefix, + GRPC_OPENID_CONFIG_URL_SUFFIX); + } + http_cb = on_openid_config_retrieved; + } + + grpc_httpcli_get( + exec_ctx, &ctx->verifier->http_ctx, ctx->pollset, &req, + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay), + http_cb, ctx); + gpr_free(req.host); + gpr_free(req.http.path); + return; + +error: + ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL); + verifier_cb_ctx_destroy(ctx); +} + +void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx, + grpc_jwt_verifier *verifier, + grpc_pollset *pollset, const char *jwt, + const char *audience, + grpc_jwt_verification_done_cb cb, + void *user_data) { + const char *dot = NULL; + grpc_json *json; + jose_header *header = NULL; + grpc_jwt_claims *claims = NULL; + gpr_slice header_buffer; + gpr_slice claims_buffer; + gpr_slice signature; + size_t signed_jwt_len; + const char *cur = jwt; + + GPR_ASSERT(verifier != NULL && jwt != NULL && audience != NULL && cb != NULL); + dot = strchr(cur, '.'); + if (dot == NULL) goto error; + json = parse_json_part_from_jwt(cur, (size_t)(dot - cur), &header_buffer); + if (json == NULL) goto error; + header = jose_header_from_json(json, header_buffer); + if (header == NULL) goto error; + + cur = dot + 1; + dot = strchr(cur, '.'); + if (dot == NULL) goto error; + json = parse_json_part_from_jwt(cur, (size_t)(dot - cur), &claims_buffer); + if (json == NULL) goto error; + claims = grpc_jwt_claims_from_json(json, claims_buffer); + if (claims == NULL) goto error; + + signed_jwt_len = (size_t)(dot - jwt); + cur = dot + 1; + signature = grpc_base64_decode(cur, 1); + if (GPR_SLICE_IS_EMPTY(signature)) goto error; + retrieve_key_and_verify( + exec_ctx, + verifier_cb_ctx_create(verifier, pollset, header, claims, audience, + signature, jwt, signed_jwt_len, user_data, cb)); + return; + +error: + if (header != NULL) jose_header_destroy(header); + if (claims != NULL) grpc_jwt_claims_destroy(claims); + cb(user_data, GRPC_JWT_VERIFIER_BAD_FORMAT, NULL); +} + +grpc_jwt_verifier *grpc_jwt_verifier_create( + const grpc_jwt_verifier_email_domain_key_url_mapping *mappings, + size_t num_mappings) { + grpc_jwt_verifier *v = gpr_malloc(sizeof(grpc_jwt_verifier)); + memset(v, 0, sizeof(grpc_jwt_verifier)); + grpc_httpcli_context_init(&v->http_ctx); + + /* We know at least of one mapping. */ + v->allocated_mappings = 1 + num_mappings; + v->mappings = gpr_malloc(v->allocated_mappings * sizeof(email_key_mapping)); + verifier_put_mapping(v, GRPC_GOOGLE_SERVICE_ACCOUNTS_EMAIL_DOMAIN, + GRPC_GOOGLE_SERVICE_ACCOUNTS_KEY_URL_PREFIX); + /* User-Provided mappings. */ + if (mappings != NULL) { + size_t i; + for (i = 0; i < num_mappings; i++) { + verifier_put_mapping(v, mappings[i].email_domain, + mappings[i].key_url_prefix); + } + } + return v; +} + +void grpc_jwt_verifier_destroy(grpc_jwt_verifier *v) { + size_t i; + if (v == NULL) return; + grpc_httpcli_context_destroy(&v->http_ctx); + if (v->mappings != NULL) { + for (i = 0; i < v->num_mappings; i++) { + gpr_free(v->mappings[i].email_domain); + gpr_free(v->mappings[i].key_url_prefix); + } + gpr_free(v->mappings); + } + gpr_free(v); +} diff --git a/src/core/lib/security/jwt_verifier.h b/src/core/lib/security/jwt_verifier.h new file mode 100644 index 0000000000..d898d2193f --- /dev/null +++ b/src/core/lib/security/jwt_verifier.h @@ -0,0 +1,136 @@ +/* + * + * Copyright 2015-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_SECURITY_JWT_VERIFIER_H +#define GRPC_CORE_SECURITY_JWT_VERIFIER_H + +#include "src/core/iomgr/pollset.h" +#include "src/core/json/json.h" + +#include +#include + +/* --- Constants. --- */ + +#define GRPC_OPENID_CONFIG_URL_SUFFIX "/.well-known/openid-configuration" +#define GRPC_GOOGLE_SERVICE_ACCOUNTS_EMAIL_DOMAIN \ + "developer.gserviceaccount.com" +#define GRPC_GOOGLE_SERVICE_ACCOUNTS_KEY_URL_PREFIX \ + "www.googleapis.com/robot/v1/metadata/x509" + +/* --- grpc_jwt_verifier_status. --- */ + +typedef enum { + GRPC_JWT_VERIFIER_OK = 0, + GRPC_JWT_VERIFIER_BAD_SIGNATURE, + GRPC_JWT_VERIFIER_BAD_FORMAT, + GRPC_JWT_VERIFIER_BAD_AUDIENCE, + GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, + GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE, + GRPC_JWT_VERIFIER_GENERIC_ERROR +} grpc_jwt_verifier_status; + +const char *grpc_jwt_verifier_status_to_string(grpc_jwt_verifier_status status); + +/* --- grpc_jwt_claims. --- */ + +typedef struct grpc_jwt_claims grpc_jwt_claims; + +void grpc_jwt_claims_destroy(grpc_jwt_claims *claims); + +/* Returns the whole JSON tree of the claims. */ +const grpc_json *grpc_jwt_claims_json(const grpc_jwt_claims *claims); + +/* Access to registered claims in https://tools.ietf.org/html/rfc7519#page-9 */ +const char *grpc_jwt_claims_subject(const grpc_jwt_claims *claims); +const char *grpc_jwt_claims_issuer(const grpc_jwt_claims *claims); +const char *grpc_jwt_claims_id(const grpc_jwt_claims *claims); +const char *grpc_jwt_claims_audience(const grpc_jwt_claims *claims); +gpr_timespec grpc_jwt_claims_issued_at(const grpc_jwt_claims *claims); +gpr_timespec grpc_jwt_claims_expires_at(const grpc_jwt_claims *claims); +gpr_timespec grpc_jwt_claims_not_before(const grpc_jwt_claims *claims); + +/* --- grpc_jwt_verifier. --- */ + +typedef struct grpc_jwt_verifier grpc_jwt_verifier; + +typedef struct { + /* The email domain is the part after the @ sign. */ + const char *email_domain; + + /* The key url prefix will be used to get the public key from the issuer: + https:/// + Therefore the key_url_prefix must NOT contain https://. */ + const char *key_url_prefix; +} grpc_jwt_verifier_email_domain_key_url_mapping; + +/* Globals to control the verifier. Not thread-safe. */ +extern gpr_timespec grpc_jwt_verifier_clock_skew; +extern gpr_timespec grpc_jwt_verifier_max_delay; + +/* The verifier can be created with some custom mappings to help with key + discovery in the case where the issuer is an email address. + mappings can be NULL in which case num_mappings MUST be 0. + A verifier object has one built-in mapping (unless overridden): + GRPC_GOOGLE_SERVICE_ACCOUNTS_EMAIL_DOMAIN -> + GRPC_GOOGLE_SERVICE_ACCOUNTS_KEY_URL_PREFIX.*/ +grpc_jwt_verifier *grpc_jwt_verifier_create( + const grpc_jwt_verifier_email_domain_key_url_mapping *mappings, + size_t num_mappings); + +/*The verifier must not be destroyed if there are still outstanding callbacks.*/ +void grpc_jwt_verifier_destroy(grpc_jwt_verifier *verifier); + +/* User provided callback that will be called when the verification of the JWT + is done (maybe in another thread). + It is the responsibility of the callee to call grpc_jwt_claims_destroy on + the claims. */ +typedef void (*grpc_jwt_verification_done_cb)(void *user_data, + grpc_jwt_verifier_status status, + grpc_jwt_claims *claims); + +/* Verifies for the JWT for the given expected audience. */ +void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx, + grpc_jwt_verifier *verifier, + grpc_pollset *pollset, const char *jwt, + const char *audience, + grpc_jwt_verification_done_cb cb, + void *user_data); + +/* --- TESTING ONLY exposed functions. --- */ + +grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, gpr_slice buffer); +grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims, + const char *audience); + +#endif /* GRPC_CORE_SECURITY_JWT_VERIFIER_H */ diff --git a/src/core/lib/security/secure_endpoint.c b/src/core/lib/security/secure_endpoint.c new file mode 100644 index 0000000000..58b081dc4a --- /dev/null +++ b/src/core/lib/security/secure_endpoint.c @@ -0,0 +1,384 @@ +/* + * + * Copyright 2015-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/security/secure_endpoint.h" +#include +#include +#include +#include +#include +#include "src/core/debug/trace.h" +#include "src/core/support/string.h" +#include "src/core/tsi/transport_security_interface.h" + +#define STAGING_BUFFER_SIZE 8192 + +typedef struct { + grpc_endpoint base; + grpc_endpoint *wrapped_ep; + struct tsi_frame_protector *protector; + gpr_mu protector_mu; + /* saved upper level callbacks and user_data. */ + grpc_closure *read_cb; + grpc_closure *write_cb; + grpc_closure on_read; + gpr_slice_buffer *read_buffer; + gpr_slice_buffer source_buffer; + /* saved handshaker leftover data to unprotect. */ + gpr_slice_buffer leftover_bytes; + /* buffers for read and write */ + gpr_slice read_staging_buffer; + + gpr_slice write_staging_buffer; + gpr_slice_buffer output_buffer; + + gpr_refcount ref; +} secure_endpoint; + +int grpc_trace_secure_endpoint = 0; + +static void destroy(grpc_exec_ctx *exec_ctx, secure_endpoint *secure_ep) { + secure_endpoint *ep = secure_ep; + grpc_endpoint_destroy(exec_ctx, ep->wrapped_ep); + tsi_frame_protector_destroy(ep->protector); + gpr_slice_buffer_destroy(&ep->leftover_bytes); + gpr_slice_unref(ep->read_staging_buffer); + gpr_slice_unref(ep->write_staging_buffer); + gpr_slice_buffer_destroy(&ep->output_buffer); + gpr_slice_buffer_destroy(&ep->source_buffer); + gpr_mu_destroy(&ep->protector_mu); + gpr_free(ep); +} + +/*#define GRPC_SECURE_ENDPOINT_REFCOUNT_DEBUG*/ +#ifdef GRPC_SECURE_ENDPOINT_REFCOUNT_DEBUG +#define SECURE_ENDPOINT_UNREF(exec_ctx, ep, reason) \ + secure_endpoint_unref((exec_ctx), (ep), (reason), __FILE__, __LINE__) +#define SECURE_ENDPOINT_REF(ep, reason) \ + secure_endpoint_ref((ep), (reason), __FILE__, __LINE__) +static void secure_endpoint_unref(secure_endpoint *ep, + grpc_closure_list *closure_list, + const char *reason, const char *file, + int line) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SECENDP unref %p : %s %d -> %d", + ep, reason, ep->ref.count, ep->ref.count - 1); + if (gpr_unref(&ep->ref)) { + destroy(exec_ctx, ep); + } +} + +static void secure_endpoint_ref(secure_endpoint *ep, const char *reason, + const char *file, int line) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SECENDP ref %p : %s %d -> %d", + ep, reason, ep->ref.count, ep->ref.count + 1); + gpr_ref(&ep->ref); +} +#else +#define SECURE_ENDPOINT_UNREF(exec_ctx, ep, reason) \ + secure_endpoint_unref((exec_ctx), (ep)) +#define SECURE_ENDPOINT_REF(ep, reason) secure_endpoint_ref((ep)) +static void secure_endpoint_unref(grpc_exec_ctx *exec_ctx, + secure_endpoint *ep) { + if (gpr_unref(&ep->ref)) { + destroy(exec_ctx, ep); + } +} + +static void secure_endpoint_ref(secure_endpoint *ep) { gpr_ref(&ep->ref); } +#endif + +static void flush_read_staging_buffer(secure_endpoint *ep, uint8_t **cur, + uint8_t **end) { + gpr_slice_buffer_add(ep->read_buffer, ep->read_staging_buffer); + ep->read_staging_buffer = gpr_slice_malloc(STAGING_BUFFER_SIZE); + *cur = GPR_SLICE_START_PTR(ep->read_staging_buffer); + *end = GPR_SLICE_END_PTR(ep->read_staging_buffer); +} + +static void call_read_cb(grpc_exec_ctx *exec_ctx, secure_endpoint *ep, + bool success) { + if (grpc_trace_secure_endpoint) { + size_t i; + for (i = 0; i < ep->read_buffer->count; i++) { + char *data = gpr_dump_slice(ep->read_buffer->slices[i], + GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "READ %p: %s", ep, data); + gpr_free(data); + } + } + ep->read_buffer = NULL; + grpc_exec_ctx_enqueue(exec_ctx, ep->read_cb, success, NULL); + SECURE_ENDPOINT_UNREF(exec_ctx, ep, "read"); +} + +static void on_read(grpc_exec_ctx *exec_ctx, void *user_data, bool success) { + unsigned i; + uint8_t keep_looping = 0; + tsi_result result = TSI_OK; + secure_endpoint *ep = (secure_endpoint *)user_data; + uint8_t *cur = GPR_SLICE_START_PTR(ep->read_staging_buffer); + uint8_t *end = GPR_SLICE_END_PTR(ep->read_staging_buffer); + + if (!success) { + gpr_slice_buffer_reset_and_unref(ep->read_buffer); + call_read_cb(exec_ctx, ep, 0); + return; + } + + /* TODO(yangg) check error, maybe bail out early */ + for (i = 0; i < ep->source_buffer.count; i++) { + gpr_slice encrypted = ep->source_buffer.slices[i]; + uint8_t *message_bytes = GPR_SLICE_START_PTR(encrypted); + size_t message_size = GPR_SLICE_LENGTH(encrypted); + + while (message_size > 0 || keep_looping) { + size_t unprotected_buffer_size_written = (size_t)(end - cur); + size_t processed_message_size = message_size; + gpr_mu_lock(&ep->protector_mu); + result = tsi_frame_protector_unprotect(ep->protector, message_bytes, + &processed_message_size, cur, + &unprotected_buffer_size_written); + gpr_mu_unlock(&ep->protector_mu); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Decryption error: %s", + tsi_result_to_string(result)); + break; + } + message_bytes += processed_message_size; + message_size -= processed_message_size; + cur += unprotected_buffer_size_written; + + if (cur == end) { + flush_read_staging_buffer(ep, &cur, &end); + /* Force to enter the loop again to extract buffered bytes in protector. + The bytes could be buffered because of running out of staging_buffer. + If this happens at the end of all slices, doing another unprotect + avoids leaving data in the protector. */ + keep_looping = 1; + } else if (unprotected_buffer_size_written > 0) { + keep_looping = 1; + } else { + keep_looping = 0; + } + } + if (result != TSI_OK) break; + } + + if (cur != GPR_SLICE_START_PTR(ep->read_staging_buffer)) { + gpr_slice_buffer_add( + ep->read_buffer, + gpr_slice_split_head( + &ep->read_staging_buffer, + (size_t)(cur - GPR_SLICE_START_PTR(ep->read_staging_buffer)))); + } + + /* TODO(yangg) experiment with moving this block after read_cb to see if it + helps latency */ + gpr_slice_buffer_reset_and_unref(&ep->source_buffer); + + if (result != TSI_OK) { + gpr_slice_buffer_reset_and_unref(ep->read_buffer); + call_read_cb(exec_ctx, ep, 0); + return; + } + + call_read_cb(exec_ctx, ep, 1); +} + +static void endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep, + gpr_slice_buffer *slices, grpc_closure *cb) { + secure_endpoint *ep = (secure_endpoint *)secure_ep; + ep->read_cb = cb; + ep->read_buffer = slices; + gpr_slice_buffer_reset_and_unref(ep->read_buffer); + + SECURE_ENDPOINT_REF(ep, "read"); + if (ep->leftover_bytes.count) { + gpr_slice_buffer_swap(&ep->leftover_bytes, &ep->source_buffer); + GPR_ASSERT(ep->leftover_bytes.count == 0); + on_read(exec_ctx, ep, 1); + return; + } + + grpc_endpoint_read(exec_ctx, ep->wrapped_ep, &ep->source_buffer, + &ep->on_read); +} + +static void flush_write_staging_buffer(secure_endpoint *ep, uint8_t **cur, + uint8_t **end) { + gpr_slice_buffer_add(&ep->output_buffer, ep->write_staging_buffer); + ep->write_staging_buffer = gpr_slice_malloc(STAGING_BUFFER_SIZE); + *cur = GPR_SLICE_START_PTR(ep->write_staging_buffer); + *end = GPR_SLICE_END_PTR(ep->write_staging_buffer); +} + +static void endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep, + gpr_slice_buffer *slices, grpc_closure *cb) { + unsigned i; + tsi_result result = TSI_OK; + secure_endpoint *ep = (secure_endpoint *)secure_ep; + uint8_t *cur = GPR_SLICE_START_PTR(ep->write_staging_buffer); + uint8_t *end = GPR_SLICE_END_PTR(ep->write_staging_buffer); + + gpr_slice_buffer_reset_and_unref(&ep->output_buffer); + + if (grpc_trace_secure_endpoint) { + for (i = 0; i < slices->count; i++) { + char *data = + gpr_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "WRITE %p: %s", ep, data); + gpr_free(data); + } + } + + for (i = 0; i < slices->count; i++) { + gpr_slice plain = slices->slices[i]; + uint8_t *message_bytes = GPR_SLICE_START_PTR(plain); + size_t message_size = GPR_SLICE_LENGTH(plain); + while (message_size > 0) { + size_t protected_buffer_size_to_send = (size_t)(end - cur); + size_t processed_message_size = message_size; + gpr_mu_lock(&ep->protector_mu); + result = tsi_frame_protector_protect(ep->protector, message_bytes, + &processed_message_size, cur, + &protected_buffer_size_to_send); + gpr_mu_unlock(&ep->protector_mu); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Encryption error: %s", + tsi_result_to_string(result)); + break; + } + message_bytes += processed_message_size; + message_size -= processed_message_size; + cur += protected_buffer_size_to_send; + + if (cur == end) { + flush_write_staging_buffer(ep, &cur, &end); + } + } + if (result != TSI_OK) break; + } + if (result == TSI_OK) { + size_t still_pending_size; + do { + size_t protected_buffer_size_to_send = (size_t)(end - cur); + gpr_mu_lock(&ep->protector_mu); + result = tsi_frame_protector_protect_flush(ep->protector, cur, + &protected_buffer_size_to_send, + &still_pending_size); + gpr_mu_unlock(&ep->protector_mu); + if (result != TSI_OK) break; + cur += protected_buffer_size_to_send; + if (cur == end) { + flush_write_staging_buffer(ep, &cur, &end); + } + } while (still_pending_size > 0); + if (cur != GPR_SLICE_START_PTR(ep->write_staging_buffer)) { + gpr_slice_buffer_add( + &ep->output_buffer, + gpr_slice_split_head( + &ep->write_staging_buffer, + (size_t)(cur - GPR_SLICE_START_PTR(ep->write_staging_buffer)))); + } + } + + if (result != TSI_OK) { + /* TODO(yangg) do different things according to the error type? */ + gpr_slice_buffer_reset_and_unref(&ep->output_buffer); + grpc_exec_ctx_enqueue(exec_ctx, cb, false, NULL); + return; + } + + grpc_endpoint_write(exec_ctx, ep->wrapped_ep, &ep->output_buffer, cb); +} + +static void endpoint_shutdown(grpc_exec_ctx *exec_ctx, + grpc_endpoint *secure_ep) { + secure_endpoint *ep = (secure_endpoint *)secure_ep; + grpc_endpoint_shutdown(exec_ctx, ep->wrapped_ep); +} + +static void endpoint_destroy(grpc_exec_ctx *exec_ctx, + grpc_endpoint *secure_ep) { + secure_endpoint *ep = (secure_endpoint *)secure_ep; + SECURE_ENDPOINT_UNREF(exec_ctx, ep, "destroy"); +} + +static void endpoint_add_to_pollset(grpc_exec_ctx *exec_ctx, + grpc_endpoint *secure_ep, + grpc_pollset *pollset) { + secure_endpoint *ep = (secure_endpoint *)secure_ep; + grpc_endpoint_add_to_pollset(exec_ctx, ep->wrapped_ep, pollset); +} + +static void endpoint_add_to_pollset_set(grpc_exec_ctx *exec_ctx, + grpc_endpoint *secure_ep, + grpc_pollset_set *pollset_set) { + secure_endpoint *ep = (secure_endpoint *)secure_ep; + grpc_endpoint_add_to_pollset_set(exec_ctx, ep->wrapped_ep, pollset_set); +} + +static char *endpoint_get_peer(grpc_endpoint *secure_ep) { + secure_endpoint *ep = (secure_endpoint *)secure_ep; + return grpc_endpoint_get_peer(ep->wrapped_ep); +} + +static const grpc_endpoint_vtable vtable = { + endpoint_read, endpoint_write, + endpoint_add_to_pollset, endpoint_add_to_pollset_set, + endpoint_shutdown, endpoint_destroy, + endpoint_get_peer}; + +grpc_endpoint *grpc_secure_endpoint_create( + struct tsi_frame_protector *protector, grpc_endpoint *transport, + gpr_slice *leftover_slices, size_t leftover_nslices) { + size_t i; + secure_endpoint *ep = (secure_endpoint *)gpr_malloc(sizeof(secure_endpoint)); + ep->base.vtable = &vtable; + ep->wrapped_ep = transport; + ep->protector = protector; + gpr_slice_buffer_init(&ep->leftover_bytes); + for (i = 0; i < leftover_nslices; i++) { + gpr_slice_buffer_add(&ep->leftover_bytes, + gpr_slice_ref(leftover_slices[i])); + } + ep->write_staging_buffer = gpr_slice_malloc(STAGING_BUFFER_SIZE); + ep->read_staging_buffer = gpr_slice_malloc(STAGING_BUFFER_SIZE); + gpr_slice_buffer_init(&ep->output_buffer); + gpr_slice_buffer_init(&ep->source_buffer); + ep->read_buffer = NULL; + grpc_closure_init(&ep->on_read, on_read, ep); + gpr_mu_init(&ep->protector_mu); + gpr_ref_init(&ep->ref, 1); + return &ep->base; +} diff --git a/src/core/lib/security/secure_endpoint.h b/src/core/lib/security/secure_endpoint.h new file mode 100644 index 0000000000..7368f8424b --- /dev/null +++ b/src/core/lib/security/secure_endpoint.h @@ -0,0 +1,49 @@ +/* + * + * Copyright 2015-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_SECURITY_SECURE_ENDPOINT_H +#define GRPC_CORE_SECURITY_SECURE_ENDPOINT_H + +#include +#include "src/core/iomgr/endpoint.h" + +struct tsi_frame_protector; + +extern int grpc_trace_secure_endpoint; + +/* Takes ownership of protector and to_wrap, and refs leftover_slices. */ +grpc_endpoint *grpc_secure_endpoint_create( + struct tsi_frame_protector *protector, grpc_endpoint *to_wrap, + gpr_slice *leftover_slices, size_t leftover_nslices); + +#endif /* GRPC_CORE_SECURITY_SECURE_ENDPOINT_H */ diff --git a/src/core/lib/security/security_connector.c b/src/core/lib/security/security_connector.c new file mode 100644 index 0000000000..fbec263eed --- /dev/null +++ b/src/core/lib/security/security_connector.c @@ -0,0 +1,812 @@ +/* + * + * Copyright 2015-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/security/security_connector.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "src/core/security/credentials.h" +#include "src/core/security/handshake.h" +#include "src/core/security/secure_endpoint.h" +#include "src/core/security/security_context.h" +#include "src/core/support/env.h" +#include "src/core/support/load_file.h" +#include "src/core/support/string.h" +#include "src/core/transport/chttp2/alpn.h" +#include "src/core/tsi/fake_transport_security.h" +#include "src/core/tsi/ssl_transport_security.h" + +/* -- Constants. -- */ + +#ifndef INSTALL_PREFIX +static const char *installed_roots_path = "/usr/share/grpc/roots.pem"; +#else +static const char *installed_roots_path = + INSTALL_PREFIX "/share/grpc/roots.pem"; +#endif + +/* -- Overridden default roots. -- */ + +static grpc_ssl_roots_override_callback ssl_roots_override_cb = NULL; + +void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) { + ssl_roots_override_cb = cb; +} + +/* -- Cipher suites. -- */ + +/* Defines the cipher suites that we accept by default. All these cipher suites + are compliant with HTTP2. */ +#define GRPC_SSL_CIPHER_SUITES \ + "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-" \ + "SHA384:ECDHE-RSA-AES256-GCM-SHA384" + +static gpr_once cipher_suites_once = GPR_ONCE_INIT; +static const char *cipher_suites = NULL; + +static void init_cipher_suites(void) { + char *overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES"); + cipher_suites = overridden != NULL ? overridden : GRPC_SSL_CIPHER_SUITES; +} + +static const char *ssl_cipher_suites(void) { + gpr_once_init(&cipher_suites_once, init_cipher_suites); + return cipher_suites; +} + +/* -- Common methods. -- */ + +/* Returns the first property with that name. */ +const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer, + const char *name) { + size_t i; + if (peer == NULL) return NULL; + for (i = 0; i < peer->property_count; i++) { + const tsi_peer_property *property = &peer->properties[i]; + if (name == NULL && property->name == NULL) { + return property; + } + if (name != NULL && property->name != NULL && + strcmp(property->name, name) == 0) { + return property; + } + } + return NULL; +} + +void grpc_server_security_connector_shutdown( + grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector) { + grpc_security_connector_handshake_list *tmp; + gpr_mu_lock(&connector->mu); + while (connector->handshaking_handshakes) { + tmp = connector->handshaking_handshakes; + grpc_security_handshake_shutdown( + exec_ctx, connector->handshaking_handshakes->handshake); + connector->handshaking_handshakes = tmp->next; + gpr_free(tmp); + } + gpr_mu_unlock(&connector->mu); +} + +void grpc_channel_security_connector_do_handshake( + grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, + grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb, + void *user_data) { + if (sc == NULL || nonsecure_endpoint == NULL) { + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); + } else { + sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, cb, user_data); + } +} + +void grpc_server_security_connector_do_handshake( + grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, + grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, void *user_data) { + if (sc == NULL || nonsecure_endpoint == NULL) { + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); + } else { + sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, cb, user_data); + } +} + +void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx, + grpc_security_connector *sc, + tsi_peer peer, + grpc_security_peer_check_cb cb, + void *user_data) { + if (sc == NULL) { + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL); + tsi_peer_destruct(&peer); + } else { + sc->vtable->check_peer(exec_ctx, sc, peer, cb, user_data); + } +} + +void grpc_channel_security_connector_check_call_host( + grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, + const char *host, grpc_auth_context *auth_context, + grpc_security_call_host_check_cb cb, void *user_data) { + if (sc == NULL || sc->check_call_host == NULL) { + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR); + } else { + sc->check_call_host(exec_ctx, sc, host, auth_context, cb, user_data); + } +} + +#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG +grpc_security_connector *grpc_security_connector_ref( + grpc_security_connector *sc, const char *file, int line, + const char *reason) { + if (sc == NULL) return NULL; + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "SECURITY_CONNECTOR:%p ref %d -> %d %s", sc, + (int)sc->refcount.count, (int)sc->refcount.count + 1, reason); +#else +grpc_security_connector *grpc_security_connector_ref( + grpc_security_connector *sc) { + if (sc == NULL) return NULL; +#endif + gpr_ref(&sc->refcount); + return sc; +} + +#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG +void grpc_security_connector_unref(grpc_security_connector *sc, + const char *file, int line, + const char *reason) { + if (sc == NULL) return; + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "SECURITY_CONNECTOR:%p unref %d -> %d %s", sc, + (int)sc->refcount.count, (int)sc->refcount.count - 1, reason); +#else +void grpc_security_connector_unref(grpc_security_connector *sc) { + if (sc == NULL) return; +#endif + if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc); +} + +static void connector_pointer_arg_destroy(void *p) { + GRPC_SECURITY_CONNECTOR_UNREF(p, "connector_pointer_arg"); +} + +static void *connector_pointer_arg_copy(void *p) { + return GRPC_SECURITY_CONNECTOR_REF(p, "connector_pointer_arg"); +} + +static int connector_pointer_cmp(void *a, void *b) { return GPR_ICMP(a, b); } + +static const grpc_arg_pointer_vtable connector_pointer_vtable = { + connector_pointer_arg_copy, connector_pointer_arg_destroy, + connector_pointer_cmp}; + +grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc) { + grpc_arg result; + result.type = GRPC_ARG_POINTER; + result.key = GRPC_SECURITY_CONNECTOR_ARG; + result.value.pointer.vtable = &connector_pointer_vtable; + result.value.pointer.p = sc; + return result; +} + +grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg) { + if (strcmp(arg->key, GRPC_SECURITY_CONNECTOR_ARG)) return NULL; + if (arg->type != GRPC_ARG_POINTER) { + gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, + GRPC_SECURITY_CONNECTOR_ARG); + return NULL; + } + return arg->value.pointer.p; +} + +grpc_security_connector *grpc_find_security_connector_in_args( + const grpc_channel_args *args) { + size_t i; + if (args == NULL) return NULL; + for (i = 0; i < args->num_args; i++) { + grpc_security_connector *sc = + grpc_security_connector_from_arg(&args->args[i]); + if (sc != NULL) return sc; + } + return NULL; +} + +/* -- Fake implementation. -- */ + +static void fake_channel_destroy(grpc_security_connector *sc) { + grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc; + grpc_call_credentials_unref(c->request_metadata_creds); + gpr_free(sc); +} + +static void fake_server_destroy(grpc_security_connector *sc) { + grpc_server_security_connector *c = (grpc_server_security_connector *)sc; + gpr_mu_destroy(&c->mu); + gpr_free(sc); +} + +static void fake_check_peer(grpc_exec_ctx *exec_ctx, + grpc_security_connector *sc, tsi_peer peer, + grpc_security_peer_check_cb cb, void *user_data) { + const char *prop_name; + grpc_security_status status = GRPC_SECURITY_OK; + grpc_auth_context *auth_context = NULL; + if (peer.property_count != 1) { + gpr_log(GPR_ERROR, "Fake peers should only have 1 property."); + status = GRPC_SECURITY_ERROR; + goto end; + } + prop_name = peer.properties[0].name; + if (prop_name == NULL || + strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) { + gpr_log(GPR_ERROR, "Unexpected property in fake peer: %s.", + prop_name == NULL ? "" : prop_name); + status = GRPC_SECURITY_ERROR; + goto end; + } + if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE, + peer.properties[0].value.length)) { + gpr_log(GPR_ERROR, "Invalid value for cert type property."); + status = GRPC_SECURITY_ERROR; + goto end; + } + auth_context = grpc_auth_context_create(NULL); + grpc_auth_context_add_cstring_property( + auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + GRPC_FAKE_TRANSPORT_SECURITY_TYPE); + +end: + cb(exec_ctx, user_data, status, auth_context); + grpc_auth_context_unref(auth_context); + tsi_peer_destruct(&peer); +} + +static void fake_channel_check_call_host(grpc_exec_ctx *exec_ctx, + grpc_channel_security_connector *sc, + const char *host, + grpc_auth_context *auth_context, + grpc_security_call_host_check_cb cb, + void *user_data) { + cb(exec_ctx, user_data, GRPC_SECURITY_OK); +} + +static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx, + grpc_channel_security_connector *sc, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *user_data) { + grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), &sc->base, + true, nonsecure_endpoint, cb, user_data); +} + +static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx, + grpc_server_security_connector *sc, + grpc_tcp_server_acceptor *acceptor, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *user_data) { + grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), &sc->base, + false, nonsecure_endpoint, cb, user_data); +} + +static grpc_security_connector_vtable fake_channel_vtable = { + fake_channel_destroy, fake_check_peer}; + +static grpc_security_connector_vtable fake_server_vtable = {fake_server_destroy, + fake_check_peer}; + +grpc_channel_security_connector *grpc_fake_channel_security_connector_create( + grpc_call_credentials *request_metadata_creds) { + grpc_channel_security_connector *c = gpr_malloc(sizeof(*c)); + memset(c, 0, sizeof(*c)); + gpr_ref_init(&c->base.refcount, 1); + c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; + c->base.vtable = &fake_channel_vtable; + c->request_metadata_creds = grpc_call_credentials_ref(request_metadata_creds); + c->check_call_host = fake_channel_check_call_host; + c->do_handshake = fake_channel_do_handshake; + return c; +} + +grpc_server_security_connector *grpc_fake_server_security_connector_create( + void) { + grpc_server_security_connector *c = + gpr_malloc(sizeof(grpc_server_security_connector)); + memset(c, 0, sizeof(*c)); + gpr_ref_init(&c->base.refcount, 1); + c->base.vtable = &fake_server_vtable; + c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; + c->do_handshake = fake_server_do_handshake; + gpr_mu_init(&c->mu); + return c; +} + +/* --- Ssl implementation. --- */ + +typedef struct { + grpc_channel_security_connector base; + tsi_ssl_handshaker_factory *handshaker_factory; + char *target_name; + char *overridden_target_name; +} grpc_ssl_channel_security_connector; + +typedef struct { + grpc_server_security_connector base; + tsi_ssl_handshaker_factory *handshaker_factory; +} grpc_ssl_server_security_connector; + +static void ssl_channel_destroy(grpc_security_connector *sc) { + grpc_ssl_channel_security_connector *c = + (grpc_ssl_channel_security_connector *)sc; + grpc_call_credentials_unref(c->base.request_metadata_creds); + if (c->handshaker_factory != NULL) { + tsi_ssl_handshaker_factory_destroy(c->handshaker_factory); + } + if (c->target_name != NULL) gpr_free(c->target_name); + if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name); + gpr_free(sc); +} + +static void ssl_server_destroy(grpc_security_connector *sc) { + grpc_ssl_server_security_connector *c = + (grpc_ssl_server_security_connector *)sc; + + if (c->handshaker_factory != NULL) { + tsi_ssl_handshaker_factory_destroy(c->handshaker_factory); + } + gpr_mu_destroy(&c->base.mu); + gpr_free(sc); +} + +static grpc_security_status ssl_create_handshaker( + tsi_ssl_handshaker_factory *handshaker_factory, bool is_client, + const char *peer_name, tsi_handshaker **handshaker) { + tsi_result result = TSI_OK; + if (handshaker_factory == NULL) return GRPC_SECURITY_ERROR; + result = tsi_ssl_handshaker_factory_create_handshaker( + handshaker_factory, is_client ? peer_name : NULL, handshaker); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return GRPC_SECURITY_ERROR; + } + return GRPC_SECURITY_OK; +} + +static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx, + grpc_channel_security_connector *sc, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *user_data) { + grpc_ssl_channel_security_connector *c = + (grpc_ssl_channel_security_connector *)sc; + tsi_handshaker *handshaker; + grpc_security_status status = ssl_create_handshaker( + c->handshaker_factory, true, + c->overridden_target_name != NULL ? c->overridden_target_name + : c->target_name, + &handshaker); + if (status != GRPC_SECURITY_OK) { + cb(exec_ctx, user_data, status, NULL, NULL); + } else { + grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true, + nonsecure_endpoint, cb, user_data); + } +} + +static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx, + grpc_server_security_connector *sc, + grpc_tcp_server_acceptor *acceptor, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, + void *user_data) { + grpc_ssl_server_security_connector *c = + (grpc_ssl_server_security_connector *)sc; + tsi_handshaker *handshaker; + grpc_security_status status = + ssl_create_handshaker(c->handshaker_factory, false, NULL, &handshaker); + if (status != GRPC_SECURITY_OK) { + cb(exec_ctx, user_data, status, NULL, NULL); + } else { + grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, false, + nonsecure_endpoint, cb, user_data); + } +} + +static int ssl_host_matches_name(const tsi_peer *peer, const char *peer_name) { + char *allocated_name = NULL; + int r; + + if (strchr(peer_name, ':') != NULL) { + char *ignored_port; + gpr_split_host_port(peer_name, &allocated_name, &ignored_port); + gpr_free(ignored_port); + peer_name = allocated_name; + if (!peer_name) return 0; + } + r = tsi_ssl_peer_matches_name(peer, peer_name); + gpr_free(allocated_name); + return r; +} + +grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer) { + size_t i; + grpc_auth_context *ctx = NULL; + const char *peer_identity_property_name = NULL; + + /* The caller has checked the certificate type property. */ + GPR_ASSERT(peer->property_count >= 1); + ctx = grpc_auth_context_create(NULL); + grpc_auth_context_add_cstring_property( + ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + GRPC_SSL_TRANSPORT_SECURITY_TYPE); + for (i = 0; i < peer->property_count; i++) { + const tsi_peer_property *prop = &peer->properties[i]; + if (prop->name == NULL) continue; + if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) { + /* If there is no subject alt name, have the CN as the identity. */ + if (peer_identity_property_name == NULL) { + peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME; + } + grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME, + prop->value.data, prop->value.length); + } else if (strcmp(prop->name, + TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { + peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME; + grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME, + prop->value.data, prop->value.length); + } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) { + grpc_auth_context_add_property(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME, + prop->value.data, prop->value.length); + } + } + if (peer_identity_property_name != NULL) { + GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( + ctx, peer_identity_property_name) == 1); + } + return ctx; +} + +static grpc_security_status ssl_check_peer(grpc_security_connector *sc, + const char *peer_name, + const tsi_peer *peer, + grpc_auth_context **auth_context) { + /* Check the ALPN. */ + const tsi_peer_property *p = + tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); + if (p == NULL) { + gpr_log(GPR_ERROR, "Missing selected ALPN property."); + return GRPC_SECURITY_ERROR; + } + if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) { + gpr_log(GPR_ERROR, "Invalid ALPN value."); + return GRPC_SECURITY_ERROR; + } + + /* Check the peer name if specified. */ + if (peer_name != NULL && !ssl_host_matches_name(peer, peer_name)) { + gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name); + return GRPC_SECURITY_ERROR; + } + *auth_context = tsi_ssl_peer_to_auth_context(peer); + return GRPC_SECURITY_OK; +} + +static void ssl_channel_check_peer(grpc_exec_ctx *exec_ctx, + grpc_security_connector *sc, tsi_peer peer, + grpc_security_peer_check_cb cb, + void *user_data) { + grpc_ssl_channel_security_connector *c = + (grpc_ssl_channel_security_connector *)sc; + grpc_security_status status; + grpc_auth_context *auth_context = NULL; + status = ssl_check_peer(sc, c->overridden_target_name != NULL + ? c->overridden_target_name + : c->target_name, + &peer, &auth_context); + cb(exec_ctx, user_data, status, auth_context); + grpc_auth_context_unref(auth_context); + tsi_peer_destruct(&peer); +} + +static void ssl_server_check_peer(grpc_exec_ctx *exec_ctx, + grpc_security_connector *sc, tsi_peer peer, + grpc_security_peer_check_cb cb, + void *user_data) { + grpc_auth_context *auth_context = NULL; + grpc_security_status status = ssl_check_peer(sc, NULL, &peer, &auth_context); + tsi_peer_destruct(&peer); + cb(exec_ctx, user_data, status, auth_context); + grpc_auth_context_unref(auth_context); +} + +static void add_shallow_auth_property_to_peer(tsi_peer *peer, + const grpc_auth_property *prop, + const char *tsi_prop_name) { + tsi_peer_property *tsi_prop = &peer->properties[peer->property_count++]; + tsi_prop->name = (char *)tsi_prop_name; + tsi_prop->value.data = prop->value; + tsi_prop->value.length = prop->value_length; +} + +tsi_peer tsi_shallow_peer_from_ssl_auth_context( + const grpc_auth_context *auth_context) { + size_t max_num_props = 0; + grpc_auth_property_iterator it; + const grpc_auth_property *prop; + tsi_peer peer; + memset(&peer, 0, sizeof(peer)); + + it = grpc_auth_context_property_iterator(auth_context); + while (grpc_auth_property_iterator_next(&it) != NULL) max_num_props++; + + if (max_num_props > 0) { + peer.properties = gpr_malloc(max_num_props * sizeof(tsi_peer_property)); + it = grpc_auth_context_property_iterator(auth_context); + while ((prop = grpc_auth_property_iterator_next(&it)) != NULL) { + if (strcmp(prop->name, GRPC_X509_SAN_PROPERTY_NAME) == 0) { + add_shallow_auth_property_to_peer( + &peer, prop, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY); + } else if (strcmp(prop->name, GRPC_X509_CN_PROPERTY_NAME) == 0) { + add_shallow_auth_property_to_peer( + &peer, prop, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); + } else if (strcmp(prop->name, GRPC_X509_PEM_CERT_PROPERTY_NAME) == 0) { + add_shallow_auth_property_to_peer(&peer, prop, + TSI_X509_PEM_CERT_PROPERTY); + } + } + } + return peer; +} + +void tsi_shallow_peer_destruct(tsi_peer *peer) { + if (peer->properties != NULL) gpr_free(peer->properties); +} + +static void ssl_channel_check_call_host(grpc_exec_ctx *exec_ctx, + grpc_channel_security_connector *sc, + const char *host, + grpc_auth_context *auth_context, + grpc_security_call_host_check_cb cb, + void *user_data) { + grpc_ssl_channel_security_connector *c = + (grpc_ssl_channel_security_connector *)sc; + grpc_security_status status = GRPC_SECURITY_ERROR; + tsi_peer peer = tsi_shallow_peer_from_ssl_auth_context(auth_context); + if (ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; + + /* If the target name was overridden, then the original target_name was + 'checked' transitively during the previous peer check at the end of the + handshake. */ + if (c->overridden_target_name != NULL && strcmp(host, c->target_name) == 0) { + status = GRPC_SECURITY_OK; + } + cb(exec_ctx, user_data, status); + tsi_shallow_peer_destruct(&peer); +} + +static grpc_security_connector_vtable ssl_channel_vtable = { + ssl_channel_destroy, ssl_channel_check_peer}; + +static grpc_security_connector_vtable ssl_server_vtable = { + ssl_server_destroy, ssl_server_check_peer}; + +static gpr_slice compute_default_pem_root_certs_once(void) { + gpr_slice result = gpr_empty_slice(); + + /* First try to load the roots from the environment. */ + char *default_root_certs_path = + gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); + if (default_root_certs_path != NULL) { + result = gpr_load_file(default_root_certs_path, 0, NULL); + gpr_free(default_root_certs_path); + } + + /* Try overridden roots if needed. */ + grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL; + if (GPR_SLICE_IS_EMPTY(result) && ssl_roots_override_cb != NULL) { + char *pem_root_certs = NULL; + ovrd_res = ssl_roots_override_cb(&pem_root_certs); + if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) { + GPR_ASSERT(pem_root_certs != NULL); + result = gpr_slice_new(pem_root_certs, strlen(pem_root_certs), gpr_free); + } + } + + /* Fall back to installed certs if needed. */ + if (GPR_SLICE_IS_EMPTY(result) && + ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) { + result = gpr_load_file(installed_roots_path, 0, NULL); + } + return result; +} + +static gpr_slice default_pem_root_certs; + +static void init_default_pem_root_certs(void) { + default_pem_root_certs = compute_default_pem_root_certs_once(); +} + +gpr_slice grpc_get_default_ssl_roots_for_testing(void) { + return compute_default_pem_root_certs_once(); +} + +size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs) { + /* TODO(jboeuf@google.com): Maybe revisit the approach which consists in + loading all the roots once for the lifetime of the process. */ + static gpr_once once = GPR_ONCE_INIT; + gpr_once_init(&once, init_default_pem_root_certs); + *pem_root_certs = GPR_SLICE_START_PTR(default_pem_root_certs); + return GPR_SLICE_LENGTH(default_pem_root_certs); +} + +grpc_security_status grpc_ssl_channel_security_connector_create( + grpc_call_credentials *request_metadata_creds, + const grpc_ssl_config *config, const char *target_name, + const char *overridden_target_name, grpc_channel_security_connector **sc) { + size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions(); + const unsigned char **alpn_protocol_strings = + gpr_malloc(sizeof(const char *) * num_alpn_protocols); + unsigned char *alpn_protocol_string_lengths = + gpr_malloc(sizeof(unsigned char) * num_alpn_protocols); + tsi_result result = TSI_OK; + grpc_ssl_channel_security_connector *c; + size_t i; + const unsigned char *pem_root_certs; + size_t pem_root_certs_size; + char *port; + + for (i = 0; i < num_alpn_protocols; i++) { + alpn_protocol_strings[i] = + (const unsigned char *)grpc_chttp2_get_alpn_version_index(i); + alpn_protocol_string_lengths[i] = + (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i)); + } + + if (config == NULL || target_name == NULL) { + gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); + goto error; + } + if (config->pem_root_certs == NULL) { + pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs); + if (pem_root_certs == NULL || pem_root_certs_size == 0) { + gpr_log(GPR_ERROR, "Could not get default pem root certs."); + goto error; + } + } else { + pem_root_certs = config->pem_root_certs; + pem_root_certs_size = config->pem_root_certs_size; + } + + c = gpr_malloc(sizeof(grpc_ssl_channel_security_connector)); + memset(c, 0, sizeof(grpc_ssl_channel_security_connector)); + + gpr_ref_init(&c->base.base.refcount, 1); + c->base.base.vtable = &ssl_channel_vtable; + c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; + c->base.request_metadata_creds = + grpc_call_credentials_ref(request_metadata_creds); + c->base.check_call_host = ssl_channel_check_call_host; + c->base.do_handshake = ssl_channel_do_handshake; + gpr_split_host_port(target_name, &c->target_name, &port); + gpr_free(port); + if (overridden_target_name != NULL) { + c->overridden_target_name = gpr_strdup(overridden_target_name); + } + result = tsi_create_ssl_client_handshaker_factory( + config->pem_private_key, config->pem_private_key_size, + config->pem_cert_chain, config->pem_cert_chain_size, pem_root_certs, + pem_root_certs_size, ssl_cipher_suites(), alpn_protocol_strings, + alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols, + &c->handshaker_factory); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + ssl_channel_destroy(&c->base.base); + *sc = NULL; + goto error; + } + *sc = &c->base; + gpr_free((void *)alpn_protocol_strings); + gpr_free(alpn_protocol_string_lengths); + return GRPC_SECURITY_OK; + +error: + gpr_free((void *)alpn_protocol_strings); + gpr_free(alpn_protocol_string_lengths); + return GRPC_SECURITY_ERROR; +} + +grpc_security_status grpc_ssl_server_security_connector_create( + const grpc_ssl_server_config *config, grpc_server_security_connector **sc) { + size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions(); + const unsigned char **alpn_protocol_strings = + gpr_malloc(sizeof(const char *) * num_alpn_protocols); + unsigned char *alpn_protocol_string_lengths = + gpr_malloc(sizeof(unsigned char) * num_alpn_protocols); + tsi_result result = TSI_OK; + grpc_ssl_server_security_connector *c; + size_t i; + + for (i = 0; i < num_alpn_protocols; i++) { + alpn_protocol_strings[i] = + (const unsigned char *)grpc_chttp2_get_alpn_version_index(i); + alpn_protocol_string_lengths[i] = + (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i)); + } + + if (config == NULL || config->num_key_cert_pairs == 0) { + gpr_log(GPR_ERROR, "An SSL server needs a key and a cert."); + goto error; + } + c = gpr_malloc(sizeof(grpc_ssl_server_security_connector)); + memset(c, 0, sizeof(grpc_ssl_server_security_connector)); + + gpr_ref_init(&c->base.base.refcount, 1); + c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; + c->base.base.vtable = &ssl_server_vtable; + result = tsi_create_ssl_server_handshaker_factory( + (const unsigned char **)config->pem_private_keys, + config->pem_private_keys_sizes, + (const unsigned char **)config->pem_cert_chains, + config->pem_cert_chains_sizes, config->num_key_cert_pairs, + config->pem_root_certs, config->pem_root_certs_size, + config->force_client_auth, ssl_cipher_suites(), alpn_protocol_strings, + alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols, + &c->handshaker_factory); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + ssl_server_destroy(&c->base.base); + *sc = NULL; + goto error; + } + gpr_mu_init(&c->base.mu); + c->base.do_handshake = ssl_server_do_handshake; + *sc = &c->base; + gpr_free((void *)alpn_protocol_strings); + gpr_free(alpn_protocol_string_lengths); + return GRPC_SECURITY_OK; + +error: + gpr_free((void *)alpn_protocol_strings); + gpr_free(alpn_protocol_string_lengths); + return GRPC_SECURITY_ERROR; +} diff --git a/src/core/lib/security/security_connector.h b/src/core/lib/security/security_connector.h new file mode 100644 index 0000000000..6f915ebb9d --- /dev/null +++ b/src/core/lib/security/security_connector.h @@ -0,0 +1,266 @@ +/* + * + * Copyright 2015-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_SECURITY_SECURITY_CONNECTOR_H +#define GRPC_CORE_SECURITY_SECURITY_CONNECTOR_H + +#include +#include "src/core/iomgr/endpoint.h" +#include "src/core/iomgr/tcp_server.h" +#include "src/core/tsi/transport_security_interface.h" + +/* --- status enum. --- */ + +typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status; + +/* --- URL schemes. --- */ + +#define GRPC_SSL_URL_SCHEME "https" +#define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security" + +/* --- security_connector object. --- + + A security connector object represents away to configure the underlying + transport security mechanism and check the resulting trusted peer. */ + +typedef struct grpc_security_connector grpc_security_connector; + +#define GRPC_SECURITY_CONNECTOR_ARG "grpc.security_connector" + +typedef void (*grpc_security_peer_check_cb)(grpc_exec_ctx *exec_ctx, + void *user_data, + grpc_security_status status, + grpc_auth_context *auth_context); + +/* Ownership of the secure_endpoint is transfered. */ +typedef void (*grpc_security_handshake_done_cb)( + grpc_exec_ctx *exec_ctx, void *user_data, grpc_security_status status, + grpc_endpoint *secure_endpoint, grpc_auth_context *auth_context); + +typedef struct { + void (*destroy)(grpc_security_connector *sc); + void (*check_peer)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc, + tsi_peer peer, grpc_security_peer_check_cb cb, + void *user_data); +} grpc_security_connector_vtable; + +typedef struct grpc_security_connector_handshake_list { + void *handshake; + struct grpc_security_connector_handshake_list *next; +} grpc_security_connector_handshake_list; + +struct grpc_security_connector { + const grpc_security_connector_vtable *vtable; + gpr_refcount refcount; + const char *url_scheme; +}; + +/* Refcounting. */ +#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG +#define GRPC_SECURITY_CONNECTOR_REF(p, r) \ + grpc_security_connector_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \ + grpc_security_connector_unref((p), __FILE__, __LINE__, (r)) +grpc_security_connector *grpc_security_connector_ref( + grpc_security_connector *policy, const char *file, int line, + const char *reason); +void grpc_security_connector_unref(grpc_security_connector *policy, + const char *file, int line, + const char *reason); +#else +#define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p)) +#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p)) +grpc_security_connector *grpc_security_connector_ref( + grpc_security_connector *policy); +void grpc_security_connector_unref(grpc_security_connector *policy); +#endif + +/* Check the peer. Callee takes ownership of the peer object. + The callback will include the resulting auth_context. */ +void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx, + grpc_security_connector *sc, + tsi_peer peer, + grpc_security_peer_check_cb cb, + void *user_data); + +/* Util to encapsulate the connector in a channel arg. */ +grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc); + +/* Util to get the connector from a channel arg. */ +grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg); + +/* Util to find the connector from channel args. */ +grpc_security_connector *grpc_find_security_connector_in_args( + const grpc_channel_args *args); + +/* --- channel_security_connector object. --- + + A channel security connector object represents away to configure the + underlying transport security mechanism on the client side. */ + +typedef struct grpc_channel_security_connector grpc_channel_security_connector; + +typedef void (*grpc_security_call_host_check_cb)(grpc_exec_ctx *exec_ctx, + void *user_data, + grpc_security_status status); + +struct grpc_channel_security_connector { + grpc_security_connector base; + grpc_call_credentials *request_metadata_creds; + void (*check_call_host)(grpc_exec_ctx *exec_ctx, + grpc_channel_security_connector *sc, const char *host, + grpc_auth_context *auth_context, + grpc_security_call_host_check_cb cb, void *user_data); + void (*do_handshake)(grpc_exec_ctx *exec_ctx, + grpc_channel_security_connector *sc, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, void *user_data); +}; + +/* Checks that the host that will be set for a call is acceptable. */ +void grpc_channel_security_connector_check_call_host( + grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, + const char *host, grpc_auth_context *auth_context, + grpc_security_call_host_check_cb cb, void *user_data); + +/* Handshake. */ +void grpc_channel_security_connector_do_handshake( + grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector, + grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb, + void *user_data); + +/* --- server_security_connector object. --- + + A server security connector object represents away to configure the + underlying transport security mechanism on the server side. */ + +typedef struct grpc_server_security_connector grpc_server_security_connector; + +struct grpc_server_security_connector { + grpc_security_connector base; + gpr_mu mu; + grpc_security_connector_handshake_list *handshaking_handshakes; + const grpc_channel_args *channel_args; + void (*do_handshake)(grpc_exec_ctx *exec_ctx, + grpc_server_security_connector *sc, + grpc_tcp_server_acceptor *acceptor, + grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, void *user_data); +}; + +void grpc_server_security_connector_do_handshake( + grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, + grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, + grpc_security_handshake_done_cb cb, void *user_data); + +void grpc_server_security_connector_shutdown( + grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector); + +/* --- Creation security connectors. --- */ + +/* For TESTING ONLY! + Creates a fake connector that emulates real channel security. */ +grpc_channel_security_connector *grpc_fake_channel_security_connector_create( + grpc_call_credentials *request_metadata_creds); + +/* For TESTING ONLY! + Creates a fake connector that emulates real server security. */ +grpc_server_security_connector *grpc_fake_server_security_connector_create( + void); + +/* Config for ssl clients. */ +typedef struct { + unsigned char *pem_private_key; + size_t pem_private_key_size; + unsigned char *pem_cert_chain; + size_t pem_cert_chain_size; + unsigned char *pem_root_certs; + size_t pem_root_certs_size; +} grpc_ssl_config; + +/* Creates an SSL channel_security_connector. + - request_metadata_creds is the credentials object which metadata + will be sent with each request. This parameter can be NULL. + - config is the SSL config to be used for the SSL channel establishment. + - is_client should be 0 for a server or a non-0 value for a client. + - secure_peer_name is the secure peer name that should be checked in + grpc_channel_security_connector_check_peer. This parameter may be NULL in + which case the peer name will not be checked. Note that if this parameter + is not NULL, then, pem_root_certs should not be NULL either. + - sc is a pointer on the connector to be created. + This function returns GRPC_SECURITY_OK in case of success or a + specific error code otherwise. +*/ +grpc_security_status grpc_ssl_channel_security_connector_create( + grpc_call_credentials *request_metadata_creds, + const grpc_ssl_config *config, const char *target_name, + const char *overridden_target_name, grpc_channel_security_connector **sc); + +/* Gets the default ssl roots. */ +size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs); + +/* Exposed for TESTING ONLY!. */ +gpr_slice grpc_get_default_ssl_roots_for_testing(void); + +/* Config for ssl servers. */ +typedef struct { + unsigned char **pem_private_keys; + size_t *pem_private_keys_sizes; + unsigned char **pem_cert_chains; + size_t *pem_cert_chains_sizes; + size_t num_key_cert_pairs; + unsigned char *pem_root_certs; + size_t pem_root_certs_size; + int force_client_auth; +} grpc_ssl_server_config; + +/* Creates an SSL server_security_connector. + - config is the SSL config to be used for the SSL channel establishment. + - sc is a pointer on the connector to be created. + This function returns GRPC_SECURITY_OK in case of success or a + specific error code otherwise. +*/ +grpc_security_status grpc_ssl_server_security_connector_create( + const grpc_ssl_server_config *config, grpc_server_security_connector **sc); + +/* Util. */ +const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer, + const char *name); + +/* Exposed for testing only. */ +grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer); +tsi_peer tsi_shallow_peer_from_ssl_auth_context( + const grpc_auth_context *auth_context); +void tsi_shallow_peer_destruct(tsi_peer *peer); + +#endif /* GRPC_CORE_SECURITY_SECURITY_CONNECTOR_H */ diff --git a/src/core/lib/security/security_context.c b/src/core/lib/security/security_context.c new file mode 100644 index 0000000000..f6afc0f633 --- /dev/null +++ b/src/core/lib/security/security_context.c @@ -0,0 +1,347 @@ +/* + * + * Copyright 2015-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 + +#include "src/core/security/security_context.h" +#include "src/core/support/string.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/call.h" + +#include +#include +#include +#include + +/* --- grpc_call --- */ + +grpc_call_error grpc_call_set_credentials(grpc_call *call, + grpc_call_credentials *creds) { + grpc_client_security_context *ctx = NULL; + GRPC_API_TRACE("grpc_call_set_credentials(call=%p, creds=%p)", 2, + (call, creds)); + if (!grpc_call_is_client(call)) { + gpr_log(GPR_ERROR, "Method is client-side only."); + return GRPC_CALL_ERROR_NOT_ON_SERVER; + } + ctx = (grpc_client_security_context *)grpc_call_context_get( + call, GRPC_CONTEXT_SECURITY); + if (ctx == NULL) { + ctx = grpc_client_security_context_create(); + ctx->creds = grpc_call_credentials_ref(creds); + grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx, + grpc_client_security_context_destroy); + } else { + grpc_call_credentials_unref(ctx->creds); + ctx->creds = grpc_call_credentials_ref(creds); + } + return GRPC_CALL_OK; +} + +grpc_auth_context *grpc_call_auth_context(grpc_call *call) { + void *sec_ctx = grpc_call_context_get(call, GRPC_CONTEXT_SECURITY); + GRPC_API_TRACE("grpc_call_auth_context(call=%p)", 1, (call)); + if (sec_ctx == NULL) return NULL; + return grpc_call_is_client(call) + ? GRPC_AUTH_CONTEXT_REF( + ((grpc_client_security_context *)sec_ctx)->auth_context, + "grpc_call_auth_context client") + : GRPC_AUTH_CONTEXT_REF( + ((grpc_server_security_context *)sec_ctx)->auth_context, + "grpc_call_auth_context server"); +} + +void grpc_auth_context_release(grpc_auth_context *context) { + GRPC_API_TRACE("grpc_auth_context_release(context=%p)", 1, (context)); + GRPC_AUTH_CONTEXT_UNREF(context, "grpc_auth_context_unref"); +} + +/* --- grpc_client_security_context --- */ + +grpc_client_security_context *grpc_client_security_context_create(void) { + grpc_client_security_context *ctx = + gpr_malloc(sizeof(grpc_client_security_context)); + memset(ctx, 0, sizeof(grpc_client_security_context)); + return ctx; +} + +void grpc_client_security_context_destroy(void *ctx) { + grpc_client_security_context *c = (grpc_client_security_context *)ctx; + grpc_call_credentials_unref(c->creds); + GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context"); + gpr_free(ctx); +} + +/* --- grpc_server_security_context --- */ + +grpc_server_security_context *grpc_server_security_context_create(void) { + grpc_server_security_context *ctx = + gpr_malloc(sizeof(grpc_server_security_context)); + memset(ctx, 0, sizeof(grpc_server_security_context)); + return ctx; +} + +void grpc_server_security_context_destroy(void *ctx) { + grpc_server_security_context *c = (grpc_server_security_context *)ctx; + GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "server_security_context"); + gpr_free(ctx); +} + +/* --- grpc_auth_context --- */ + +static grpc_auth_property_iterator empty_iterator = {NULL, 0, NULL}; + +grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained) { + grpc_auth_context *ctx = gpr_malloc(sizeof(grpc_auth_context)); + memset(ctx, 0, sizeof(grpc_auth_context)); + gpr_ref_init(&ctx->refcount, 1); + if (chained != NULL) { + ctx->chained = GRPC_AUTH_CONTEXT_REF(chained, "chained"); + ctx->peer_identity_property_name = + ctx->chained->peer_identity_property_name; + } + return ctx; +} + +#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG +grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *ctx, + const char *file, int line, + const char *reason) { + if (ctx == NULL) return NULL; + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "AUTH_CONTEXT:%p ref %d -> %d %s", ctx, (int)ctx->refcount.count, + (int)ctx->refcount.count + 1, reason); +#else +grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *ctx) { + if (ctx == NULL) return NULL; +#endif + gpr_ref(&ctx->refcount); + return ctx; +} + +#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG +void grpc_auth_context_unref(grpc_auth_context *ctx, const char *file, int line, + const char *reason) { + if (ctx == NULL) return; + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "AUTH_CONTEXT:%p unref %d -> %d %s", ctx, (int)ctx->refcount.count, + (int)ctx->refcount.count - 1, reason); +#else +void grpc_auth_context_unref(grpc_auth_context *ctx) { + if (ctx == NULL) return; +#endif + if (gpr_unref(&ctx->refcount)) { + size_t i; + GRPC_AUTH_CONTEXT_UNREF(ctx->chained, "chained"); + if (ctx->properties.array != NULL) { + for (i = 0; i < ctx->properties.count; i++) { + grpc_auth_property_reset(&ctx->properties.array[i]); + } + gpr_free(ctx->properties.array); + } + gpr_free(ctx); + } +} + +const char *grpc_auth_context_peer_identity_property_name( + const grpc_auth_context *ctx) { + GRPC_API_TRACE("grpc_auth_context_peer_identity_property_name(ctx=%p)", 1, + (ctx)); + return ctx->peer_identity_property_name; +} + +int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context *ctx, + const char *name) { + grpc_auth_property_iterator it = + grpc_auth_context_find_properties_by_name(ctx, name); + const grpc_auth_property *prop = grpc_auth_property_iterator_next(&it); + GRPC_API_TRACE( + "grpc_auth_context_set_peer_identity_property_name(ctx=%p, name=%s)", 2, + (ctx, name)); + if (prop == NULL) { + gpr_log(GPR_ERROR, "Property name %s not found in auth context.", + name != NULL ? name : "NULL"); + return 0; + } + ctx->peer_identity_property_name = prop->name; + return 1; +} + +int grpc_auth_context_peer_is_authenticated(const grpc_auth_context *ctx) { + GRPC_API_TRACE("grpc_auth_context_peer_is_authenticated(ctx=%p)", 1, (ctx)); + return ctx->peer_identity_property_name == NULL ? 0 : 1; +} + +grpc_auth_property_iterator grpc_auth_context_property_iterator( + const grpc_auth_context *ctx) { + grpc_auth_property_iterator it = empty_iterator; + GRPC_API_TRACE("grpc_auth_context_property_iterator(ctx=%p)", 1, (ctx)); + if (ctx == NULL) return it; + it.ctx = ctx; + return it; +} + +const grpc_auth_property *grpc_auth_property_iterator_next( + grpc_auth_property_iterator *it) { + GRPC_API_TRACE("grpc_auth_property_iterator_next(it=%p)", 1, (it)); + if (it == NULL || it->ctx == NULL) return NULL; + while (it->index == it->ctx->properties.count) { + if (it->ctx->chained == NULL) return NULL; + it->ctx = it->ctx->chained; + it->index = 0; + } + if (it->name == NULL) { + return &it->ctx->properties.array[it->index++]; + } else { + while (it->index < it->ctx->properties.count) { + const grpc_auth_property *prop = &it->ctx->properties.array[it->index++]; + GPR_ASSERT(prop->name != NULL); + if (strcmp(it->name, prop->name) == 0) { + return prop; + } + } + /* We could not find the name, try another round. */ + return grpc_auth_property_iterator_next(it); + } +} + +grpc_auth_property_iterator grpc_auth_context_find_properties_by_name( + const grpc_auth_context *ctx, const char *name) { + grpc_auth_property_iterator it = empty_iterator; + GRPC_API_TRACE("grpc_auth_context_find_properties_by_name(ctx=%p, name=%s)", + 2, (ctx, name)); + if (ctx == NULL || name == NULL) return empty_iterator; + it.ctx = ctx; + it.name = name; + return it; +} + +grpc_auth_property_iterator grpc_auth_context_peer_identity( + const grpc_auth_context *ctx) { + GRPC_API_TRACE("grpc_auth_context_peer_identity(ctx=%p)", 1, (ctx)); + if (ctx == NULL) return empty_iterator; + return grpc_auth_context_find_properties_by_name( + ctx, ctx->peer_identity_property_name); +} + +static void ensure_auth_context_capacity(grpc_auth_context *ctx) { + if (ctx->properties.count == ctx->properties.capacity) { + ctx->properties.capacity = + GPR_MAX(ctx->properties.capacity + 8, ctx->properties.capacity * 2); + ctx->properties.array = + gpr_realloc(ctx->properties.array, + ctx->properties.capacity * sizeof(grpc_auth_property)); + } +} + +void grpc_auth_context_add_property(grpc_auth_context *ctx, const char *name, + const char *value, size_t value_length) { + grpc_auth_property *prop; + GRPC_API_TRACE( + "grpc_auth_context_add_property(ctx=%p, name=%s, value=%*.*s, " + "value_length=%lu)", + 6, (ctx, name, (int)value_length, (int)value_length, value, + (unsigned long)value_length)); + ensure_auth_context_capacity(ctx); + prop = &ctx->properties.array[ctx->properties.count++]; + prop->name = gpr_strdup(name); + prop->value = gpr_malloc(value_length + 1); + memcpy(prop->value, value, value_length); + prop->value[value_length] = '\0'; + prop->value_length = value_length; +} + +void grpc_auth_context_add_cstring_property(grpc_auth_context *ctx, + const char *name, + const char *value) { + grpc_auth_property *prop; + GRPC_API_TRACE( + "grpc_auth_context_add_cstring_property(ctx=%p, name=%s, value=%s)", 3, + (ctx, name, value)); + ensure_auth_context_capacity(ctx); + prop = &ctx->properties.array[ctx->properties.count++]; + prop->name = gpr_strdup(name); + prop->value = gpr_strdup(value); + prop->value_length = strlen(value); +} + +void grpc_auth_property_reset(grpc_auth_property *property) { + gpr_free(property->name); + gpr_free(property->value); + memset(property, 0, sizeof(grpc_auth_property)); +} + +static void auth_context_pointer_arg_destroy(void *p) { + GRPC_AUTH_CONTEXT_UNREF(p, "auth_context_pointer_arg"); +} + +static void *auth_context_pointer_arg_copy(void *p) { + return GRPC_AUTH_CONTEXT_REF(p, "auth_context_pointer_arg"); +} + +static int auth_context_pointer_cmp(void *a, void *b) { return GPR_ICMP(a, b); } + +static const grpc_arg_pointer_vtable auth_context_pointer_vtable = { + auth_context_pointer_arg_copy, auth_context_pointer_arg_destroy, + auth_context_pointer_cmp}; + +grpc_arg grpc_auth_context_to_arg(grpc_auth_context *p) { + grpc_arg arg; + memset(&arg, 0, sizeof(grpc_arg)); + arg.type = GRPC_ARG_POINTER; + arg.key = GRPC_AUTH_CONTEXT_ARG; + arg.value.pointer.p = p; + arg.value.pointer.vtable = &auth_context_pointer_vtable; + return arg; +} + +grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg) { + if (strcmp(arg->key, GRPC_AUTH_CONTEXT_ARG) != 0) return NULL; + if (arg->type != GRPC_ARG_POINTER) { + gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, + GRPC_AUTH_CONTEXT_ARG); + return NULL; + } + return arg->value.pointer.p; +} + +grpc_auth_context *grpc_find_auth_context_in_args( + const grpc_channel_args *args) { + size_t i; + if (args == NULL) return NULL; + for (i = 0; i < args->num_args; i++) { + grpc_auth_context *p = grpc_auth_context_from_arg(&args->args[i]); + if (p != NULL) return p; + } + return NULL; +} diff --git a/src/core/lib/security/security_context.h b/src/core/lib/security/security_context.h new file mode 100644 index 0000000000..61601f538b --- /dev/null +++ b/src/core/lib/security/security_context.h @@ -0,0 +1,114 @@ +/* + * + * Copyright 2015-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_SECURITY_SECURITY_CONTEXT_H +#define GRPC_CORE_SECURITY_SECURITY_CONTEXT_H + +#include "src/core/iomgr/pollset.h" +#include "src/core/security/credentials.h" + +/* --- grpc_auth_context --- + + High level authentication context object. Can optionally be chained. */ + +/* Property names are always NULL terminated. */ + +typedef struct { + grpc_auth_property *array; + size_t count; + size_t capacity; +} grpc_auth_property_array; + +struct grpc_auth_context { + struct grpc_auth_context *chained; + grpc_auth_property_array properties; + gpr_refcount refcount; + const char *peer_identity_property_name; + grpc_pollset *pollset; +}; + +/* Creation. */ +grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained); + +/* Refcounting. */ +#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG +#define GRPC_AUTH_CONTEXT_REF(p, r) \ + grpc_auth_context_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_AUTH_CONTEXT_UNREF(p, r) \ + grpc_auth_context_unref((p), __FILE__, __LINE__, (r)) +grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *policy, + const char *file, int line, + const char *reason); +void grpc_auth_context_unref(grpc_auth_context *policy, const char *file, + int line, const char *reason); +#else +#define GRPC_AUTH_CONTEXT_REF(p, r) grpc_auth_context_ref((p)) +#define GRPC_AUTH_CONTEXT_UNREF(p, r) grpc_auth_context_unref((p)) +grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *policy); +void grpc_auth_context_unref(grpc_auth_context *policy); +#endif + +void grpc_auth_property_reset(grpc_auth_property *property); + +/* --- grpc_client_security_context --- + + Internal client-side security context. */ + +typedef struct { + grpc_call_credentials *creds; + grpc_auth_context *auth_context; +} grpc_client_security_context; + +grpc_client_security_context *grpc_client_security_context_create(void); +void grpc_client_security_context_destroy(void *ctx); + +/* --- grpc_server_security_context --- + + Internal server-side security context. */ + +typedef struct { + grpc_auth_context *auth_context; +} grpc_server_security_context; + +grpc_server_security_context *grpc_server_security_context_create(void); +void grpc_server_security_context_destroy(void *ctx); + +/* --- Channel args for auth context --- */ +#define GRPC_AUTH_CONTEXT_ARG "grpc.auth_context" + +grpc_arg grpc_auth_context_to_arg(grpc_auth_context *c); +grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg); +grpc_auth_context *grpc_find_auth_context_in_args( + const grpc_channel_args *args); + +#endif /* GRPC_CORE_SECURITY_SECURITY_CONTEXT_H */ diff --git a/src/core/lib/security/server_auth_filter.c b/src/core/lib/security/server_auth_filter.c new file mode 100644 index 0000000000..f3c411d6d4 --- /dev/null +++ b/src/core/lib/security/server_auth_filter.c @@ -0,0 +1,264 @@ +/* + * + * Copyright 2015-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 + +#include "src/core/security/auth_filters.h" +#include "src/core/security/credentials.h" +#include "src/core/security/security_context.h" + +#include +#include + +typedef struct call_data { + grpc_metadata_batch *recv_initial_metadata; + /* Closure to call when finished with the auth_on_recv hook. */ + grpc_closure *on_done_recv; + /* Receive closures are chained: we inject this closure as the on_done_recv + up-call on transport_op, and remember to call our on_done_recv member after + handling it. */ + grpc_closure auth_on_recv; + grpc_transport_stream_op transport_op; + grpc_metadata_array md; + const grpc_metadata *consumed_md; + size_t num_consumed_md; + grpc_auth_context *auth_context; +} call_data; + +typedef struct channel_data { + grpc_auth_context *auth_context; + grpc_server_credentials *creds; +} channel_data; + +static grpc_metadata_array metadata_batch_to_md_array( + const grpc_metadata_batch *batch) { + grpc_linked_mdelem *l; + grpc_metadata_array result; + grpc_metadata_array_init(&result); + for (l = batch->list.head; l != NULL; l = l->next) { + grpc_metadata *usr_md = NULL; + grpc_mdelem *md = l->md; + grpc_mdstr *key = md->key; + grpc_mdstr *value = md->value; + if (result.count == result.capacity) { + result.capacity = GPR_MAX(result.capacity + 8, result.capacity * 2); + result.metadata = + gpr_realloc(result.metadata, result.capacity * sizeof(grpc_metadata)); + } + usr_md = &result.metadata[result.count++]; + usr_md->key = grpc_mdstr_as_c_string(key); + usr_md->value = grpc_mdstr_as_c_string(value); + usr_md->value_length = GPR_SLICE_LENGTH(value->slice); + } + return result; +} + +static grpc_mdelem *remove_consumed_md(void *user_data, grpc_mdelem *md) { + grpc_call_element *elem = user_data; + call_data *calld = elem->call_data; + size_t i; + for (i = 0; i < calld->num_consumed_md; i++) { + const grpc_metadata *consumed_md = &calld->consumed_md[i]; + /* Maybe we could do a pointer comparison but we do not have any guarantee + that the metadata processor used the same pointers for consumed_md in the + callback. */ + if (GPR_SLICE_LENGTH(md->key->slice) != strlen(consumed_md->key) || + GPR_SLICE_LENGTH(md->value->slice) != consumed_md->value_length) { + continue; + } + if (memcmp(GPR_SLICE_START_PTR(md->key->slice), consumed_md->key, + GPR_SLICE_LENGTH(md->key->slice)) == 0 && + memcmp(GPR_SLICE_START_PTR(md->value->slice), consumed_md->value, + GPR_SLICE_LENGTH(md->value->slice)) == 0) { + return NULL; /* Delete. */ + } + } + return md; +} + +/* called from application code */ +static void on_md_processing_done( + void *user_data, const grpc_metadata *consumed_md, size_t num_consumed_md, + const grpc_metadata *response_md, size_t num_response_md, + grpc_status_code status, const char *error_details) { + grpc_call_element *elem = user_data; + call_data *calld = elem->call_data; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + /* TODO(jboeuf): Implement support for response_md. */ + if (response_md != NULL && num_response_md > 0) { + gpr_log(GPR_INFO, + "response_md in auth metadata processing not supported for now. " + "Ignoring..."); + } + + if (status == GRPC_STATUS_OK) { + calld->consumed_md = consumed_md; + calld->num_consumed_md = num_consumed_md; + grpc_metadata_batch_filter(calld->recv_initial_metadata, remove_consumed_md, + elem); + grpc_metadata_array_destroy(&calld->md); + calld->on_done_recv->cb(&exec_ctx, calld->on_done_recv->cb_arg, 1); + } else { + gpr_slice message; + grpc_transport_stream_op close_op; + memset(&close_op, 0, sizeof(close_op)); + grpc_metadata_array_destroy(&calld->md); + error_details = error_details != NULL + ? error_details + : "Authentication metadata processing failed."; + message = gpr_slice_from_copied_string(error_details); + calld->transport_op.send_initial_metadata = NULL; + if (calld->transport_op.send_message != NULL) { + grpc_byte_stream_destroy(&exec_ctx, calld->transport_op.send_message); + calld->transport_op.send_message = NULL; + } + calld->transport_op.send_trailing_metadata = NULL; + grpc_transport_stream_op_add_close(&close_op, status, &message); + grpc_call_next_op(&exec_ctx, elem, &close_op); + calld->on_done_recv->cb(&exec_ctx, calld->on_done_recv->cb_arg, 0); + } + + grpc_exec_ctx_finish(&exec_ctx); +} + +static void auth_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, + bool success) { + grpc_call_element *elem = user_data; + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + if (success) { + if (chand->creds->processor.process != NULL) { + calld->md = metadata_batch_to_md_array(calld->recv_initial_metadata); + chand->creds->processor.process( + chand->creds->processor.state, calld->auth_context, + calld->md.metadata, calld->md.count, on_md_processing_done, elem); + return; + } + } + calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, success); +} + +static void set_recv_ops_md_callbacks(grpc_call_element *elem, + grpc_transport_stream_op *op) { + call_data *calld = elem->call_data; + + if (op->recv_initial_metadata != NULL) { + /* substitute our callback for the higher callback */ + calld->recv_initial_metadata = op->recv_initial_metadata; + calld->on_done_recv = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = &calld->auth_on_recv; + calld->transport_op = *op; + } +} + +/* Called either: + - in response to an API call (or similar) from above, to send something + - a network event (or similar) from below, to receive something + op contains type and call direction information, in addition to the data + that is being sent or received. */ +static void auth_start_transport_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + set_recv_ops_md_callbacks(elem, op); + grpc_call_next_op(exec_ctx, elem, op); +} + +/* Constructor for call_data */ +static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args) { + /* grab pointers to our data from the call element */ + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + grpc_server_security_context *server_ctx = NULL; + + /* initialize members */ + memset(calld, 0, sizeof(*calld)); + grpc_closure_init(&calld->auth_on_recv, auth_on_recv, elem); + + if (args->context[GRPC_CONTEXT_SECURITY].value != NULL) { + args->context[GRPC_CONTEXT_SECURITY].destroy( + args->context[GRPC_CONTEXT_SECURITY].value); + } + + server_ctx = grpc_server_security_context_create(); + server_ctx->auth_context = grpc_auth_context_create(chand->auth_context); + calld->auth_context = server_ctx->auth_context; + + args->context[GRPC_CONTEXT_SECURITY].value = server_ctx; + args->context[GRPC_CONTEXT_SECURITY].destroy = + grpc_server_security_context_destroy; +} + +static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_pollset *pollset) {} + +/* Destructor for call_data */ +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) {} + +/* Constructor for channel_data */ +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + grpc_auth_context *auth_context = + grpc_find_auth_context_in_args(args->channel_args); + grpc_server_credentials *creds = + grpc_find_server_credentials_in_args(args->channel_args); + /* grab pointers to our data from the channel element */ + channel_data *chand = elem->channel_data; + + GPR_ASSERT(!args->is_last); + GPR_ASSERT(auth_context != NULL); + GPR_ASSERT(creds != NULL); + + /* initialize members */ + chand->auth_context = + GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter"); + chand->creds = grpc_server_credentials_ref(creds); +} + +/* Destructor for channel data */ +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) { + /* grab pointers to our data from the channel element */ + channel_data *chand = elem->channel_data; + GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter"); + grpc_server_credentials_unref(chand->creds); +} + +const grpc_channel_filter grpc_server_auth_filter = { + auth_start_transport_op, grpc_channel_next_op, sizeof(call_data), + init_call_elem, set_pollset, destroy_call_elem, + sizeof(channel_data), init_channel_elem, destroy_channel_elem, + grpc_call_next_get_peer, "server-auth"}; diff --git a/src/core/lib/security/server_secure_chttp2.c b/src/core/lib/security/server_secure_chttp2.c new file mode 100644 index 0000000000..da29ca934b --- /dev/null +++ b/src/core/lib/security/server_secure_chttp2.c @@ -0,0 +1,264 @@ +/* + * + * Copyright 2015-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 + +#include + +#include +#include +#include +#include +#include "src/core/channel/channel_args.h" +#include "src/core/channel/http_server_filter.h" +#include "src/core/iomgr/endpoint.h" +#include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/tcp_server.h" +#include "src/core/security/auth_filters.h" +#include "src/core/security/credentials.h" +#include "src/core/security/security_connector.h" +#include "src/core/security/security_context.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/server.h" +#include "src/core/transport/chttp2_transport.h" + +typedef struct grpc_server_secure_state { + grpc_server *server; + grpc_tcp_server *tcp; + grpc_server_security_connector *sc; + grpc_server_credentials *creds; + int is_shutdown; + gpr_mu mu; + gpr_refcount refcount; + grpc_closure destroy_closure; + grpc_closure *destroy_callback; +} grpc_server_secure_state; + +static void state_ref(grpc_server_secure_state *state) { + gpr_ref(&state->refcount); +} + +static void state_unref(grpc_server_secure_state *state) { + if (gpr_unref(&state->refcount)) { + /* ensure all threads have unlocked */ + gpr_mu_lock(&state->mu); + gpr_mu_unlock(&state->mu); + /* clean up */ + GRPC_SECURITY_CONNECTOR_UNREF(&state->sc->base, "server"); + grpc_server_credentials_unref(state->creds); + gpr_free(state); + } +} + +static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep, + grpc_transport *transport, + grpc_auth_context *auth_context) { + grpc_server_secure_state *state = statep; + grpc_channel_args *args_copy; + grpc_arg args_to_add[2]; + args_to_add[0] = grpc_server_credentials_to_arg(state->creds); + args_to_add[1] = grpc_auth_context_to_arg(auth_context); + args_copy = grpc_channel_args_copy_and_add( + grpc_server_get_channel_args(state->server), args_to_add, + GPR_ARRAY_SIZE(args_to_add)); + grpc_server_setup_transport(exec_ctx, state->server, transport, args_copy); + grpc_channel_args_destroy(args_copy); +} + +static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, + grpc_security_status status, + grpc_endpoint *secure_endpoint, + grpc_auth_context *auth_context) { + grpc_server_secure_state *state = statep; + grpc_transport *transport; + if (status == GRPC_SECURITY_OK) { + if (secure_endpoint) { + gpr_mu_lock(&state->mu); + if (!state->is_shutdown) { + transport = grpc_create_chttp2_transport( + exec_ctx, grpc_server_get_channel_args(state->server), + secure_endpoint, 0); + setup_transport(exec_ctx, state, transport, auth_context); + grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); + } else { + /* We need to consume this here, because the server may already have + * gone away. */ + grpc_endpoint_destroy(exec_ctx, secure_endpoint); + } + gpr_mu_unlock(&state->mu); + } + } else { + gpr_log(GPR_ERROR, "Secure transport failed with error %d", status); + } + state_unref(state); +} + +static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, + grpc_tcp_server_acceptor *acceptor) { + grpc_server_secure_state *state = statep; + state_ref(state); + grpc_server_security_connector_do_handshake( + exec_ctx, state->sc, acceptor, tcp, on_secure_handshake_done, state); +} + +/* Server callback: start listening on our ports */ +static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep, + grpc_pollset **pollsets, size_t pollset_count) { + grpc_server_secure_state *state = statep; + grpc_tcp_server_start(exec_ctx, state->tcp, pollsets, pollset_count, + on_accept, state); +} + +static void destroy_done(grpc_exec_ctx *exec_ctx, void *statep, bool success) { + grpc_server_secure_state *state = statep; + if (state->destroy_callback != NULL) { + state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg, + success); + } + grpc_server_security_connector_shutdown(exec_ctx, state->sc); + state_unref(state); +} + +/* Server callback: destroy the tcp listener (so we don't generate further + callbacks) */ +static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep, + grpc_closure *callback) { + grpc_server_secure_state *state = statep; + grpc_tcp_server *tcp; + gpr_mu_lock(&state->mu); + state->is_shutdown = 1; + state->destroy_callback = callback; + tcp = state->tcp; + gpr_mu_unlock(&state->mu); + grpc_tcp_server_unref(exec_ctx, tcp); +} + +int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, + grpc_server_credentials *creds) { + grpc_resolved_addresses *resolved = NULL; + grpc_tcp_server *tcp = NULL; + grpc_server_secure_state *state = NULL; + size_t i; + unsigned count = 0; + int port_num = -1; + int port_temp; + grpc_security_status status = GRPC_SECURITY_ERROR; + grpc_server_security_connector *sc = NULL; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + GRPC_API_TRACE( + "grpc_server_add_secure_http2_port(" + "server=%p, addr=%s, creds=%p)", + 3, (server, addr, creds)); + + /* create security context */ + if (creds == NULL) goto error; + status = grpc_server_credentials_create_security_connector(creds, &sc); + if (status != GRPC_SECURITY_OK) { + gpr_log(GPR_ERROR, + "Unable to create secure server with credentials of type %s.", + creds->type); + goto error; + } + sc->channel_args = grpc_server_get_channel_args(server); + + /* resolve address */ + resolved = grpc_blocking_resolve_address(addr, "https"); + if (!resolved) { + goto error; + } + state = gpr_malloc(sizeof(*state)); + memset(state, 0, sizeof(*state)); + grpc_closure_init(&state->destroy_closure, destroy_done, state); + tcp = grpc_tcp_server_create(&state->destroy_closure); + if (!tcp) { + goto error; + } + + state->server = server; + state->tcp = tcp; + state->sc = sc; + state->creds = grpc_server_credentials_ref(creds); + state->is_shutdown = 0; + gpr_mu_init(&state->mu); + gpr_ref_init(&state->refcount, 1); + + for (i = 0; i < resolved->naddrs; i++) { + port_temp = grpc_tcp_server_add_port( + tcp, (struct sockaddr *)&resolved->addrs[i].addr, + resolved->addrs[i].len); + if (port_temp > 0) { + if (port_num == -1) { + port_num = port_temp; + } else { + GPR_ASSERT(port_num == port_temp); + } + count++; + } + } + if (count == 0) { + gpr_log(GPR_ERROR, "No address added out of total %d resolved", + resolved->naddrs); + goto error; + } + if (count != resolved->naddrs) { + gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved", + count, resolved->naddrs); + /* if it's an error, don't we want to goto error; here ? */ + } + grpc_resolved_addresses_destroy(resolved); + + /* Register with the server only upon success */ + grpc_server_add_listener(&exec_ctx, server, state, start, destroy); + + grpc_exec_ctx_finish(&exec_ctx); + return port_num; + +/* Error path: cleanup and return */ +error: + if (resolved) { + grpc_resolved_addresses_destroy(resolved); + } + if (tcp) { + grpc_tcp_server_unref(&exec_ctx, tcp); + } else { + if (sc) { + GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server"); + } + if (state) { + gpr_free(state); + } + } + grpc_exec_ctx_finish(&exec_ctx); + return 0; +} diff --git a/src/core/lib/statistics/census_init.c b/src/core/lib/statistics/census_init.c new file mode 100644 index 0000000000..b6a962f228 --- /dev/null +++ b/src/core/lib/statistics/census_init.c @@ -0,0 +1,48 @@ +/* + * + * Copyright 2015-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/statistics/census_interface.h" + +#include +#include "src/core/statistics/census_rpc_stats.h" +#include "src/core/statistics/census_tracing.h" + +void census_init(void) { + census_tracing_init(); + census_stats_store_init(); +} + +void census_shutdown(void) { + census_stats_store_shutdown(); + census_tracing_shutdown(); +} diff --git a/src/core/lib/statistics/census_interface.h b/src/core/lib/statistics/census_interface.h new file mode 100644 index 0000000000..ce8ff92cd4 --- /dev/null +++ b/src/core/lib/statistics/census_interface.h @@ -0,0 +1,76 @@ +/* + * + * Copyright 2015-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_STATISTICS_CENSUS_INTERFACE_H +#define GRPC_CORE_STATISTICS_CENSUS_INTERFACE_H + +#include + +/* Maximum length of an individual census trace annotation. */ +#define CENSUS_MAX_ANNOTATION_LENGTH 200 + +/* Structure of a census op id. Define as structure because 64bit integer is not + available on every platform for C89. */ +typedef struct census_op_id { + uint32_t upper; + uint32_t lower; +} census_op_id; + +typedef struct census_rpc_stats census_rpc_stats; + +/* Initializes Census library. No-op if Census is already initialized. */ +void census_init(void); + +/* Shutdown Census Library. */ +void census_shutdown(void); + +/* Annotates grpc method name on a census_op_id. The method name has the format + of /. Returns 0 iff + op_id and method_name are all valid. op_id is valid after its creation and + before calling census_tracing_end_op(). + + TODO(hongyu): Figure out valid characters set for service name and command + name and document requirements here.*/ +int census_add_method_tag(census_op_id op_id, const char *method_name); + +/* Annotates tracing information to a specific op_id. + Up to CENSUS_MAX_ANNOTATION_LENGTH bytes are recorded. */ +void census_tracing_print(census_op_id op_id, const char *annotation); + +/* Starts tracing for an RPC. Returns a locally unique census_op_id */ +census_op_id census_tracing_start_op(void); + +/* Ends tracing. Calling this function will invalidate the input op_id. */ +void census_tracing_end_op(census_op_id op_id); + +#endif /* GRPC_CORE_STATISTICS_CENSUS_INTERFACE_H */ diff --git a/src/core/lib/statistics/census_log.c b/src/core/lib/statistics/census_log.c new file mode 100644 index 0000000000..3802d1cc7a --- /dev/null +++ b/src/core/lib/statistics/census_log.c @@ -0,0 +1,603 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* Available log space is divided up in blocks of + CENSUS_LOG_2_MAX_RECORD_SIZE bytes. A block can be in one of the + following three data structures: + - Free blocks (free_block_list) + - Blocks with unread data (dirty_block_list) + - Blocks currently attached to cores (core_local_blocks[]) + + census_log_start_write() moves a block from core_local_blocks[] to the + end of dirty_block_list when block: + - is out-of-space OR + - has an incomplete record (an incomplete record occurs when a thread calls + census_log_start_write() and is context-switched before calling + census_log_end_write() + So, blocks in dirty_block_list are ordered, from oldest to newest, by time + when block is detached from the core. + + census_log_read_next() first iterates over dirty_block_list and then + core_local_blocks[]. It moves completely read blocks from dirty_block_list + to free_block_list. Blocks in core_local_blocks[] are not freed, even when + completely read. + + If log is configured to discard old records and free_block_list is empty, + census_log_start_write() iterates over dirty_block_list to allocate a + new block. It moves the oldest available block (no pending read/write) to + core_local_blocks[]. + + core_local_block_struct is used to implement a map from core id to the block + associated with that core. This mapping is advisory. It is possible that the + block returned by this mapping is no longer associated with that core. This + mapping is updated, lazily, by census_log_start_write(). + + Locking in block struct: + + Exclusive g_log.lock must be held before calling any functions operatong on + block structs except census_log_start_write() and + census_log_end_write(). + + Writes to a block are serialized via writer_lock. + census_log_start_write() acquires this lock and + census_log_end_write() releases it. On failure to acquire the lock, + writer allocates a new block for the current core and updates + core_local_block accordingly. + + Simultaneous read and write access is allowed. Reader can safely read up to + committed bytes (bytes_committed). + + reader_lock protects the block, currently being read, from getting recycled. + start_read() acquires reader_lock and end_read() releases the lock. + + Read/write access to a block is disabled via try_disable_access(). It returns + with both writer_lock and reader_lock held. These locks are subsequently + released by enable_access() to enable access to the block. + + A note on naming: Most function/struct names are prepended by cl_ + (shorthand for census_log). Further, functions that manipulate structures + include the name of the structure, which will be passed as the first + argument. E.g. cl_block_initialize() will initialize a cl_block. +*/ +#include "src/core/statistics/census_log.h" +#include +#include +#include +#include +#include +#include +#include +#include + +/* End of platform specific code */ + +typedef struct census_log_block_list_struct { + struct census_log_block_list_struct *next; + struct census_log_block_list_struct *prev; + struct census_log_block *block; +} cl_block_list_struct; + +typedef struct census_log_block { + /* Pointer to underlying buffer */ + char *buffer; + gpr_atm writer_lock; + gpr_atm reader_lock; + /* Keeps completely written bytes. Declared atomic because accessed + simultaneously by reader and writer. */ + gpr_atm bytes_committed; + /* Bytes already read */ + int32_t bytes_read; + /* Links for list */ + cl_block_list_struct link; +/* We want this structure to be cacheline aligned. We assume the following + sizes for the various parts on 32/64bit systems: + type 32b size 64b size + char* 4 8 + 3x gpr_atm 12 24 + int32_t 4 8 (assumes padding) + cl_block_list_struct 12 24 + TOTAL 32 64 + + Depending on the size of our cacheline and the architecture, we + selectively add char buffering to this structure. The size is checked + via assert in census_log_initialize(). */ +#if defined(GPR_ARCH_64) +#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 64) +#else +#if defined(GPR_ARCH_32) +#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 32) +#else +#error "Unknown architecture" +#endif +#endif +#if CL_BLOCK_PAD_SIZE > 0 + char padding[CL_BLOCK_PAD_SIZE]; +#endif +} cl_block; + +/* A list of cl_blocks, doubly-linked through cl_block::link. */ +typedef struct census_log_block_list { + int32_t count; /* Number of items in list. */ + cl_block_list_struct ht; /* head/tail of linked list. */ +} cl_block_list; + +/* Cacheline aligned block pointers to avoid false sharing. Block pointer must + be initialized via set_block(), before calling other functions */ +typedef struct census_log_core_local_block { + gpr_atm block; +/* Ensure cachline alignment: we assume sizeof(gpr_atm) == 4 or 8 */ +#if defined(GPR_ARCH_64) +#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 8) +#else +#if defined(GPR_ARCH_32) +#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 4) +#else +#error "Unknown architecture" +#endif +#endif +#if CL_CORE_LOCAL_BLOCK_PAD_SIZE > 0 + char padding[CL_CORE_LOCAL_BLOCK_PAD_SIZE]; +#endif +} cl_core_local_block; + +struct census_log { + int discard_old_records; + /* Number of cores (aka hardware-contexts) */ + unsigned num_cores; + /* number of CENSUS_LOG_2_MAX_RECORD_SIZE blocks in log */ + int32_t num_blocks; + cl_block *blocks; /* Block metadata. */ + cl_core_local_block *core_local_blocks; /* Keeps core to block mappings. */ + gpr_mu lock; + int initialized; /* has log been initialized? */ + /* Keeps the state of the reader iterator. A value of 0 indicates that + iterator has reached the end. census_log_init_reader() resets the + value to num_core to restart iteration. */ + uint32_t read_iterator_state; + /* Points to the block being read. If non-NULL, the block is locked for + reading (block_being_read_->reader_lock is held). */ + cl_block *block_being_read; + /* A non-zero value indicates that log is full. */ + gpr_atm is_full; + char *buffer; + cl_block_list free_block_list; + cl_block_list dirty_block_list; + gpr_atm out_of_space_count; +}; + +/* Single internal log */ +static struct census_log g_log; + +/* Functions that operate on an atomic memory location used as a lock */ + +/* Returns non-zero if lock is acquired */ +static int cl_try_lock(gpr_atm *lock) { return gpr_atm_acq_cas(lock, 0, 1); } + +static void cl_unlock(gpr_atm *lock) { gpr_atm_rel_store(lock, 0); } + +/* Functions that operate on cl_core_local_block's */ + +static void cl_core_local_block_set_block(cl_core_local_block *clb, + cl_block *block) { + gpr_atm_rel_store(&clb->block, (gpr_atm)block); +} + +static cl_block *cl_core_local_block_get_block(cl_core_local_block *clb) { + return (cl_block *)gpr_atm_acq_load(&clb->block); +} + +/* Functions that operate on cl_block_list_struct's */ + +static void cl_block_list_struct_initialize(cl_block_list_struct *bls, + cl_block *block) { + bls->next = bls->prev = bls; + bls->block = block; +} + +/* Functions that operate on cl_block_list's */ + +static void cl_block_list_initialize(cl_block_list *list) { + list->count = 0; + cl_block_list_struct_initialize(&list->ht, NULL); +} + +/* Returns head of *this, or NULL if empty. */ +static cl_block *cl_block_list_head(cl_block_list *list) { + return list->ht.next->block; +} + +/* Insert element *e after *pos. */ +static void cl_block_list_insert(cl_block_list *list, cl_block_list_struct *pos, + cl_block_list_struct *e) { + list->count++; + e->next = pos->next; + e->prev = pos; + e->next->prev = e; + e->prev->next = e; +} + +/* Insert block at the head of the list */ +static void cl_block_list_insert_at_head(cl_block_list *list, cl_block *block) { + cl_block_list_insert(list, &list->ht, &block->link); +} + +/* Insert block at the tail of the list */ +static void cl_block_list_insert_at_tail(cl_block_list *list, cl_block *block) { + cl_block_list_insert(list, list->ht.prev, &block->link); +} + +/* Removes block *b. Requires *b be in the list. */ +static void cl_block_list_remove(cl_block_list *list, cl_block *b) { + list->count--; + b->link.next->prev = b->link.prev; + b->link.prev->next = b->link.next; +} + +/* Functions that operate on cl_block's */ + +static void cl_block_initialize(cl_block *block, char *buffer) { + block->buffer = buffer; + gpr_atm_rel_store(&block->writer_lock, 0); + gpr_atm_rel_store(&block->reader_lock, 0); + gpr_atm_rel_store(&block->bytes_committed, 0); + block->bytes_read = 0; + cl_block_list_struct_initialize(&block->link, block); +} + +/* Guards against exposing partially written buffer to the reader. */ +static void cl_block_set_bytes_committed(cl_block *block, + int32_t bytes_committed) { + gpr_atm_rel_store(&block->bytes_committed, bytes_committed); +} + +static int32_t cl_block_get_bytes_committed(cl_block *block) { + return gpr_atm_acq_load(&block->bytes_committed); +} + +/* Tries to disable future read/write access to this block. Succeeds if: + - no in-progress write AND + - no in-progress read AND + - 'discard_data' set to true OR no unread data + On success, clears the block state and returns with writer_lock_ and + reader_lock_ held. These locks are released by a subsequent + cl_block_access_enable() call. */ +static int cl_block_try_disable_access(cl_block *block, int discard_data) { + if (!cl_try_lock(&block->writer_lock)) { + return 0; + } + if (!cl_try_lock(&block->reader_lock)) { + cl_unlock(&block->writer_lock); + return 0; + } + if (!discard_data && + (block->bytes_read != cl_block_get_bytes_committed(block))) { + cl_unlock(&block->reader_lock); + cl_unlock(&block->writer_lock); + return 0; + } + cl_block_set_bytes_committed(block, 0); + block->bytes_read = 0; + return 1; +} + +static void cl_block_enable_access(cl_block *block) { + cl_unlock(&block->reader_lock); + cl_unlock(&block->writer_lock); +} + +/* Returns with writer_lock held. */ +static void *cl_block_start_write(cl_block *block, size_t size) { + int32_t bytes_committed; + if (!cl_try_lock(&block->writer_lock)) { + return NULL; + } + bytes_committed = cl_block_get_bytes_committed(block); + if (bytes_committed + size > CENSUS_LOG_MAX_RECORD_SIZE) { + cl_unlock(&block->writer_lock); + return NULL; + } + return block->buffer + bytes_committed; +} + +/* Releases writer_lock and increments committed bytes by 'bytes_written'. + 'bytes_written' must be <= 'size' specified in the corresponding + StartWrite() call. This function is thread-safe. */ +static void cl_block_end_write(cl_block *block, size_t bytes_written) { + cl_block_set_bytes_committed( + block, cl_block_get_bytes_committed(block) + bytes_written); + cl_unlock(&block->writer_lock); +} + +/* Returns a pointer to the first unread byte in buffer. The number of bytes + available are returned in 'bytes_available'. Acquires reader lock that is + released by a subsequent cl_block_end_read() call. Returns NULL if: + - read in progress + - no data available */ +static void *cl_block_start_read(cl_block *block, size_t *bytes_available) { + void *record; + if (!cl_try_lock(&block->reader_lock)) { + return NULL; + } + /* bytes_committed may change from under us. Use bytes_available to update + bytes_read below. */ + *bytes_available = cl_block_get_bytes_committed(block) - block->bytes_read; + if (*bytes_available == 0) { + cl_unlock(&block->reader_lock); + return NULL; + } + record = block->buffer + block->bytes_read; + block->bytes_read += *bytes_available; + return record; +} + +static void cl_block_end_read(cl_block *block) { + cl_unlock(&block->reader_lock); +} + +/* Internal functions operating on g_log */ + +/* Allocates a new free block (or recycles an available dirty block if log is + configured to discard old records). Returns NULL if out-of-space. */ +static cl_block *cl_allocate_block(void) { + cl_block *block = cl_block_list_head(&g_log.free_block_list); + if (block != NULL) { + cl_block_list_remove(&g_log.free_block_list, block); + return block; + } + if (!g_log.discard_old_records) { + /* No free block and log is configured to keep old records. */ + return NULL; + } + /* Recycle dirty block. Start from the oldest. */ + for (block = cl_block_list_head(&g_log.dirty_block_list); block != NULL; + block = block->link.next->block) { + if (cl_block_try_disable_access(block, 1 /* discard data */)) { + cl_block_list_remove(&g_log.dirty_block_list, block); + return block; + } + } + return NULL; +} + +/* Allocates a new block and updates core id => block mapping. 'old_block' + points to the block that the caller thinks is attached to + 'core_id'. 'old_block' may be NULL. Returns non-zero if: + - allocated a new block OR + - 'core_id' => 'old_block' mapping changed (another thread allocated a + block before lock was acquired). */ +static int cl_allocate_core_local_block(int32_t core_id, cl_block *old_block) { + /* Now that we have the lock, check if core-local mapping has changed. */ + cl_core_local_block *core_local_block = &g_log.core_local_blocks[core_id]; + cl_block *block = cl_core_local_block_get_block(core_local_block); + if ((block != NULL) && (block != old_block)) { + return 1; + } + if (block != NULL) { + cl_core_local_block_set_block(core_local_block, NULL); + cl_block_list_insert_at_tail(&g_log.dirty_block_list, block); + } + block = cl_allocate_block(); + if (block == NULL) { + gpr_atm_rel_store(&g_log.is_full, 1); + return 0; + } + cl_core_local_block_set_block(core_local_block, block); + cl_block_enable_access(block); + return 1; +} + +static cl_block *cl_get_block(void *record) { + uintptr_t p = (uintptr_t)((char *)record - g_log.buffer); + uintptr_t index = p >> CENSUS_LOG_2_MAX_RECORD_SIZE; + return &g_log.blocks[index]; +} + +/* Gets the next block to read and tries to free 'prev' block (if not NULL). + Returns NULL if reached the end. */ +static cl_block *cl_next_block_to_read(cl_block *prev) { + cl_block *block = NULL; + if (g_log.read_iterator_state == g_log.num_cores) { + /* We are traversing dirty list; find the next dirty block. */ + if (prev != NULL) { + /* Try to free the previous block if there is no unread data. This block + may have unread data if previously incomplete record completed between + read_next() calls. */ + block = prev->link.next->block; + if (cl_block_try_disable_access(prev, 0 /* do not discard data */)) { + cl_block_list_remove(&g_log.dirty_block_list, prev); + cl_block_list_insert_at_head(&g_log.free_block_list, prev); + gpr_atm_rel_store(&g_log.is_full, 0); + } + } else { + block = cl_block_list_head(&g_log.dirty_block_list); + } + if (block != NULL) { + return block; + } + /* We are done with the dirty list; moving on to core-local blocks. */ + } + while (g_log.read_iterator_state > 0) { + g_log.read_iterator_state--; + block = cl_core_local_block_get_block( + &g_log.core_local_blocks[g_log.read_iterator_state]); + if (block != NULL) { + return block; + } + } + return NULL; +} + +/* External functions: primary stats_log interface */ +void census_log_initialize(size_t size_in_mb, int discard_old_records) { + int32_t ix; + /* Check cacheline alignment. */ + GPR_ASSERT(sizeof(cl_block) % GPR_CACHELINE_SIZE == 0); + GPR_ASSERT(sizeof(cl_core_local_block) % GPR_CACHELINE_SIZE == 0); + GPR_ASSERT(!g_log.initialized); + g_log.discard_old_records = discard_old_records; + g_log.num_cores = gpr_cpu_num_cores(); + /* Ensure at least as many blocks as there are cores. */ + g_log.num_blocks = GPR_MAX( + g_log.num_cores, (size_in_mb << 20) >> CENSUS_LOG_2_MAX_RECORD_SIZE); + gpr_mu_init(&g_log.lock); + g_log.read_iterator_state = 0; + g_log.block_being_read = NULL; + gpr_atm_rel_store(&g_log.is_full, 0); + g_log.core_local_blocks = (cl_core_local_block *)gpr_malloc_aligned( + g_log.num_cores * sizeof(cl_core_local_block), GPR_CACHELINE_SIZE_LOG); + memset(g_log.core_local_blocks, 0, + g_log.num_cores * sizeof(cl_core_local_block)); + g_log.blocks = (cl_block *)gpr_malloc_aligned( + g_log.num_blocks * sizeof(cl_block), GPR_CACHELINE_SIZE_LOG); + memset(g_log.blocks, 0, g_log.num_blocks * sizeof(cl_block)); + g_log.buffer = gpr_malloc(g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE); + memset(g_log.buffer, 0, g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE); + cl_block_list_initialize(&g_log.free_block_list); + cl_block_list_initialize(&g_log.dirty_block_list); + for (ix = 0; ix < g_log.num_blocks; ++ix) { + cl_block *block = g_log.blocks + ix; + cl_block_initialize(block, + g_log.buffer + (CENSUS_LOG_MAX_RECORD_SIZE * ix)); + cl_block_try_disable_access(block, 1 /* discard data */); + cl_block_list_insert_at_tail(&g_log.free_block_list, block); + } + gpr_atm_rel_store(&g_log.out_of_space_count, 0); + g_log.initialized = 1; +} + +void census_log_shutdown(void) { + GPR_ASSERT(g_log.initialized); + gpr_mu_destroy(&g_log.lock); + gpr_free_aligned(g_log.core_local_blocks); + g_log.core_local_blocks = NULL; + gpr_free_aligned(g_log.blocks); + g_log.blocks = NULL; + gpr_free(g_log.buffer); + g_log.buffer = NULL; + g_log.initialized = 0; +} + +void *census_log_start_write(size_t size) { + /* Used to bound number of times block allocation is attempted. */ + int32_t attempts_remaining = g_log.num_blocks; + /* TODO(aveitch): move this inside the do loop when current_cpu is fixed */ + int32_t core_id = gpr_cpu_current_cpu(); + GPR_ASSERT(g_log.initialized); + if (size > CENSUS_LOG_MAX_RECORD_SIZE) { + return NULL; + } + do { + int allocated; + void *record = NULL; + cl_block *block = + cl_core_local_block_get_block(&g_log.core_local_blocks[core_id]); + if (block && (record = cl_block_start_write(block, size))) { + return record; + } + /* Need to allocate a new block. We are here if: + - No block associated with the core OR + - Write in-progress on the block OR + - block is out of space */ + if (gpr_atm_acq_load(&g_log.is_full)) { + gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1); + return NULL; + } + gpr_mu_lock(&g_log.lock); + allocated = cl_allocate_core_local_block(core_id, block); + gpr_mu_unlock(&g_log.lock); + if (!allocated) { + gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1); + return NULL; + } + } while (attempts_remaining--); + /* Give up. */ + gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1); + return NULL; +} + +void census_log_end_write(void *record, size_t bytes_written) { + GPR_ASSERT(g_log.initialized); + cl_block_end_write(cl_get_block(record), bytes_written); +} + +void census_log_init_reader(void) { + GPR_ASSERT(g_log.initialized); + gpr_mu_lock(&g_log.lock); + /* If a block is locked for reading unlock it. */ + if (g_log.block_being_read != NULL) { + cl_block_end_read(g_log.block_being_read); + g_log.block_being_read = NULL; + } + g_log.read_iterator_state = g_log.num_cores; + gpr_mu_unlock(&g_log.lock); +} + +const void *census_log_read_next(size_t *bytes_available) { + GPR_ASSERT(g_log.initialized); + gpr_mu_lock(&g_log.lock); + if (g_log.block_being_read != NULL) { + cl_block_end_read(g_log.block_being_read); + } + do { + g_log.block_being_read = cl_next_block_to_read(g_log.block_being_read); + if (g_log.block_being_read != NULL) { + void *record = + cl_block_start_read(g_log.block_being_read, bytes_available); + if (record != NULL) { + gpr_mu_unlock(&g_log.lock); + return record; + } + } + } while (g_log.block_being_read != NULL); + gpr_mu_unlock(&g_log.lock); + return NULL; +} + +size_t census_log_remaining_space(void) { + size_t space; + GPR_ASSERT(g_log.initialized); + gpr_mu_lock(&g_log.lock); + if (g_log.discard_old_records) { + /* Remaining space is not meaningful; just return the entire log space. */ + space = g_log.num_blocks << CENSUS_LOG_2_MAX_RECORD_SIZE; + } else { + space = g_log.free_block_list.count * CENSUS_LOG_MAX_RECORD_SIZE; + } + gpr_mu_unlock(&g_log.lock); + return space; +} + +int census_log_out_of_space_count(void) { + GPR_ASSERT(g_log.initialized); + return gpr_atm_acq_load(&g_log.out_of_space_count); +} diff --git a/src/core/lib/statistics/census_log.h b/src/core/lib/statistics/census_log.h new file mode 100644 index 0000000000..e7ce0d4433 --- /dev/null +++ b/src/core/lib/statistics/census_log.h @@ -0,0 +1,91 @@ +/* + * + * Copyright 2015-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_STATISTICS_CENSUS_LOG_H +#define GRPC_CORE_STATISTICS_CENSUS_LOG_H + +#include + +/* Maximum record size, in bytes. */ +#define CENSUS_LOG_2_MAX_RECORD_SIZE 14 /* 2^14 = 16KB */ +#define CENSUS_LOG_MAX_RECORD_SIZE (1 << CENSUS_LOG_2_MAX_RECORD_SIZE) + +/* Initialize the statistics logging subsystem with the given log size. A log + size of 0 will result in the smallest possible log for the platform + (approximately CENSUS_LOG_MAX_RECORD_SIZE * gpr_cpu_num_cores()). If + discard_old_records is non-zero, then new records will displace older ones + when the log is full. This function must be called before any other + census_log functions. +*/ +void census_log_initialize(size_t size_in_mb, int discard_old_records); + +/* Shutdown the logging subsystem. Caller must ensure that: + - no in progress or future call to any census_log functions + - no incomplete records +*/ +void census_log_shutdown(void); + +/* Allocates and returns a 'size' bytes record and marks it in use. A + subsequent census_log_end_write() marks the record complete. The + 'bytes_written' census_log_end_write() argument must be <= + 'size'. Returns NULL if out-of-space AND: + - log is configured to keep old records OR + - all blocks are pinned by incomplete records. +*/ +void *census_log_start_write(size_t size); + +void census_log_end_write(void *record, size_t bytes_written); + +/* census_log_read_next() iterates over blocks with data and for each block + returns a pointer to the first unread byte. The number of bytes that can be + read are returned in 'bytes_available'. Reader is expected to read all + available data. Reading the data consumes it i.e. it cannot be read again. + census_log_read_next() returns NULL if the end is reached i.e last block + is read. census_log_init_reader() starts the iteration or aborts the + current iteration. +*/ +void census_log_init_reader(void); +const void *census_log_read_next(size_t *bytes_available); + +/* Returns estimated remaining space across all blocks, in bytes. If log is + configured to discard old records, returns total log space. Otherwise, + returns space available in empty blocks (partially filled blocks are + treated as full). +*/ +size_t census_log_remaining_space(void); + +/* Returns the number of times gprc_stats_log_start_write() failed due to + out-of-space. */ +int census_log_out_of_space_count(void); + +#endif /* GRPC_CORE_STATISTICS_CENSUS_LOG_H */ diff --git a/src/core/lib/statistics/census_rpc_stats.c b/src/core/lib/statistics/census_rpc_stats.c new file mode 100644 index 0000000000..c78d6fd612 --- /dev/null +++ b/src/core/lib/statistics/census_rpc_stats.c @@ -0,0 +1,253 @@ +/* + * + * Copyright 2015-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 + +#include +#include +#include +#include "src/core/statistics/census_interface.h" +#include "src/core/statistics/census_rpc_stats.h" +#include "src/core/statistics/census_tracing.h" +#include "src/core/statistics/hash_table.h" +#include "src/core/statistics/window_stats.h" +#include "src/core/support/murmur_hash.h" +#include "src/core/support/string.h" + +#define NUM_INTERVALS 3 +#define MINUTE_INTERVAL 0 +#define HOUR_INTERVAL 1 +#define TOTAL_INTERVAL 2 + +/* for easier typing */ +typedef census_per_method_rpc_stats per_method_stats; + +/* Ensure mu is only initialized once. */ +static gpr_once g_stats_store_mu_init = GPR_ONCE_INIT; +/* Guards two stats stores. */ +static gpr_mu g_mu; +static census_ht *g_client_stats_store = NULL; +static census_ht *g_server_stats_store = NULL; + +static void init_mutex(void) { gpr_mu_init(&g_mu); } + +static void init_mutex_once(void) { + gpr_once_init(&g_stats_store_mu_init, init_mutex); +} + +static int cmp_str_keys(const void *k1, const void *k2) { + return strcmp((const char *)k1, (const char *)k2); +} + +/* TODO(hongyu): replace it with cityhash64 */ +static uint64_t simple_hash(const void *k) { + size_t len = strlen(k); + uint64_t higher = gpr_murmur_hash3((const char *)k, len / 2, 0); + return higher << 32 | + gpr_murmur_hash3((const char *)k + len / 2, len - len / 2, 0); +} + +static void delete_stats(void *stats) { + census_window_stats_destroy((struct census_window_stats *)stats); +} + +static void delete_key(void *key) { gpr_free(key); } + +static const census_ht_option ht_opt = { + CENSUS_HT_POINTER /* key type */, 1999 /* n_of_buckets */, + simple_hash /* hash function */, cmp_str_keys /* key comparator */, + delete_stats /* data deleter */, delete_key /* key deleter */ +}; + +static void init_rpc_stats(void *stats) { + memset(stats, 0, sizeof(census_rpc_stats)); +} + +static void stat_add_proportion(double p, void *base, const void *addme) { + census_rpc_stats *b = (census_rpc_stats *)base; + census_rpc_stats *a = (census_rpc_stats *)addme; + b->cnt += p * a->cnt; + b->rpc_error_cnt += p * a->rpc_error_cnt; + b->app_error_cnt += p * a->app_error_cnt; + b->elapsed_time_ms += p * a->elapsed_time_ms; + b->api_request_bytes += p * a->api_request_bytes; + b->wire_request_bytes += p * a->wire_request_bytes; + b->api_response_bytes += p * a->api_response_bytes; + b->wire_response_bytes += p * a->wire_response_bytes; +} + +static void stat_add(void *base, const void *addme) { + stat_add_proportion(1.0, base, addme); +} + +static gpr_timespec min_hour_total_intervals[3] = { + {60, 0}, {3600, 0}, {36000000, 0}}; + +static const census_window_stats_stat_info window_stats_settings = { + sizeof(census_rpc_stats), init_rpc_stats, stat_add, stat_add_proportion}; + +census_rpc_stats *census_rpc_stats_create_empty(void) { + census_rpc_stats *ret = + (census_rpc_stats *)gpr_malloc(sizeof(census_rpc_stats)); + memset(ret, 0, sizeof(census_rpc_stats)); + return ret; +} + +void census_aggregated_rpc_stats_set_empty(census_aggregated_rpc_stats *data) { + int i = 0; + for (i = 0; i < data->num_entries; i++) { + if (data->stats[i].method != NULL) { + gpr_free((void *)data->stats[i].method); + } + } + if (data->stats != NULL) { + gpr_free(data->stats); + } + data->num_entries = 0; + data->stats = NULL; +} + +static void record_stats(census_ht *store, census_op_id op_id, + const census_rpc_stats *stats) { + gpr_mu_lock(&g_mu); + if (store != NULL) { + census_trace_obj *trace = NULL; + census_internal_lock_trace_store(); + trace = census_get_trace_obj_locked(op_id); + if (trace != NULL) { + const char *method_name = census_get_trace_method_name(trace); + struct census_window_stats *window_stats = NULL; + census_ht_key key; + key.ptr = (void *)method_name; + window_stats = census_ht_find(store, key); + census_internal_unlock_trace_store(); + if (window_stats == NULL) { + window_stats = census_window_stats_create(3, min_hour_total_intervals, + 30, &window_stats_settings); + key.ptr = gpr_strdup(key.ptr); + census_ht_insert(store, key, (void *)window_stats); + } + census_window_stats_add(window_stats, gpr_now(GPR_CLOCK_REALTIME), stats); + } else { + census_internal_unlock_trace_store(); + } + } + gpr_mu_unlock(&g_mu); +} + +void census_record_rpc_client_stats(census_op_id op_id, + const census_rpc_stats *stats) { + record_stats(g_client_stats_store, op_id, stats); +} + +void census_record_rpc_server_stats(census_op_id op_id, + const census_rpc_stats *stats) { + record_stats(g_server_stats_store, op_id, stats); +} + +/* Get stats from input stats store */ +static void get_stats(census_ht *store, census_aggregated_rpc_stats *data) { + GPR_ASSERT(data != NULL); + if (data->num_entries != 0) { + census_aggregated_rpc_stats_set_empty(data); + } + gpr_mu_lock(&g_mu); + if (store != NULL) { + size_t n; + unsigned i, j; + gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); + census_ht_kv *kv = census_ht_get_all_elements(store, &n); + if (kv != NULL) { + data->num_entries = n; + data->stats = + (per_method_stats *)gpr_malloc(sizeof(per_method_stats) * n); + for (i = 0; i < n; i++) { + census_window_stats_sums sums[NUM_INTERVALS]; + for (j = 0; j < NUM_INTERVALS; j++) { + sums[j].statistic = (void *)census_rpc_stats_create_empty(); + } + data->stats[i].method = gpr_strdup(kv[i].k.ptr); + census_window_stats_get_sums(kv[i].v, now, sums); + data->stats[i].minute_stats = + *(census_rpc_stats *)sums[MINUTE_INTERVAL].statistic; + data->stats[i].hour_stats = + *(census_rpc_stats *)sums[HOUR_INTERVAL].statistic; + data->stats[i].total_stats = + *(census_rpc_stats *)sums[TOTAL_INTERVAL].statistic; + for (j = 0; j < NUM_INTERVALS; j++) { + gpr_free(sums[j].statistic); + } + } + gpr_free(kv); + } + } + gpr_mu_unlock(&g_mu); +} + +void census_get_client_stats(census_aggregated_rpc_stats *data) { + get_stats(g_client_stats_store, data); +} + +void census_get_server_stats(census_aggregated_rpc_stats *data) { + get_stats(g_server_stats_store, data); +} + +void census_stats_store_init(void) { + init_mutex_once(); + gpr_mu_lock(&g_mu); + if (g_client_stats_store == NULL && g_server_stats_store == NULL) { + g_client_stats_store = census_ht_create(&ht_opt); + g_server_stats_store = census_ht_create(&ht_opt); + } else { + gpr_log(GPR_ERROR, "Census stats store already initialized."); + } + gpr_mu_unlock(&g_mu); +} + +void census_stats_store_shutdown(void) { + init_mutex_once(); + gpr_mu_lock(&g_mu); + if (g_client_stats_store != NULL) { + census_ht_destroy(g_client_stats_store); + g_client_stats_store = NULL; + } else { + gpr_log(GPR_ERROR, "Census server stats store not initialized."); + } + if (g_server_stats_store != NULL) { + census_ht_destroy(g_server_stats_store); + g_server_stats_store = NULL; + } else { + gpr_log(GPR_ERROR, "Census client stats store not initialized."); + } + gpr_mu_unlock(&g_mu); +} diff --git a/src/core/lib/statistics/census_rpc_stats.h b/src/core/lib/statistics/census_rpc_stats.h new file mode 100644 index 0000000000..f7f220e45f --- /dev/null +++ b/src/core/lib/statistics/census_rpc_stats.h @@ -0,0 +1,101 @@ +/* + * + * Copyright 2015-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_STATISTICS_CENSUS_RPC_STATS_H +#define GRPC_CORE_STATISTICS_CENSUS_RPC_STATS_H + +#include +#include "src/core/statistics/census_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct census_rpc_stats { + uint64_t cnt; + uint64_t rpc_error_cnt; + uint64_t app_error_cnt; + double elapsed_time_ms; + double api_request_bytes; + double wire_request_bytes; + double api_response_bytes; + double wire_response_bytes; +}; + +/* Creates an empty rpc stats object on heap. */ +census_rpc_stats *census_rpc_stats_create_empty(void); + +typedef struct census_per_method_rpc_stats { + const char *method; + census_rpc_stats minute_stats; /* cumulative stats in the past minute */ + census_rpc_stats hour_stats; /* cumulative stats in the past hour */ + census_rpc_stats total_stats; /* cumulative stats from last gc */ +} census_per_method_rpc_stats; + +typedef struct census_aggregated_rpc_stats { + int num_entries; + census_per_method_rpc_stats *stats; +} census_aggregated_rpc_stats; + +/* Initializes an aggregated rpc stats object to an empty state. */ +void census_aggregated_rpc_stats_set_empty(census_aggregated_rpc_stats *data); + +/* Records client side stats of a rpc. */ +void census_record_rpc_client_stats(census_op_id op_id, + const census_rpc_stats *stats); + +/* Records server side stats of a rpc. */ +void census_record_rpc_server_stats(census_op_id op_id, + const census_rpc_stats *stats); + +/* The following two functions are intended for inprocess query of + per-service per-method stats from grpc implementations. */ + +/* Populates *data_map with server side aggregated per-service per-method + stats. + DO NOT CALL from outside of grpc code. */ +void census_get_server_stats(census_aggregated_rpc_stats *data_map); + +/* Populates *data_map with client side aggregated per-service per-method + stats. + DO NOT CALL from outside of grpc code. */ +void census_get_client_stats(census_aggregated_rpc_stats *data_map); + +void census_stats_store_init(void); +void census_stats_store_shutdown(void); + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_STATISTICS_CENSUS_RPC_STATS_H */ diff --git a/src/core/lib/statistics/census_tracing.c b/src/core/lib/statistics/census_tracing.c new file mode 100644 index 0000000000..ad82498eba --- /dev/null +++ b/src/core/lib/statistics/census_tracing.c @@ -0,0 +1,241 @@ +/* + * + * Copyright 2015-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/statistics/census_tracing.h" +#include "src/core/statistics/census_interface.h" + +#include +#include + +#include +#include +#include +#include +#include "src/core/statistics/hash_table.h" +#include "src/core/support/string.h" + +void census_trace_obj_destroy(census_trace_obj *obj) { + census_trace_annotation *p = obj->annotations; + while (p != NULL) { + census_trace_annotation *next = p->next; + gpr_free(p); + p = next; + } + gpr_free(obj->method); + gpr_free(obj); +} + +static void delete_trace_obj(void *obj) { + census_trace_obj_destroy((census_trace_obj *)obj); +} + +static const census_ht_option ht_opt = { + CENSUS_HT_UINT64 /* key type */, + 571 /* n_of_buckets */, + NULL /* hash */, + NULL /* compare_keys */, + delete_trace_obj /* delete data */, + NULL /* delete key */ +}; + +static gpr_once g_init_mutex_once = GPR_ONCE_INIT; +static gpr_mu g_mu; /* Guards following two static variables. */ +static census_ht *g_trace_store = NULL; +static uint64_t g_id = 0; + +static census_ht_key op_id_as_key(census_op_id *id) { + return *(census_ht_key *)id; +} + +static uint64_t op_id_2_uint64(census_op_id *id) { + uint64_t ret; + memcpy(&ret, id, sizeof(census_op_id)); + return ret; +} + +static void init_mutex(void) { gpr_mu_init(&g_mu); } + +static void init_mutex_once(void) { + gpr_once_init(&g_init_mutex_once, init_mutex); +} + +census_op_id census_tracing_start_op(void) { + gpr_mu_lock(&g_mu); + { + census_trace_obj *ret = gpr_malloc(sizeof(census_trace_obj)); + memset(ret, 0, sizeof(census_trace_obj)); + g_id++; + memcpy(&ret->id, &g_id, sizeof(census_op_id)); + ret->rpc_stats.cnt = 1; + ret->ts = gpr_now(GPR_CLOCK_REALTIME); + census_ht_insert(g_trace_store, op_id_as_key(&ret->id), (void *)ret); + gpr_log(GPR_DEBUG, "Start tracing for id %lu", g_id); + gpr_mu_unlock(&g_mu); + return ret->id; + } +} + +int census_add_method_tag(census_op_id op_id, const char *method) { + int ret = 0; + census_trace_obj *trace = NULL; + gpr_mu_lock(&g_mu); + trace = census_ht_find(g_trace_store, op_id_as_key(&op_id)); + if (trace == NULL) { + ret = 1; + } else { + trace->method = gpr_strdup(method); + } + gpr_mu_unlock(&g_mu); + return ret; +} + +void census_tracing_print(census_op_id op_id, const char *anno_txt) { + census_trace_obj *trace = NULL; + gpr_mu_lock(&g_mu); + trace = census_ht_find(g_trace_store, op_id_as_key(&op_id)); + if (trace != NULL) { + census_trace_annotation *anno = gpr_malloc(sizeof(census_trace_annotation)); + anno->ts = gpr_now(GPR_CLOCK_REALTIME); + { + char *d = anno->txt; + const char *s = anno_txt; + int n = 0; + for (; n < CENSUS_MAX_ANNOTATION_LENGTH && *s != '\0'; ++n) { + *d++ = *s++; + } + *d = '\0'; + } + anno->next = trace->annotations; + trace->annotations = anno; + } + gpr_mu_unlock(&g_mu); +} + +void census_tracing_end_op(census_op_id op_id) { + census_trace_obj *trace = NULL; + gpr_mu_lock(&g_mu); + trace = census_ht_find(g_trace_store, op_id_as_key(&op_id)); + if (trace != NULL) { + trace->rpc_stats.elapsed_time_ms = gpr_timespec_to_micros( + gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), trace->ts)); + gpr_log(GPR_DEBUG, "End tracing for id %lu, method %s, latency %f us", + op_id_2_uint64(&op_id), trace->method, + trace->rpc_stats.elapsed_time_ms); + census_ht_erase(g_trace_store, op_id_as_key(&op_id)); + } + gpr_mu_unlock(&g_mu); +} + +void census_tracing_init(void) { + init_mutex_once(); + gpr_mu_lock(&g_mu); + if (g_trace_store == NULL) { + g_id = 1; + g_trace_store = census_ht_create(&ht_opt); + } else { + gpr_log(GPR_ERROR, "Census trace store already initialized."); + } + gpr_mu_unlock(&g_mu); +} + +void census_tracing_shutdown(void) { + gpr_mu_lock(&g_mu); + if (g_trace_store != NULL) { + census_ht_destroy(g_trace_store); + g_trace_store = NULL; + } else { + gpr_log(GPR_ERROR, "Census trace store is not initialized."); + } + gpr_mu_unlock(&g_mu); +} + +void census_internal_lock_trace_store(void) { gpr_mu_lock(&g_mu); } + +void census_internal_unlock_trace_store(void) { gpr_mu_unlock(&g_mu); } + +census_trace_obj *census_get_trace_obj_locked(census_op_id op_id) { + if (g_trace_store == NULL) { + gpr_log(GPR_ERROR, "Census trace store is not initialized."); + return NULL; + } + return (census_trace_obj *)census_ht_find(g_trace_store, + op_id_as_key(&op_id)); +} + +const char *census_get_trace_method_name(const census_trace_obj *trace) { + return trace->method; +} + +static census_trace_annotation *dup_annotation_chain( + census_trace_annotation *from) { + census_trace_annotation *ret = NULL; + census_trace_annotation **to = &ret; + for (; from != NULL; from = from->next) { + *to = gpr_malloc(sizeof(census_trace_annotation)); + memcpy(*to, from, sizeof(census_trace_annotation)); + to = &(*to)->next; + } + return ret; +} + +static census_trace_obj *trace_obj_dup(census_trace_obj *from) { + census_trace_obj *to = NULL; + GPR_ASSERT(from != NULL); + to = gpr_malloc(sizeof(census_trace_obj)); + to->id = from->id; + to->ts = from->ts; + to->rpc_stats = from->rpc_stats; + to->method = gpr_strdup(from->method); + to->annotations = dup_annotation_chain(from->annotations); + return to; +} + +census_trace_obj **census_get_active_ops(int *num_active_ops) { + census_trace_obj **ret = NULL; + gpr_mu_lock(&g_mu); + if (g_trace_store != NULL) { + size_t n = 0; + census_ht_kv *all_kvs = census_ht_get_all_elements(g_trace_store, &n); + *num_active_ops = (int)n; + if (n != 0) { + size_t i = 0; + ret = gpr_malloc(sizeof(census_trace_obj *) * n); + for (i = 0; i < n; i++) { + ret[i] = trace_obj_dup((census_trace_obj *)all_kvs[i].v); + } + } + gpr_free(all_kvs); + } + gpr_mu_unlock(&g_mu); + return ret; +} diff --git a/src/core/lib/statistics/census_tracing.h b/src/core/lib/statistics/census_tracing.h new file mode 100644 index 0000000000..b611e95bf4 --- /dev/null +++ b/src/core/lib/statistics/census_tracing.h @@ -0,0 +1,96 @@ +/* + * + * Copyright 2015-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_STATISTICS_CENSUS_TRACING_H +#define GRPC_CORE_STATISTICS_CENSUS_TRACING_H + +#include +#include "src/core/statistics/census_rpc_stats.h" + +/* WARNING: The data structures and APIs provided by this file are for GRPC + library's internal use ONLY. They might be changed in backward-incompatible + ways and are not subject to any deprecation policy. + They are not recommended for external use. + */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Struct for a trace annotation. */ +typedef struct census_trace_annotation { + gpr_timespec ts; /* timestamp of the annotation */ + char txt[CENSUS_MAX_ANNOTATION_LENGTH + 1]; /* actual txt annotation */ + struct census_trace_annotation *next; +} census_trace_annotation; + +typedef struct census_trace_obj { + census_op_id id; + gpr_timespec ts; + census_rpc_stats rpc_stats; + char *method; + census_trace_annotation *annotations; +} census_trace_obj; + +/* Deletes trace object. */ +void census_trace_obj_destroy(census_trace_obj *obj); + +/* Initializes trace store. This function is thread safe. */ +void census_tracing_init(void); + +/* Shutsdown trace store. This function is thread safe. */ +void census_tracing_shutdown(void); + +/* Gets trace obj corresponding to the input op_id. Returns NULL if trace store + is not initialized or trace obj is not found. Requires trace store being + locked before calling this function. */ +census_trace_obj *census_get_trace_obj_locked(census_op_id op_id); + +/* The following two functions acquire and release the trace store global lock. + They are for census internal use only. */ +void census_internal_lock_trace_store(void); +void census_internal_unlock_trace_store(void); + +/* Gets method name associated with the input trace object. */ +const char *census_get_trace_method_name(const census_trace_obj *trace); + +/* Returns an array of pointers to trace objects of currently active operations + and fills in number of active operations. Returns NULL if there are no active + operations. + Caller owns the returned objects. */ +census_trace_obj **census_get_active_ops(int *num_active_ops); + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_STATISTICS_CENSUS_TRACING_H */ diff --git a/src/core/lib/statistics/hash_table.c b/src/core/lib/statistics/hash_table.c new file mode 100644 index 0000000000..3ef79c0d7d --- /dev/null +++ b/src/core/lib/statistics/hash_table.c @@ -0,0 +1,303 @@ +/* + * + * Copyright 2015-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/statistics/hash_table.h" + +#include +#include + +#include +#include +#include + +#define CENSUS_HT_NUM_BUCKETS 1999 + +/* A single hash table data entry */ +typedef struct ht_entry { + census_ht_key key; + void *data; + struct ht_entry *next; +} ht_entry; + +/* hash table bucket */ +typedef struct bucket { + /* NULL if bucket is empty */ + ht_entry *next; + /* -1 if all buckets are empty. */ + int32_t prev_non_empty_bucket; + /* -1 if all buckets are empty. */ + int32_t next_non_empty_bucket; +} bucket; + +struct unresizable_hash_table { + /* Number of entries in the table */ + size_t size; + /* Number of buckets */ + uint32_t num_buckets; + /* Array of buckets initialized at creation time. Memory consumption is + 16 bytes per bucket on a 64-bit platform. */ + bucket *buckets; + /* Index of the first non-empty bucket. -1 iff size == 0. */ + int32_t first_non_empty_bucket; + /* Index of the last non_empty bucket. -1 iff size == 0. */ + int32_t last_non_empty_bucket; + /* Immutable options of this hash table, initialized at creation time. */ + census_ht_option options; +}; + +typedef struct entry_locator { + int32_t bucket_idx; + int is_first_in_chain; + int found; + ht_entry *prev_entry; +} entry_locator; + +/* Asserts if option is not valid. */ +void check_options(const census_ht_option *option) { + GPR_ASSERT(option != NULL); + GPR_ASSERT(option->num_buckets > 0); + GPR_ASSERT(option->key_type == CENSUS_HT_UINT64 || + option->key_type == CENSUS_HT_POINTER); + if (option->key_type == CENSUS_HT_UINT64) { + GPR_ASSERT(option->hash == NULL); + } else if (option->key_type == CENSUS_HT_POINTER) { + GPR_ASSERT(option->hash != NULL); + GPR_ASSERT(option->compare_keys != NULL); + } +} + +#define REMOVE_NEXT(options, ptr) \ + do { \ + ht_entry *tmp = (ptr)->next; \ + (ptr)->next = tmp->next; \ + delete_entry(options, tmp); \ + } while (0) + +static void delete_entry(const census_ht_option *opt, ht_entry *p) { + if (opt->delete_data != NULL) { + opt->delete_data(p->data); + } + if (opt->delete_key != NULL) { + opt->delete_key(p->key.ptr); + } + gpr_free(p); +} + +static uint64_t hash(const census_ht_option *opt, census_ht_key key) { + return opt->key_type == CENSUS_HT_UINT64 ? key.val : opt->hash(key.ptr); +} + +census_ht *census_ht_create(const census_ht_option *option) { + int i; + census_ht *ret = NULL; + check_options(option); + ret = (census_ht *)gpr_malloc(sizeof(census_ht)); + ret->size = 0; + ret->num_buckets = option->num_buckets; + ret->buckets = (bucket *)gpr_malloc(sizeof(bucket) * ret->num_buckets); + ret->options = *option; + /* initialize each bucket */ + for (i = 0; i < ret->options.num_buckets; i++) { + ret->buckets[i].prev_non_empty_bucket = -1; + ret->buckets[i].next_non_empty_bucket = -1; + ret->buckets[i].next = NULL; + } + return ret; +} + +static int32_t find_bucket_idx(const census_ht *ht, census_ht_key key) { + return hash(&ht->options, key) % ht->num_buckets; +} + +static int keys_match(const census_ht_option *opt, const ht_entry *p, + const census_ht_key key) { + GPR_ASSERT(opt->key_type == CENSUS_HT_UINT64 || + opt->key_type == CENSUS_HT_POINTER); + if (opt->key_type == CENSUS_HT_UINT64) return p->key.val == key.val; + return !opt->compare_keys((p->key).ptr, key.ptr); +} + +static entry_locator ht_find(const census_ht *ht, census_ht_key key) { + entry_locator loc = {0, 0, 0, NULL}; + int32_t idx = 0; + ht_entry *ptr = NULL; + GPR_ASSERT(ht != NULL); + idx = find_bucket_idx(ht, key); + ptr = ht->buckets[idx].next; + if (ptr == NULL) { + /* bucket is empty */ + return loc; + } + if (keys_match(&ht->options, ptr, key)) { + loc.bucket_idx = idx; + loc.is_first_in_chain = 1; + loc.found = 1; + return loc; + } else { + for (; ptr->next != NULL; ptr = ptr->next) { + if (keys_match(&ht->options, ptr->next, key)) { + loc.bucket_idx = idx; + loc.is_first_in_chain = 0; + loc.found = 1; + loc.prev_entry = ptr; + return loc; + } + } + } + /* Could not find the key */ + return loc; +} + +void *census_ht_find(const census_ht *ht, census_ht_key key) { + entry_locator loc = ht_find(ht, key); + if (loc.found == 0) { + return NULL; + } + return loc.is_first_in_chain ? ht->buckets[loc.bucket_idx].next->data + : loc.prev_entry->next->data; +} + +void census_ht_insert(census_ht *ht, census_ht_key key, void *data) { + int32_t idx = find_bucket_idx(ht, key); + ht_entry *ptr = NULL; + entry_locator loc = ht_find(ht, key); + if (loc.found) { + /* Replace old value with new value. */ + ptr = loc.is_first_in_chain ? ht->buckets[loc.bucket_idx].next + : loc.prev_entry->next; + if (ht->options.delete_data != NULL) { + ht->options.delete_data(ptr->data); + } + ptr->data = data; + return; + } + + /* first entry in the table. */ + if (ht->size == 0) { + ht->buckets[idx].next_non_empty_bucket = -1; + ht->buckets[idx].prev_non_empty_bucket = -1; + ht->first_non_empty_bucket = idx; + ht->last_non_empty_bucket = idx; + } else if (ht->buckets[idx].next == NULL) { + /* first entry in the bucket. */ + ht->buckets[ht->last_non_empty_bucket].next_non_empty_bucket = idx; + ht->buckets[idx].prev_non_empty_bucket = ht->last_non_empty_bucket; + ht->buckets[idx].next_non_empty_bucket = -1; + ht->last_non_empty_bucket = idx; + } + ptr = (ht_entry *)gpr_malloc(sizeof(ht_entry)); + ptr->key = key; + ptr->data = data; + ptr->next = ht->buckets[idx].next; + ht->buckets[idx].next = ptr; + ht->size++; +} + +void census_ht_erase(census_ht *ht, census_ht_key key) { + entry_locator loc = ht_find(ht, key); + if (loc.found == 0) { + /* noop if not found */ + return; + } + ht->size--; + if (loc.is_first_in_chain) { + bucket *b = &ht->buckets[loc.bucket_idx]; + GPR_ASSERT(b->next != NULL); + /* The only entry in the bucket */ + if (b->next->next == NULL) { + int prev = b->prev_non_empty_bucket; + int next = b->next_non_empty_bucket; + if (prev != -1) { + ht->buckets[prev].next_non_empty_bucket = next; + } else { + ht->first_non_empty_bucket = next; + } + if (next != -1) { + ht->buckets[next].prev_non_empty_bucket = prev; + } else { + ht->last_non_empty_bucket = prev; + } + } + REMOVE_NEXT(&ht->options, b); + } else { + GPR_ASSERT(loc.prev_entry->next != NULL); + REMOVE_NEXT(&ht->options, loc.prev_entry); + } +} + +/* Returns NULL if input table is empty. */ +census_ht_kv *census_ht_get_all_elements(const census_ht *ht, size_t *num) { + census_ht_kv *ret = NULL; + int i = 0; + int32_t idx = -1; + GPR_ASSERT(ht != NULL && num != NULL); + *num = ht->size; + if (*num == 0) { + return NULL; + } + + ret = (census_ht_kv *)gpr_malloc(sizeof(census_ht_kv) * ht->size); + idx = ht->first_non_empty_bucket; + while (idx >= 0) { + ht_entry *ptr = ht->buckets[idx].next; + for (; ptr != NULL; ptr = ptr->next) { + ret[i].k = ptr->key; + ret[i].v = ptr->data; + i++; + } + idx = ht->buckets[idx].next_non_empty_bucket; + } + return ret; +} + +static void ht_delete_entry_chain(const census_ht_option *options, + ht_entry *first) { + if (first == NULL) { + return; + } + if (first->next != NULL) { + ht_delete_entry_chain(options, first->next); + } + delete_entry(options, first); +} + +void census_ht_destroy(census_ht *ht) { + unsigned i; + for (i = 0; i < ht->num_buckets; ++i) { + ht_delete_entry_chain(&ht->options, ht->buckets[i].next); + } + gpr_free(ht->buckets); + gpr_free(ht); +} + +size_t census_ht_get_size(const census_ht *ht) { return ht->size; } diff --git a/src/core/lib/statistics/hash_table.h b/src/core/lib/statistics/hash_table.h new file mode 100644 index 0000000000..f4bf2ba49a --- /dev/null +++ b/src/core/lib/statistics/hash_table.h @@ -0,0 +1,131 @@ +/* + * + * Copyright 2015-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_STATISTICS_HASH_TABLE_H +#define GRPC_CORE_STATISTICS_HASH_TABLE_H + +#include + +#include + +/* A chain based hash table with fixed number of buckets. + Your probably shouldn't use this code directly. It is implemented for the + use case in census trace store and stats store, where number of entries in + the table is in the scale of upto several thousands, entries are added and + removed from the table very frequently (~100k/s), the frequency of find() + operations is roughly several times of the frequency of insert() and erase() + Comparing to find(), the insert(), erase() and get_all_entries() operations + are much less freqent (<1/s). + + Per bucket memory overhead is about (8 + sizeof(intptr_t) bytes. + Per entry memory overhead is about (8 + 2 * sizeof(intptr_t) bytes. + + All functions are not thread-safe. Synchronization will be provided in the + upper layer (in trace store and stats store). +*/ + +/* Opaque hash table struct */ +typedef struct unresizable_hash_table census_ht; + +/* Currently, the hash_table can take two types of keys. (uint64 for trace + store and const char* for stats store). */ +typedef union { + uint64_t val; + void *ptr; +} census_ht_key; + +typedef enum census_ht_key_type { + CENSUS_HT_UINT64 = 0, + CENSUS_HT_POINTER = 1 +} census_ht_key_type; + +typedef struct census_ht_option { + /* Type of hash key */ + census_ht_key_type key_type; + /* Desired number of buckets, preferably a prime number */ + int32_t num_buckets; + /* Fucntion to calculate uint64 hash value of the key. Only takes effect if + key_type is POINTER. */ + uint64_t (*hash)(const void *); + /* Function to compare two keys, returns 0 iff equal. Only takes effect if + key_type is POINTER */ + int (*compare_keys)(const void *k1, const void *k2); + /* Value deleter. NULL if no specialized delete function is needed. */ + void (*delete_data)(void *); + /* Key deleter. NULL if table does not own the key. (e.g. key is part of the + value or key is not owned by the table.) */ + void (*delete_key)(void *); +} census_ht_option; + +/* Creates a hashtable with fixed number of buckets according to the settings + specified in 'options' arg. Function pointers "hash" and "compare_keys" must + be provided if key_type is POINTER. Asserts if fail to create. */ +census_ht *census_ht_create(const census_ht_option *options); + +/* Deletes hash table instance. Frees all dynamic memory owned by ht.*/ +void census_ht_destroy(census_ht *ht); + +/* Inserts the input key-val pair into hash_table. If an entry with the same key + exists in the table, the corresponding value will be overwritten by the input + val. */ +void census_ht_insert(census_ht *ht, census_ht_key key, void *val); + +/* Returns pointer to data, returns NULL if not found. */ +void *census_ht_find(const census_ht *ht, census_ht_key key); + +/* Erase hash table entry with input key. Noop if key is not found. */ +void census_ht_erase(census_ht *ht, census_ht_key key); + +typedef struct census_ht_kv { + census_ht_key k; + void *v; +} census_ht_kv; + +/* Returns an array of pointers to all values in the hash table. Order of the + elements can be arbitrary. Sets 'num' to the size of returned array. Caller + owns returned array. */ +census_ht_kv *census_ht_get_all_elements(const census_ht *ht, size_t *num); + +/* Returns number of elements kept. */ +size_t census_ht_get_size(const census_ht *ht); + +/* Functor applied on each key-value pair while iterating through entries in the + table. The functor should not mutate data. */ +typedef void (*census_ht_itr_cb)(census_ht_key key, const void *val_ptr, + void *state); + +/* Iterates through all key-value pairs in the hash_table. The callback function + should not invalidate data entries. */ +uint64_t census_ht_for_all(const census_ht *ht, census_ht_itr_cb); + +#endif /* GRPC_CORE_STATISTICS_HASH_TABLE_H */ diff --git a/src/core/lib/statistics/window_stats.c b/src/core/lib/statistics/window_stats.c new file mode 100644 index 0000000000..eb296865a0 --- /dev/null +++ b/src/core/lib/statistics/window_stats.c @@ -0,0 +1,316 @@ +/* + * + * Copyright 2015-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/statistics/window_stats.h" +#include +#include +#include +#include +#include +#include +#include + +/* typedefs make typing long names easier. Use cws (for census_window_stats) */ +typedef census_window_stats_stat_info cws_stat_info; +typedef struct census_window_stats_sum cws_sum; + +/* Each interval is composed of a number of buckets, which hold a count of + entries and a single statistic */ +typedef struct census_window_stats_bucket { + int64_t count; + void *statistic; +} cws_bucket; + +/* Each interval has a set of buckets, and the variables needed to keep + track of their current state */ +typedef struct census_window_stats_interval_stats { + /* The buckets. There will be 'granularity' + 1 of these. */ + cws_bucket *buckets; + /* Index of the bucket containing the smallest time interval. */ + int bottom_bucket; + /* The smallest time storable in the current window. */ + int64_t bottom; + /* The largest time storable in the current window + 1ns */ + int64_t top; + /* The width of each bucket in ns. */ + int64_t width; +} cws_interval_stats; + +typedef struct census_window_stats { + /* Number of intervals. */ + int nintervals; + /* Number of buckets in each interval. 'granularity' + 1. */ + int nbuckets; + /* Record of stat_info. */ + cws_stat_info stat_info; + /* Stats for each interval. */ + cws_interval_stats *interval_stats; + /* The time the newset stat was recorded. */ + int64_t newest_time; +} window_stats; + +/* Calculate an actual bucket index from a logical index 'IDX'. Other + parameters supply information on the interval struct and overall stats. */ +#define BUCKET_IDX(IS, IDX, WSTATS) \ + ((IS->bottom_bucket + (IDX)) % WSTATS->nbuckets) + +/* The maximum seconds value we can have in a valid timespec. More than this + will result in overflow in timespec_to_ns(). This works out to ~292 years. + TODO: consider using doubles instead of int64. */ +static int64_t max_seconds = (GPR_INT64_MAX - GPR_NS_PER_SEC) / GPR_NS_PER_SEC; + +static int64_t timespec_to_ns(const gpr_timespec ts) { + if (ts.tv_sec > max_seconds) { + return GPR_INT64_MAX - 1; + } + return ts.tv_sec * GPR_NS_PER_SEC + ts.tv_nsec; +} + +static void cws_initialize_statistic(void *statistic, + const cws_stat_info *stat_info) { + if (stat_info->stat_initialize == NULL) { + memset(statistic, 0, stat_info->stat_size); + } else { + stat_info->stat_initialize(statistic); + } +} + +/* Create and initialize a statistic */ +static void *cws_create_statistic(const cws_stat_info *stat_info) { + void *stat = gpr_malloc(stat_info->stat_size); + cws_initialize_statistic(stat, stat_info); + return stat; +} + +window_stats *census_window_stats_create(int nintervals, + const gpr_timespec intervals[], + int granularity, + const cws_stat_info *stat_info) { + window_stats *ret; + int i; + /* validate inputs */ + GPR_ASSERT(nintervals > 0 && granularity > 2 && intervals != NULL && + stat_info != NULL); + for (i = 0; i < nintervals; i++) { + int64_t ns = timespec_to_ns(intervals[i]); + GPR_ASSERT(intervals[i].tv_sec >= 0 && intervals[i].tv_nsec >= 0 && + intervals[i].tv_nsec < GPR_NS_PER_SEC && ns >= 100 && + granularity * 10 <= ns); + } + /* Allocate and initialize relevant data structures */ + ret = (window_stats *)gpr_malloc(sizeof(window_stats)); + ret->nintervals = nintervals; + ret->nbuckets = granularity + 1; + ret->stat_info = *stat_info; + ret->interval_stats = + (cws_interval_stats *)gpr_malloc(nintervals * sizeof(cws_interval_stats)); + for (i = 0; i < nintervals; i++) { + int64_t size_ns = timespec_to_ns(intervals[i]); + cws_interval_stats *is = ret->interval_stats + i; + cws_bucket *buckets = is->buckets = + (cws_bucket *)gpr_malloc(ret->nbuckets * sizeof(cws_bucket)); + int b; + for (b = 0; b < ret->nbuckets; b++) { + buckets[b].statistic = cws_create_statistic(stat_info); + buckets[b].count = 0; + } + is->bottom_bucket = 0; + is->bottom = 0; + is->width = size_ns / granularity; + /* Check for possible overflow issues, and maximize interval size if the + user requested something large enough. */ + if ((GPR_INT64_MAX - is->width) > size_ns) { + is->top = size_ns + is->width; + } else { + is->top = GPR_INT64_MAX; + is->width = GPR_INT64_MAX / (granularity + 1); + } + /* If size doesn't divide evenly, we can have a width slightly too small; + better to have it slightly large. */ + if ((size_ns - (granularity + 1) * is->width) > 0) { + is->width += 1; + } + } + ret->newest_time = 0; + return ret; +} + +/* When we try adding a measurement above the current interval range, we + need to "shift" the buckets sufficiently to cover the new range. */ +static void cws_shift_buckets(const window_stats *wstats, + cws_interval_stats *is, int64_t when_ns) { + int i; + /* number of bucket time widths to "shift" */ + int shift; + /* number of buckets to clear */ + int nclear; + GPR_ASSERT(when_ns >= is->top); + /* number of bucket time widths to "shift" */ + shift = ((when_ns - is->top) / is->width) + 1; + /* number of buckets to clear - limited by actual number of buckets */ + nclear = GPR_MIN(shift, wstats->nbuckets); + for (i = 0; i < nclear; i++) { + int b = BUCKET_IDX(is, i, wstats); + is->buckets[b].count = 0; + cws_initialize_statistic(is->buckets[b].statistic, &wstats->stat_info); + } + /* adjust top/bottom times and current bottom bucket */ + is->bottom_bucket = BUCKET_IDX(is, shift, wstats); + is->top += shift * is->width; + is->bottom += shift * is->width; +} + +void census_window_stats_add(window_stats *wstats, const gpr_timespec when, + const void *stat_value) { + int i; + int64_t when_ns = timespec_to_ns(when); + GPR_ASSERT(wstats->interval_stats != NULL); + for (i = 0; i < wstats->nintervals; i++) { + cws_interval_stats *is = wstats->interval_stats + i; + cws_bucket *bucket; + if (when_ns < is->bottom) { /* Below smallest time in interval: drop */ + continue; + } + if (when_ns >= is->top) { /* above limit: shift buckets */ + cws_shift_buckets(wstats, is, when_ns); + } + /* Add the stat. */ + GPR_ASSERT(is->bottom <= when_ns && when_ns < is->top); + bucket = is->buckets + + BUCKET_IDX(is, (when_ns - is->bottom) / is->width, wstats); + bucket->count++; + wstats->stat_info.stat_add(bucket->statistic, stat_value); + } + if (when_ns > wstats->newest_time) { + wstats->newest_time = when_ns; + } +} + +/* Add a specific bucket contents to an accumulating total. */ +static void cws_add_bucket_to_sum(cws_sum *sum, const cws_bucket *bucket, + const cws_stat_info *stat_info) { + sum->count += bucket->count; + stat_info->stat_add(sum->statistic, bucket->statistic); +} + +/* Add a proportion to an accumulating sum. */ +static void cws_add_proportion_to_sum(double p, cws_sum *sum, + const cws_bucket *bucket, + const cws_stat_info *stat_info) { + sum->count += p * bucket->count; + stat_info->stat_add_proportion(p, sum->statistic, bucket->statistic); +} + +void census_window_stats_get_sums(const window_stats *wstats, + const gpr_timespec when, cws_sum sums[]) { + int i; + int64_t when_ns = timespec_to_ns(when); + GPR_ASSERT(wstats->interval_stats != NULL); + for (i = 0; i < wstats->nintervals; i++) { + int when_bucket; + int new_bucket; + double last_proportion = 1.0; + double bottom_proportion; + cws_interval_stats *is = wstats->interval_stats + i; + cws_sum *sum = sums + i; + sum->count = 0; + cws_initialize_statistic(sum->statistic, &wstats->stat_info); + if (when_ns < is->bottom) { + continue; + } + if (when_ns >= is->top) { + cws_shift_buckets(wstats, is, when_ns); + } + /* Calculating the appropriate amount of which buckets to use can get + complicated. Essentially there are two cases: + 1) if the "top" bucket (new_bucket, where the newest additions to the + stats recorded are entered) corresponds to 'when', then we need + to take a proportion of it - (if when < newest_time) or the full + thing. We also (possibly) need to take a corresponding + proportion of the bottom bucket. + 2) Other cases, we just take a straight proportion. + */ + when_bucket = (when_ns - is->bottom) / is->width; + new_bucket = (wstats->newest_time - is->bottom) / is->width; + if (new_bucket == when_bucket) { + int64_t bottom_bucket_time = is->bottom + when_bucket * is->width; + if (when_ns < wstats->newest_time) { + last_proportion = (double)(when_ns - bottom_bucket_time) / + (double)(wstats->newest_time - bottom_bucket_time); + bottom_proportion = + (double)(is->width - (when_ns - bottom_bucket_time)) / is->width; + } else { + bottom_proportion = + (double)(is->width - (wstats->newest_time - bottom_bucket_time)) / + is->width; + } + } else { + last_proportion = + (double)(when_ns + 1 - is->bottom - when_bucket * is->width) / + is->width; + bottom_proportion = 1.0 - last_proportion; + } + cws_add_proportion_to_sum(last_proportion, sum, + is->buckets + BUCKET_IDX(is, when_bucket, wstats), + &wstats->stat_info); + if (when_bucket != 0) { /* last bucket isn't also bottom bucket */ + int b; + /* Add all of "bottom" bucket if we are looking at a subset of the + full interval, or a proportion if we are adding full interval. */ + cws_add_proportion_to_sum( + (when_bucket == wstats->nbuckets - 1 ? bottom_proportion : 1.0), sum, + is->buckets + is->bottom_bucket, &wstats->stat_info); + /* Add all the remaining buckets (everything but top and bottom). */ + for (b = 1; b < when_bucket; b++) { + cws_add_bucket_to_sum(sum, is->buckets + BUCKET_IDX(is, b, wstats), + &wstats->stat_info); + } + } + } +} + +void census_window_stats_destroy(window_stats *wstats) { + int i; + GPR_ASSERT(wstats->interval_stats != NULL); + for (i = 0; i < wstats->nintervals; i++) { + int b; + for (b = 0; b < wstats->nbuckets; b++) { + gpr_free(wstats->interval_stats[i].buckets[b].statistic); + } + gpr_free(wstats->interval_stats[i].buckets); + } + gpr_free(wstats->interval_stats); + /* Ensure any use-after free triggers assert. */ + wstats->interval_stats = NULL; + gpr_free(wstats); +} diff --git a/src/core/lib/statistics/window_stats.h b/src/core/lib/statistics/window_stats.h new file mode 100644 index 0000000000..774277180f --- /dev/null +++ b/src/core/lib/statistics/window_stats.h @@ -0,0 +1,173 @@ +/* + * + * Copyright 2015-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_STATISTICS_WINDOW_STATS_H +#define GRPC_CORE_STATISTICS_WINDOW_STATS_H + +#include + +/* Keep rolling sums of a user-defined statistic (containing a number of + measurements) over a a number of time intervals ("windows"). For example, + you can use a window_stats object to answer questions such as + "Approximately how many RPCs/s did I receive over the past minute, and + approximately how many bytes did I send out over that period?". + + The type of data to record, and the time intervals to keep are specified + when creating the object via a call to census_window_stats_create(). + + A window's interval is divided into one or more "buckets"; the interval + must be divisible by the number of buckets. Internally, these buckets + control the granularity of window_stats' measurements. Increasing the + number of buckets lets the object respond more quickly to changes in the + overall rate of data added into the object, at the cost of additional + memory usage. + + Here's some code which keeps one minute/hour measurements for two values + (latency in seconds and bytes transferred), with each interval divided into + 4 buckets. + + typedef struct my_stat { + double latency; + int bytes; + } my_stat; + + void add_my_stat(void* base, const void* addme) { + my_stat* b = (my_stat*)base; + const my_stat* a = (const my_stat*)addme; + b->latency += a->latency; + b->bytes += a->bytes; + } + + void add_proportion_my_stat(double p, void* base, const void* addme) { + (my_stat*)result->latency += p * (const my_stat*)base->latency; + (my_stat*)result->bytes += p * (const my_stat*)base->bytes; + } + + #define kNumIntervals 2 + #define kMinInterval 0 + #define kHourInterval 1 + #define kNumBuckets 4 + + const struct census_window_stats_stat_info kMyStatInfo + = { sizeof(my_stat), NULL, add_my_stat, add_proportion_my_stat }; + gpr_timespec intervals[kNumIntervals] = {{60, 0}, {3600, 0}}; + my_stat stat; + my_stat sums[kNumIntervals]; + census_window_stats_sums result[kNumIntervals]; + struct census_window_stats* stats + = census_window_stats_create(kNumIntervals, intervals, kNumBuckets, + &kMyStatInfo); + // Record a new event, taking 15.3ms, transferring 1784 bytes. + stat.latency = 0.153; + stat.bytes = 1784; + census_window_stats_add(stats, gpr_now(GPR_CLOCK_REALTIME), &stat); + // Get sums and print them out + result[kMinInterval].statistic = &sums[kMinInterval]; + result[kHourInterval].statistic = &sums[kHourInterval]; + census_window_stats_get_sums(stats, gpr_now(GPR_CLOCK_REALTIME), result); + printf("%d events/min, average time %gs, average bytes %g\n", + result[kMinInterval].count, + (my_stat*)result[kMinInterval].statistic->latency / + result[kMinInterval].count, + (my_stat*)result[kMinInterval].statistic->bytes / + result[kMinInterval].count + ); + printf("%d events/hr, average time %gs, average bytes %g\n", + result[kHourInterval].count, + (my_stat*)result[kHourInterval].statistic->latency / + result[kHourInterval].count, + (my_stat*)result[kHourInterval].statistic->bytes / + result[kHourInterval].count + ); +*/ + +/* Opaque structure for representing window_stats object */ +struct census_window_stats; + +/* Information provided by API user on the information they want to record */ +typedef struct census_window_stats_stat_info { + /* Number of bytes in user-defined object. */ + size_t stat_size; + /* Function to initialize a user-defined statistics object. If this is set + * to NULL, then the object will be zero-initialized. */ + void (*stat_initialize)(void *stat); + /* Function to add one user-defined statistics object ('addme') to 'base' */ + void (*stat_add)(void *base, const void *addme); + /* As for previous function, but only add a proportion 'p'. This API will + currently only use 'p' values in the range [0,1], but other values are + possible in the future, and should be supported. */ + void (*stat_add_proportion)(double p, void *base, const void *addme); +} census_window_stats_stat_info; + +/* Create a new window_stats object. 'nintervals' is the number of + 'intervals', and must be >=1. 'granularity' is the number of buckets, with + a larger number using more memory, but providing greater accuracy of + results. 'granularity should be > 2. We also require that each interval be + at least 10 * 'granularity' nanoseconds in size. 'stat_info' contains + information about the statistic to be gathered. Intervals greater than ~192 + years will be treated as essentially infinite in size. This function will + GPR_ASSERT() if the object cannot be created or any of the parameters have + invalid values. This function is thread-safe. */ +struct census_window_stats *census_window_stats_create( + int nintervals, const gpr_timespec intervals[], int granularity, + const census_window_stats_stat_info *stat_info); + +/* Add a new measurement (in 'stat_value'), as of a given time ('when'). + This function is thread-compatible. */ +void census_window_stats_add(struct census_window_stats *wstats, + const gpr_timespec when, const void *stat_value); + +/* Structure used to record a single intervals sum for a given statistic */ +typedef struct census_window_stats_sum { + /* Total count of samples. Note that because some internal interpolation + is performed, the count of samples returned for each interval may not be an + integral value. */ + double count; + /* Sum for statistic */ + void *statistic; +} census_window_stats_sums; + +/* Retrieve a set of all values stored in a window_stats object 'wstats'. The + number of 'sums' MUST be the same as the number 'nintervals' used in + census_window_stats_create(). This function is thread-compatible. */ +void census_window_stats_get_sums(const struct census_window_stats *wstats, + const gpr_timespec when, + struct census_window_stats_sum sums[]); + +/* Destroy a window_stats object. Once this function has been called, the + object will no longer be usable from any of the above functions (and + calling them will most likely result in a NULL-pointer dereference or + assertion failure). This function is thread-compatible. */ +void census_window_stats_destroy(struct census_window_stats *wstats); + +#endif /* GRPC_CORE_STATISTICS_WINDOW_STATS_H */ diff --git a/src/core/lib/support/alloc.c b/src/core/lib/support/alloc.c new file mode 100644 index 0000000000..fd9fb8f5e7 --- /dev/null +++ b/src/core/lib/support/alloc.c @@ -0,0 +1,90 @@ +/* + * + * Copyright 2015-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 + +#include +#include +#include +#include "src/core/profiling/timers.h" + +static gpr_allocation_functions g_alloc_functions = {malloc, realloc, free}; + +gpr_allocation_functions gpr_get_allocation_functions() { + return g_alloc_functions; +} + +void gpr_set_allocation_functions(gpr_allocation_functions functions) { + GPR_ASSERT(functions.malloc_fn != NULL); + GPR_ASSERT(functions.realloc_fn != NULL); + GPR_ASSERT(functions.free_fn != NULL); + g_alloc_functions = functions; +} + +void *gpr_malloc(size_t size) { + void *p; + GPR_TIMER_BEGIN("gpr_malloc", 0); + p = g_alloc_functions.malloc_fn(size); + if (!p) { + abort(); + } + GPR_TIMER_END("gpr_malloc", 0); + return p; +} + +void gpr_free(void *p) { + GPR_TIMER_BEGIN("gpr_free", 0); + g_alloc_functions.free_fn(p); + GPR_TIMER_END("gpr_free", 0); +} + +void *gpr_realloc(void *p, size_t size) { + GPR_TIMER_BEGIN("gpr_realloc", 0); + p = g_alloc_functions.realloc_fn(p, size); + if (!p) { + abort(); + } + GPR_TIMER_END("gpr_realloc", 0); + return p; +} + +void *gpr_malloc_aligned(size_t size, size_t alignment_log) { + size_t alignment = ((size_t)1) << alignment_log; + size_t extra = alignment - 1 + sizeof(void *); + void *p = gpr_malloc(size + extra); + void **ret = (void **)(((uintptr_t)p + extra) & ~(alignment - 1)); + ret[-1] = p; + return (void *)ret; +} + +void gpr_free_aligned(void *ptr) { gpr_free(((void **)ptr)[-1]); } diff --git a/src/core/lib/support/avl.c b/src/core/lib/support/avl.c new file mode 100644 index 0000000000..f378b3ee17 --- /dev/null +++ b/src/core/lib/support/avl.c @@ -0,0 +1,288 @@ +/* + * + * Copyright 2015-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 + +#include +#include + +#include +#include +#include + +gpr_avl gpr_avl_create(const gpr_avl_vtable *vtable) { + gpr_avl out; + out.vtable = vtable; + out.root = NULL; + return out; +} + +static gpr_avl_node *ref_node(gpr_avl_node *node) { + if (node) { + gpr_ref(&node->refs); + } + return node; +} + +static void unref_node(const gpr_avl_vtable *vtable, gpr_avl_node *node) { + if (node == NULL) { + return; + } + if (gpr_unref(&node->refs)) { + vtable->destroy_key(node->key); + vtable->destroy_value(node->value); + unref_node(vtable, node->left); + unref_node(vtable, node->right); + gpr_free(node); + } +} + +static long node_height(gpr_avl_node *node) { + return node == NULL ? 0 : node->height; +} + +#ifndef NDEBUG +static long calculate_height(gpr_avl_node *node) { + return node == NULL ? 0 : 1 + GPR_MAX(calculate_height(node->left), + calculate_height(node->right)); +} + +static gpr_avl_node *assert_invariants(gpr_avl_node *n) { + if (n == NULL) return NULL; + assert_invariants(n->left); + assert_invariants(n->right); + assert(calculate_height(n) == n->height); + assert(labs(node_height(n->left) - node_height(n->right)) <= 1); + return n; +} +#else +static gpr_avl_node *assert_invariants(gpr_avl_node *n) { return n; } +#endif + +gpr_avl_node *new_node(void *key, void *value, gpr_avl_node *left, + gpr_avl_node *right) { + gpr_avl_node *node = gpr_malloc(sizeof(*node)); + gpr_ref_init(&node->refs, 1); + node->key = key; + node->value = value; + node->left = assert_invariants(left); + node->right = assert_invariants(right); + node->height = 1 + GPR_MAX(node_height(left), node_height(right)); + return node; +} + +static gpr_avl_node *get(const gpr_avl_vtable *vtable, gpr_avl_node *node, + void *key) { + long cmp; + + if (node == NULL) { + return NULL; + } + + cmp = vtable->compare_keys(node->key, key); + if (cmp == 0) { + return node; + } else if (cmp > 0) { + return get(vtable, node->left, key); + } else { + return get(vtable, node->right, key); + } +} + +void *gpr_avl_get(gpr_avl avl, void *key) { + gpr_avl_node *node = get(avl.vtable, avl.root, key); + return node ? node->value : NULL; +} + +static gpr_avl_node *rotate_left(const gpr_avl_vtable *vtable, void *key, + void *value, gpr_avl_node *left, + gpr_avl_node *right) { + gpr_avl_node *n = + new_node(vtable->copy_key(right->key), vtable->copy_value(right->value), + new_node(key, value, left, ref_node(right->left)), + ref_node(right->right)); + unref_node(vtable, right); + return n; +} + +static gpr_avl_node *rotate_right(const gpr_avl_vtable *vtable, void *key, + void *value, gpr_avl_node *left, + gpr_avl_node *right) { + gpr_avl_node *n = new_node( + vtable->copy_key(left->key), vtable->copy_value(left->value), + ref_node(left->left), new_node(key, value, ref_node(left->right), right)); + unref_node(vtable, left); + return n; +} + +static gpr_avl_node *rotate_left_right(const gpr_avl_vtable *vtable, void *key, + void *value, gpr_avl_node *left, + gpr_avl_node *right) { + /* rotate_right(..., rotate_left(left), right) */ + gpr_avl_node *n = new_node( + vtable->copy_key(left->right->key), + vtable->copy_value(left->right->value), + new_node(vtable->copy_key(left->key), vtable->copy_value(left->value), + ref_node(left->left), ref_node(left->right->left)), + new_node(key, value, ref_node(left->right->right), right)); + unref_node(vtable, left); + return n; +} + +static gpr_avl_node *rotate_right_left(const gpr_avl_vtable *vtable, void *key, + void *value, gpr_avl_node *left, + gpr_avl_node *right) { + /* rotate_left(..., left, rotate_right(right)) */ + gpr_avl_node *n = new_node( + vtable->copy_key(right->left->key), + vtable->copy_value(right->left->value), + new_node(key, value, left, ref_node(right->left->left)), + new_node(vtable->copy_key(right->key), vtable->copy_value(right->value), + ref_node(right->left->right), ref_node(right->right))); + unref_node(vtable, right); + return n; +} + +static gpr_avl_node *rebalance(const gpr_avl_vtable *vtable, void *key, + void *value, gpr_avl_node *left, + gpr_avl_node *right) { + switch (node_height(left) - node_height(right)) { + case 2: + if (node_height(left->left) - node_height(left->right) == -1) { + return assert_invariants( + rotate_left_right(vtable, key, value, left, right)); + } else { + return assert_invariants(rotate_right(vtable, key, value, left, right)); + } + case -2: + if (node_height(right->left) - node_height(right->right) == 1) { + return assert_invariants( + rotate_right_left(vtable, key, value, left, right)); + } else { + return assert_invariants(rotate_left(vtable, key, value, left, right)); + } + default: + return assert_invariants(new_node(key, value, left, right)); + } +} + +static gpr_avl_node *add(const gpr_avl_vtable *vtable, gpr_avl_node *node, + void *key, void *value) { + long cmp; + if (node == NULL) { + return new_node(key, value, NULL, NULL); + } + cmp = vtable->compare_keys(node->key, key); + if (cmp == 0) { + return new_node(key, value, ref_node(node->left), ref_node(node->right)); + } else if (cmp > 0) { + return rebalance( + vtable, vtable->copy_key(node->key), vtable->copy_value(node->value), + add(vtable, node->left, key, value), ref_node(node->right)); + } else { + return rebalance(vtable, vtable->copy_key(node->key), + vtable->copy_value(node->value), ref_node(node->left), + add(vtable, node->right, key, value)); + } +} + +gpr_avl gpr_avl_add(gpr_avl avl, void *key, void *value) { + gpr_avl_node *old_root = avl.root; + avl.root = add(avl.vtable, avl.root, key, value); + assert_invariants(avl.root); + unref_node(avl.vtable, old_root); + return avl; +} + +static gpr_avl_node *in_order_head(gpr_avl_node *node) { + while (node->left != NULL) { + node = node->left; + } + return node; +} + +static gpr_avl_node *in_order_tail(gpr_avl_node *node) { + while (node->right != NULL) { + node = node->right; + } + return node; +} + +static gpr_avl_node *remove(const gpr_avl_vtable *vtable, gpr_avl_node *node, + void *key) { + long cmp; + if (node == NULL) { + return NULL; + } + cmp = vtable->compare_keys(node->key, key); + if (cmp == 0) { + if (node->left == NULL) { + return ref_node(node->right); + } else if (node->right == NULL) { + return ref_node(node->left); + } else if (node->left->height < node->right->height) { + gpr_avl_node *h = in_order_head(node->right); + return rebalance(vtable, vtable->copy_key(h->key), + vtable->copy_value(h->value), ref_node(node->left), + remove(vtable, node->right, h->key)); + } else { + gpr_avl_node *h = in_order_tail(node->left); + return rebalance( + vtable, vtable->copy_key(h->key), vtable->copy_value(h->value), + remove(vtable, node->left, h->key), ref_node(node->right)); + } + } else if (cmp > 0) { + return rebalance(vtable, vtable->copy_key(node->key), + vtable->copy_value(node->value), + remove(vtable, node->left, key), ref_node(node->right)); + } else { + return rebalance(vtable, vtable->copy_key(node->key), + vtable->copy_value(node->value), ref_node(node->left), + remove(vtable, node->right, key)); + } +} + +gpr_avl gpr_avl_remove(gpr_avl avl, void *key) { + gpr_avl_node *old_root = avl.root; + avl.root = remove(avl.vtable, avl.root, key); + assert_invariants(avl.root); + unref_node(avl.vtable, old_root); + return avl; +} + +gpr_avl gpr_avl_ref(gpr_avl avl) { + ref_node(avl.root); + return avl; +} + +void gpr_avl_unref(gpr_avl avl) { unref_node(avl.vtable, avl.root); } diff --git a/src/core/lib/support/backoff.c b/src/core/lib/support/backoff.c new file mode 100644 index 0000000000..4ccfb774ed --- /dev/null +++ b/src/core/lib/support/backoff.c @@ -0,0 +1,76 @@ +/* + * + * 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/support/backoff.h" + +#include + +void gpr_backoff_init(gpr_backoff *backoff, double multiplier, double jitter, + int64_t min_timeout_millis, int64_t max_timeout_millis) { + backoff->multiplier = multiplier; + backoff->jitter = jitter; + backoff->min_timeout_millis = min_timeout_millis; + backoff->max_timeout_millis = max_timeout_millis; + backoff->rng_state = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec; +} + +gpr_timespec gpr_backoff_begin(gpr_backoff *backoff, gpr_timespec now) { + backoff->current_timeout_millis = backoff->min_timeout_millis; + return gpr_time_add( + now, gpr_time_from_millis(backoff->current_timeout_millis, GPR_TIMESPAN)); +} + +/* Generate a random number between 0 and 1. */ +static double generate_uniform_random_number(uint32_t *rng_state) { + *rng_state = (1103515245 * *rng_state + 12345) % ((uint32_t)1 << 31); + return *rng_state / (double)((uint32_t)1 << 31); +} + +gpr_timespec gpr_backoff_step(gpr_backoff *backoff, gpr_timespec now) { + double new_timeout_millis = + backoff->multiplier * (double)backoff->current_timeout_millis; + double jitter_range = backoff->jitter * new_timeout_millis; + double jitter = + (2 * generate_uniform_random_number(&backoff->rng_state) - 1) * + jitter_range; + backoff->current_timeout_millis = + GPR_CLAMP((int64_t)(new_timeout_millis + jitter), + backoff->min_timeout_millis, backoff->max_timeout_millis); + return gpr_time_add( + now, gpr_time_from_millis(backoff->current_timeout_millis, GPR_TIMESPAN)); +} + +void gpr_backoff_reset(gpr_backoff *backoff) { + // forces step() to return a timeout of min_timeout_millis + backoff->current_timeout_millis = 0; +} diff --git a/src/core/lib/support/backoff.h b/src/core/lib/support/backoff.h new file mode 100644 index 0000000000..0f933c3149 --- /dev/null +++ b/src/core/lib/support/backoff.h @@ -0,0 +1,68 @@ +/* + * + * 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_SUPPORT_BACKOFF_H +#define GRPC_CORE_SUPPORT_BACKOFF_H + +#include + +typedef struct { + /// const: multiplier between retry attempts + double multiplier; + /// const: amount to randomize backoffs + double jitter; + /// const: minimum time between retries in milliseconds + int64_t min_timeout_millis; + /// const: maximum time between retries in milliseconds + int64_t max_timeout_millis; + + /// random number generator + uint32_t rng_state; + + /// current retry timeout in milliseconds + int64_t current_timeout_millis; +} gpr_backoff; + +/// Initialize backoff machinery - does not need to be destroyed +void gpr_backoff_init(gpr_backoff *backoff, double multiplier, double jitter, + int64_t min_timeout_millis, int64_t max_timeout_millis); + +/// Begin retry loop: returns a timespec for the NEXT retry +gpr_timespec gpr_backoff_begin(gpr_backoff *backoff, gpr_timespec now); +/// Step a retry loop: returns a timespec for the NEXT retry +gpr_timespec gpr_backoff_step(gpr_backoff *backoff, gpr_timespec now); +/// Reset the backoff, so the next gpr_backoff_step will be a gpr_backoff_begin +/// instead +void gpr_backoff_reset(gpr_backoff *backoff); + +#endif /* GRPC_CORE_SUPPORT_BACKOFF_H */ diff --git a/src/core/lib/support/block_annotate.h b/src/core/lib/support/block_annotate.h new file mode 100644 index 0000000000..79a18039f4 --- /dev/null +++ b/src/core/lib/support/block_annotate.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2015-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_SUPPORT_BLOCK_ANNOTATE_H +#define GRPC_CORE_SUPPORT_BLOCK_ANNOTATE_H + +/* These annotations identify the beginning and end of regions where + the code may block for reasons other than synchronization functions. + These include poll, epoll, and getaddrinfo. */ + +#define GRPC_SCHEDULING_START_BLOCKING_REGION \ + do { \ + } while (0) +#define GRPC_SCHEDULING_END_BLOCKING_REGION \ + do { \ + } while (0) + +#endif /* GRPC_CORE_SUPPORT_BLOCK_ANNOTATE_H */ diff --git a/src/core/lib/support/cmdline.c b/src/core/lib/support/cmdline.c new file mode 100644 index 0000000000..eff46a1655 --- /dev/null +++ b/src/core/lib/support/cmdline.c @@ -0,0 +1,347 @@ +/* + * + * Copyright 2015-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 + +#include +#include +#include + +#include +#include +#include +#include "src/core/support/string.h" + +typedef enum { ARGTYPE_INT, ARGTYPE_BOOL, ARGTYPE_STRING } argtype; + +typedef struct arg { + const char *name; + const char *help; + argtype type; + void *value; + struct arg *next; +} arg; + +struct gpr_cmdline { + const char *description; + arg *args; + const char *argv0; + + const char *extra_arg_name; + const char *extra_arg_help; + void (*extra_arg)(void *user_data, const char *arg); + void *extra_arg_user_data; + + int (*state)(gpr_cmdline *cl, char *arg); + arg *cur_arg; + + int survive_failure; +}; + +static int normal_state(gpr_cmdline *cl, char *arg); + +gpr_cmdline *gpr_cmdline_create(const char *description) { + gpr_cmdline *cl = gpr_malloc(sizeof(gpr_cmdline)); + memset(cl, 0, sizeof(gpr_cmdline)); + + cl->description = description; + cl->state = normal_state; + + return cl; +} + +void gpr_cmdline_set_survive_failure(gpr_cmdline *cl) { + cl->survive_failure = 1; +} + +void gpr_cmdline_destroy(gpr_cmdline *cl) { + while (cl->args) { + arg *a = cl->args; + cl->args = a->next; + gpr_free(a); + } + gpr_free(cl); +} + +static void add_arg(gpr_cmdline *cl, const char *name, const char *help, + argtype type, void *value) { + arg *a; + + for (a = cl->args; a; a = a->next) { + GPR_ASSERT(0 != strcmp(a->name, name)); + } + + a = gpr_malloc(sizeof(arg)); + memset(a, 0, sizeof(arg)); + a->name = name; + a->help = help; + a->type = type; + a->value = value; + a->next = cl->args; + cl->args = a; +} + +void gpr_cmdline_add_int(gpr_cmdline *cl, const char *name, const char *help, + int *value) { + add_arg(cl, name, help, ARGTYPE_INT, value); +} + +void gpr_cmdline_add_flag(gpr_cmdline *cl, const char *name, const char *help, + int *value) { + add_arg(cl, name, help, ARGTYPE_BOOL, value); +} + +void gpr_cmdline_add_string(gpr_cmdline *cl, const char *name, const char *help, + char **value) { + add_arg(cl, name, help, ARGTYPE_STRING, value); +} + +void gpr_cmdline_on_extra_arg( + gpr_cmdline *cl, const char *name, const char *help, + void (*on_extra_arg)(void *user_data, const char *arg), void *user_data) { + GPR_ASSERT(!cl->extra_arg); + GPR_ASSERT(on_extra_arg); + + cl->extra_arg = on_extra_arg; + cl->extra_arg_user_data = user_data; + cl->extra_arg_name = name; + cl->extra_arg_help = help; +} + +/* recursively descend argument list, adding the last element + to s first - so that arguments are added in the order they were + added to the list by api calls */ +static void add_args_to_usage(gpr_strvec *s, arg *a) { + char *tmp; + + if (!a) return; + add_args_to_usage(s, a->next); + + switch (a->type) { + case ARGTYPE_BOOL: + gpr_asprintf(&tmp, " [--%s|--no-%s]", a->name, a->name); + gpr_strvec_add(s, tmp); + break; + case ARGTYPE_STRING: + gpr_asprintf(&tmp, " [--%s=string]", a->name); + gpr_strvec_add(s, tmp); + break; + case ARGTYPE_INT: + gpr_asprintf(&tmp, " [--%s=int]", a->name); + gpr_strvec_add(s, tmp); + break; + } +} + +char *gpr_cmdline_usage_string(gpr_cmdline *cl, const char *argv0) { + /* TODO(ctiller): make this prettier */ + gpr_strvec s; + char *tmp; + const char *name = strrchr(argv0, '/'); + + if (name) { + name++; + } else { + name = argv0; + } + + gpr_strvec_init(&s); + + gpr_asprintf(&tmp, "Usage: %s", name); + gpr_strvec_add(&s, tmp); + add_args_to_usage(&s, cl->args); + if (cl->extra_arg) { + gpr_asprintf(&tmp, " [%s...]", cl->extra_arg_name); + gpr_strvec_add(&s, tmp); + } + gpr_strvec_add(&s, gpr_strdup("\n")); + + tmp = gpr_strvec_flatten(&s, NULL); + gpr_strvec_destroy(&s); + return tmp; +} + +static int print_usage_and_die(gpr_cmdline *cl) { + char *usage = gpr_cmdline_usage_string(cl, cl->argv0); + fprintf(stderr, "%s", usage); + gpr_free(usage); + if (!cl->survive_failure) { + exit(1); + } + return 0; +} + +static int extra_state(gpr_cmdline *cl, char *str) { + if (!cl->extra_arg) { + return print_usage_and_die(cl); + } + cl->extra_arg(cl->extra_arg_user_data, str); + return 1; +} + +static arg *find_arg(gpr_cmdline *cl, char *name) { + arg *a; + + for (a = cl->args; a; a = a->next) { + if (0 == strcmp(a->name, name)) { + break; + } + } + + if (!a) { + fprintf(stderr, "Unknown argument: %s\n", name); + return NULL; + } + + return a; +} + +static int value_state(gpr_cmdline *cl, char *str) { + long intval; + char *end; + + GPR_ASSERT(cl->cur_arg); + + switch (cl->cur_arg->type) { + case ARGTYPE_INT: + intval = strtol(str, &end, 0); + if (*end || intval < INT_MIN || intval > INT_MAX) { + fprintf(stderr, "expected integer, got '%s' for %s\n", str, + cl->cur_arg->name); + return print_usage_and_die(cl); + } + *(int *)cl->cur_arg->value = (int)intval; + break; + case ARGTYPE_BOOL: + if (0 == strcmp(str, "1") || 0 == strcmp(str, "true")) { + *(int *)cl->cur_arg->value = 1; + } else if (0 == strcmp(str, "0") || 0 == strcmp(str, "false")) { + *(int *)cl->cur_arg->value = 0; + } else { + fprintf(stderr, "expected boolean, got '%s' for %s\n", str, + cl->cur_arg->name); + return print_usage_and_die(cl); + } + break; + case ARGTYPE_STRING: + *(char **)cl->cur_arg->value = str; + break; + } + + cl->state = normal_state; + return 1; +} + +static int normal_state(gpr_cmdline *cl, char *str) { + char *eq = NULL; + char *tmp = NULL; + char *arg_name = NULL; + int r = 1; + + if (0 == strcmp(str, "-help") || 0 == strcmp(str, "--help") || + 0 == strcmp(str, "-h")) { + return print_usage_and_die(cl); + } + + cl->cur_arg = NULL; + + if (str[0] == '-') { + if (str[1] == '-') { + if (str[2] == 0) { + /* handle '--' to move to just extra args */ + cl->state = extra_state; + return 1; + } + str += 2; + } else { + str += 1; + } + /* first byte of str is now past the leading '-' or '--' */ + if (str[0] == 'n' && str[1] == 'o' && str[2] == '-') { + /* str is of the form '--no-foo' - it's a flag disable */ + str += 3; + cl->cur_arg = find_arg(cl, str); + if (cl->cur_arg == NULL) { + return print_usage_and_die(cl); + } + if (cl->cur_arg->type != ARGTYPE_BOOL) { + fprintf(stderr, "%s is not a flag argument\n", str); + return print_usage_and_die(cl); + } + *(int *)cl->cur_arg->value = 0; + return 1; /* early out */ + } + eq = strchr(str, '='); + if (eq != NULL) { + /* copy the string into a temp buffer and extract the name */ + tmp = arg_name = gpr_malloc((size_t)(eq - str + 1)); + memcpy(arg_name, str, (size_t)(eq - str)); + arg_name[eq - str] = 0; + } else { + arg_name = str; + } + cl->cur_arg = find_arg(cl, arg_name); + if (cl->cur_arg == NULL) { + return print_usage_and_die(cl); + } + if (eq != NULL) { + /* str was of the type --foo=value, parse the value */ + r = value_state(cl, eq + 1); + } else if (cl->cur_arg->type != ARGTYPE_BOOL) { + /* flag types don't have a '--foo value' variant, other types do */ + cl->state = value_state; + } else { + /* flag parameter: just set the value */ + *(int *)cl->cur_arg->value = 1; + } + } else { + r = extra_state(cl, str); + } + + gpr_free(tmp); + return r; +} + +int gpr_cmdline_parse(gpr_cmdline *cl, int argc, char **argv) { + int i; + + GPR_ASSERT(argc >= 1); + cl->argv0 = argv[0]; + + for (i = 1; i < argc; i++) { + if (!cl->state(cl, argv[i])) { + return 0; + } + } + return 1; +} diff --git a/src/core/lib/support/cpu_iphone.c b/src/core/lib/support/cpu_iphone.c new file mode 100644 index 0000000000..82b49b47bc --- /dev/null +++ b/src/core/lib/support/cpu_iphone.c @@ -0,0 +1,49 @@ +/* + * + * Copyright 2015, 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 + +#ifdef GPR_CPU_IPHONE + +/* Probably 2 instead of 1, but see comment on gpr_cpu_current_cpu. */ +unsigned gpr_cpu_num_cores(void) { return 1; } + +/* Most code that's using this is using it to shard across work queues. So + unless profiling shows it's a problem or there appears a way to detect the + currently running CPU core, let's have it shard the default way. + Note that the interface in cpu.h lets gpr_cpu_num_cores return 0, but doing + it makes it impossible for gpr_cpu_current_cpu to satisfy its stated range, + and some code might be relying on it. */ +unsigned gpr_cpu_current_cpu(void) { return 0; } + +#endif /* GPR_CPU_IPHONE */ diff --git a/src/core/lib/support/cpu_linux.c b/src/core/lib/support/cpu_linux.c new file mode 100644 index 0000000000..5597df2d03 --- /dev/null +++ b/src/core/lib/support/cpu_linux.c @@ -0,0 +1,78 @@ +/* + * + * Copyright 2015-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 _GNU_SOURCE +#define _GNU_SOURCE +#endif /* _GNU_SOURCE */ + +#include + +#ifdef GPR_CPU_LINUX + +#include +#include +#include +#include + +#include +#include +#include + +static int ncpus = 0; + +static void init_num_cpus() { + /* This must be signed. sysconf returns -1 when the number cannot be + determined */ + ncpus = (int)sysconf(_SC_NPROCESSORS_ONLN); + if (ncpus < 1) { + gpr_log(GPR_ERROR, "Cannot determine number of CPUs: assuming 1"); + ncpus = 1; + } +} + +unsigned gpr_cpu_num_cores(void) { + static gpr_once once = GPR_ONCE_INIT; + gpr_once_init(&once, init_num_cpus); + return (unsigned)ncpus; +} + +unsigned gpr_cpu_current_cpu(void) { + int cpu = sched_getcpu(); + if (cpu < 0) { + gpr_log(GPR_ERROR, "Error determining current CPU: %s\n", strerror(errno)); + return 0; + } + return (unsigned)cpu; +} + +#endif /* GPR_CPU_LINUX */ diff --git a/src/core/lib/support/cpu_posix.c b/src/core/lib/support/cpu_posix.c new file mode 100644 index 0000000000..e508ddd8ca --- /dev/null +++ b/src/core/lib/support/cpu_posix.c @@ -0,0 +1,77 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_CPU_POSIX + +#include +#include +#include + +#include +#include + +static __thread char magic_thread_local; + +static long ncpus = 0; + +static void init_ncpus() { + ncpus = sysconf(_SC_NPROCESSORS_ONLN); + if (ncpus < 1 || ncpus > INT32_MAX) { + gpr_log(GPR_ERROR, "Cannot determine number of CPUs: assuming 1"); + ncpus = 1; + } +} + +unsigned gpr_cpu_num_cores(void) { + static gpr_once once = GPR_ONCE_INIT; + gpr_once_init(&once, init_ncpus); + return (unsigned)ncpus; +} + +/* This is a cheap, but good enough, pointer hash for sharding things: */ +static size_t shard_ptr(const void *info) { + size_t x = (size_t)info; + return ((x >> 4) ^ (x >> 9) ^ (x >> 14)) % gpr_cpu_num_cores(); +} + +unsigned gpr_cpu_current_cpu(void) { + /* NOTE: there's no way I know to return the actual cpu index portably... + most code that's using this is using it to shard across work queues though, + so here we use thread identity instead to achieve a similar though not + identical effect */ + return (unsigned)shard_ptr(&magic_thread_local); +} + +#endif /* GPR_CPU_POSIX */ diff --git a/src/core/lib/support/cpu_windows.c b/src/core/lib/support/cpu_windows.c new file mode 100644 index 0000000000..ce32eb0a9d --- /dev/null +++ b/src/core/lib/support/cpu_windows.c @@ -0,0 +1,47 @@ +/* + * + * Copyright 2015, 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 + +#ifdef GPR_WIN32 +#include + +unsigned gpr_cpu_num_cores(void) { + SYSTEM_INFO si; + GetSystemInfo(&si); + return si.dwNumberOfProcessors; +} + +unsigned gpr_cpu_current_cpu(void) { return GetCurrentProcessorNumber(); } + +#endif /* GPR_WIN32 */ diff --git a/src/core/lib/support/env.h b/src/core/lib/support/env.h new file mode 100644 index 0000000000..2902456947 --- /dev/null +++ b/src/core/lib/support/env.h @@ -0,0 +1,60 @@ +/* + * + * Copyright 2015-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_SUPPORT_ENV_H +#define GRPC_CORE_SUPPORT_ENV_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Env utility functions */ + +/* Gets the environment variable value with the specified name. + Returns a newly allocated string. It is the responsability of the caller to + gpr_free the return value if not NULL (which means that the environment + variable exists). */ +char *gpr_getenv(const char *name); + +/* Sets the the environment with the specified name to the specified value. */ +void gpr_setenv(const char *name, const char *value); + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_SUPPORT_ENV_H */ diff --git a/src/core/lib/support/env_linux.c b/src/core/lib/support/env_linux.c new file mode 100644 index 0000000000..fe51f846b7 --- /dev/null +++ b/src/core/lib/support/env_linux.c @@ -0,0 +1,89 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* for secure_getenv. */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include + +#ifdef GPR_LINUX_ENV + +#include "src/core/support/env.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include "src/core/support/string.h" + +char *gpr_getenv(const char *name) { +#if defined(GPR_BACKWARDS_COMPATIBILITY_MODE) + typedef char *(*getenv_type)(const char *); + static getenv_type getenv_func = NULL; + /* Check to see which getenv variant is supported (go from most + * to least secure) */ + const char *names[] = {"secure_getenv", "__secure_getenv", "getenv"}; + for (size_t i = 0; getenv_func == NULL && i < GPR_ARRAY_SIZE(names); i++) { + getenv_func = (getenv_type)dlsym(RTLD_DEFAULT, names[i]); + if (getenv_func != NULL && strstr(names[i], "secure") == NULL) { + gpr_log(GPR_DEBUG, + "Warning: insecure environment read function '%s' used", + names[i]); + } + } + char *result = getenv_func(name); + return result == NULL ? result : gpr_strdup(result); +#elif __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17) + char *result = secure_getenv(name); + return result == NULL ? result : gpr_strdup(result); +#else + gpr_log(GPR_DEBUG, "Warning: insecure environment read function '%s' used", + "getenv"); + char *result = getenv(name); + return result == NULL ? result : gpr_strdup(result); +#endif +} + +void gpr_setenv(const char *name, const char *value) { + int res = setenv(name, value, 1); + GPR_ASSERT(res == 0); +} + +#endif /* GPR_LINUX_ENV */ diff --git a/src/core/lib/support/env_posix.c b/src/core/lib/support/env_posix.c new file mode 100644 index 0000000000..256212be76 --- /dev/null +++ b/src/core/lib/support/env_posix.c @@ -0,0 +1,57 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_ENV + +#include "src/core/support/env.h" + +#include + +#include + +#include +#include "src/core/support/string.h" + +char *gpr_getenv(const char *name) { + char *result = getenv(name); + return result == NULL ? result : gpr_strdup(result); +} + +void gpr_setenv(const char *name, const char *value) { + int res = setenv(name, value, 1); + GPR_ASSERT(res == 0); +} + +#endif /* GPR_POSIX_ENV */ diff --git a/src/core/lib/support/env_win32.c b/src/core/lib/support/env_win32.c new file mode 100644 index 0000000000..10258283ba --- /dev/null +++ b/src/core/lib/support/env_win32.c @@ -0,0 +1,73 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_WIN32 + +#include "src/core/support/env.h" +#include "src/core/support/string.h" + +#ifdef __MINGW32__ +errno_t getenv_s(size_t *size_needed, char *buffer, size_t size, + const char *varname); +#else +#include +#endif + +#include +#include +#include + +char *gpr_getenv(const char *name) { + size_t size; + char *result = NULL; + errno_t err; + + err = getenv_s(&size, NULL, 0, name); + if (err || (size == 0)) return NULL; + result = gpr_malloc(size); + err = getenv_s(&size, result, size, name); + if (err) { + gpr_free(result); + return NULL; + } + return result; +} + +void gpr_setenv(const char *name, const char *value) { + errno_t res = _putenv_s(name, value); + GPR_ASSERT(res == 0); +} + +#endif /* GPR_WIN32 */ diff --git a/src/core/lib/support/histogram.c b/src/core/lib/support/histogram.c new file mode 100644 index 0000000000..62227be1a6 --- /dev/null +++ b/src/core/lib/support/histogram.c @@ -0,0 +1,244 @@ +/* + * + * Copyright 2015-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 + +#include +#include +#include + +#include +#include +#include +#include + +/* Histograms are stored with exponentially increasing bucket sizes. + The first bucket is [0, m) where m = 1 + resolution + Bucket n (n>=1) contains [m**n, m**(n+1)) + There are sufficient buckets to reach max_bucket_start */ + +struct gpr_histogram { + /* Sum of all values seen so far */ + double sum; + /* Sum of squares of all values seen so far */ + double sum_of_squares; + /* number of values seen so far */ + double count; + /* m in the description */ + double multiplier; + double one_on_log_multiplier; + /* minimum value seen */ + double min_seen; + /* maximum value seen */ + double max_seen; + /* maximum representable value */ + double max_possible; + /* number of buckets */ + size_t num_buckets; + /* the buckets themselves */ + uint32_t *buckets; +}; + +/* determine a bucket index given a value - does no bounds checking */ +static size_t bucket_for_unchecked(gpr_histogram *h, double x) { + return (size_t)(log(x) * h->one_on_log_multiplier); +} + +/* bounds checked version of the above */ +static size_t bucket_for(gpr_histogram *h, double x) { + size_t bucket = bucket_for_unchecked(h, GPR_CLAMP(x, 1.0, h->max_possible)); + GPR_ASSERT(bucket < h->num_buckets); + return bucket; +} + +/* at what value does a bucket start? */ +static double bucket_start(gpr_histogram *h, double x) { + return pow(h->multiplier, x); +} + +gpr_histogram *gpr_histogram_create(double resolution, + double max_bucket_start) { + gpr_histogram *h = gpr_malloc(sizeof(gpr_histogram)); + GPR_ASSERT(resolution > 0.0); + GPR_ASSERT(max_bucket_start > resolution); + h->sum = 0.0; + h->sum_of_squares = 0.0; + h->multiplier = 1.0 + resolution; + h->one_on_log_multiplier = 1.0 / log(1.0 + resolution); + h->max_possible = max_bucket_start; + h->count = 0.0; + h->min_seen = max_bucket_start; + h->max_seen = 0.0; + h->num_buckets = bucket_for_unchecked(h, max_bucket_start) + 1; + GPR_ASSERT(h->num_buckets > 1); + GPR_ASSERT(h->num_buckets < 100000000); + h->buckets = gpr_malloc(sizeof(uint32_t) * h->num_buckets); + memset(h->buckets, 0, sizeof(uint32_t) * h->num_buckets); + return h; +} + +void gpr_histogram_destroy(gpr_histogram *h) { + gpr_free(h->buckets); + gpr_free(h); +} + +void gpr_histogram_add(gpr_histogram *h, double x) { + h->sum += x; + h->sum_of_squares += x * x; + h->count++; + if (x < h->min_seen) { + h->min_seen = x; + } + if (x > h->max_seen) { + h->max_seen = x; + } + h->buckets[bucket_for(h, x)]++; +} + +int gpr_histogram_merge(gpr_histogram *dst, const gpr_histogram *src) { + if ((dst->num_buckets != src->num_buckets) || + (dst->multiplier != src->multiplier)) { + /* Fail because these histograms don't match */ + return 0; + } + gpr_histogram_merge_contents(dst, src->buckets, src->num_buckets, + src->min_seen, src->max_seen, src->sum, + src->sum_of_squares, src->count); + return 1; +} + +void gpr_histogram_merge_contents(gpr_histogram *dst, const uint32_t *data, + size_t data_count, double min_seen, + double max_seen, double sum, + double sum_of_squares, double count) { + size_t i; + GPR_ASSERT(dst->num_buckets == data_count); + dst->sum += sum; + dst->sum_of_squares += sum_of_squares; + dst->count += count; + if (min_seen < dst->min_seen) { + dst->min_seen = min_seen; + } + if (max_seen > dst->max_seen) { + dst->max_seen = max_seen; + } + for (i = 0; i < dst->num_buckets; i++) { + dst->buckets[i] += data[i]; + } +} + +static double threshold_for_count_below(gpr_histogram *h, double count_below) { + double count_so_far; + double lower_bound; + double upper_bound; + size_t lower_idx; + size_t upper_idx; + + if (h->count == 0) { + return 0.0; + } + + if (count_below <= 0) { + return h->min_seen; + } + if (count_below >= h->count) { + return h->max_seen; + } + + /* find the lowest bucket that gets us above count_below */ + count_so_far = 0.0; + for (lower_idx = 0; lower_idx < h->num_buckets; lower_idx++) { + count_so_far += h->buckets[lower_idx]; + if (count_so_far >= count_below) { + break; + } + } + if (count_so_far == count_below) { + /* this bucket hits the threshold exactly... we should be midway through + any run of zero values following the bucket */ + for (upper_idx = lower_idx + 1; upper_idx < h->num_buckets; upper_idx++) { + if (h->buckets[upper_idx]) { + break; + } + } + return (bucket_start(h, (double)lower_idx) + + bucket_start(h, (double)upper_idx)) / + 2.0; + } else { + /* treat values as uniform throughout the bucket, and find where this value + should lie */ + lower_bound = bucket_start(h, (double)lower_idx); + upper_bound = bucket_start(h, (double)(lower_idx + 1)); + return GPR_CLAMP(upper_bound - + (upper_bound - lower_bound) * + (count_so_far - count_below) / + h->buckets[lower_idx], + h->min_seen, h->max_seen); + } +} + +double gpr_histogram_percentile(gpr_histogram *h, double percentile) { + return threshold_for_count_below(h, h->count * percentile / 100.0); +} + +double gpr_histogram_mean(gpr_histogram *h) { + GPR_ASSERT(h->count != 0); + return h->sum / h->count; +} + +double gpr_histogram_stddev(gpr_histogram *h) { + return sqrt(gpr_histogram_variance(h)); +} + +double gpr_histogram_variance(gpr_histogram *h) { + if (h->count == 0) return 0.0; + return (h->sum_of_squares * h->count - h->sum * h->sum) / + (h->count * h->count); +} + +double gpr_histogram_maximum(gpr_histogram *h) { return h->max_seen; } + +double gpr_histogram_minimum(gpr_histogram *h) { return h->min_seen; } + +double gpr_histogram_count(gpr_histogram *h) { return h->count; } + +double gpr_histogram_sum(gpr_histogram *h) { return h->sum; } + +double gpr_histogram_sum_of_squares(gpr_histogram *h) { + return h->sum_of_squares; +} + +const uint32_t *gpr_histogram_get_contents(gpr_histogram *h, size_t *size) { + *size = h->num_buckets; + return h->buckets; +} diff --git a/src/core/lib/support/host_port.c b/src/core/lib/support/host_port.c new file mode 100644 index 0000000000..31243a7221 --- /dev/null +++ b/src/core/lib/support/host_port.c @@ -0,0 +1,110 @@ +/* + * + * Copyright 2015-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 + +#include + +#include +#include +#include +#include "src/core/support/string.h" + +int gpr_join_host_port(char **out, const char *host, int port) { + if (host[0] != '[' && strchr(host, ':') != NULL) { + /* IPv6 literals must be enclosed in brackets. */ + return gpr_asprintf(out, "[%s]:%d", host, port); + } else { + /* Ordinary non-bracketed host:port. */ + return gpr_asprintf(out, "%s:%d", host, port); + } +} + +int gpr_split_host_port(const char *name, char **host, char **port) { + const char *host_start; + size_t host_len; + const char *port_start; + + *host = NULL; + *port = NULL; + + if (name[0] == '[') { + /* Parse a bracketed host, typically an IPv6 literal. */ + const char *rbracket = strchr(name, ']'); + if (rbracket == NULL) { + /* Unmatched [ */ + return 0; + } + if (rbracket[1] == '\0') { + /* ] */ + port_start = NULL; + } else if (rbracket[1] == ':') { + /* ]: */ + port_start = rbracket + 2; + } else { + /* ] */ + return 0; + } + host_start = name + 1; + host_len = (size_t)(rbracket - host_start); + if (memchr(host_start, ':', host_len) == NULL) { + /* Require all bracketed hosts to contain a colon, because a hostname or + IPv4 address should never use brackets. */ + return 0; + } + } else { + const char *colon = strchr(name, ':'); + if (colon != NULL && strchr(colon + 1, ':') == NULL) { + /* Exactly 1 colon. Split into host:port. */ + host_start = name; + host_len = (size_t)(colon - name); + port_start = colon + 1; + } else { + /* 0 or 2+ colons. Bare hostname or IPv6 litearal. */ + host_start = name; + host_len = strlen(name); + port_start = NULL; + } + } + + /* Allocate return values. */ + *host = gpr_malloc(host_len + 1); + memcpy(*host, host_start, host_len); + (*host)[host_len] = '\0'; + + if (port_start != NULL) { + *port = gpr_strdup(port_start); + } + + return 1; +} diff --git a/src/core/lib/support/load_file.c b/src/core/lib/support/load_file.c new file mode 100644 index 0000000000..650bd62ccb --- /dev/null +++ b/src/core/lib/support/load_file.c @@ -0,0 +1,91 @@ +/* + * + * Copyright 2015-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/support/load_file.h" + +#include +#include + +#include +#include +#include + +#include "src/core/support/block_annotate.h" +#include "src/core/support/string.h" + +gpr_slice gpr_load_file(const char *filename, int add_null_terminator, + int *success) { + unsigned char *contents = NULL; + size_t contents_size = 0; + char *error_msg = NULL; + gpr_slice result = gpr_empty_slice(); + FILE *file; + size_t bytes_read = 0; + + GRPC_SCHEDULING_START_BLOCKING_REGION; + file = fopen(filename, "rb"); + if (file == NULL) { + gpr_asprintf(&error_msg, "Could not open file %s (error = %s).", filename, + strerror(errno)); + GPR_ASSERT(error_msg != NULL); + goto end; + } + fseek(file, 0, SEEK_END); + /* Converting to size_t on the assumption that it will not fail */ + contents_size = (size_t)ftell(file); + fseek(file, 0, SEEK_SET); + contents = gpr_malloc(contents_size + (add_null_terminator ? 1 : 0)); + bytes_read = fread(contents, 1, contents_size, file); + if (bytes_read < contents_size) { + GPR_ASSERT(ferror(file)); + gpr_asprintf(&error_msg, "Error %s occured while reading file %s.", + strerror(errno), filename); + GPR_ASSERT(error_msg != NULL); + goto end; + } + if (success != NULL) *success = 1; + if (add_null_terminator) { + contents[contents_size++] = 0; + } + result = gpr_slice_new(contents, contents_size, gpr_free); + +end: + if (error_msg != NULL) { + gpr_log(GPR_ERROR, "%s", error_msg); + gpr_free(error_msg); + if (success != NULL) *success = 0; + } + if (file != NULL) fclose(file); + GRPC_SCHEDULING_END_BLOCKING_REGION; + return result; +} diff --git a/src/core/lib/support/load_file.h b/src/core/lib/support/load_file.h new file mode 100644 index 0000000000..5896654e9a --- /dev/null +++ b/src/core/lib/support/load_file.h @@ -0,0 +1,55 @@ +/* + * + * Copyright 2015-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_SUPPORT_LOAD_FILE_H +#define GRPC_CORE_SUPPORT_LOAD_FILE_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Loads the content of a file into a slice. add_null_terminator will add + a NULL terminator if non-zero. The success parameter, if not NULL, + will be set to 1 in case of success and 0 in case of failure. */ +gpr_slice gpr_load_file(const char *filename, int add_null_terminator, + int *success); + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_SUPPORT_LOAD_FILE_H */ diff --git a/src/core/lib/support/log.c b/src/core/lib/support/log.c new file mode 100644 index 0000000000..04156a5b1f --- /dev/null +++ b/src/core/lib/support/log.c @@ -0,0 +1,66 @@ +/* + * + * Copyright 2015, 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 +#include + +#include +#include + +extern void gpr_default_log(gpr_log_func_args *args); +static gpr_log_func g_log_func = gpr_default_log; + +const char *gpr_log_severity_string(gpr_log_severity severity) { + switch (severity) { + case GPR_LOG_SEVERITY_DEBUG: + return "D"; + case GPR_LOG_SEVERITY_INFO: + return "I"; + case GPR_LOG_SEVERITY_ERROR: + return "E"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +void gpr_log_message(const char *file, int line, gpr_log_severity severity, + const char *message) { + gpr_log_func_args lfargs; + memset(&lfargs, 0, sizeof(lfargs)); + lfargs.file = file; + lfargs.line = line; + lfargs.severity = severity; + lfargs.message = message; + g_log_func(&lfargs); +} + +void gpr_set_log_function(gpr_log_func f) { g_log_func = f; } diff --git a/src/core/lib/support/log_android.c b/src/core/lib/support/log_android.c new file mode 100644 index 0000000000..640c9d7099 --- /dev/null +++ b/src/core/lib/support/log_android.c @@ -0,0 +1,87 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_ANDROID + +#include +#include +#include +#include +#include +#include + +static android_LogPriority severity_to_log_priority(gpr_log_severity severity) { + switch (severity) { + case GPR_LOG_SEVERITY_DEBUG: + return ANDROID_LOG_DEBUG; + case GPR_LOG_SEVERITY_INFO: + return ANDROID_LOG_INFO; + case GPR_LOG_SEVERITY_ERROR: + return ANDROID_LOG_ERROR; + } + return ANDROID_LOG_DEFAULT; +} + +void gpr_log(const char *file, int line, gpr_log_severity severity, + const char *format, ...) { + char *message = NULL; + va_list args; + va_start(args, format); + vasprintf(&message, format, args); + va_end(args); + gpr_log_message(file, line, severity, message); + free(message); +} + +void gpr_default_log(gpr_log_func_args *args) { + char *final_slash; + const char *display_file; + char *output = NULL; + + final_slash = strrchr(args->file, '/'); + if (final_slash == NULL) + display_file = args->file; + else + display_file = final_slash + 1; + + asprintf(&output, "%s:%d] %s", display_file, args->line, args->message); + + __android_log_write(severity_to_log_priority(args->severity), "GRPC", output); + + /* allocated by asprintf => use free, not gpr_free */ + free(output); +} + +#endif /* GPR_ANDROID */ diff --git a/src/core/lib/support/log_linux.c b/src/core/lib/support/log_linux.c new file mode 100644 index 0000000000..e60512c526 --- /dev/null +++ b/src/core/lib/support/log_linux.c @@ -0,0 +1,105 @@ +/* + * + * Copyright 2015-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 _POSIX_SOURCE +#define _POSIX_SOURCE +#endif + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include + +#ifdef GPR_LINUX + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static long gettid(void) { return syscall(__NR_gettid); } + +void gpr_log(const char *file, int line, gpr_log_severity severity, + const char *format, ...) { + char *message = NULL; + va_list args; + va_start(args, format); + if (vasprintf(&message, format, args) == -1) { + va_end(args); + return; + } + va_end(args); + gpr_log_message(file, line, severity, message); + free(message); +} + +void gpr_default_log(gpr_log_func_args *args) { + char *final_slash; + char *prefix; + const char *display_file; + char time_buffer[64]; + time_t timer; + gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); + struct tm tm; + + timer = (time_t)now.tv_sec; + final_slash = strrchr(args->file, '/'); + if (final_slash == NULL) + display_file = args->file; + else + display_file = final_slash + 1; + + if (!localtime_r(&timer, &tm)) { + strcpy(time_buffer, "error:localtime"); + } else if (0 == + strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { + strcpy(time_buffer, "error:strftime"); + } + + gpr_asprintf(&prefix, "%s%s.%09d %7tu %s:%d]", + gpr_log_severity_string(args->severity), time_buffer, + (int)(now.tv_nsec), gettid(), display_file, args->line); + + fprintf(stderr, "%-60s %s\n", prefix, args->message); + gpr_free(prefix); +} + +#endif diff --git a/src/core/lib/support/log_posix.c b/src/core/lib/support/log_posix.c new file mode 100644 index 0000000000..7429dd0a2c --- /dev/null +++ b/src/core/lib/support/log_posix.c @@ -0,0 +1,102 @@ +/* + * + * Copyright 2015-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 + +#if defined(GPR_POSIX_LOG) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static intptr_t gettid(void) { return (intptr_t)pthread_self(); } + +void gpr_log(const char *file, int line, gpr_log_severity severity, + const char *format, ...) { + char buf[64]; + char *allocated = NULL; + char *message = NULL; + int ret; + va_list args; + va_start(args, format); + ret = vsnprintf(buf, sizeof(buf), format, args); + va_end(args); + if (ret < 0) { + message = NULL; + } else if ((size_t)ret <= sizeof(buf) - 1) { + message = buf; + } else { + message = allocated = gpr_malloc((size_t)ret + 1); + va_start(args, format); + vsnprintf(message, (size_t)(ret + 1), format, args); + va_end(args); + } + gpr_log_message(file, line, severity, message); + gpr_free(allocated); +} + +void gpr_default_log(gpr_log_func_args *args) { + char *final_slash; + const char *display_file; + char time_buffer[64]; + time_t timer; + gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); + struct tm tm; + + timer = (time_t)now.tv_sec; + final_slash = strrchr(args->file, '/'); + if (final_slash == NULL) + display_file = args->file; + else + display_file = final_slash + 1; + + if (!localtime_r(&timer, &tm)) { + strcpy(time_buffer, "error:localtime"); + } else if (0 == + strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { + strcpy(time_buffer, "error:strftime"); + } + + fprintf(stderr, "%s%s.%09d %7tu %s:%d] %s\n", + gpr_log_severity_string(args->severity), time_buffer, + (int)(now.tv_nsec), gettid(), display_file, args->line, + args->message); +} + +#endif /* defined(GPR_POSIX_LOG) */ diff --git a/src/core/lib/support/log_win32.c b/src/core/lib/support/log_win32.c new file mode 100644 index 0000000000..89ec0917d5 --- /dev/null +++ b/src/core/lib/support/log_win32.c @@ -0,0 +1,126 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_WIN32 + +#include +#include + +#include +#include +#include +#include +#include + +#include "src/core/support/string.h" +#include "src/core/support/string_win32.h" + +void gpr_log(const char *file, int line, gpr_log_severity severity, + const char *format, ...) { + char *message = NULL; + va_list args; + int ret; + + /* Determine the length. */ + va_start(args, format); + ret = _vscprintf(format, args); + va_end(args); + if (ret < 0) { + message = NULL; + } else { + /* Allocate a new buffer, with space for the NUL terminator. */ + size_t strp_buflen = (size_t)ret + 1; + message = gpr_malloc(strp_buflen); + + /* Print to the buffer. */ + va_start(args, format); + ret = vsnprintf_s(message, strp_buflen, _TRUNCATE, format, args); + va_end(args); + if ((size_t)ret != strp_buflen - 1) { + /* This should never happen. */ + gpr_free(message); + message = NULL; + } + } + + gpr_log_message(file, line, severity, message); + gpr_free(message); +} + +/* Simple starter implementation */ +void gpr_default_log(gpr_log_func_args *args) { + char *final_slash; + const char *display_file; + char time_buffer[64]; + time_t timer; + gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); + struct tm tm; + + timer = (time_t)now.tv_sec; + final_slash = strrchr(args->file, '\\'); + if (final_slash == NULL) + display_file = args->file; + else + display_file = final_slash + 1; + + if (localtime_s(&tm, &timer)) { + strcpy(time_buffer, "error:localtime"); + } else if (0 == + strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { + strcpy(time_buffer, "error:strftime"); + } + + fprintf(stderr, "%s%s.%09u %5lu %s:%d] %s\n", + gpr_log_severity_string(args->severity), time_buffer, + (int)(now.tv_nsec), GetCurrentThreadId(), display_file, args->line, + args->message); + fflush(stderr); +} + +char *gpr_format_message(int messageid) { + LPTSTR tmessage; + char *message; + DWORD status = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, (DWORD)messageid, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)(&tmessage), 0, NULL); + if (status == 0) return gpr_strdup("Unable to retrieve error string"); + message = gpr_tchar_to_char(tmessage); + LocalFree(tmessage); + return message; +} + +#endif /* GPR_WIN32 */ diff --git a/src/core/lib/support/murmur_hash.c b/src/core/lib/support/murmur_hash.c new file mode 100644 index 0000000000..a5261c0cc0 --- /dev/null +++ b/src/core/lib/support/murmur_hash.c @@ -0,0 +1,96 @@ +/* + * + * Copyright 2015, 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/support/murmur_hash.h" + +#define ROTL32(x, r) ((x) << (r)) | ((x) >> (32 - (r))) + +#define FMIX32(h) \ + (h) ^= (h) >> 16; \ + (h) *= 0x85ebca6b; \ + (h) ^= (h) >> 13; \ + (h) *= 0xc2b2ae35; \ + (h) ^= (h) >> 16; + +/* Block read - if your platform needs to do endian-swapping or can only + handle aligned reads, do the conversion here */ +#define GETBLOCK32(p, i) (p)[(i)] + +uint32_t gpr_murmur_hash3(const void *key, size_t len, uint32_t seed) { + const uint8_t *data = (const uint8_t *)key; + const size_t nblocks = len / 4; + int i; + + uint32_t h1 = seed; + uint32_t k1; + + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + + const uint32_t *blocks = ((const uint32_t *)key) + nblocks; + const uint8_t *tail = (const uint8_t *)(data + nblocks * 4); + + /* body */ + for (i = -(int)nblocks; i; i++) { + k1 = GETBLOCK32(blocks, i); + + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + + h1 ^= k1; + h1 = ROTL32(h1, 13); + h1 = h1 * 5 + 0xe6546b64; + } + + k1 = 0; + + /* tail */ + switch (len & 3) { + case 3: + k1 ^= ((uint32_t)tail[2]) << 16; + case 2: + k1 ^= ((uint32_t)tail[1]) << 8; + case 1: + k1 ^= tail[0]; + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + h1 ^= k1; + }; + + /* finalization */ + h1 ^= (uint32_t)len; + FMIX32(h1); + return h1; +} diff --git a/src/core/lib/support/murmur_hash.h b/src/core/lib/support/murmur_hash.h new file mode 100644 index 0000000000..0f0b399e5d --- /dev/null +++ b/src/core/lib/support/murmur_hash.h @@ -0,0 +1,44 @@ +/* + * + * Copyright 2015-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_SUPPORT_MURMUR_HASH_H +#define GRPC_CORE_SUPPORT_MURMUR_HASH_H + +#include + +#include + +/* compute the hash of key (length len) */ +uint32_t gpr_murmur_hash3(const void *key, size_t len, uint32_t seed); + +#endif /* GRPC_CORE_SUPPORT_MURMUR_HASH_H */ diff --git a/src/core/lib/support/slice.c b/src/core/lib/support/slice.c new file mode 100644 index 0000000000..b9a7c77bda --- /dev/null +++ b/src/core/lib/support/slice.c @@ -0,0 +1,343 @@ +/* + * + * Copyright 2015, 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 +#include +#include + +#include + +gpr_slice gpr_empty_slice(void) { + gpr_slice out; + out.refcount = 0; + out.data.inlined.length = 0; + return out; +} + +gpr_slice gpr_slice_ref(gpr_slice slice) { + if (slice.refcount) { + slice.refcount->ref(slice.refcount); + } + return slice; +} + +void gpr_slice_unref(gpr_slice slice) { + if (slice.refcount) { + slice.refcount->unref(slice.refcount); + } +} + +/* gpr_slice_from_static_string support structure - a refcount that does + nothing */ +static void noop_ref_or_unref(void *unused) {} + +static gpr_slice_refcount noop_refcount = {noop_ref_or_unref, + noop_ref_or_unref}; + +gpr_slice gpr_slice_from_static_string(const char *s) { + gpr_slice slice; + slice.refcount = &noop_refcount; + slice.data.refcounted.bytes = (uint8_t *)s; + slice.data.refcounted.length = strlen(s); + return slice; +} + +/* gpr_slice_new support structures - we create a refcount object extended + with the user provided data pointer & destroy function */ +typedef struct new_slice_refcount { + gpr_slice_refcount rc; + gpr_refcount refs; + void (*user_destroy)(void *); + void *user_data; +} new_slice_refcount; + +static void new_slice_ref(void *p) { + new_slice_refcount *r = p; + gpr_ref(&r->refs); +} + +static void new_slice_unref(void *p) { + new_slice_refcount *r = p; + if (gpr_unref(&r->refs)) { + r->user_destroy(r->user_data); + gpr_free(r); + } +} + +gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) { + gpr_slice slice; + new_slice_refcount *rc = gpr_malloc(sizeof(new_slice_refcount)); + gpr_ref_init(&rc->refs, 1); + rc->rc.ref = new_slice_ref; + rc->rc.unref = new_slice_unref; + rc->user_destroy = destroy; + rc->user_data = p; + + slice.refcount = &rc->rc; + slice.data.refcounted.bytes = p; + slice.data.refcounted.length = len; + return slice; +} + +/* gpr_slice_new_with_len support structures - we create a refcount object + extended with the user provided data pointer & destroy function */ +typedef struct new_with_len_slice_refcount { + gpr_slice_refcount rc; + gpr_refcount refs; + void *user_data; + size_t user_length; + void (*user_destroy)(void *, size_t); +} new_with_len_slice_refcount; + +static void new_with_len_ref(void *p) { + new_with_len_slice_refcount *r = p; + gpr_ref(&r->refs); +} + +static void new_with_len_unref(void *p) { + new_with_len_slice_refcount *r = p; + if (gpr_unref(&r->refs)) { + r->user_destroy(r->user_data, r->user_length); + gpr_free(r); + } +} + +gpr_slice gpr_slice_new_with_len(void *p, size_t len, + void (*destroy)(void *, size_t)) { + gpr_slice slice; + new_with_len_slice_refcount *rc = + gpr_malloc(sizeof(new_with_len_slice_refcount)); + gpr_ref_init(&rc->refs, 1); + rc->rc.ref = new_with_len_ref; + rc->rc.unref = new_with_len_unref; + rc->user_destroy = destroy; + rc->user_data = p; + rc->user_length = len; + + slice.refcount = &rc->rc; + slice.data.refcounted.bytes = p; + slice.data.refcounted.length = len; + return slice; +} + +gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t length) { + gpr_slice slice = gpr_slice_malloc(length); + memcpy(GPR_SLICE_START_PTR(slice), source, length); + return slice; +} + +gpr_slice gpr_slice_from_copied_string(const char *source) { + return gpr_slice_from_copied_buffer(source, strlen(source)); +} + +typedef struct { + gpr_slice_refcount base; + gpr_refcount refs; +} malloc_refcount; + +static void malloc_ref(void *p) { + malloc_refcount *r = p; + gpr_ref(&r->refs); +} + +static void malloc_unref(void *p) { + malloc_refcount *r = p; + if (gpr_unref(&r->refs)) { + gpr_free(r); + } +} + +gpr_slice gpr_slice_malloc(size_t length) { + gpr_slice slice; + + if (length > sizeof(slice.data.inlined.bytes)) { + /* Memory layout used by the slice created here: + + +-----------+----------------------------------------------------------+ + | refcount | bytes | + +-----------+----------------------------------------------------------+ + + refcount is a malloc_refcount + bytes is an array of bytes of the requested length + Both parts are placed in the same allocation returned from gpr_malloc */ + malloc_refcount *rc = gpr_malloc(sizeof(malloc_refcount) + length); + + /* Initial refcount on rc is 1 - and it's up to the caller to release + this reference. */ + gpr_ref_init(&rc->refs, 1); + + rc->base.ref = malloc_ref; + rc->base.unref = malloc_unref; + + /* Build up the slice to be returned. */ + /* The slices refcount points back to the allocated block. */ + slice.refcount = &rc->base; + /* The data bytes are placed immediately after the refcount struct */ + slice.data.refcounted.bytes = (uint8_t *)(rc + 1); + /* And the length of the block is set to the requested length */ + slice.data.refcounted.length = length; + } else { + /* small slice: just inline the data */ + slice.refcount = NULL; + slice.data.inlined.length = (uint8_t)length; + } + return slice; +} + +gpr_slice gpr_slice_sub_no_ref(gpr_slice source, size_t begin, size_t end) { + gpr_slice subset; + + GPR_ASSERT(end >= begin); + + if (source.refcount) { + /* Enforce preconditions */ + GPR_ASSERT(source.data.refcounted.length >= end); + + /* Build the result */ + subset.refcount = source.refcount; + /* Point into the source array */ + subset.data.refcounted.bytes = source.data.refcounted.bytes + begin; + subset.data.refcounted.length = end - begin; + } else { + /* Enforce preconditions */ + GPR_ASSERT(source.data.inlined.length >= end); + subset.refcount = NULL; + subset.data.inlined.length = (uint8_t)(end - begin); + memcpy(subset.data.inlined.bytes, source.data.inlined.bytes + begin, + end - begin); + } + return subset; +} + +gpr_slice gpr_slice_sub(gpr_slice source, size_t begin, size_t end) { + gpr_slice subset; + + if (end - begin <= sizeof(subset.data.inlined.bytes)) { + subset.refcount = NULL; + subset.data.inlined.length = (uint8_t)(end - begin); + memcpy(subset.data.inlined.bytes, GPR_SLICE_START_PTR(source) + begin, + end - begin); + } else { + subset = gpr_slice_sub_no_ref(source, begin, end); + /* Bump the refcount */ + subset.refcount->ref(subset.refcount); + } + return subset; +} + +gpr_slice gpr_slice_split_tail(gpr_slice *source, size_t split) { + gpr_slice tail; + + if (source->refcount == NULL) { + /* inlined data, copy it out */ + GPR_ASSERT(source->data.inlined.length >= split); + tail.refcount = NULL; + tail.data.inlined.length = (uint8_t)(source->data.inlined.length - split); + memcpy(tail.data.inlined.bytes, source->data.inlined.bytes + split, + tail.data.inlined.length); + source->data.inlined.length = (uint8_t)split; + } else { + size_t tail_length = source->data.refcounted.length - split; + GPR_ASSERT(source->data.refcounted.length >= split); + if (tail_length < sizeof(tail.data.inlined.bytes)) { + /* Copy out the bytes - it'll be cheaper than refcounting */ + tail.refcount = NULL; + tail.data.inlined.length = (uint8_t)tail_length; + memcpy(tail.data.inlined.bytes, source->data.refcounted.bytes + split, + tail_length); + } else { + /* Build the result */ + tail.refcount = source->refcount; + /* Bump the refcount */ + tail.refcount->ref(tail.refcount); + /* Point into the source array */ + tail.data.refcounted.bytes = source->data.refcounted.bytes + split; + tail.data.refcounted.length = tail_length; + } + source->data.refcounted.length = split; + } + + return tail; +} + +gpr_slice gpr_slice_split_head(gpr_slice *source, size_t split) { + gpr_slice head; + + if (source->refcount == NULL) { + GPR_ASSERT(source->data.inlined.length >= split); + + head.refcount = NULL; + head.data.inlined.length = (uint8_t)split; + memcpy(head.data.inlined.bytes, source->data.inlined.bytes, split); + source->data.inlined.length = + (uint8_t)(source->data.inlined.length - split); + memmove(source->data.inlined.bytes, source->data.inlined.bytes + split, + source->data.inlined.length); + } else if (split < sizeof(head.data.inlined.bytes)) { + GPR_ASSERT(source->data.refcounted.length >= split); + + head.refcount = NULL; + head.data.inlined.length = (uint8_t)split; + memcpy(head.data.inlined.bytes, source->data.refcounted.bytes, split); + source->data.refcounted.bytes += split; + source->data.refcounted.length -= split; + } else { + GPR_ASSERT(source->data.refcounted.length >= split); + + /* Build the result */ + head.refcount = source->refcount; + /* Bump the refcount */ + head.refcount->ref(head.refcount); + /* Point into the source array */ + head.data.refcounted.bytes = source->data.refcounted.bytes; + head.data.refcounted.length = split; + source->data.refcounted.bytes += split; + source->data.refcounted.length -= split; + } + + return head; +} + +int gpr_slice_cmp(gpr_slice a, gpr_slice b) { + int d = (int)(GPR_SLICE_LENGTH(a) - GPR_SLICE_LENGTH(b)); + if (d != 0) return d; + return memcmp(GPR_SLICE_START_PTR(a), GPR_SLICE_START_PTR(b), + GPR_SLICE_LENGTH(a)); +} + +int gpr_slice_str_cmp(gpr_slice a, const char *b) { + size_t b_length = strlen(b); + int d = (int)(GPR_SLICE_LENGTH(a) - b_length); + if (d != 0) return d; + return memcmp(GPR_SLICE_START_PTR(a), b, b_length); +} diff --git a/src/core/lib/support/slice_buffer.c b/src/core/lib/support/slice_buffer.c new file mode 100644 index 0000000000..66f111d767 --- /dev/null +++ b/src/core/lib/support/slice_buffer.c @@ -0,0 +1,282 @@ +/* + * + * Copyright 2015, 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 +#include + +#include + +#include +#include +#include + +/* grow a buffer; requires GRPC_SLICE_BUFFER_INLINE_ELEMENTS > 1 */ +#define GROW(x) (3 * (x) / 2) + +static void maybe_embiggen(gpr_slice_buffer *sb) { + if (sb->count == sb->capacity) { + sb->capacity = GROW(sb->capacity); + GPR_ASSERT(sb->capacity > sb->count); + if (sb->slices == sb->inlined) { + sb->slices = gpr_malloc(sb->capacity * sizeof(gpr_slice)); + memcpy(sb->slices, sb->inlined, sb->count * sizeof(gpr_slice)); + } else { + sb->slices = gpr_realloc(sb->slices, sb->capacity * sizeof(gpr_slice)); + } + } +} + +void gpr_slice_buffer_init(gpr_slice_buffer *sb) { + sb->count = 0; + sb->length = 0; + sb->capacity = GRPC_SLICE_BUFFER_INLINE_ELEMENTS; + sb->slices = sb->inlined; +} + +void gpr_slice_buffer_destroy(gpr_slice_buffer *sb) { + gpr_slice_buffer_reset_and_unref(sb); + if (sb->slices != sb->inlined) { + gpr_free(sb->slices); + } +} + +uint8_t *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, size_t n) { + gpr_slice *back; + uint8_t *out; + + sb->length += n; + + if (sb->count == 0) goto add_new; + back = &sb->slices[sb->count - 1]; + if (back->refcount) goto add_new; + if ((back->data.inlined.length + n) > sizeof(back->data.inlined.bytes)) + goto add_new; + out = back->data.inlined.bytes + back->data.inlined.length; + back->data.inlined.length = (uint8_t)(back->data.inlined.length + n); + return out; + +add_new: + maybe_embiggen(sb); + back = &sb->slices[sb->count]; + sb->count++; + back->refcount = NULL; + back->data.inlined.length = (uint8_t)n; + return back->data.inlined.bytes; +} + +size_t gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb, gpr_slice s) { + size_t out = sb->count; + maybe_embiggen(sb); + sb->slices[out] = s; + sb->length += GPR_SLICE_LENGTH(s); + sb->count = out + 1; + return out; +} + +void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_slice s) { + size_t n = sb->count; + /* if both the last slice in the slice buffer and the slice being added + are inlined (that is, that they carry their data inside the slice data + structure), and the back slice is not full, then concatenate directly + into the back slice, preventing many small slices being passed into + writes */ + if (!s.refcount && n) { + gpr_slice *back = &sb->slices[n - 1]; + if (!back->refcount && back->data.inlined.length < GPR_SLICE_INLINED_SIZE) { + if (s.data.inlined.length + back->data.inlined.length <= + GPR_SLICE_INLINED_SIZE) { + memcpy(back->data.inlined.bytes + back->data.inlined.length, + s.data.inlined.bytes, s.data.inlined.length); + back->data.inlined.length = + (uint8_t)(back->data.inlined.length + s.data.inlined.length); + } else { + size_t cp1 = GPR_SLICE_INLINED_SIZE - back->data.inlined.length; + memcpy(back->data.inlined.bytes + back->data.inlined.length, + s.data.inlined.bytes, cp1); + back->data.inlined.length = GPR_SLICE_INLINED_SIZE; + maybe_embiggen(sb); + back = &sb->slices[n]; + sb->count = n + 1; + back->refcount = NULL; + back->data.inlined.length = (uint8_t)(s.data.inlined.length - cp1); + memcpy(back->data.inlined.bytes, s.data.inlined.bytes + cp1, + s.data.inlined.length - cp1); + } + sb->length += s.data.inlined.length; + return; /* early out */ + } + } + gpr_slice_buffer_add_indexed(sb, s); +} + +void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *s, size_t n) { + size_t i; + for (i = 0; i < n; i++) { + gpr_slice_buffer_add(sb, s[i]); + } +} + +void gpr_slice_buffer_pop(gpr_slice_buffer *sb) { + if (sb->count != 0) { + size_t count = --sb->count; + sb->length -= GPR_SLICE_LENGTH(sb->slices[count]); + } +} + +void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb) { + size_t i; + + for (i = 0; i < sb->count; i++) { + gpr_slice_unref(sb->slices[i]); + } + + sb->count = 0; + sb->length = 0; +} + +void gpr_slice_buffer_swap(gpr_slice_buffer *a, gpr_slice_buffer *b) { + GPR_SWAP(size_t, a->count, b->count); + GPR_SWAP(size_t, a->capacity, b->capacity); + GPR_SWAP(size_t, a->length, b->length); + + if (a->slices == a->inlined) { + if (b->slices == b->inlined) { + /* swap contents of inlined buffer */ + gpr_slice temp[GRPC_SLICE_BUFFER_INLINE_ELEMENTS]; + memcpy(temp, a->slices, b->count * sizeof(gpr_slice)); + memcpy(a->slices, b->slices, a->count * sizeof(gpr_slice)); + memcpy(b->slices, temp, b->count * sizeof(gpr_slice)); + } else { + /* a is inlined, b is not - copy a inlined into b, fix pointers */ + a->slices = b->slices; + b->slices = b->inlined; + memcpy(b->slices, a->inlined, b->count * sizeof(gpr_slice)); + } + } else if (b->slices == b->inlined) { + /* b is inlined, a is not - copy b inlined int a, fix pointers */ + b->slices = a->slices; + a->slices = a->inlined; + memcpy(a->slices, b->inlined, a->count * sizeof(gpr_slice)); + } else { + /* no inlining: easy swap */ + GPR_SWAP(gpr_slice *, a->slices, b->slices); + } +} + +void gpr_slice_buffer_move_into(gpr_slice_buffer *src, gpr_slice_buffer *dst) { + /* anything to move? */ + if (src->count == 0) { + return; + } + /* anything in dst? */ + if (dst->count == 0) { + gpr_slice_buffer_swap(src, dst); + return; + } + /* both buffers have data - copy, and reset src */ + gpr_slice_buffer_addn(dst, src->slices, src->count); + src->count = 0; + src->length = 0; +} + +void gpr_slice_buffer_move_first(gpr_slice_buffer *src, size_t n, + gpr_slice_buffer *dst) { + size_t src_idx; + size_t output_len = dst->length + n; + size_t new_input_len = src->length - n; + GPR_ASSERT(src->length >= n); + if (src->length == n) { + gpr_slice_buffer_move_into(src, dst); + return; + } + src_idx = 0; + while (src_idx < src->capacity) { + gpr_slice slice = src->slices[src_idx]; + size_t slice_len = GPR_SLICE_LENGTH(slice); + if (n > slice_len) { + gpr_slice_buffer_add(dst, slice); + n -= slice_len; + src_idx++; + } else if (n == slice_len) { + gpr_slice_buffer_add(dst, slice); + src_idx++; + break; + } else { /* n < slice_len */ + src->slices[src_idx] = gpr_slice_split_tail(&slice, n); + GPR_ASSERT(GPR_SLICE_LENGTH(slice) == n); + GPR_ASSERT(GPR_SLICE_LENGTH(src->slices[src_idx]) == slice_len - n); + gpr_slice_buffer_add(dst, slice); + break; + } + } + GPR_ASSERT(dst->length == output_len); + memmove(src->slices, src->slices + src_idx, + sizeof(gpr_slice) * (src->count - src_idx)); + src->count -= src_idx; + src->length = new_input_len; + GPR_ASSERT(src->count > 0); +} + +void gpr_slice_buffer_trim_end(gpr_slice_buffer *sb, size_t n, + gpr_slice_buffer *garbage) { + GPR_ASSERT(n <= sb->length); + sb->length -= n; + for (;;) { + size_t idx = sb->count - 1; + gpr_slice slice = sb->slices[idx]; + size_t slice_len = GPR_SLICE_LENGTH(slice); + if (slice_len > n) { + sb->slices[idx] = gpr_slice_split_head(&slice, slice_len - n); + gpr_slice_buffer_add_indexed(garbage, slice); + return; + } else if (slice_len == n) { + gpr_slice_buffer_add_indexed(garbage, slice); + sb->count = idx; + return; + } else { + gpr_slice_buffer_add_indexed(garbage, slice); + n -= slice_len; + sb->count = idx; + } + } +} + +gpr_slice gpr_slice_buffer_take_first(gpr_slice_buffer *sb) { + gpr_slice slice; + GPR_ASSERT(sb->count > 0); + slice = sb->slices[0]; + memmove(&sb->slices[0], &sb->slices[1], (sb->count - 1) * sizeof(gpr_slice)); + sb->count--; + sb->length -= GPR_SLICE_LENGTH(slice); + return slice; +} diff --git a/src/core/lib/support/stack_lockfree.c b/src/core/lib/support/stack_lockfree.c new file mode 100644 index 0000000000..8e0bbfaee8 --- /dev/null +++ b/src/core/lib/support/stack_lockfree.c @@ -0,0 +1,185 @@ +/* + * + * Copyright 2015-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/support/stack_lockfree.h" + +#include +#include + +#include +#include +#include +#include + +/* The lockfree node structure is a single architecture-level + word that allows for an atomic CAS to set it up. */ +struct lockfree_node_contents { + /* next thing to look at. Actual index for head, next index otherwise */ + uint16_t index; +#ifdef GPR_ARCH_64 + uint16_t pad; + uint32_t aba_ctr; +#else +#ifdef GPR_ARCH_32 + uint16_t aba_ctr; +#else +#error Unsupported bit width architecture +#endif +#endif +}; + +/* Use a union to make sure that these are in the same bits as an atm word */ +typedef union lockfree_node { + gpr_atm atm; + struct lockfree_node_contents contents; +} lockfree_node; + +/* make sure that entries aligned to 8-bytes */ +#define ENTRY_ALIGNMENT_BITS 3 +/* reserve this entry as invalid */ +#define INVALID_ENTRY_INDEX ((1 << 16) - 1) + +struct gpr_stack_lockfree { + lockfree_node *entries; + lockfree_node head; /* An atomic entry describing curr head */ + +#ifndef NDEBUG + /* Bitmap of pushed entries to check for double-push or pop */ + gpr_atm pushed[(INVALID_ENTRY_INDEX + 1) / (8 * sizeof(gpr_atm))]; +#endif +}; + +gpr_stack_lockfree *gpr_stack_lockfree_create(size_t entries) { + gpr_stack_lockfree *stack; + stack = gpr_malloc(sizeof(*stack)); + /* Since we only allocate 16 bits to represent an entry number, + * make sure that we are within the desired range */ + /* Reserve the highest entry number as a dummy */ + GPR_ASSERT(entries < INVALID_ENTRY_INDEX); + stack->entries = gpr_malloc_aligned(entries * sizeof(stack->entries[0]), + ENTRY_ALIGNMENT_BITS); + /* Clear out all entries */ + memset(stack->entries, 0, entries * sizeof(stack->entries[0])); + memset(&stack->head, 0, sizeof(stack->head)); +#ifndef NDEBUG + memset(&stack->pushed, 0, sizeof(stack->pushed)); +#endif + + GPR_ASSERT(sizeof(stack->entries->atm) == sizeof(stack->entries->contents)); + + /* Point the head at reserved dummy entry */ + stack->head.contents.index = INVALID_ENTRY_INDEX; +/* Fill in the pad and aba_ctr to avoid confusing memcheck tools */ +#ifdef GPR_ARCH_64 + stack->head.contents.pad = 0; +#endif + stack->head.contents.aba_ctr = 0; + return stack; +} + +void gpr_stack_lockfree_destroy(gpr_stack_lockfree *stack) { + gpr_free_aligned(stack->entries); + gpr_free(stack); +} + +int gpr_stack_lockfree_push(gpr_stack_lockfree *stack, int entry) { + lockfree_node head; + lockfree_node newhead; + lockfree_node curent; + lockfree_node newent; + + /* First fill in the entry's index and aba ctr for new head */ + newhead.contents.index = (uint16_t)entry; +#ifdef GPR_ARCH_64 + /* Fill in the pad to avoid confusing memcheck tools */ + newhead.contents.pad = 0; +#endif + + /* Also post-increment the aba_ctr */ + curent.atm = gpr_atm_no_barrier_load(&stack->entries[entry].atm); + newhead.contents.aba_ctr = ++curent.contents.aba_ctr; + gpr_atm_no_barrier_store(&stack->entries[entry].atm, curent.atm); + +#ifndef NDEBUG + /* Check for double push */ + { + int pushed_index = entry / (int)(8 * sizeof(gpr_atm)); + int pushed_bit = entry % (int)(8 * sizeof(gpr_atm)); + gpr_atm old_val; + + old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index], + ((gpr_atm)1 << pushed_bit)); + GPR_ASSERT((old_val & (((gpr_atm)1) << pushed_bit)) == 0); + } +#endif + + do { + /* Atomically get the existing head value for use */ + head.atm = gpr_atm_no_barrier_load(&(stack->head.atm)); + /* Point to it */ + newent.atm = gpr_atm_no_barrier_load(&stack->entries[entry].atm); + newent.contents.index = head.contents.index; + gpr_atm_no_barrier_store(&stack->entries[entry].atm, newent.atm); + } while (!gpr_atm_rel_cas(&(stack->head.atm), head.atm, newhead.atm)); + /* Use rel_cas above to make sure that entry index is set properly */ + return head.contents.index == INVALID_ENTRY_INDEX; +} + +int gpr_stack_lockfree_pop(gpr_stack_lockfree *stack) { + lockfree_node head; + lockfree_node newhead; + + do { + head.atm = gpr_atm_acq_load(&(stack->head.atm)); + if (head.contents.index == INVALID_ENTRY_INDEX) { + return -1; + } + newhead.atm = + gpr_atm_no_barrier_load(&(stack->entries[head.contents.index].atm)); + + } while (!gpr_atm_no_barrier_cas(&(stack->head.atm), head.atm, newhead.atm)); +#ifndef NDEBUG + /* Check for valid pop */ + { + int pushed_index = head.contents.index / (8 * sizeof(gpr_atm)); + int pushed_bit = head.contents.index % (8 * sizeof(gpr_atm)); + gpr_atm old_val; + + old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index], + -((gpr_atm)1 << pushed_bit)); + GPR_ASSERT((old_val & (((gpr_atm)1) << pushed_bit)) != 0); + } +#endif + + return head.contents.index; +} diff --git a/src/core/lib/support/stack_lockfree.h b/src/core/lib/support/stack_lockfree.h new file mode 100644 index 0000000000..d6fd06d67c --- /dev/null +++ b/src/core/lib/support/stack_lockfree.h @@ -0,0 +1,53 @@ +/* + * + * Copyright 2015-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_SUPPORT_STACK_LOCKFREE_H +#define GRPC_CORE_SUPPORT_STACK_LOCKFREE_H + +#include + +typedef struct gpr_stack_lockfree gpr_stack_lockfree; + +/* This stack must specify the maximum number of entries to track. + The current implementation only allows up to 65534 entries */ +gpr_stack_lockfree *gpr_stack_lockfree_create(size_t entries); +void gpr_stack_lockfree_destroy(gpr_stack_lockfree *stack); + +/* Pass in a valid entry number for the next stack entry */ +/* Returns 1 if this is the first element on the stack, 0 otherwise */ +int gpr_stack_lockfree_push(gpr_stack_lockfree *, int entry); + +/* Returns -1 on empty or the actual entry number */ +int gpr_stack_lockfree_pop(gpr_stack_lockfree *stack); + +#endif /* GRPC_CORE_SUPPORT_STACK_LOCKFREE_H */ diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c new file mode 100644 index 0000000000..1f541de40f --- /dev/null +++ b/src/core/lib/support/string.c @@ -0,0 +1,296 @@ +/* + * + * Copyright 2015, 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/support/string.h" + +#include +#include +#include + +#include +#include +#include +#include + +char *gpr_strdup(const char *src) { + char *dst; + size_t len; + + if (!src) { + return NULL; + } + + len = strlen(src) + 1; + dst = gpr_malloc(len); + + memcpy(dst, src, len); + + return dst; +} + +typedef struct { + size_t capacity; + size_t length; + char *data; +} dump_out; + +static dump_out dump_out_create(void) { + dump_out r = {0, 0, NULL}; + return r; +} + +static void dump_out_append(dump_out *out, char c) { + if (out->length == out->capacity) { + out->capacity = GPR_MAX(8, 2 * out->capacity); + out->data = gpr_realloc(out->data, out->capacity); + } + out->data[out->length++] = c; +} + +static void hexdump(dump_out *out, const char *buf, size_t len) { + static const char hex[16] = "0123456789abcdef"; + + const uint8_t *const beg = (const uint8_t *)buf; + const uint8_t *const end = beg + len; + const uint8_t *cur; + + for (cur = beg; cur != end; ++cur) { + if (cur != beg) dump_out_append(out, ' '); + dump_out_append(out, hex[*cur >> 4]); + dump_out_append(out, hex[*cur & 0xf]); + } +} + +static void asciidump(dump_out *out, const char *buf, size_t len) { + const uint8_t *const beg = (const uint8_t *)buf; + const uint8_t *const end = beg + len; + const uint8_t *cur; + int out_was_empty = (out->length == 0); + if (!out_was_empty) { + dump_out_append(out, ' '); + dump_out_append(out, '\''); + } + for (cur = beg; cur != end; ++cur) { + dump_out_append(out, (char)(isprint(*cur) ? *(char *)cur : '.')); + } + if (!out_was_empty) { + dump_out_append(out, '\''); + } +} + +char *gpr_dump(const char *buf, size_t len, uint32_t flags) { + dump_out out = dump_out_create(); + if (flags & GPR_DUMP_HEX) { + hexdump(&out, buf, len); + } + if (flags & GPR_DUMP_ASCII) { + asciidump(&out, buf, len); + } + dump_out_append(&out, 0); + return out.data; +} + +char *gpr_dump_slice(gpr_slice s, uint32_t flags) { + return gpr_dump((const char *)GPR_SLICE_START_PTR(s), GPR_SLICE_LENGTH(s), + flags); +} + +int gpr_parse_bytes_to_uint32(const char *buf, size_t len, uint32_t *result) { + uint32_t out = 0; + uint32_t new; + size_t i; + + if (len == 0) return 0; /* must have some bytes */ + + for (i = 0; i < len; i++) { + if (buf[i] < '0' || buf[i] > '9') return 0; /* bad char */ + new = 10 * out + (uint32_t)(buf[i] - '0'); + if (new < out) return 0; /* overflow */ + out = new; + } + + *result = out; + return 1; +} + +void gpr_reverse_bytes(char *str, int len) { + char *p1, *p2; + for (p1 = str, p2 = str + len - 1; p2 > p1; ++p1, --p2) { + char temp = *p1; + *p1 = *p2; + *p2 = temp; + } +} + +int gpr_ltoa(long value, char *string) { + long sign; + int i = 0; + + if (value == 0) { + string[0] = '0'; + string[1] = 0; + return 1; + } + + sign = value < 0 ? -1 : 1; + while (value) { + string[i++] = (char)('0' + sign * (value % 10)); + value /= 10; + } + if (sign < 0) string[i++] = '-'; + gpr_reverse_bytes(string, i); + string[i] = 0; + return i; +} + +int int64_ttoa(int64_t value, char *string) { + int64_t sign; + int i = 0; + + if (value == 0) { + string[0] = '0'; + string[1] = 0; + return 1; + } + + sign = value < 0 ? -1 : 1; + while (value) { + string[i++] = (char)('0' + sign * (value % 10)); + value /= 10; + } + if (sign < 0) string[i++] = '-'; + gpr_reverse_bytes(string, i); + string[i] = 0; + return i; +} + +char *gpr_strjoin(const char **strs, size_t nstrs, size_t *final_length) { + return gpr_strjoin_sep(strs, nstrs, "", final_length); +} + +char *gpr_strjoin_sep(const char **strs, size_t nstrs, const char *sep, + size_t *final_length) { + const size_t sep_len = strlen(sep); + size_t out_length = 0; + size_t i; + char *out; + for (i = 0; i < nstrs; i++) { + out_length += strlen(strs[i]); + } + out_length += 1; /* null terminator */ + if (nstrs > 0) { + out_length += sep_len * (nstrs - 1); /* separators */ + } + out = gpr_malloc(out_length); + out_length = 0; + for (i = 0; i < nstrs; i++) { + const size_t slen = strlen(strs[i]); + if (i != 0) { + memcpy(out + out_length, sep, sep_len); + out_length += sep_len; + } + memcpy(out + out_length, strs[i], slen); + out_length += slen; + } + out[out_length] = 0; + if (final_length != NULL) { + *final_length = out_length; + } + return out; +} + +/** Finds the initial (\a begin) and final (\a end) offsets of the next + * substring from \a str + \a read_offset until the next \a sep or the end of \a + * str. + * + * Returns 1 and updates \a begin and \a end. Returns 0 otherwise. */ +static int slice_find_separator_offset(const gpr_slice str, const char *sep, + const size_t read_offset, size_t *begin, + size_t *end) { + size_t i; + const uint8_t *str_ptr = GPR_SLICE_START_PTR(str) + read_offset; + const size_t str_len = GPR_SLICE_LENGTH(str) - read_offset; + const size_t sep_len = strlen(sep); + if (str_len < sep_len) { + return 0; + } + + for (i = 0; i <= str_len - sep_len; i++) { + if (memcmp(str_ptr + i, sep, sep_len) == 0) { + *begin = read_offset; + *end = read_offset + i; + return 1; + } + } + return 0; +} + +void gpr_slice_split(gpr_slice str, const char *sep, gpr_slice_buffer *dst) { + const size_t sep_len = strlen(sep); + size_t begin, end; + + GPR_ASSERT(sep_len > 0); + + if (slice_find_separator_offset(str, sep, 0, &begin, &end) != 0) { + do { + gpr_slice_buffer_add_indexed(dst, gpr_slice_sub(str, begin, end)); + } while (slice_find_separator_offset(str, sep, end + sep_len, &begin, + &end) != 0); + gpr_slice_buffer_add_indexed( + dst, gpr_slice_sub(str, end + sep_len, GPR_SLICE_LENGTH(str))); + } else { /* no sep found, add whole input */ + gpr_slice_buffer_add_indexed(dst, gpr_slice_ref(str)); + } +} + +void gpr_strvec_init(gpr_strvec *sv) { memset(sv, 0, sizeof(*sv)); } + +void gpr_strvec_destroy(gpr_strvec *sv) { + size_t i; + for (i = 0; i < sv->count; i++) { + gpr_free(sv->strs[i]); + } + gpr_free(sv->strs); +} + +void gpr_strvec_add(gpr_strvec *sv, char *str) { + if (sv->count == sv->capacity) { + sv->capacity = GPR_MAX(sv->capacity + 8, sv->capacity * 2); + sv->strs = gpr_realloc(sv->strs, sizeof(char *) * sv->capacity); + } + sv->strs[sv->count++] = str; +} + +char *gpr_strvec_flatten(gpr_strvec *sv, size_t *final_length) { + return gpr_strjoin((const char **)sv->strs, sv->count, final_length); +} diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h new file mode 100644 index 0000000000..8ff16882ab --- /dev/null +++ b/src/core/lib/support/string.h @@ -0,0 +1,121 @@ +/* + * + * Copyright 2015-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_SUPPORT_STRING_H +#define GRPC_CORE_SUPPORT_STRING_H + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* String utility functions */ + +/* Flags for gpr_dump function. */ +#define GPR_DUMP_HEX 0x00000001 +#define GPR_DUMP_ASCII 0x00000002 + +/* Converts array buf, of length len, into a C string according to the flags. + Result should be freed with gpr_free() */ +char *gpr_dump(const char *buf, size_t len, uint32_t flags); + +/* Calls gpr_dump on a slice. */ +char *gpr_dump_slice(gpr_slice slice, uint32_t flags); + +/* Parses an array of bytes into an integer (base 10). Returns 1 on success, + 0 on failure. */ +int gpr_parse_bytes_to_uint32(const char *data, size_t length, + uint32_t *result); + +/* Minimum buffer size for calling ltoa */ +#define GPR_LTOA_MIN_BUFSIZE (3 * sizeof(long)) + +/* Convert a long to a string in base 10; returns the length of the + output string (or 0 on failure). + output must be at least GPR_LTOA_MIN_BUFSIZE bytes long. */ +int gpr_ltoa(long value, char *output); + +/* Minimum buffer size for calling int64toa */ +#define GPR_INT64TOA_MIN_BUFSIZE (3 * sizeof(int64_t)) + +/* Convert an int64 to a string in base 10; returns the length of the +output string (or 0 on failure). +output must be at least GPR_INT64TOA_MIN_BUFSIZE bytes long. +NOTE: This function ensures sufficient bit width even on Win x64, +where long is 32bit is size.*/ +int int64_ttoa(int64_t value, char *output); + +/* Reverse a run of bytes */ +void gpr_reverse_bytes(char *str, int len); + +/* Join a set of strings, returning the resulting string. + Total combined length (excluding null terminator) is returned in total_length + if it is non-null. */ +char *gpr_strjoin(const char **strs, size_t nstrs, size_t *total_length); + +/* Join a set of strings using a separator, returning the resulting string. + Total combined length (excluding null terminator) is returned in total_length + if it is non-null. */ +char *gpr_strjoin_sep(const char **strs, size_t nstrs, const char *sep, + size_t *total_length); + +/** Split \a str by the separator \a sep. Results are stored in \a dst, which + * should be a properly initialized instance. */ +void gpr_slice_split(gpr_slice str, const char *sep, gpr_slice_buffer *dst); + +/* A vector of strings... for building up a final string one piece at a time */ +typedef struct { + char **strs; + size_t count; + size_t capacity; +} gpr_strvec; + +/* Initialize/destroy */ +void gpr_strvec_init(gpr_strvec *strs); +void gpr_strvec_destroy(gpr_strvec *strs); +/* Add a string to a strvec, takes ownership of the string */ +void gpr_strvec_add(gpr_strvec *strs, char *add); +/* Return a joined string with all added substrings, optionally setting + total_length as per gpr_strjoin */ +char *gpr_strvec_flatten(gpr_strvec *strs, size_t *total_length); + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_SUPPORT_STRING_H */ diff --git a/src/core/lib/support/string_posix.c b/src/core/lib/support/string_posix.c new file mode 100644 index 0000000000..a73b3106a5 --- /dev/null +++ b/src/core/lib/support/string_posix.c @@ -0,0 +1,86 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_STRING + +#include +#include +#include + +#include + +int gpr_asprintf(char **strp, const char *format, ...) { + va_list args; + int ret; + char buf[64]; + size_t strp_buflen; + + /* Use a constant-sized buffer to determine the length. */ + va_start(args, format); + ret = vsnprintf(buf, sizeof(buf), format, args); + va_end(args); + if (ret < 0) { + *strp = NULL; + return -1; + } + + /* Allocate a new buffer, with space for the NUL terminator. */ + strp_buflen = (size_t)ret + 1; + if ((*strp = gpr_malloc(strp_buflen)) == NULL) { + /* This shouldn't happen, because gpr_malloc() calls abort(). */ + return -1; + } + + /* Return early if we have all the bytes. */ + if (strp_buflen <= sizeof(buf)) { + memcpy(*strp, buf, strp_buflen); + return ret; + } + + /* Try again using the larger buffer. */ + va_start(args, format); + ret = vsnprintf(*strp, strp_buflen, format, args); + va_end(args); + if ((size_t)ret == strp_buflen - 1) { + return ret; + } + + /* This should never happen. */ + gpr_free(*strp); + *strp = NULL; + return -1; +} + +#endif /* GPR_POSIX_STRING */ diff --git a/src/core/lib/support/string_win32.c b/src/core/lib/support/string_win32.c new file mode 100644 index 0000000000..0780907994 --- /dev/null +++ b/src/core/lib/support/string_win32.c @@ -0,0 +1,109 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* Posix code for gpr snprintf support. */ + +#include + +#ifdef GPR_WIN32 + +#include +#include +#include + +#include + +#include "src/core/support/string.h" + +int gpr_asprintf(char **strp, const char *format, ...) { + va_list args; + int ret; + size_t strp_buflen; + + /* Determine the length. */ + va_start(args, format); + ret = _vscprintf(format, args); + va_end(args); + if (ret < 0) { + *strp = NULL; + return -1; + } + + /* Allocate a new buffer, with space for the NUL terminator. */ + strp_buflen = (size_t)ret + 1; + if ((*strp = gpr_malloc(strp_buflen)) == NULL) { + /* This shouldn't happen, because gpr_malloc() calls abort(). */ + return -1; + } + + /* Print to the buffer. */ + va_start(args, format); + ret = vsnprintf_s(*strp, strp_buflen, _TRUNCATE, format, args); + va_end(args); + if ((size_t)ret == strp_buflen - 1) { + return ret; + } + + /* This should never happen. */ + gpr_free(*strp); + *strp = NULL; + return -1; +} + +#if defined UNICODE || defined _UNICODE +LPTSTR +gpr_char_to_tchar(LPCSTR input) { + LPTSTR ret; + int needed = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0); + if (needed <= 0) return NULL; + ret = gpr_malloc((unsigned)needed * sizeof(TCHAR)); + MultiByteToWideChar(CP_UTF8, 0, input, -1, ret, needed); + return ret; +} + +LPSTR +gpr_tchar_to_char(LPCTSTR input) { + LPSTR ret; + int needed = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL); + if (needed <= 0) return NULL; + ret = gpr_malloc((unsigned)needed); + WideCharToMultiByte(CP_UTF8, 0, input, -1, ret, needed, NULL, NULL); + return ret; +} +#else +char *gpr_tchar_to_char(LPTSTR input) { return gpr_strdup(input); } + +char *gpr_char_to_tchar(LPTSTR input) { return gpr_strdup(input); } +#endif + +#endif /* GPR_WIN32 */ diff --git a/src/core/lib/support/string_win32.h b/src/core/lib/support/string_win32.h new file mode 100644 index 0000000000..c9ae8d9932 --- /dev/null +++ b/src/core/lib/support/string_win32.h @@ -0,0 +1,47 @@ +/* + * + * Copyright 2015-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_SUPPORT_STRING_WIN32_H +#define GRPC_CORE_SUPPORT_STRING_WIN32_H + +#include + +#ifdef GPR_WIN32 + +/* These allocate new strings using gpr_malloc to convert from and to utf-8. */ +LPTSTR gpr_char_to_tchar(LPCSTR input); +LPSTR gpr_tchar_to_char(LPCTSTR input); + +#endif /* GPR_WIN32 */ + +#endif /* GRPC_CORE_SUPPORT_STRING_WIN32_H */ diff --git a/src/core/lib/support/subprocess_posix.c b/src/core/lib/support/subprocess_posix.c new file mode 100644 index 0000000000..662e7dd999 --- /dev/null +++ b/src/core/lib/support/subprocess_posix.c @@ -0,0 +1,112 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_SUBPROCESS + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct gpr_subprocess { + int pid; + int joined; +}; + +const char *gpr_subprocess_binary_extension() { return ""; } + +gpr_subprocess *gpr_subprocess_create(int argc, const char **argv) { + gpr_subprocess *r; + int pid; + char **exec_args; + + pid = fork(); + if (pid == -1) { + return NULL; + } else if (pid == 0) { + exec_args = gpr_malloc(((size_t)argc + 1) * sizeof(char *)); + memcpy(exec_args, argv, (size_t)argc * sizeof(char *)); + exec_args[argc] = NULL; + execv(exec_args[0], exec_args); + /* if we reach here, an error has occurred */ + gpr_log(GPR_ERROR, "execv '%s' failed: %s", exec_args[0], strerror(errno)); + _exit(1); + return NULL; + } else { + r = gpr_malloc(sizeof(gpr_subprocess)); + memset(r, 0, sizeof(*r)); + r->pid = pid; + return r; + } +} + +void gpr_subprocess_destroy(gpr_subprocess *p) { + if (!p->joined) { + kill(p->pid, SIGKILL); + gpr_subprocess_join(p); + } + gpr_free(p); +} + +int gpr_subprocess_join(gpr_subprocess *p) { + int status; +retry: + if (waitpid(p->pid, &status, 0) == -1) { + if (errno == EINTR) { + goto retry; + } + gpr_log(GPR_ERROR, "waitpid failed: %s", strerror(errno)); + return -1; + } + return status; +} + +void gpr_subprocess_interrupt(gpr_subprocess *p) { + if (!p->joined) { + kill(p->pid, SIGINT); + } +} + +#endif /* GPR_POSIX_SUBPROCESS */ diff --git a/src/core/lib/support/subprocess_windows.c b/src/core/lib/support/subprocess_windows.c new file mode 100644 index 0000000000..6afbefeb2b --- /dev/null +++ b/src/core/lib/support/subprocess_windows.c @@ -0,0 +1,141 @@ +/* + * + * 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 + +#ifdef GPR_WINDOWS_SUBPROCESS + +#include +#include +#include + +#include +#include +#include +#include "src/core/support/string.h" +#include "src/core/support/string_win32.h" + +struct gpr_subprocess { + PROCESS_INFORMATION pi; + int joined; + int interrupted; +}; + +const char *gpr_subprocess_binary_extension() { return ".exe"; } + +gpr_subprocess *gpr_subprocess_create(int argc, const char **argv) { + gpr_subprocess *r; + + STARTUPINFO si; + PROCESS_INFORMATION pi; + + char *args = gpr_strjoin_sep(argv, (size_t)argc, " ", NULL); + TCHAR *args_tchar; + + args_tchar = gpr_char_to_tchar(args); + gpr_free(args); + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + memset(&pi, 0, sizeof(pi)); + + if (!CreateProcess(NULL, args_tchar, NULL, NULL, FALSE, + CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi)) { + gpr_free(args_tchar); + return NULL; + } + gpr_free(args_tchar); + + r = gpr_malloc(sizeof(gpr_subprocess)); + memset(r, 0, sizeof(*r)); + r->pi = pi; + return r; +} + +void gpr_subprocess_destroy(gpr_subprocess *p) { + if (p) { + if (!p->joined) { + gpr_subprocess_interrupt(p); + gpr_subprocess_join(p); + } + if (p->pi.hProcess) { + CloseHandle(p->pi.hProcess); + } + if (p->pi.hThread) { + CloseHandle(p->pi.hThread); + } + gpr_free(p); + } +} + +int gpr_subprocess_join(gpr_subprocess *p) { + DWORD dwExitCode; + if (GetExitCodeProcess(p->pi.hProcess, &dwExitCode)) { + if (dwExitCode == STILL_ACTIVE) { + if (WaitForSingleObject(p->pi.hProcess, INFINITE) == WAIT_OBJECT_0) { + p->joined = 1; + goto getExitCode; + } + return -1; // failed to join + } else { + goto getExitCode; + } + } else { + return -1; // failed to get exit code + } + +getExitCode: + if (p->interrupted) { + return 0; + } + if (GetExitCodeProcess(p->pi.hProcess, &dwExitCode)) { + return (int)dwExitCode; + } else { + return -1; // failed to get exit code + } +} + +void gpr_subprocess_interrupt(gpr_subprocess *p) { + DWORD dwExitCode; + if (GetExitCodeProcess(p->pi.hProcess, &dwExitCode)) { + if (dwExitCode == STILL_ACTIVE) { + gpr_log(GPR_INFO, "sending ctrl-break"); + GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, p->pi.dwProcessId); + p->joined = 1; + p->interrupted = 1; + } + } + return; +} + +#endif /* GPR_WINDOWS_SUBPROCESS */ diff --git a/src/core/lib/support/sync.c b/src/core/lib/support/sync.c new file mode 100644 index 0000000000..800cf20287 --- /dev/null +++ b/src/core/lib/support/sync.c @@ -0,0 +1,127 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* Generic implementation of synchronization primitives. */ + +#include +#include +#include + +/* Number of mutexes to allocate for events, to avoid lock contention. + Should be a prime. */ +enum { event_sync_partitions = 31 }; + +/* Events are partitioned by address to avoid lock contention. */ +static struct sync_array_s { + gpr_mu mu; + gpr_cv cv; +} sync_array[event_sync_partitions]; + +/* This routine is executed once on first use, via event_once */ +static gpr_once event_once = GPR_ONCE_INIT; +static void event_initialize(void) { + int i; + for (i = 0; i != event_sync_partitions; i++) { + gpr_mu_init(&sync_array[i].mu); + gpr_cv_init(&sync_array[i].cv); + } +} + +/* Hash ev into an element of sync_array[]. */ +static struct sync_array_s *hash(gpr_event *ev) { + return &sync_array[((uintptr_t)ev) % event_sync_partitions]; +} + +void gpr_event_init(gpr_event *ev) { + gpr_once_init(&event_once, &event_initialize); + ev->state = 0; +} + +void gpr_event_set(gpr_event *ev, void *value) { + struct sync_array_s *s = hash(ev); + gpr_mu_lock(&s->mu); + GPR_ASSERT(gpr_atm_acq_load(&ev->state) == 0); + gpr_atm_rel_store(&ev->state, (gpr_atm)value); + gpr_cv_broadcast(&s->cv); + gpr_mu_unlock(&s->mu); + GPR_ASSERT(value != NULL); +} + +void *gpr_event_get(gpr_event *ev) { + return (void *)gpr_atm_acq_load(&ev->state); +} + +void *gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline) { + void *result = (void *)gpr_atm_acq_load(&ev->state); + if (result == NULL) { + struct sync_array_s *s = hash(ev); + gpr_mu_lock(&s->mu); + do { + result = (void *)gpr_atm_acq_load(&ev->state); + } while (result == NULL && !gpr_cv_wait(&s->cv, &s->mu, abs_deadline)); + gpr_mu_unlock(&s->mu); + } + return result; +} + +void gpr_ref_init(gpr_refcount *r, int n) { gpr_atm_rel_store(&r->count, n); } + +void gpr_ref(gpr_refcount *r) { gpr_atm_no_barrier_fetch_add(&r->count, 1); } + +void gpr_ref_non_zero(gpr_refcount *r) { + gpr_atm prior = gpr_atm_no_barrier_fetch_add(&r->count, 1); + GPR_ASSERT(prior > 0); +} + +void gpr_refn(gpr_refcount *r, int n) { + gpr_atm_no_barrier_fetch_add(&r->count, n); +} + +int gpr_unref(gpr_refcount *r) { + gpr_atm prior = gpr_atm_full_fetch_add(&r->count, -1); + GPR_ASSERT(prior > 0); + return prior == 1; +} + +void gpr_stats_init(gpr_stats_counter *c, intptr_t n) { + gpr_atm_rel_store(&c->value, n); +} + +void gpr_stats_inc(gpr_stats_counter *c, intptr_t inc) { + gpr_atm_no_barrier_fetch_add(&c->value, inc); +} + +intptr_t gpr_stats_read(const gpr_stats_counter *c) { + /* don't need acquire-load, but we have no no-barrier load yet */ + return gpr_atm_acq_load(&c->value); +} diff --git a/src/core/lib/support/sync_posix.c b/src/core/lib/support/sync_posix.c new file mode 100644 index 0000000000..be4d0ac1c9 --- /dev/null +++ b/src/core/lib/support/sync_posix.c @@ -0,0 +1,104 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_SYNC + +#include +#include +#include +#include +#include +#include "src/core/profiling/timers.h" + +void gpr_mu_init(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_init(mu, NULL) == 0); } + +void gpr_mu_destroy(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_destroy(mu) == 0); } + +void gpr_mu_lock(gpr_mu* mu) { + GPR_TIMER_BEGIN("gpr_mu_lock", 0); + GPR_ASSERT(pthread_mutex_lock(mu) == 0); + GPR_TIMER_END("gpr_mu_lock", 0); +} + +void gpr_mu_unlock(gpr_mu* mu) { + GPR_TIMER_BEGIN("gpr_mu_unlock", 0); + GPR_ASSERT(pthread_mutex_unlock(mu) == 0); + GPR_TIMER_END("gpr_mu_unlock", 0); +} + +int gpr_mu_trylock(gpr_mu* mu) { + int err; + GPR_TIMER_BEGIN("gpr_mu_trylock", 0); + err = pthread_mutex_trylock(mu); + GPR_ASSERT(err == 0 || err == EBUSY); + GPR_TIMER_END("gpr_mu_trylock", 0); + return err == 0; +} + +/*----------------------------------------*/ + +void gpr_cv_init(gpr_cv* cv) { GPR_ASSERT(pthread_cond_init(cv, NULL) == 0); } + +void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); } + +int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { + int err = 0; + if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) == + 0) { + err = pthread_cond_wait(cv, mu); + } else { + struct timespec abs_deadline_ts; + abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME); + abs_deadline_ts.tv_sec = (time_t)abs_deadline.tv_sec; + abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; + err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts); + } + GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); + return err == ETIMEDOUT; +} + +void gpr_cv_signal(gpr_cv* cv) { GPR_ASSERT(pthread_cond_signal(cv) == 0); } + +void gpr_cv_broadcast(gpr_cv* cv) { + GPR_ASSERT(pthread_cond_broadcast(cv) == 0); +} + +/*----------------------------------------*/ + +void gpr_once_init(gpr_once* once, void (*init_function)(void)) { + GPR_ASSERT(pthread_once(once, init_function) == 0); +} + +#endif /* GRP_POSIX_SYNC */ diff --git a/src/core/lib/support/sync_win32.c b/src/core/lib/support/sync_win32.c new file mode 100644 index 0000000000..41998ebcb6 --- /dev/null +++ b/src/core/lib/support/sync_win32.c @@ -0,0 +1,133 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* Win32 code for gpr synchronization support. */ + +#include + +#ifdef GPR_WIN32 + +#include +#include +#include + +void gpr_mu_init(gpr_mu *mu) { + InitializeCriticalSection(&mu->cs); + mu->locked = 0; +} + +void gpr_mu_destroy(gpr_mu *mu) { DeleteCriticalSection(&mu->cs); } + +void gpr_mu_lock(gpr_mu *mu) { + EnterCriticalSection(&mu->cs); + GPR_ASSERT(!mu->locked); + mu->locked = 1; +} + +void gpr_mu_unlock(gpr_mu *mu) { + mu->locked = 0; + LeaveCriticalSection(&mu->cs); +} + +int gpr_mu_trylock(gpr_mu *mu) { + int result = TryEnterCriticalSection(&mu->cs); + if (result) { + if (mu->locked) { /* This thread already holds the lock. */ + LeaveCriticalSection(&mu->cs); /* Decrement lock count. */ + result = 0; /* Indicate failure */ + } + mu->locked = 1; + } + return result; +} + +/*----------------------------------------*/ + +void gpr_cv_init(gpr_cv *cv) { InitializeConditionVariable(cv); } + +void gpr_cv_destroy(gpr_cv *cv) { + /* Condition variables don't need destruction in Win32. */ +} + +int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline) { + int timeout = 0; + DWORD timeout_max_ms; + mu->locked = 0; + if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) == + 0) { + SleepConditionVariableCS(cv, &mu->cs, INFINITE); + } else { + abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME); + gpr_timespec now = gpr_now(abs_deadline.clock_type); + int64_t now_ms = (int64_t)now.tv_sec * 1000 + now.tv_nsec / 1000000; + int64_t deadline_ms = + (int64_t)abs_deadline.tv_sec * 1000 + abs_deadline.tv_nsec / 1000000; + if (now_ms >= deadline_ms) { + timeout = 1; + } else { + if ((deadline_ms - now_ms) >= INFINITE) { + timeout_max_ms = INFINITE - 1; + } else { + timeout_max_ms = (DWORD)(deadline_ms - now_ms); + } + timeout = (SleepConditionVariableCS(cv, &mu->cs, timeout_max_ms) == 0 && + GetLastError() == ERROR_TIMEOUT); + } + } + mu->locked = 1; + return timeout; +} + +void gpr_cv_signal(gpr_cv *cv) { WakeConditionVariable(cv); } + +void gpr_cv_broadcast(gpr_cv *cv) { WakeAllConditionVariable(cv); } + +/*----------------------------------------*/ + +static void *dummy; +struct run_once_func_arg { + void (*init_function)(void); +}; +static BOOL CALLBACK run_once_func(gpr_once *once, void *v, void **pv) { + struct run_once_func_arg *arg = v; + (*arg->init_function)(); + return 1; +} + +void gpr_once_init(gpr_once *once, void (*init_function)(void)) { + struct run_once_func_arg arg; + arg.init_function = init_function; + InitOnceExecuteOnce(once, run_once_func, &arg, &dummy); +} + +#endif /* GPR_WIN32 */ diff --git a/src/core/lib/support/thd.c b/src/core/lib/support/thd.c new file mode 100644 index 0000000000..41daeb5d0e --- /dev/null +++ b/src/core/lib/support/thd.c @@ -0,0 +1,64 @@ +/* + * + * Copyright 2015, 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. + * + */ + +/* Posix implementation for gpr threads. */ + +#include + +#include + +enum { GPR_THD_JOINABLE = 1 }; + +gpr_thd_options gpr_thd_options_default(void) { + gpr_thd_options options; + memset(&options, 0, sizeof(options)); + return options; +} + +void gpr_thd_options_set_detached(gpr_thd_options* options) { + options->flags &= ~GPR_THD_JOINABLE; +} + +void gpr_thd_options_set_joinable(gpr_thd_options* options) { + options->flags |= GPR_THD_JOINABLE; +} + +int gpr_thd_options_is_detached(const gpr_thd_options* options) { + if (!options) return 1; + return (options->flags & GPR_THD_JOINABLE) == 0; +} + +int gpr_thd_options_is_joinable(const gpr_thd_options* options) { + if (!options) return 0; + return (options->flags & GPR_THD_JOINABLE) == GPR_THD_JOINABLE; +} diff --git a/src/core/lib/support/thd_internal.h b/src/core/lib/support/thd_internal.h new file mode 100644 index 0000000000..33b904e59b --- /dev/null +++ b/src/core/lib/support/thd_internal.h @@ -0,0 +1,39 @@ +/* + * + * Copyright 2015-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_SUPPORT_THD_INTERNAL_H +#define GRPC_CORE_SUPPORT_THD_INTERNAL_H + +/* Internal interfaces between modules within the gpr support library. */ + +#endif /* GRPC_CORE_SUPPORT_THD_INTERNAL_H */ diff --git a/src/core/lib/support/thd_posix.c b/src/core/lib/support/thd_posix.c new file mode 100644 index 0000000000..4d874d3656 --- /dev/null +++ b/src/core/lib/support/thd_posix.c @@ -0,0 +1,94 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* Posix implementation for gpr threads. */ + +#include + +#ifdef GPR_POSIX_SYNC + +#include +#include +#include +#include +#include +#include +#include + +struct thd_arg { + void (*body)(void *arg); /* body of a thread */ + void *arg; /* argument to a thread */ +}; + +/* Body of every thread started via gpr_thd_new. */ +static void *thread_body(void *v) { + struct thd_arg a = *(struct thd_arg *)v; + free(v); + (*a.body)(a.arg); + return NULL; +} + +int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, + const gpr_thd_options *options) { + int thread_started; + pthread_attr_t attr; + pthread_t p; + /* don't use gpr_malloc as we may cause an infinite recursion with + * the profiling code */ + struct thd_arg *a = malloc(sizeof(*a)); + GPR_ASSERT(a != NULL); + a->body = thd_body; + a->arg = arg; + + GPR_ASSERT(pthread_attr_init(&attr) == 0); + if (gpr_thd_options_is_detached(options)) { + GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == + 0); + } else { + GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == + 0); + } + thread_started = (pthread_create(&p, &attr, &thread_body, a) == 0); + GPR_ASSERT(pthread_attr_destroy(&attr) == 0); + if (!thread_started) { + free(a); + } + *t = (gpr_thd_id)p; + return thread_started; +} + +gpr_thd_id gpr_thd_currentid(void) { return (gpr_thd_id)pthread_self(); } + +void gpr_thd_join(gpr_thd_id t) { pthread_join((pthread_t)t, NULL); } + +#endif /* GPR_POSIX_SYNC */ diff --git a/src/core/lib/support/thd_win32.c b/src/core/lib/support/thd_win32.c new file mode 100644 index 0000000000..630eb7f625 --- /dev/null +++ b/src/core/lib/support/thd_win32.c @@ -0,0 +1,117 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* Windows implementation for gpr threads. */ + +#include + +#ifdef GPR_WIN32 + +#include +#include +#include +#include + +#if defined(_MSC_VER) +#define thread_local __declspec(thread) +#elif defined(__GNUC__) +#define thread_local __thread +#else +#error "Unknown compiler - please file a bug report" +#endif + +struct thd_info { + void (*body)(void *arg); /* body of a thread */ + void *arg; /* argument to a thread */ + HANDLE join_event; /* if joinable, the join event */ + int joinable; /* true if not detached */ +}; + +static thread_local struct thd_info *g_thd_info; + +/* Destroys a thread info */ +static void destroy_thread(struct thd_info *t) { + if (t->joinable) CloseHandle(t->join_event); + gpr_free(t); +} + +/* Body of every thread started via gpr_thd_new. */ +static DWORD WINAPI thread_body(void *v) { + g_thd_info = (struct thd_info *)v; + g_thd_info->body(g_thd_info->arg); + if (g_thd_info->joinable) { + BOOL ret = SetEvent(g_thd_info->join_event); + GPR_ASSERT(ret); + } else { + destroy_thread(g_thd_info); + } + return 0; +} + +int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, + const gpr_thd_options *options) { + HANDLE handle; + struct thd_info *info = gpr_malloc(sizeof(*info)); + info->body = thd_body; + info->arg = arg; + *t = 0; + if (gpr_thd_options_is_joinable(options)) { + info->joinable = 1; + info->join_event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (info->join_event == NULL) { + gpr_free(info); + return 0; + } + } else { + info->joinable = 0; + } + handle = CreateThread(NULL, 64 * 1024, thread_body, info, 0, NULL); + if (handle == NULL) { + destroy_thread(info); + } else { + *t = (gpr_thd_id)info; + CloseHandle(handle); + } + return handle != NULL; +} + +gpr_thd_id gpr_thd_currentid(void) { return (gpr_thd_id)g_thd_info; } + +void gpr_thd_join(gpr_thd_id t) { + struct thd_info *info = (struct thd_info *)t; + DWORD ret = WaitForSingleObject(info->join_event, INFINITE); + GPR_ASSERT(ret == WAIT_OBJECT_0); + destroy_thread(info); +} + +#endif /* GPR_WIN32 */ diff --git a/src/core/lib/support/time.c b/src/core/lib/support/time.c new file mode 100644 index 0000000000..0e2c8fcf1a --- /dev/null +++ b/src/core/lib/support/time.c @@ -0,0 +1,304 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* Generic implementation of time calls. */ + +#include +#include +#include +#include +#include + +int gpr_time_cmp(gpr_timespec a, gpr_timespec b) { + int cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec); + GPR_ASSERT(a.clock_type == b.clock_type); + if (cmp == 0) { + cmp = (a.tv_nsec > b.tv_nsec) - (a.tv_nsec < b.tv_nsec); + } + return cmp; +} + +gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b) { + return gpr_time_cmp(a, b) < 0 ? a : b; +} + +gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b) { + return gpr_time_cmp(a, b) > 0 ? a : b; +} + +gpr_timespec gpr_time_0(gpr_clock_type type) { + gpr_timespec out; + out.tv_sec = 0; + out.tv_nsec = 0; + out.clock_type = type; + return out; +} + +gpr_timespec gpr_inf_future(gpr_clock_type type) { + gpr_timespec out; + out.tv_sec = INT64_MAX; + out.tv_nsec = 0; + out.clock_type = type; + return out; +} + +gpr_timespec gpr_inf_past(gpr_clock_type type) { + gpr_timespec out; + out.tv_sec = INT64_MIN; + out.tv_nsec = 0; + out.clock_type = type; + return out; +} + +/* TODO(ctiller): consider merging _nanos, _micros, _millis into a single + function for maintainability. Similarly for _seconds, _minutes, and _hours */ + +gpr_timespec gpr_time_from_nanos(int64_t ns, gpr_clock_type type) { + gpr_timespec result; + result.clock_type = type; + if (ns == INT64_MAX) { + result = gpr_inf_future(type); + } else if (ns == INT64_MIN) { + result = gpr_inf_past(type); + } else if (ns >= 0) { + result.tv_sec = ns / GPR_NS_PER_SEC; + result.tv_nsec = (int32_t)(ns - result.tv_sec * GPR_NS_PER_SEC); + } else { + /* Calculation carefully formulated to avoid any possible under/overflow. */ + result.tv_sec = (-(999999999 - (ns + GPR_NS_PER_SEC)) / GPR_NS_PER_SEC) - 1; + result.tv_nsec = (int32_t)(ns - result.tv_sec * GPR_NS_PER_SEC); + } + return result; +} + +gpr_timespec gpr_time_from_micros(int64_t us, gpr_clock_type type) { + gpr_timespec result; + result.clock_type = type; + if (us == INT64_MAX) { + result = gpr_inf_future(type); + } else if (us == INT64_MIN) { + result = gpr_inf_past(type); + } else if (us >= 0) { + result.tv_sec = us / 1000000; + result.tv_nsec = (int32_t)((us - result.tv_sec * 1000000) * 1000); + } else { + /* Calculation carefully formulated to avoid any possible under/overflow. */ + result.tv_sec = (-(999999 - (us + 1000000)) / 1000000) - 1; + result.tv_nsec = (int32_t)((us - result.tv_sec * 1000000) * 1000); + } + return result; +} + +gpr_timespec gpr_time_from_millis(int64_t ms, gpr_clock_type type) { + gpr_timespec result; + result.clock_type = type; + if (ms == INT64_MAX) { + result = gpr_inf_future(type); + } else if (ms == INT64_MIN) { + result = gpr_inf_past(type); + } else if (ms >= 0) { + result.tv_sec = ms / 1000; + result.tv_nsec = (int32_t)((ms - result.tv_sec * 1000) * 1000000); + } else { + /* Calculation carefully formulated to avoid any possible under/overflow. */ + result.tv_sec = (-(999 - (ms + 1000)) / 1000) - 1; + result.tv_nsec = (int32_t)((ms - result.tv_sec * 1000) * 1000000); + } + return result; +} + +gpr_timespec gpr_time_from_seconds(int64_t s, gpr_clock_type type) { + gpr_timespec result; + result.clock_type = type; + if (s == INT64_MAX) { + result = gpr_inf_future(type); + } else if (s == INT64_MIN) { + result = gpr_inf_past(type); + } else { + result.tv_sec = s; + result.tv_nsec = 0; + } + return result; +} + +gpr_timespec gpr_time_from_minutes(int64_t m, gpr_clock_type type) { + gpr_timespec result; + result.clock_type = type; + if (m >= INT64_MAX / 60) { + result = gpr_inf_future(type); + } else if (m <= INT64_MIN / 60) { + result = gpr_inf_past(type); + } else { + result.tv_sec = m * 60; + result.tv_nsec = 0; + } + return result; +} + +gpr_timespec gpr_time_from_hours(int64_t h, gpr_clock_type type) { + gpr_timespec result; + result.clock_type = type; + if (h >= INT64_MAX / 3600) { + result = gpr_inf_future(type); + } else if (h <= INT64_MIN / 3600) { + result = gpr_inf_past(type); + } else { + result.tv_sec = h * 3600; + result.tv_nsec = 0; + } + return result; +} + +gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) { + gpr_timespec sum; + int64_t inc = 0; + GPR_ASSERT(b.clock_type == GPR_TIMESPAN); + sum.clock_type = a.clock_type; + sum.tv_nsec = a.tv_nsec + b.tv_nsec; + if (sum.tv_nsec >= GPR_NS_PER_SEC) { + sum.tv_nsec -= GPR_NS_PER_SEC; + inc++; + } + if (a.tv_sec == INT64_MAX || a.tv_sec == INT64_MIN) { + sum = a; + } else if (b.tv_sec == INT64_MAX || + (b.tv_sec >= 0 && a.tv_sec >= INT64_MAX - b.tv_sec)) { + sum = gpr_inf_future(sum.clock_type); + } else if (b.tv_sec == INT64_MIN || + (b.tv_sec <= 0 && a.tv_sec <= INT64_MIN - b.tv_sec)) { + sum = gpr_inf_past(sum.clock_type); + } else { + sum.tv_sec = a.tv_sec + b.tv_sec; + if (inc != 0 && sum.tv_sec == INT64_MAX - 1) { + sum = gpr_inf_future(sum.clock_type); + } else { + sum.tv_sec += inc; + } + } + return sum; +} + +gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) { + gpr_timespec diff; + int64_t dec = 0; + if (b.clock_type == GPR_TIMESPAN) { + diff.clock_type = a.clock_type; + } else { + GPR_ASSERT(a.clock_type == b.clock_type); + diff.clock_type = GPR_TIMESPAN; + } + diff.tv_nsec = a.tv_nsec - b.tv_nsec; + if (diff.tv_nsec < 0) { + diff.tv_nsec += GPR_NS_PER_SEC; + dec++; + } + if (a.tv_sec == INT64_MAX || a.tv_sec == INT64_MIN) { + diff = a; + } else if (b.tv_sec == INT64_MIN || + (b.tv_sec <= 0 && a.tv_sec >= INT64_MAX + b.tv_sec)) { + diff = gpr_inf_future(GPR_CLOCK_REALTIME); + } else if (b.tv_sec == INT64_MAX || + (b.tv_sec >= 0 && a.tv_sec <= INT64_MIN + b.tv_sec)) { + diff = gpr_inf_past(GPR_CLOCK_REALTIME); + } else { + diff.tv_sec = a.tv_sec - b.tv_sec; + if (dec != 0 && diff.tv_sec == INT64_MIN + 1) { + diff = gpr_inf_past(GPR_CLOCK_REALTIME); + } else { + diff.tv_sec -= dec; + } + } + return diff; +} + +int gpr_time_similar(gpr_timespec a, gpr_timespec b, gpr_timespec threshold) { + int cmp_ab; + + GPR_ASSERT(a.clock_type == b.clock_type); + GPR_ASSERT(threshold.clock_type == GPR_TIMESPAN); + + cmp_ab = gpr_time_cmp(a, b); + if (cmp_ab == 0) return 1; + if (cmp_ab < 0) { + return gpr_time_cmp(gpr_time_sub(b, a), threshold) <= 0; + } else { + return gpr_time_cmp(gpr_time_sub(a, b), threshold) <= 0; + } +} + +int32_t gpr_time_to_millis(gpr_timespec t) { + if (t.tv_sec >= 2147483) { + if (t.tv_sec == 2147483 && t.tv_nsec < 648 * GPR_NS_PER_MS) { + return 2147483 * GPR_MS_PER_SEC + t.tv_nsec / GPR_NS_PER_MS; + } + return 2147483647; + } else if (t.tv_sec <= -2147483) { + /* TODO(ctiller): correct handling here (it's so far in the past do we + care?) */ + return -2147483647; + } else { + return (int32_t)(t.tv_sec * GPR_MS_PER_SEC + t.tv_nsec / GPR_NS_PER_MS); + } +} + +double gpr_timespec_to_micros(gpr_timespec t) { + return (double)t.tv_sec * GPR_US_PER_SEC + t.tv_nsec * 1e-3; +} + +gpr_timespec gpr_convert_clock_type(gpr_timespec t, gpr_clock_type clock_type) { + if (t.clock_type == clock_type) { + return t; + } + + if (t.tv_nsec == 0) { + if (t.tv_sec == INT64_MAX) { + t.clock_type = clock_type; + return t; + } + if (t.tv_sec == INT64_MIN) { + t.clock_type = clock_type; + return t; + } + } + + if (clock_type == GPR_TIMESPAN) { + return gpr_time_sub(t, gpr_now(t.clock_type)); + } + + if (t.clock_type == GPR_TIMESPAN) { + return gpr_time_add(gpr_now(clock_type), t); + } + + return gpr_time_add(gpr_now(clock_type), + gpr_time_sub(t, gpr_now(t.clock_type))); +} diff --git a/src/core/lib/support/time_posix.c b/src/core/lib/support/time_posix.c new file mode 100644 index 0000000000..f999e08cb0 --- /dev/null +++ b/src/core/lib/support/time_posix.c @@ -0,0 +1,170 @@ +/* + * + * Copyright 2015-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 +#include + +#ifdef GPR_POSIX_TIME + +#include +#include +#include +#ifdef __linux__ +#include +#endif +#include +#include +#include "src/core/support/block_annotate.h" + +static struct timespec timespec_from_gpr(gpr_timespec gts) { + struct timespec rv; + if (sizeof(time_t) < sizeof(int64_t)) { + /* fine to assert, as this is only used in gpr_sleep_until */ + GPR_ASSERT(gts.tv_sec <= INT32_MAX && gts.tv_sec >= INT32_MIN); + } + rv.tv_sec = (time_t)gts.tv_sec; + rv.tv_nsec = gts.tv_nsec; + return rv; +} + +#if _POSIX_TIMERS > 0 +static gpr_timespec gpr_from_timespec(struct timespec ts, + gpr_clock_type clock_type) { + /* + * timespec.tv_sec can have smaller size than gpr_timespec.tv_sec, + * but we are only using this function to implement gpr_now + * so there's no need to handle "infinity" values. + */ + gpr_timespec rv; + rv.tv_sec = ts.tv_sec; + rv.tv_nsec = (int32_t)ts.tv_nsec; + rv.clock_type = clock_type; + return rv; +} + +/** maps gpr_clock_type --> clockid_t for clock_gettime */ +static const clockid_t clockid_for_gpr_clock[] = {CLOCK_MONOTONIC, + CLOCK_REALTIME}; + +void gpr_time_init(void) { gpr_precise_clock_init(); } + +gpr_timespec gpr_now(gpr_clock_type clock_type) { + struct timespec now; + GPR_ASSERT(clock_type != GPR_TIMESPAN); + if (clock_type == GPR_CLOCK_PRECISE) { + gpr_timespec ret; + gpr_precise_clock_now(&ret); + return ret; + } else { +#if defined(GPR_BACKWARDS_COMPATIBILITY_MODE) && defined(__linux__) + /* avoid ABI problems by invoking syscalls directly */ + syscall(SYS_clock_gettime, clockid_for_gpr_clock[clock_type], &now); +#else + clock_gettime(clockid_for_gpr_clock[clock_type], &now); +#endif + return gpr_from_timespec(now, clock_type); + } +} +#else +/* For some reason Apple's OSes haven't implemented clock_gettime. */ + +#include +#include +#include + +static double g_time_scale; +static uint64_t g_time_start; + +void gpr_time_init(void) { + mach_timebase_info_data_t tb = {0, 1}; + gpr_precise_clock_init(); + mach_timebase_info(&tb); + g_time_scale = tb.numer; + g_time_scale /= tb.denom; + g_time_start = mach_absolute_time(); +} + +gpr_timespec gpr_now(gpr_clock_type clock) { + gpr_timespec now; + struct timeval now_tv; + double now_dbl; + + now.clock_type = clock; + switch (clock) { + case GPR_CLOCK_REALTIME: + gettimeofday(&now_tv, NULL); + now.tv_sec = now_tv.tv_sec; + now.tv_nsec = now_tv.tv_usec * 1000; + break; + case GPR_CLOCK_MONOTONIC: + now_dbl = (mach_absolute_time() - g_time_start) * g_time_scale; + now.tv_sec = (int64_t)(now_dbl * 1e-9); + now.tv_nsec = (int32_t)(now_dbl - ((double)now.tv_sec) * 1e9); + break; + case GPR_CLOCK_PRECISE: + gpr_precise_clock_now(&now); + break; + case GPR_TIMESPAN: + abort(); + } + + return now; +} +#endif + +void gpr_sleep_until(gpr_timespec until) { + gpr_timespec now; + gpr_timespec delta; + struct timespec delta_ts; + int ns_result; + + for (;;) { + /* We could simplify by using clock_nanosleep instead, but it might be + * slightly less portable. */ + now = gpr_now(until.clock_type); + if (gpr_time_cmp(until, now) <= 0) { + return; + } + + delta = gpr_time_sub(until, now); + delta_ts = timespec_from_gpr(delta); + GRPC_SCHEDULING_START_BLOCKING_REGION; + ns_result = nanosleep(&delta_ts, NULL); + GRPC_SCHEDULING_END_BLOCKING_REGION; + if (ns_result == 0) { + break; + } + } +} + +#endif /* GPR_POSIX_TIME */ diff --git a/src/core/lib/support/time_precise.c b/src/core/lib/support/time_precise.c new file mode 100644 index 0000000000..a2cf74bc84 --- /dev/null +++ b/src/core/lib/support/time_precise.c @@ -0,0 +1,89 @@ +/* + * + * Copyright 2015, 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 +#include +#include + +#ifdef GRPC_TIMERS_RDTSC +#if defined(__i386__) +static void gpr_get_cycle_counter(long long int *clk) { + long long int ret; + __asm__ volatile("rdtsc" : "=A"(ret)); + *clk = ret; +} + +// ---------------------------------------------------------------- +#elif defined(__x86_64__) || defined(__amd64__) +static void gpr_get_cycle_counter(long long int *clk) { + unsigned long long low, high; + __asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); + *clk = (long long)(high << 32) | (long long)low; +} +#endif + +static double cycles_per_second = 0; +static long long int start_cycle; +void gpr_precise_clock_init(void) { + time_t start; + long long end_cycle; + gpr_log(GPR_DEBUG, "Calibrating timers"); + start = time(NULL); + while (time(NULL) == start) + ; + gpr_get_cycle_counter(&start_cycle); + while (time(NULL) <= start + 10) + ; + gpr_get_cycle_counter(&end_cycle); + cycles_per_second = (double)(end_cycle - start_cycle) / 10.0; + gpr_log(GPR_DEBUG, "... cycles_per_second = %f\n", cycles_per_second); +} + +void gpr_precise_clock_now(gpr_timespec *clk) { + long long int counter; + double secs; + gpr_get_cycle_counter(&counter); + secs = (double)(counter - start_cycle) / cycles_per_second; + clk->clock_type = GPR_CLOCK_PRECISE; + clk->tv_sec = (int64_t)secs; + clk->tv_nsec = (int32_t)(1e9 * (secs - (double)clk->tv_sec)); +} + +#else /* GRPC_TIMERS_RDTSC */ +void gpr_precise_clock_init(void) {} + +void gpr_precise_clock_now(gpr_timespec *clk) { + *clk = gpr_now(GPR_CLOCK_REALTIME); + clk->clock_type = GPR_CLOCK_PRECISE; +} +#endif /* GRPC_TIMERS_RDTSC */ diff --git a/src/core/lib/support/time_precise.h b/src/core/lib/support/time_precise.h new file mode 100644 index 0000000000..871c99a623 --- /dev/null +++ b/src/core/lib/support/time_precise.h @@ -0,0 +1,42 @@ +/* + * + * Copyright 2015-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_SUPPORT_TIME_PRECISE_H +#define GRPC_CORE_SUPPORT_TIME_PRECISE_H + +#include + +void gpr_precise_clock_init(void); +void gpr_precise_clock_now(gpr_timespec *clk); + +#endif /* GRPC_CORE_SUPPORT_TIME_PRECISE_H */ diff --git a/src/core/lib/support/time_win32.c b/src/core/lib/support/time_win32.c new file mode 100644 index 0000000000..2c344d3f3b --- /dev/null +++ b/src/core/lib/support/time_win32.c @@ -0,0 +1,110 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* Win32 code for gpr time support. */ + +#include + +#ifdef GPR_WIN32 + +#include +#include +#include +#include +#include +#include + +#include "src/core/support/block_annotate.h" + +static LARGE_INTEGER g_start_time; +static double g_time_scale; + +void gpr_time_init(void) { + LARGE_INTEGER frequency; + QueryPerformanceFrequency(&frequency); + QueryPerformanceCounter(&g_start_time); + g_time_scale = 1.0 / (double)frequency.QuadPart; +} + +gpr_timespec gpr_now(gpr_clock_type clock) { + gpr_timespec now_tv; + LONGLONG diff; + struct _timeb now_tb; + LARGE_INTEGER timestamp; + double now_dbl; + now_tv.clock_type = clock; + switch (clock) { + case GPR_CLOCK_REALTIME: + _ftime_s(&now_tb); + now_tv.tv_sec = (int64_t)now_tb.time; + now_tv.tv_nsec = now_tb.millitm * 1000000; + break; + case GPR_CLOCK_MONOTONIC: + case GPR_CLOCK_PRECISE: + QueryPerformanceCounter(×tamp); + diff = timestamp.QuadPart - g_start_time.QuadPart; + now_dbl = (double)diff * g_time_scale; + now_tv.tv_sec = (int64_t)now_dbl; + now_tv.tv_nsec = (int32_t)((now_dbl - (double)now_tv.tv_sec) * 1e9); + break; + case GPR_TIMESPAN: + abort(); + break; + } + return now_tv; +} + +void gpr_sleep_until(gpr_timespec until) { + gpr_timespec now; + gpr_timespec delta; + int64_t sleep_millis; + + for (;;) { + /* We could simplify by using clock_nanosleep instead, but it might be + * slightly less portable. */ + now = gpr_now(until.clock_type); + if (gpr_time_cmp(until, now) <= 0) { + return; + } + + delta = gpr_time_sub(until, now); + sleep_millis = + delta.tv_sec * GPR_MS_PER_SEC + delta.tv_nsec / GPR_NS_PER_MS; + GPR_ASSERT((sleep_millis >= 0) && (sleep_millis <= INT_MAX)); + GRPC_SCHEDULING_START_BLOCKING_REGION; + Sleep((DWORD)sleep_millis); + GRPC_SCHEDULING_END_BLOCKING_REGION; + } +} + +#endif /* GPR_WIN32 */ diff --git a/src/core/lib/support/tls_pthread.c b/src/core/lib/support/tls_pthread.c new file mode 100644 index 0000000000..9683a6e547 --- /dev/null +++ b/src/core/lib/support/tls_pthread.c @@ -0,0 +1,45 @@ +/* + * + * Copyright 2015, 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 + +#ifdef GPR_PTHREAD_TLS + +#include + +intptr_t gpr_tls_set(struct gpr_pthread_thread_local *tls, intptr_t value) { + GPR_ASSERT(0 == pthread_setspecific(tls->key, (void *)value)); + return value; +} + +#endif /* GPR_PTHREAD_TLS */ diff --git a/src/core/lib/support/tmpfile.h b/src/core/lib/support/tmpfile.h new file mode 100644 index 0000000000..df6f8692bb --- /dev/null +++ b/src/core/lib/support/tmpfile.h @@ -0,0 +1,55 @@ +/* + * + * Copyright 2015-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_SUPPORT_TMPFILE_H +#define GRPC_CORE_SUPPORT_TMPFILE_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Creates a temporary file from a prefix. + If tmp_filename is not NULL, *tmp_filename is assigned the name of the + created file and it is the responsibility of the caller to gpr_free it + unless an error occurs in which case it will be set to NULL. */ +FILE *gpr_tmpfile(const char *prefix, char **tmp_filename); + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_SUPPORT_TMPFILE_H */ diff --git a/src/core/lib/support/tmpfile_posix.c b/src/core/lib/support/tmpfile_posix.c new file mode 100644 index 0000000000..b16eeacf9d --- /dev/null +++ b/src/core/lib/support/tmpfile_posix.c @@ -0,0 +1,85 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_POSIX_FILE + +#include "src/core/support/tmpfile.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include "src/core/support/string.h" + +FILE *gpr_tmpfile(const char *prefix, char **tmp_filename) { + FILE *result = NULL; + char *template; + int fd; + + if (tmp_filename != NULL) *tmp_filename = NULL; + + gpr_asprintf(&template, "/tmp/%s_XXXXXX", prefix); + GPR_ASSERT(template != NULL); + + fd = mkstemp(template); + if (fd == -1) { + gpr_log(GPR_ERROR, "mkstemp failed for template %s with error %s.", + template, strerror(errno)); + goto end; + } + result = fdopen(fd, "w+"); + if (result == NULL) { + gpr_log(GPR_ERROR, "Could not open file %s from fd %d (error = %s).", + template, fd, strerror(errno)); + unlink(template); + close(fd); + goto end; + } + +end: + if (result != NULL && tmp_filename != NULL) { + *tmp_filename = template; + } else { + gpr_free(template); + } + return result; +} + +#endif /* GPR_POSIX_FILE */ diff --git a/src/core/lib/support/tmpfile_win32.c b/src/core/lib/support/tmpfile_win32.c new file mode 100644 index 0000000000..3000f0029f --- /dev/null +++ b/src/core/lib/support/tmpfile_win32.c @@ -0,0 +1,84 @@ +/* + * + * Copyright 2015-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 + +#ifdef GPR_WIN32 + +#include +#include +#include +#include + +#include +#include +#include + +#include "src/core/support/string_win32.h" +#include "src/core/support/tmpfile.h" + +FILE *gpr_tmpfile(const char *prefix, char **tmp_filename_out) { + FILE *result = NULL; + LPTSTR template_string = NULL; + TCHAR tmp_path[MAX_PATH]; + TCHAR tmp_filename[MAX_PATH]; + DWORD status; + UINT success; + + if (tmp_filename_out != NULL) *tmp_filename_out = NULL; + + /* Convert our prefix to TCHAR. */ + template_string = gpr_char_to_tchar(prefix); + GPR_ASSERT(template_string); + + /* Get the path to the best temporary folder available. */ + status = GetTempPath(MAX_PATH, tmp_path); + if (status == 0 || status > MAX_PATH) goto end; + + /* Generate a unique filename with our template + temporary path. */ + success = GetTempFileName(tmp_path, template_string, 0, tmp_filename); + if (!success) goto end; + + /* Open a file there. */ + if (_tfopen_s(&result, tmp_filename, TEXT("wb+")) != 0) goto end; + +end: + if (result && tmp_filename_out) { + *tmp_filename_out = gpr_tchar_to_char(tmp_filename); + } + + gpr_free(template_string); + return result; +} + +#endif /* GPR_WIN32 */ diff --git a/src/core/lib/support/wrap_memcpy.c b/src/core/lib/support/wrap_memcpy.c new file mode 100644 index 0000000000..15c289f7b8 --- /dev/null +++ b/src/core/lib/support/wrap_memcpy.c @@ -0,0 +1,53 @@ +/* + * + * 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 + +/* Provide a wrapped memcpy for targets that need to be backwards + * compatible with older libc's. + * + * Enable by setting LDFLAGS=-Wl,-wrap,memcpy when linking. + */ + +#ifdef __linux__ +#ifdef __x86_64__ +__asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); +void *__wrap_memcpy(void *destination, const void *source, size_t num) { + return memcpy(destination, source, num); +} +#else /* !__x86_64__ */ +void *__wrap_memcpy(void *destination, const void *source, size_t num) { + return memmove(destination, source, num); +} +#endif +#endif diff --git a/src/core/lib/surface/alarm.c b/src/core/lib/surface/alarm.c new file mode 100644 index 0000000000..1085285f95 --- /dev/null +++ b/src/core/lib/surface/alarm.c @@ -0,0 +1,84 @@ +/* + * + * Copyright 2015-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 +#include +#include "src/core/iomgr/timer.h" +#include "src/core/surface/completion_queue.h" + +struct grpc_alarm { + grpc_timer alarm; + grpc_cq_completion completion; + /** completion queue where events about this alarm will be posted */ + grpc_completion_queue *cq; + /** user supplied tag */ + void *tag; +}; + +static void do_nothing_end_completion(grpc_exec_ctx *exec_ctx, void *arg, + grpc_cq_completion *c) {} + +static void alarm_cb(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + grpc_alarm *alarm = arg; + grpc_cq_end_op(exec_ctx, alarm->cq, alarm->tag, success, + do_nothing_end_completion, NULL, &alarm->completion); +} + +grpc_alarm *grpc_alarm_create(grpc_completion_queue *cq, gpr_timespec deadline, + void *tag) { + grpc_alarm *alarm = gpr_malloc(sizeof(grpc_alarm)); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + GRPC_CQ_INTERNAL_REF(cq, "alarm"); + alarm->cq = cq; + alarm->tag = tag; + + grpc_cq_begin_op(cq, tag); + grpc_timer_init(&exec_ctx, &alarm->alarm, + gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC), + alarm_cb, alarm, gpr_now(GPR_CLOCK_MONOTONIC)); + grpc_exec_ctx_finish(&exec_ctx); + return alarm; +} + +void grpc_alarm_cancel(grpc_alarm *alarm) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_timer_cancel(&exec_ctx, &alarm->alarm); + grpc_exec_ctx_finish(&exec_ctx); +} + +void grpc_alarm_destroy(grpc_alarm *alarm) { + grpc_alarm_cancel(alarm); + GRPC_CQ_INTERNAL_UNREF(alarm->cq, "alarm"); + gpr_free(alarm); +} diff --git a/src/core/lib/surface/api_trace.c b/src/core/lib/surface/api_trace.c new file mode 100644 index 0000000000..9f0b900d46 --- /dev/null +++ b/src/core/lib/surface/api_trace.c @@ -0,0 +1,36 @@ +/* + * + * Copyright 2015, 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/surface/api_trace.h" + +int grpc_api_trace = 0; diff --git a/src/core/lib/surface/api_trace.h b/src/core/lib/surface/api_trace.h new file mode 100644 index 0000000000..af53829de4 --- /dev/null +++ b/src/core/lib/surface/api_trace.h @@ -0,0 +1,65 @@ +/* + * + * Copyright 2015-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_SURFACE_API_TRACE_H +#define GRPC_CORE_SURFACE_API_TRACE_H + +#include +#include "src/core/debug/trace.h" + +extern int grpc_api_trace; + +/* Provide unwrapping macros because we're in C89 and variadic macros weren't + introduced until C99... */ +#define GRPC_API_TRACE_UNWRAP0() +#define GRPC_API_TRACE_UNWRAP1(a) , a +#define GRPC_API_TRACE_UNWRAP2(a, b) , a, b +#define GRPC_API_TRACE_UNWRAP3(a, b, c) , a, b, c +#define GRPC_API_TRACE_UNWRAP4(a, b, c, d) , a, b, c, d +#define GRPC_API_TRACE_UNWRAP5(a, b, c, d, e) , a, b, c, d, e +#define GRPC_API_TRACE_UNWRAP6(a, b, c, d, e, f) , a, b, c, d, e, f +#define GRPC_API_TRACE_UNWRAP7(a, b, c, d, e, f, g) , a, b, c, d, e, f, g +#define GRPC_API_TRACE_UNWRAP8(a, b, c, d, e, f, g, h) , a, b, c, d, e, f, g, h +#define GRPC_API_TRACE_UNWRAP9(a, b, c, d, e, f, g, h, i) \ + , a, b, c, d, e, f, g, h, i +#define GRPC_API_TRACE_UNWRAP10(a, b, c, d, e, f, g, h, i, j) \ + , a, b, c, d, e, f, g, h, i, j + +/* Due to the limitations of C89's preprocessor, the arity of the var-arg list + 'nargs' must be specified. */ +#define GRPC_API_TRACE(fmt, nargs, args) \ + if (grpc_api_trace) { \ + gpr_log(GPR_INFO, fmt GRPC_API_TRACE_UNWRAP##nargs args); \ + } + +#endif /* GRPC_CORE_SURFACE_API_TRACE_H */ diff --git a/src/core/lib/surface/byte_buffer.c b/src/core/lib/surface/byte_buffer.c new file mode 100644 index 0000000000..fb39c4531d --- /dev/null +++ b/src/core/lib/surface/byte_buffer.c @@ -0,0 +1,97 @@ +/* + * + * Copyright 2015, 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 +#include +#include + +grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices, + size_t nslices) { + return grpc_raw_compressed_byte_buffer_create(slices, nslices, + GRPC_COMPRESS_NONE); +} + +grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create( + gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression) { + size_t i; + grpc_byte_buffer *bb = malloc(sizeof(grpc_byte_buffer)); + bb->type = GRPC_BB_RAW; + bb->data.raw.compression = compression; + gpr_slice_buffer_init(&bb->data.raw.slice_buffer); + for (i = 0; i < nslices; i++) { + gpr_slice_ref(slices[i]); + gpr_slice_buffer_add(&bb->data.raw.slice_buffer, slices[i]); + } + return bb; +} + +grpc_byte_buffer *grpc_raw_byte_buffer_from_reader( + grpc_byte_buffer_reader *reader) { + grpc_byte_buffer *bb = malloc(sizeof(grpc_byte_buffer)); + gpr_slice slice; + bb->type = GRPC_BB_RAW; + bb->data.raw.compression = GRPC_COMPRESS_NONE; + gpr_slice_buffer_init(&bb->data.raw.slice_buffer); + + while (grpc_byte_buffer_reader_next(reader, &slice)) { + gpr_slice_buffer_add(&bb->data.raw.slice_buffer, slice); + } + return bb; +} + +grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb) { + switch (bb->type) { + case GRPC_BB_RAW: + return grpc_raw_byte_buffer_create(bb->data.raw.slice_buffer.slices, + bb->data.raw.slice_buffer.count); + } + GPR_UNREACHABLE_CODE(return NULL); +} + +void grpc_byte_buffer_destroy(grpc_byte_buffer *bb) { + if (!bb) return; + switch (bb->type) { + case GRPC_BB_RAW: + gpr_slice_buffer_destroy(&bb->data.raw.slice_buffer); + break; + } + free(bb); +} + +size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) { + switch (bb->type) { + case GRPC_BB_RAW: + return bb->data.raw.slice_buffer.length; + } + GPR_UNREACHABLE_CODE(return 0); +} diff --git a/src/core/lib/surface/byte_buffer_reader.c b/src/core/lib/surface/byte_buffer_reader.c new file mode 100644 index 0000000000..4a418faaed --- /dev/null +++ b/src/core/lib/surface/byte_buffer_reader.c @@ -0,0 +1,123 @@ +/* + * + * Copyright 2015-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 +#include + +#include +#include +#include +#include +#include +#include + +#include "src/core/compression/message_compress.h" + +static int is_compressed(grpc_byte_buffer *buffer) { + switch (buffer->type) { + case GRPC_BB_RAW: + if (buffer->data.raw.compression == GRPC_COMPRESS_NONE) { + return 0 /* GPR_FALSE */; + } + break; + } + return 1 /* GPR_TRUE */; +} + +void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader, + grpc_byte_buffer *buffer) { + gpr_slice_buffer decompressed_slices_buffer; + reader->buffer_in = buffer; + switch (reader->buffer_in->type) { + case GRPC_BB_RAW: + gpr_slice_buffer_init(&decompressed_slices_buffer); + if (is_compressed(reader->buffer_in)) { + grpc_msg_decompress(reader->buffer_in->data.raw.compression, + &reader->buffer_in->data.raw.slice_buffer, + &decompressed_slices_buffer); + reader->buffer_out = + grpc_raw_byte_buffer_create(decompressed_slices_buffer.slices, + decompressed_slices_buffer.count); + gpr_slice_buffer_destroy(&decompressed_slices_buffer); + } else { /* not compressed, use the input buffer as output */ + reader->buffer_out = reader->buffer_in; + } + reader->current.index = 0; + break; + } +} + +void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader) { + switch (reader->buffer_in->type) { + case GRPC_BB_RAW: + /* keeping the same if-else structure as in the init function */ + if (is_compressed(reader->buffer_in)) { + grpc_byte_buffer_destroy(reader->buffer_out); + } + break; + } +} + +int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader, + gpr_slice *slice) { + switch (reader->buffer_in->type) { + case GRPC_BB_RAW: { + gpr_slice_buffer *slice_buffer; + slice_buffer = &reader->buffer_out->data.raw.slice_buffer; + if (reader->current.index < slice_buffer->count) { + *slice = gpr_slice_ref(slice_buffer->slices[reader->current.index]); + reader->current.index += 1; + return 1; + } + break; + } + } + return 0; +} + +gpr_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader) { + gpr_slice in_slice; + size_t bytes_read = 0; + const size_t input_size = grpc_byte_buffer_length(reader->buffer_out); + gpr_slice out_slice = gpr_slice_malloc(input_size); + uint8_t *const outbuf = GPR_SLICE_START_PTR(out_slice); /* just an alias */ + + while (grpc_byte_buffer_reader_next(reader, &in_slice) != 0) { + const size_t slice_length = GPR_SLICE_LENGTH(in_slice); + memcpy(&(outbuf[bytes_read]), GPR_SLICE_START_PTR(in_slice), slice_length); + bytes_read += slice_length; + gpr_slice_unref(in_slice); + GPR_ASSERT(bytes_read <= input_size); + } + return out_slice; +} diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c new file mode 100644 index 0000000000..6f1cd1df10 --- /dev/null +++ b/src/core/lib/surface/call.c @@ -0,0 +1,1491 @@ +/* + * + * Copyright 2015-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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "src/core/channel/channel_stack.h" +#include "src/core/compression/algorithm_metadata.h" +#include "src/core/iomgr/timer.h" +#include "src/core/profiling/timers.h" +#include "src/core/support/string.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/call.h" +#include "src/core/surface/channel.h" +#include "src/core/surface/completion_queue.h" +#include "src/core/transport/static_metadata.h" + +/** The maximum number of concurrent batches possible. + Based upon the maximum number of individually queueable ops in the batch + api: + - initial metadata send + - message send + - status/close send (depending on client/server) + - initial metadata recv + - message recv + - status/close recv (depending on client/server) */ +#define MAX_CONCURRENT_BATCHES 6 + +typedef struct { + grpc_ioreq_completion_func on_complete; + void *user_data; + int success; +} completed_request; + +#define MAX_SEND_EXTRA_METADATA_COUNT 3 + +/* Status data for a request can come from several sources; this + enumerates them all, and acts as a priority sorting for which + status to return to the application - earlier entries override + later ones */ +typedef enum { + /* Status came from the application layer overriding whatever + the wire says */ + STATUS_FROM_API_OVERRIDE = 0, + /* Status was created by some internal channel stack operation */ + STATUS_FROM_CORE, + /* Status came from 'the wire' - or somewhere below the surface + layer */ + STATUS_FROM_WIRE, + /* Status came from the server sending status */ + STATUS_FROM_SERVER_STATUS, + STATUS_SOURCE_COUNT +} status_source; + +typedef struct { + uint8_t is_set; + grpc_status_code code; + grpc_mdstr *details; +} received_status; + +/* How far through the GRPC stream have we read? */ +typedef enum { + /* We are still waiting for initial metadata to complete */ + READ_STATE_INITIAL = 0, + /* We have gotten initial metadata, and are reading either + messages or trailing metadata */ + READ_STATE_GOT_INITIAL_METADATA, + /* The stream is closed for reading */ + READ_STATE_READ_CLOSED, + /* The stream is closed for reading & writing */ + READ_STATE_STREAM_CLOSED +} read_state; + +typedef enum { + WRITE_STATE_INITIAL = 0, + WRITE_STATE_STARTED, + WRITE_STATE_WRITE_CLOSED +} write_state; + +typedef struct batch_control { + grpc_call *call; + grpc_cq_completion cq_completion; + grpc_closure finish_batch; + void *notify_tag; + gpr_refcount steps_to_complete; + + uint8_t send_initial_metadata; + uint8_t send_message; + uint8_t send_final_op; + uint8_t recv_initial_metadata; + uint8_t recv_message; + uint8_t recv_final_op; + uint8_t is_notify_tag_closure; + uint8_t success; +} batch_control; + +struct grpc_call { + grpc_completion_queue *cq; + grpc_channel *channel; + grpc_call *parent; + grpc_call *first_child; + /* TODO(ctiller): share with cq if possible? */ + gpr_mu mu; + + /* client or server call */ + uint8_t is_client; + /* is the alarm set */ + uint8_t have_alarm; + /** has grpc_call_destroy been called */ + uint8_t destroy_called; + /** flag indicating that cancellation is inherited */ + uint8_t cancellation_is_inherited; + /** bitmask of live batches */ + uint8_t used_batches; + /** which ops are in-flight */ + uint8_t sent_initial_metadata; + uint8_t sending_message; + uint8_t sent_final_op; + uint8_t received_initial_metadata; + uint8_t receiving_message; + uint8_t received_final_op; + + /* have we received initial metadata */ + bool has_initial_md_been_received; + + batch_control active_batches[MAX_CONCURRENT_BATCHES]; + + /* first idx: is_receiving, second idx: is_trailing */ + grpc_metadata_batch metadata_batch[2][2]; + + /* Buffered read metadata waiting to be returned to the application. + Element 0 is initial metadata, element 1 is trailing metadata. */ + grpc_metadata_array *buffered_metadata[2]; + + /* Received call statuses from various sources */ + received_status status[STATUS_SOURCE_COUNT]; + + /* Compression algorithm for the call */ + grpc_compression_algorithm compression_algorithm; + /* Supported encodings (compression algorithms), a bitset */ + uint32_t encodings_accepted_by_peer; + + /* Contexts for various subsystems (security, tracing, ...). */ + grpc_call_context_element context[GRPC_CONTEXT_COUNT]; + + /* Deadline alarm - if have_alarm is non-zero */ + grpc_timer alarm; + + /* for the client, extra metadata is initial metadata; for the + server, it's trailing metadata */ + grpc_linked_mdelem send_extra_metadata[MAX_SEND_EXTRA_METADATA_COUNT]; + int send_extra_metadata_count; + gpr_timespec send_deadline; + + /** siblings: children of the same parent form a list, and this list is + protected under + parent->mu */ + grpc_call *sibling_next; + grpc_call *sibling_prev; + + grpc_slice_buffer_stream sending_stream; + grpc_byte_stream *receiving_stream; + grpc_byte_buffer **receiving_buffer; + gpr_slice receiving_slice; + grpc_closure receiving_slice_ready; + grpc_closure receiving_stream_ready; + grpc_closure receiving_initial_metadata_ready; + uint32_t test_only_last_message_flags; + + union { + struct { + grpc_status_code *status; + char **status_details; + size_t *status_details_capacity; + } client; + struct { + int *cancelled; + } server; + } final_op; + + struct { + void *bctlp; + bool success; + } saved_receiving_stream_ready_ctx; +}; + +#define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call) + 1)) +#define CALL_FROM_CALL_STACK(call_stack) (((grpc_call *)(call_stack)) - 1) +#define CALL_ELEM_FROM_CALL(call, idx) \ + grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx) +#define CALL_FROM_TOP_ELEM(top_elem) \ + CALL_FROM_CALL_STACK(grpc_call_stack_from_top_element(top_elem)) + +static void set_deadline_alarm(grpc_exec_ctx *exec_ctx, grpc_call *call, + gpr_timespec deadline); +static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call, + grpc_transport_stream_op *op); +static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c, + grpc_status_code status, + const char *description); +static void destroy_call(grpc_exec_ctx *exec_ctx, void *call_stack, + bool success); +static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, + bool success); + +grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call, + uint32_t propagation_mask, + grpc_completion_queue *cq, + const void *server_transport_data, + grpc_mdelem **add_initial_metadata, + size_t add_initial_metadata_count, + gpr_timespec send_deadline) { + size_t i, j; + grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_call *call; + GPR_TIMER_BEGIN("grpc_call_create", 0); + call = gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size); + memset(call, 0, sizeof(grpc_call)); + gpr_mu_init(&call->mu); + call->channel = channel; + call->cq = cq; + call->parent = parent_call; + call->is_client = server_transport_data == NULL; + if (call->is_client) { + GPR_ASSERT(add_initial_metadata_count < MAX_SEND_EXTRA_METADATA_COUNT); + for (i = 0; i < add_initial_metadata_count; i++) { + call->send_extra_metadata[i].md = add_initial_metadata[i]; + } + call->send_extra_metadata_count = (int)add_initial_metadata_count; + } else { + GPR_ASSERT(add_initial_metadata_count == 0); + call->send_extra_metadata_count = 0; + } + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + call->metadata_batch[i][j].deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); + } + } + call->send_deadline = send_deadline; + GRPC_CHANNEL_INTERNAL_REF(channel, "call"); + /* initial refcount dropped by grpc_call_destroy */ + grpc_call_stack_init(&exec_ctx, channel_stack, 1, destroy_call, call, + call->context, server_transport_data, + CALL_STACK_FROM_CALL(call)); + if (cq != NULL) { + GRPC_CQ_INTERNAL_REF(cq, "bind"); + grpc_call_stack_set_pollset(&exec_ctx, CALL_STACK_FROM_CALL(call), + grpc_cq_pollset(cq)); + } + if (parent_call != NULL) { + GRPC_CALL_INTERNAL_REF(parent_call, "child"); + GPR_ASSERT(call->is_client); + GPR_ASSERT(!parent_call->is_client); + + gpr_mu_lock(&parent_call->mu); + + if (propagation_mask & GRPC_PROPAGATE_DEADLINE) { + send_deadline = gpr_time_min( + gpr_convert_clock_type(send_deadline, + parent_call->send_deadline.clock_type), + parent_call->send_deadline); + } + /* for now GRPC_PROPAGATE_TRACING_CONTEXT *MUST* be passed with + * GRPC_PROPAGATE_STATS_CONTEXT */ + /* TODO(ctiller): This should change to use the appropriate census start_op + * call. */ + if (propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) { + GPR_ASSERT(propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT); + grpc_call_context_set(call, GRPC_CONTEXT_TRACING, + parent_call->context[GRPC_CONTEXT_TRACING].value, + NULL); + } else { + GPR_ASSERT(propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT); + } + if (propagation_mask & GRPC_PROPAGATE_CANCELLATION) { + call->cancellation_is_inherited = 1; + } + + if (parent_call->first_child == NULL) { + parent_call->first_child = call; + call->sibling_next = call->sibling_prev = call; + } else { + call->sibling_next = parent_call->first_child; + call->sibling_prev = parent_call->first_child->sibling_prev; + call->sibling_next->sibling_prev = call->sibling_prev->sibling_next = + call; + } + + gpr_mu_unlock(&parent_call->mu); + } + if (gpr_time_cmp(send_deadline, gpr_inf_future(send_deadline.clock_type)) != + 0) { + set_deadline_alarm(&exec_ctx, call, send_deadline); + } + grpc_exec_ctx_finish(&exec_ctx); + GPR_TIMER_END("grpc_call_create", 0); + return call; +} + +void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call, + grpc_completion_queue *cq) { + GPR_ASSERT(cq); + call->cq = cq; + GRPC_CQ_INTERNAL_REF(cq, "bind"); + grpc_call_stack_set_pollset(exec_ctx, CALL_STACK_FROM_CALL(call), + grpc_cq_pollset(cq)); +} + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +#define REF_REASON reason +#define REF_ARG , const char *reason +#else +#define REF_REASON "" +#define REF_ARG +#endif +void grpc_call_internal_ref(grpc_call *c REF_ARG) { + GRPC_CALL_STACK_REF(CALL_STACK_FROM_CALL(c), REF_REASON); +} +void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *c REF_ARG) { + GRPC_CALL_STACK_UNREF(exec_ctx, CALL_STACK_FROM_CALL(c), REF_REASON); +} + +static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, bool success) { + size_t i; + int ii; + grpc_call *c = call; + GPR_TIMER_BEGIN("destroy_call", 0); + for (i = 0; i < 2; i++) { + grpc_metadata_batch_destroy( + &c->metadata_batch[1 /* is_receiving */][i /* is_initial */]); + } + if (c->receiving_stream != NULL) { + grpc_byte_stream_destroy(exec_ctx, c->receiving_stream); + } + grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c)); + GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, c->channel, "call"); + gpr_mu_destroy(&c->mu); + for (i = 0; i < STATUS_SOURCE_COUNT; i++) { + if (c->status[i].details) { + GRPC_MDSTR_UNREF(c->status[i].details); + } + } + for (ii = 0; ii < c->send_extra_metadata_count; ii++) { + GRPC_MDELEM_UNREF(c->send_extra_metadata[ii].md); + } + for (i = 0; i < GRPC_CONTEXT_COUNT; i++) { + if (c->context[i].destroy) { + c->context[i].destroy(c->context[i].value); + } + } + if (c->cq) { + GRPC_CQ_INTERNAL_UNREF(c->cq, "bind"); + } + gpr_free(c); + GPR_TIMER_END("destroy_call", 0); +} + +static void set_status_code(grpc_call *call, status_source source, + uint32_t status) { + if (call->status[source].is_set) return; + + call->status[source].is_set = 1; + call->status[source].code = (grpc_status_code)status; + + /* TODO(ctiller): what to do about the flush that was previously here */ +} + +static void set_compression_algorithm(grpc_call *call, + grpc_compression_algorithm algo) { + call->compression_algorithm = algo; +} + +grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm( + grpc_call *call) { + grpc_compression_algorithm algorithm; + gpr_mu_lock(&call->mu); + algorithm = call->compression_algorithm; + gpr_mu_unlock(&call->mu); + return algorithm; +} + +uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) { + uint32_t flags; + gpr_mu_lock(&call->mu); + flags = call->test_only_last_message_flags; + gpr_mu_unlock(&call->mu); + return flags; +} + +static void destroy_encodings_accepted_by_peer(void *p) { return; } + +static void set_encodings_accepted_by_peer(grpc_call *call, grpc_mdelem *mdel) { + size_t i; + grpc_compression_algorithm algorithm; + gpr_slice_buffer accept_encoding_parts; + gpr_slice accept_encoding_slice; + void *accepted_user_data; + + accepted_user_data = + grpc_mdelem_get_user_data(mdel, destroy_encodings_accepted_by_peer); + if (accepted_user_data != NULL) { + call->encodings_accepted_by_peer = + (uint32_t)(((uintptr_t)accepted_user_data) - 1); + return; + } + + accept_encoding_slice = mdel->value->slice; + gpr_slice_buffer_init(&accept_encoding_parts); + gpr_slice_split(accept_encoding_slice, ",", &accept_encoding_parts); + + /* No need to zero call->encodings_accepted_by_peer: grpc_call_create already + * zeroes the whole grpc_call */ + /* Always support no compression */ + GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE); + for (i = 0; i < accept_encoding_parts.count; i++) { + const gpr_slice *accept_encoding_entry_slice = + &accept_encoding_parts.slices[i]; + if (grpc_compression_algorithm_parse( + (const char *)GPR_SLICE_START_PTR(*accept_encoding_entry_slice), + GPR_SLICE_LENGTH(*accept_encoding_entry_slice), &algorithm)) { + GPR_BITSET(&call->encodings_accepted_by_peer, algorithm); + } else { + char *accept_encoding_entry_str = + gpr_dump_slice(*accept_encoding_entry_slice, GPR_DUMP_ASCII); + gpr_log(GPR_ERROR, + "Invalid entry in accept encoding metadata: '%s'. Ignoring.", + accept_encoding_entry_str); + gpr_free(accept_encoding_entry_str); + } + } + + gpr_slice_buffer_destroy(&accept_encoding_parts); + + grpc_mdelem_set_user_data( + mdel, destroy_encodings_accepted_by_peer, + (void *)(((uintptr_t)call->encodings_accepted_by_peer) + 1)); +} + +uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) { + uint32_t encodings_accepted_by_peer; + gpr_mu_lock(&call->mu); + encodings_accepted_by_peer = call->encodings_accepted_by_peer; + gpr_mu_unlock(&call->mu); + return encodings_accepted_by_peer; +} + +static void set_status_details(grpc_call *call, status_source source, + grpc_mdstr *status) { + if (call->status[source].details != NULL) { + GRPC_MDSTR_UNREF(call->status[source].details); + } + call->status[source].details = status; +} + +static void get_final_status(grpc_call *call, + void (*set_value)(grpc_status_code code, + void *user_data), + void *set_value_user_data) { + int i; + for (i = 0; i < STATUS_SOURCE_COUNT; i++) { + if (call->status[i].is_set) { + set_value(call->status[i].code, set_value_user_data); + return; + } + } + if (call->is_client) { + set_value(GRPC_STATUS_UNKNOWN, set_value_user_data); + } else { + set_value(GRPC_STATUS_OK, set_value_user_data); + } +} + +static void get_final_details(grpc_call *call, char **out_details, + size_t *out_details_capacity) { + int i; + for (i = 0; i < STATUS_SOURCE_COUNT; i++) { + if (call->status[i].is_set) { + if (call->status[i].details) { + gpr_slice details = call->status[i].details->slice; + size_t len = GPR_SLICE_LENGTH(details); + if (len + 1 > *out_details_capacity) { + *out_details_capacity = + GPR_MAX(len + 1, *out_details_capacity * 3 / 2); + *out_details = gpr_realloc(*out_details, *out_details_capacity); + } + memcpy(*out_details, GPR_SLICE_START_PTR(details), len); + (*out_details)[len] = 0; + } else { + goto no_details; + } + return; + } + } + +no_details: + if (0 == *out_details_capacity) { + *out_details_capacity = 8; + *out_details = gpr_malloc(*out_details_capacity); + } + **out_details = 0; +} + +static grpc_linked_mdelem *linked_from_md(grpc_metadata *md) { + return (grpc_linked_mdelem *)&md->internal_data; +} + +static int prepare_application_metadata(grpc_call *call, int count, + grpc_metadata *metadata, + int is_trailing, + int prepend_extra_metadata) { + int i; + grpc_metadata_batch *batch = + &call->metadata_batch[0 /* is_receiving */][is_trailing]; + if (prepend_extra_metadata) { + if (call->send_extra_metadata_count == 0) { + prepend_extra_metadata = 0; + } else { + for (i = 0; i < call->send_extra_metadata_count; i++) { + GRPC_MDELEM_REF(call->send_extra_metadata[i].md); + } + for (i = 1; i < call->send_extra_metadata_count; i++) { + call->send_extra_metadata[i].prev = &call->send_extra_metadata[i - 1]; + } + for (i = 0; i < call->send_extra_metadata_count - 1; i++) { + call->send_extra_metadata[i].next = &call->send_extra_metadata[i + 1]; + } + } + } + for (i = 0; i < count; i++) { + grpc_metadata *md = &metadata[i]; + grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data; + GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data)); + l->md = grpc_mdelem_from_string_and_buffer( + md->key, (const uint8_t *)md->value, md->value_length); + if (!grpc_header_key_is_legal(grpc_mdstr_as_c_string(l->md->key), + GRPC_MDSTR_LENGTH(l->md->key))) { + gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s", + grpc_mdstr_as_c_string(l->md->key)); + return 0; + } else if (!grpc_is_binary_header(grpc_mdstr_as_c_string(l->md->key), + GRPC_MDSTR_LENGTH(l->md->key)) && + !grpc_header_nonbin_value_is_legal( + grpc_mdstr_as_c_string(l->md->value), + GRPC_MDSTR_LENGTH(l->md->value))) { + gpr_log(GPR_ERROR, "attempt to send invalid metadata value"); + return 0; + } + } + for (i = 1; i < count; i++) { + linked_from_md(&metadata[i])->prev = linked_from_md(&metadata[i - 1]); + } + for (i = 0; i < count - 1; i++) { + linked_from_md(&metadata[i])->next = linked_from_md(&metadata[i + 1]); + } + switch (prepend_extra_metadata * 2 + (count != 0)) { + case 0: + /* no prepend, no metadata => nothing to do */ + batch->list.head = batch->list.tail = NULL; + break; + case 1: + /* metadata, but no prepend */ + batch->list.head = linked_from_md(&metadata[0]); + batch->list.tail = linked_from_md(&metadata[count - 1]); + batch->list.head->prev = NULL; + batch->list.tail->next = NULL; + break; + case 2: + /* prepend, but no md */ + batch->list.head = &call->send_extra_metadata[0]; + batch->list.tail = + &call->send_extra_metadata[call->send_extra_metadata_count - 1]; + batch->list.head->prev = NULL; + batch->list.tail->next = NULL; + break; + case 3: + /* prepend AND md */ + batch->list.head = &call->send_extra_metadata[0]; + call->send_extra_metadata[call->send_extra_metadata_count - 1].next = + linked_from_md(&metadata[0]); + linked_from_md(&metadata[0])->prev = + &call->send_extra_metadata[call->send_extra_metadata_count - 1]; + batch->list.tail = linked_from_md(&metadata[count - 1]); + batch->list.head->prev = NULL; + batch->list.tail->next = NULL; + break; + default: + GPR_UNREACHABLE_CODE(return 0); + } + + return 1; +} + +void grpc_call_destroy(grpc_call *c) { + int cancel; + grpc_call *parent = c->parent; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + GPR_TIMER_BEGIN("grpc_call_destroy", 0); + GRPC_API_TRACE("grpc_call_destroy(c=%p)", 1, (c)); + + if (parent) { + gpr_mu_lock(&parent->mu); + if (c == parent->first_child) { + parent->first_child = c->sibling_next; + if (c == parent->first_child) { + parent->first_child = NULL; + } + c->sibling_prev->sibling_next = c->sibling_next; + c->sibling_next->sibling_prev = c->sibling_prev; + } + gpr_mu_unlock(&parent->mu); + GRPC_CALL_INTERNAL_UNREF(&exec_ctx, parent, "child"); + } + + gpr_mu_lock(&c->mu); + GPR_ASSERT(!c->destroy_called); + c->destroy_called = 1; + if (c->have_alarm) { + grpc_timer_cancel(&exec_ctx, &c->alarm); + } + cancel = !c->received_final_op; + gpr_mu_unlock(&c->mu); + if (cancel) grpc_call_cancel(c, NULL); + GRPC_CALL_INTERNAL_UNREF(&exec_ctx, c, "destroy"); + grpc_exec_ctx_finish(&exec_ctx); + GPR_TIMER_END("grpc_call_destroy", 0); +} + +grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved) { + GRPC_API_TRACE("grpc_call_cancel(call=%p, reserved=%p)", 2, (call, reserved)); + GPR_ASSERT(!reserved); + return grpc_call_cancel_with_status(call, GRPC_STATUS_CANCELLED, "Cancelled", + NULL); +} + +grpc_call_error grpc_call_cancel_with_status(grpc_call *c, + grpc_status_code status, + const char *description, + void *reserved) { + grpc_call_error r; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GRPC_API_TRACE( + "grpc_call_cancel_with_status(" + "c=%p, status=%d, description=%s, reserved=%p)", + 4, (c, (int)status, description, reserved)); + GPR_ASSERT(reserved == NULL); + gpr_mu_lock(&c->mu); + r = cancel_with_status(&exec_ctx, c, status, description); + gpr_mu_unlock(&c->mu); + grpc_exec_ctx_finish(&exec_ctx); + return r; +} + +typedef struct cancel_closure { + grpc_closure closure; + grpc_call *call; + grpc_status_code status; +} cancel_closure; + +static void done_cancel(grpc_exec_ctx *exec_ctx, void *ccp, bool success) { + cancel_closure *cc = ccp; + GRPC_CALL_INTERNAL_UNREF(exec_ctx, cc->call, "cancel"); + gpr_free(cc); +} + +static void send_cancel(grpc_exec_ctx *exec_ctx, void *ccp, bool success) { + grpc_transport_stream_op op; + cancel_closure *cc = ccp; + memset(&op, 0, sizeof(op)); + op.cancel_with_status = cc->status; + /* reuse closure to catch completion */ + grpc_closure_init(&cc->closure, done_cancel, cc); + op.on_complete = &cc->closure; + execute_op(exec_ctx, cc->call, &op); +} + +static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c, + grpc_status_code status, + const char *description) { + grpc_mdstr *details = + description ? grpc_mdstr_from_string(description) : NULL; + cancel_closure *cc = gpr_malloc(sizeof(*cc)); + + GPR_ASSERT(status != GRPC_STATUS_OK); + + set_status_code(c, STATUS_FROM_API_OVERRIDE, (uint32_t)status); + set_status_details(c, STATUS_FROM_API_OVERRIDE, details); + + grpc_closure_init(&cc->closure, send_cancel, cc); + cc->call = c; + cc->status = status; + GRPC_CALL_INTERNAL_REF(c, "cancel"); + grpc_exec_ctx_enqueue(exec_ctx, &cc->closure, true, NULL); + + return GRPC_CALL_OK; +} + +static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call, + grpc_transport_stream_op *op) { + grpc_call_element *elem; + + GPR_TIMER_BEGIN("execute_op", 0); + elem = CALL_ELEM_FROM_CALL(call, 0); + op->context = call->context; + elem->filter->start_transport_stream_op(exec_ctx, elem, op); + GPR_TIMER_END("execute_op", 0); +} + +char *grpc_call_get_peer(grpc_call *call) { + grpc_call_element *elem = CALL_ELEM_FROM_CALL(call, 0); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + char *result; + GRPC_API_TRACE("grpc_call_get_peer(%p)", 1, (call)); + result = elem->filter->get_peer(&exec_ctx, elem); + if (result == NULL) { + result = grpc_channel_get_target(call->channel); + } + if (result == NULL) { + result = gpr_strdup("unknown"); + } + grpc_exec_ctx_finish(&exec_ctx); + return result; +} + +grpc_call *grpc_call_from_top_element(grpc_call_element *elem) { + return CALL_FROM_TOP_ELEM(elem); +} + +static void call_alarm(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + grpc_call *call = arg; + gpr_mu_lock(&call->mu); + call->have_alarm = 0; + if (success) { + cancel_with_status(exec_ctx, call, GRPC_STATUS_DEADLINE_EXCEEDED, + "Deadline Exceeded"); + } + gpr_mu_unlock(&call->mu); + GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "alarm"); +} + +static void set_deadline_alarm(grpc_exec_ctx *exec_ctx, grpc_call *call, + gpr_timespec deadline) { + if (call->have_alarm) { + gpr_log(GPR_ERROR, "Attempt to set deadline alarm twice"); + assert(0); + return; + } + GRPC_CALL_INTERNAL_REF(call, "alarm"); + call->have_alarm = 1; + call->send_deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); + grpc_timer_init(exec_ctx, &call->alarm, call->send_deadline, call_alarm, call, + gpr_now(GPR_CLOCK_MONOTONIC)); +} + +/* we offset status by a small amount when storing it into transport metadata + as metadata cannot store a 0 value (which is used as OK for grpc_status_codes + */ +#define STATUS_OFFSET 1 +static void destroy_status(void *ignored) {} + +static uint32_t decode_status(grpc_mdelem *md) { + uint32_t status; + void *user_data; + if (md == GRPC_MDELEM_GRPC_STATUS_0) return 0; + if (md == GRPC_MDELEM_GRPC_STATUS_1) return 1; + if (md == GRPC_MDELEM_GRPC_STATUS_2) return 2; + user_data = grpc_mdelem_get_user_data(md, destroy_status); + if (user_data != NULL) { + status = ((uint32_t)(intptr_t)user_data) - STATUS_OFFSET; + } else { + if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value), + GPR_SLICE_LENGTH(md->value->slice), + &status)) { + status = GRPC_STATUS_UNKNOWN; /* could not parse status code */ + } + grpc_mdelem_set_user_data(md, destroy_status, + (void *)(intptr_t)(status + STATUS_OFFSET)); + } + return status; +} + +static uint32_t decode_compression(grpc_mdelem *md) { + grpc_compression_algorithm algorithm = + grpc_compression_algorithm_from_mdstr(md->value); + if (algorithm == GRPC_COMPRESS_ALGORITHMS_COUNT) { + const char *md_c_str = grpc_mdstr_as_c_string(md->value); + gpr_log(GPR_ERROR, "Invalid compression algorithm: '%s'", md_c_str); + } + return algorithm; +} + +static grpc_mdelem *recv_common_filter(grpc_call *call, grpc_mdelem *elem) { + if (elem->key == GRPC_MDSTR_GRPC_STATUS) { + GPR_TIMER_BEGIN("status", 0); + set_status_code(call, STATUS_FROM_WIRE, decode_status(elem)); + GPR_TIMER_END("status", 0); + return NULL; + } else if (elem->key == GRPC_MDSTR_GRPC_MESSAGE) { + GPR_TIMER_BEGIN("status-details", 0); + set_status_details(call, STATUS_FROM_WIRE, GRPC_MDSTR_REF(elem->value)); + GPR_TIMER_END("status-details", 0); + return NULL; + } + return elem; +} + +static grpc_mdelem *publish_app_metadata(grpc_call *call, grpc_mdelem *elem, + int is_trailing) { + grpc_metadata_array *dest; + grpc_metadata *mdusr; + GPR_TIMER_BEGIN("publish_app_metadata", 0); + dest = call->buffered_metadata[is_trailing]; + if (dest->count == dest->capacity) { + dest->capacity = GPR_MAX(dest->capacity + 8, dest->capacity * 2); + dest->metadata = + gpr_realloc(dest->metadata, sizeof(grpc_metadata) * dest->capacity); + } + mdusr = &dest->metadata[dest->count++]; + mdusr->key = grpc_mdstr_as_c_string(elem->key); + mdusr->value = grpc_mdstr_as_c_string(elem->value); + mdusr->value_length = GPR_SLICE_LENGTH(elem->value->slice); + GPR_TIMER_END("publish_app_metadata", 0); + return elem; +} + +static grpc_mdelem *recv_initial_filter(void *callp, grpc_mdelem *elem) { + grpc_call *call = callp; + elem = recv_common_filter(call, elem); + if (elem == NULL) { + return NULL; + } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) { + GPR_TIMER_BEGIN("compression_algorithm", 0); + set_compression_algorithm(call, decode_compression(elem)); + GPR_TIMER_END("compression_algorithm", 0); + return NULL; + } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) { + GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0); + set_encodings_accepted_by_peer(call, elem); + GPR_TIMER_END("encodings_accepted_by_peer", 0); + return NULL; + } else { + return publish_app_metadata(call, elem, 0); + } +} + +static grpc_mdelem *recv_trailing_filter(void *callp, grpc_mdelem *elem) { + grpc_call *call = callp; + elem = recv_common_filter(call, elem); + if (elem == NULL) { + return NULL; + } else { + return publish_app_metadata(call, elem, 1); + } +} + +grpc_call_stack *grpc_call_get_call_stack(grpc_call *call) { + return CALL_STACK_FROM_CALL(call); +} + +/* + * BATCH API IMPLEMENTATION + */ + +static void set_status_value_directly(grpc_status_code status, void *dest) { + *(grpc_status_code *)dest = status; +} + +static void set_cancelled_value(grpc_status_code status, void *dest) { + *(int *)dest = (status != GRPC_STATUS_OK); +} + +static int are_write_flags_valid(uint32_t flags) { + /* check that only bits in GRPC_WRITE_(INTERNAL?)_USED_MASK are set */ + const uint32_t allowed_write_positions = + (GRPC_WRITE_USED_MASK | GRPC_WRITE_INTERNAL_USED_MASK); + const uint32_t invalid_positions = ~allowed_write_positions; + return !(flags & invalid_positions); +} + +static batch_control *allocate_batch_control(grpc_call *call) { + size_t i; + for (i = 0; i < MAX_CONCURRENT_BATCHES; i++) { + if ((call->used_batches & (1 << i)) == 0) { + call->used_batches = (uint8_t)(call->used_batches | (uint8_t)(1 << i)); + return &call->active_batches[i]; + } + } + return NULL; +} + +static void finish_batch_completion(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_cq_completion *storage) { + batch_control *bctl = user_data; + grpc_call *call = bctl->call; + gpr_mu_lock(&call->mu); + call->used_batches = (uint8_t)( + call->used_batches & ~(uint8_t)(1 << (bctl - call->active_batches))); + gpr_mu_unlock(&call->mu); + GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion"); +} + +static void post_batch_completion(grpc_exec_ctx *exec_ctx, + batch_control *bctl) { + grpc_call *call = bctl->call; + if (bctl->is_notify_tag_closure) { + grpc_exec_ctx_enqueue(exec_ctx, bctl->notify_tag, bctl->success, NULL); + gpr_mu_lock(&call->mu); + bctl->call->used_batches = + (uint8_t)(bctl->call->used_batches & + ~(uint8_t)(1 << (bctl - bctl->call->active_batches))); + gpr_mu_unlock(&call->mu); + GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion"); + } else { + grpc_cq_end_op(exec_ctx, bctl->call->cq, bctl->notify_tag, bctl->success, + finish_batch_completion, bctl, &bctl->cq_completion); + } +} + +static void continue_receiving_slices(grpc_exec_ctx *exec_ctx, + batch_control *bctl) { + grpc_call *call = bctl->call; + for (;;) { + size_t remaining = call->receiving_stream->length - + (*call->receiving_buffer)->data.raw.slice_buffer.length; + if (remaining == 0) { + call->receiving_message = 0; + grpc_byte_stream_destroy(exec_ctx, call->receiving_stream); + call->receiving_stream = NULL; + if (gpr_unref(&bctl->steps_to_complete)) { + post_batch_completion(exec_ctx, bctl); + } + return; + } + if (grpc_byte_stream_next(exec_ctx, call->receiving_stream, + &call->receiving_slice, remaining, + &call->receiving_slice_ready)) { + gpr_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, + call->receiving_slice); + } else { + return; + } + } +} + +static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, + bool success) { + batch_control *bctl = bctlp; + grpc_call *call = bctl->call; + + if (success) { + gpr_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, + call->receiving_slice); + continue_receiving_slices(exec_ctx, bctl); + } else { + grpc_byte_stream_destroy(exec_ctx, call->receiving_stream); + call->receiving_stream = NULL; + grpc_byte_buffer_destroy(*call->receiving_buffer); + *call->receiving_buffer = NULL; + if (gpr_unref(&bctl->steps_to_complete)) { + post_batch_completion(exec_ctx, bctl); + } + } +} + +static void process_data_after_md(grpc_exec_ctx *exec_ctx, batch_control *bctl, + bool success) { + grpc_call *call = bctl->call; + if (call->receiving_stream == NULL) { + *call->receiving_buffer = NULL; + call->receiving_message = 0; + if (gpr_unref(&bctl->steps_to_complete)) { + post_batch_completion(exec_ctx, bctl); + } + } else if (call->receiving_stream->length > + grpc_channel_get_max_message_length(call->channel)) { + cancel_with_status(exec_ctx, call, GRPC_STATUS_INTERNAL, + "Max message size exceeded"); + grpc_byte_stream_destroy(exec_ctx, call->receiving_stream); + call->receiving_stream = NULL; + *call->receiving_buffer = NULL; + call->receiving_message = 0; + if (gpr_unref(&bctl->steps_to_complete)) { + post_batch_completion(exec_ctx, bctl); + } + } else { + call->test_only_last_message_flags = call->receiving_stream->flags; + if ((call->receiving_stream->flags & GRPC_WRITE_INTERNAL_COMPRESS) && + (call->compression_algorithm > GRPC_COMPRESS_NONE)) { + *call->receiving_buffer = grpc_raw_compressed_byte_buffer_create( + NULL, 0, call->compression_algorithm); + } else { + *call->receiving_buffer = grpc_raw_byte_buffer_create(NULL, 0); + } + grpc_closure_init(&call->receiving_slice_ready, receiving_slice_ready, + bctl); + continue_receiving_slices(exec_ctx, bctl); + /* early out */ + return; + } +} + +static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp, + bool success) { + batch_control *bctl = bctlp; + grpc_call *call = bctl->call; + + gpr_mu_lock(&bctl->call->mu); + if (bctl->call->has_initial_md_been_received) { + gpr_mu_unlock(&bctl->call->mu); + process_data_after_md(exec_ctx, bctlp, success); + } else { + call->saved_receiving_stream_ready_ctx.bctlp = bctlp; + call->saved_receiving_stream_ready_ctx.success = success; + gpr_mu_unlock(&bctl->call->mu); + } +} + +static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx, + void *bctlp, bool success) { + batch_control *bctl = bctlp; + grpc_call *call = bctl->call; + + gpr_mu_lock(&call->mu); + + grpc_metadata_batch *md = + &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */]; + grpc_metadata_batch_filter(md, recv_initial_filter, call); + call->has_initial_md_been_received = true; + + if (gpr_time_cmp(md->deadline, gpr_inf_future(md->deadline.clock_type)) != + 0 && + !call->is_client) { + GPR_TIMER_BEGIN("set_deadline_alarm", 0); + set_deadline_alarm(exec_ctx, call, md->deadline); + GPR_TIMER_END("set_deadline_alarm", 0); + } + + if (call->saved_receiving_stream_ready_ctx.bctlp != NULL) { + grpc_closure *saved_rsr_closure = grpc_closure_create( + receiving_stream_ready, call->saved_receiving_stream_ready_ctx.bctlp); + grpc_exec_ctx_enqueue(exec_ctx, saved_rsr_closure, + call->saved_receiving_stream_ready_ctx.success, NULL); + call->saved_receiving_stream_ready_ctx.bctlp = NULL; + } + + gpr_mu_unlock(&call->mu); + + if (gpr_unref(&bctl->steps_to_complete)) { + post_batch_completion(exec_ctx, bctl); + } +} + +static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, bool success) { + batch_control *bctl = bctlp; + grpc_call *call = bctl->call; + grpc_call *child_call; + grpc_call *next_child_call; + + gpr_mu_lock(&call->mu); + if (bctl->send_initial_metadata) { + grpc_metadata_batch_destroy( + &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]); + } + if (bctl->send_message) { + call->sending_message = 0; + } + if (bctl->send_final_op) { + grpc_metadata_batch_destroy( + &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]); + } + if (bctl->recv_final_op) { + grpc_metadata_batch *md = + &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; + grpc_metadata_batch_filter(md, recv_trailing_filter, call); + + if (call->have_alarm) { + grpc_timer_cancel(exec_ctx, &call->alarm); + } + /* propagate cancellation to any interested children */ + child_call = call->first_child; + if (child_call != NULL) { + do { + next_child_call = child_call->sibling_next; + if (child_call->cancellation_is_inherited) { + GRPC_CALL_INTERNAL_REF(child_call, "propagate_cancel"); + grpc_call_cancel(child_call, NULL); + GRPC_CALL_INTERNAL_UNREF(exec_ctx, child_call, "propagate_cancel"); + } + child_call = next_child_call; + } while (child_call != call->first_child); + } + + if (call->is_client) { + get_final_status(call, set_status_value_directly, + call->final_op.client.status); + get_final_details(call, call->final_op.client.status_details, + call->final_op.client.status_details_capacity); + } else { + get_final_status(call, set_cancelled_value, + call->final_op.server.cancelled); + } + + success = 1; + } + bctl->success = success != 0; + gpr_mu_unlock(&call->mu); + if (gpr_unref(&bctl->steps_to_complete)) { + post_batch_completion(exec_ctx, bctl); + } +} + +static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, + grpc_call *call, const grpc_op *ops, + size_t nops, void *notify_tag, + int is_notify_tag_closure) { + grpc_transport_stream_op stream_op; + size_t i; + const grpc_op *op; + batch_control *bctl; + int num_completion_callbacks_needed = 1; + grpc_call_error error = GRPC_CALL_OK; + + GPR_TIMER_BEGIN("grpc_call_start_batch", 0); + + GRPC_CALL_LOG_BATCH(GPR_INFO, call, ops, nops, notify_tag); + + memset(&stream_op, 0, sizeof(stream_op)); + + /* TODO(ctiller): this feels like it could be made lock-free */ + gpr_mu_lock(&call->mu); + bctl = allocate_batch_control(call); + memset(bctl, 0, sizeof(*bctl)); + bctl->call = call; + bctl->notify_tag = notify_tag; + bctl->is_notify_tag_closure = (uint8_t)(is_notify_tag_closure != 0); + + if (nops == 0) { + GRPC_CALL_INTERNAL_REF(call, "completion"); + bctl->success = 1; + if (!is_notify_tag_closure) { + grpc_cq_begin_op(call->cq, notify_tag); + } + gpr_mu_unlock(&call->mu); + post_batch_completion(exec_ctx, bctl); + error = GRPC_CALL_OK; + goto done; + } + + /* rewrite batch ops into a transport op */ + for (i = 0; i < nops; i++) { + op = &ops[i]; + if (op->reserved != NULL) { + error = GRPC_CALL_ERROR; + goto done_with_error; + } + switch (op->op) { + case GRPC_OP_SEND_INITIAL_METADATA: + /* Flag validation: currently allow no flags */ + if (op->flags != 0) { + error = GRPC_CALL_ERROR_INVALID_FLAGS; + goto done_with_error; + } + if (call->sent_initial_metadata) { + error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; + goto done_with_error; + } + if (op->data.send_initial_metadata.count > INT_MAX) { + error = GRPC_CALL_ERROR_INVALID_METADATA; + goto done_with_error; + } + bctl->send_initial_metadata = 1; + call->sent_initial_metadata = 1; + if (!prepare_application_metadata( + call, (int)op->data.send_initial_metadata.count, + op->data.send_initial_metadata.metadata, 0, call->is_client)) { + error = GRPC_CALL_ERROR_INVALID_METADATA; + goto done_with_error; + } + /* TODO(ctiller): just make these the same variable? */ + call->metadata_batch[0][0].deadline = call->send_deadline; + stream_op.send_initial_metadata = + &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]; + break; + case GRPC_OP_SEND_MESSAGE: + if (!are_write_flags_valid(op->flags)) { + error = GRPC_CALL_ERROR_INVALID_FLAGS; + goto done_with_error; + } + if (op->data.send_message == NULL) { + error = GRPC_CALL_ERROR_INVALID_MESSAGE; + goto done_with_error; + } + if (call->sending_message) { + error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; + goto done_with_error; + } + bctl->send_message = 1; + call->sending_message = 1; + grpc_slice_buffer_stream_init( + &call->sending_stream, + &op->data.send_message->data.raw.slice_buffer, op->flags); + stream_op.send_message = &call->sending_stream.base; + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + /* Flag validation: currently allow no flags */ + if (op->flags != 0) { + error = GRPC_CALL_ERROR_INVALID_FLAGS; + goto done_with_error; + } + if (!call->is_client) { + error = GRPC_CALL_ERROR_NOT_ON_SERVER; + goto done_with_error; + } + if (call->sent_final_op) { + error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; + goto done_with_error; + } + bctl->send_final_op = 1; + call->sent_final_op = 1; + stream_op.send_trailing_metadata = + &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]; + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + /* Flag validation: currently allow no flags */ + if (op->flags != 0) { + error = GRPC_CALL_ERROR_INVALID_FLAGS; + goto done_with_error; + } + if (call->is_client) { + error = GRPC_CALL_ERROR_NOT_ON_CLIENT; + goto done_with_error; + } + if (call->sent_final_op) { + error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; + goto done_with_error; + } + if (op->data.send_status_from_server.trailing_metadata_count > + INT_MAX) { + error = GRPC_CALL_ERROR_INVALID_METADATA; + goto done_with_error; + } + bctl->send_final_op = 1; + call->sent_final_op = 1; + call->send_extra_metadata_count = 1; + call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem( + call->channel, op->data.send_status_from_server.status); + if (op->data.send_status_from_server.status_details != NULL) { + call->send_extra_metadata[1].md = grpc_mdelem_from_metadata_strings( + GRPC_MDSTR_GRPC_MESSAGE, + grpc_mdstr_from_string( + op->data.send_status_from_server.status_details)); + call->send_extra_metadata_count++; + set_status_details( + call, STATUS_FROM_API_OVERRIDE, + GRPC_MDSTR_REF(call->send_extra_metadata[1].md->value)); + } + set_status_code(call, STATUS_FROM_API_OVERRIDE, + (uint32_t)op->data.send_status_from_server.status); + if (!prepare_application_metadata( + call, + (int)op->data.send_status_from_server.trailing_metadata_count, + op->data.send_status_from_server.trailing_metadata, 1, 1)) { + error = GRPC_CALL_ERROR_INVALID_METADATA; + goto done_with_error; + } + stream_op.send_trailing_metadata = + &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]; + break; + case GRPC_OP_RECV_INITIAL_METADATA: + /* Flag validation: currently allow no flags */ + if (op->flags != 0) { + error = GRPC_CALL_ERROR_INVALID_FLAGS; + goto done_with_error; + } + if (call->received_initial_metadata) { + error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; + goto done_with_error; + } + call->received_initial_metadata = 1; + call->buffered_metadata[0] = op->data.recv_initial_metadata; + grpc_closure_init(&call->receiving_initial_metadata_ready, + receiving_initial_metadata_ready, bctl); + bctl->recv_initial_metadata = 1; + stream_op.recv_initial_metadata = + &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */]; + stream_op.recv_initial_metadata_ready = + &call->receiving_initial_metadata_ready; + num_completion_callbacks_needed++; + break; + case GRPC_OP_RECV_MESSAGE: + /* Flag validation: currently allow no flags */ + if (op->flags != 0) { + error = GRPC_CALL_ERROR_INVALID_FLAGS; + goto done_with_error; + } + if (call->receiving_message) { + error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; + goto done_with_error; + } + call->receiving_message = 1; + bctl->recv_message = 1; + call->receiving_buffer = op->data.recv_message; + stream_op.recv_message = &call->receiving_stream; + grpc_closure_init(&call->receiving_stream_ready, receiving_stream_ready, + bctl); + stream_op.recv_message_ready = &call->receiving_stream_ready; + num_completion_callbacks_needed++; + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + /* Flag validation: currently allow no flags */ + if (op->flags != 0) { + error = GRPC_CALL_ERROR_INVALID_FLAGS; + goto done_with_error; + } + if (!call->is_client) { + error = GRPC_CALL_ERROR_NOT_ON_SERVER; + goto done_with_error; + } + if (call->received_final_op) { + error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; + goto done_with_error; + } + call->received_final_op = 1; + call->buffered_metadata[1] = + op->data.recv_status_on_client.trailing_metadata; + call->final_op.client.status = op->data.recv_status_on_client.status; + call->final_op.client.status_details = + op->data.recv_status_on_client.status_details; + call->final_op.client.status_details_capacity = + op->data.recv_status_on_client.status_details_capacity; + bctl->recv_final_op = 1; + stream_op.recv_trailing_metadata = + &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + /* Flag validation: currently allow no flags */ + if (op->flags != 0) { + error = GRPC_CALL_ERROR_INVALID_FLAGS; + goto done_with_error; + } + if (call->is_client) { + error = GRPC_CALL_ERROR_NOT_ON_CLIENT; + goto done_with_error; + } + if (call->received_final_op) { + error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; + goto done_with_error; + } + call->received_final_op = 1; + call->final_op.server.cancelled = + op->data.recv_close_on_server.cancelled; + bctl->recv_final_op = 1; + stream_op.recv_trailing_metadata = + &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; + break; + } + } + + GRPC_CALL_INTERNAL_REF(call, "completion"); + if (!is_notify_tag_closure) { + grpc_cq_begin_op(call->cq, notify_tag); + } + gpr_ref_init(&bctl->steps_to_complete, num_completion_callbacks_needed); + + stream_op.context = call->context; + grpc_closure_init(&bctl->finish_batch, finish_batch, bctl); + stream_op.on_complete = &bctl->finish_batch; + gpr_mu_unlock(&call->mu); + + execute_op(exec_ctx, call, &stream_op); + +done: + GPR_TIMER_END("grpc_call_start_batch", 0); + return error; + +done_with_error: + /* reverse any mutations that occured */ + if (bctl->send_initial_metadata) { + call->sent_initial_metadata = 0; + grpc_metadata_batch_clear(&call->metadata_batch[0][0]); + } + if (bctl->send_message) { + call->sending_message = 0; + grpc_byte_stream_destroy(exec_ctx, &call->sending_stream.base); + } + if (bctl->send_final_op) { + call->sent_final_op = 0; + grpc_metadata_batch_clear(&call->metadata_batch[0][1]); + } + if (bctl->recv_initial_metadata) { + call->received_initial_metadata = 0; + } + if (bctl->recv_message) { + call->receiving_message = 0; + } + if (bctl->recv_final_op) { + call->received_final_op = 0; + } + gpr_mu_unlock(&call->mu); + goto done; +} + +grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops, + size_t nops, void *tag, void *reserved) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_call_error err; + + GRPC_API_TRACE( + "grpc_call_start_batch(call=%p, ops=%p, nops=%lu, tag=%p, reserved=%p)", + 5, (call, ops, (unsigned long)nops, tag, reserved)); + + if (reserved != NULL) { + err = GRPC_CALL_ERROR; + } else { + err = call_start_batch(&exec_ctx, call, ops, nops, tag, 0); + } + + grpc_exec_ctx_finish(&exec_ctx); + return err; +} + +grpc_call_error grpc_call_start_batch_and_execute(grpc_exec_ctx *exec_ctx, + grpc_call *call, + const grpc_op *ops, + size_t nops, + grpc_closure *closure) { + return call_start_batch(exec_ctx, call, ops, nops, closure, 1); +} + +void grpc_call_context_set(grpc_call *call, grpc_context_index elem, + void *value, void (*destroy)(void *value)) { + if (call->context[elem].destroy) { + call->context[elem].destroy(call->context[elem].value); + } + call->context[elem].value = value; + call->context[elem].destroy = destroy; +} + +void *grpc_call_context_get(grpc_call *call, grpc_context_index elem) { + return call->context[elem].value; +} + +uint8_t grpc_call_is_client(grpc_call *call) { return call->is_client; } + +grpc_compression_algorithm grpc_call_compression_for_level( + grpc_call *call, grpc_compression_level level) { + gpr_mu_lock(&call->mu); + const uint32_t accepted_encodings = call->encodings_accepted_by_peer; + gpr_mu_unlock(&call->mu); + return grpc_compression_algorithm_for_level(level, accepted_encodings); +} diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h new file mode 100644 index 0000000000..d2edf03d45 --- /dev/null +++ b/src/core/lib/surface/call.h @@ -0,0 +1,116 @@ +/* + * + * Copyright 2015-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_SURFACE_CALL_H +#define GRPC_CORE_SURFACE_CALL_H + +#include "src/core/channel/channel_stack.h" +#include "src/core/channel/context.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/surface_trace.h" + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*grpc_ioreq_completion_func)(grpc_exec_ctx *exec_ctx, + grpc_call *call, int success, + void *user_data); + +grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call, + uint32_t propagation_mask, + grpc_completion_queue *cq, + const void *server_transport_data, + grpc_mdelem **add_initial_metadata, + size_t add_initial_metadata_count, + gpr_timespec send_deadline); + +void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call, + grpc_completion_queue *cq); + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +void grpc_call_internal_ref(grpc_call *call, const char *reason); +void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *call, + const char *reason); +#define GRPC_CALL_INTERNAL_REF(call, reason) \ + grpc_call_internal_ref(call, reason) +#define GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, reason) \ + grpc_call_internal_unref(exec_ctx, call, reason) +#else +void grpc_call_internal_ref(grpc_call *call); +void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *call); +#define GRPC_CALL_INTERNAL_REF(call, reason) grpc_call_internal_ref(call) +#define GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, reason) \ + grpc_call_internal_unref(exec_ctx, call) +#endif + +grpc_call_stack *grpc_call_get_call_stack(grpc_call *call); + +grpc_call_error grpc_call_start_batch_and_execute(grpc_exec_ctx *exec_ctx, + grpc_call *call, + const grpc_op *ops, + size_t nops, + grpc_closure *closure); + +/* Given the top call_element, get the call object. */ +grpc_call *grpc_call_from_top_element(grpc_call_element *surface_element); + +void grpc_call_log_batch(char *file, int line, gpr_log_severity severity, + grpc_call *call, const grpc_op *ops, size_t nops, + void *tag); + +/* Set a context pointer. + No thread safety guarantees are made wrt this value. */ +void grpc_call_context_set(grpc_call *call, grpc_context_index elem, + void *value, void (*destroy)(void *value)); +/* Get a context pointer. */ +void *grpc_call_context_get(grpc_call *call, grpc_context_index elem); + +#define GRPC_CALL_LOG_BATCH(sev, call, ops, nops, tag) \ + if (grpc_api_trace) grpc_call_log_batch(sev, call, ops, nops, tag) + +uint8_t grpc_call_is_client(grpc_call *call); + +/* Return an appropriate compression algorithm for the requested compression \a + * level in the context of \a call. */ +grpc_compression_algorithm grpc_call_compression_for_level( + grpc_call *call, grpc_compression_level level); + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_SURFACE_CALL_H */ diff --git a/src/core/lib/surface/call_details.c b/src/core/lib/surface/call_details.c new file mode 100644 index 0000000000..60f0029819 --- /dev/null +++ b/src/core/lib/surface/call_details.c @@ -0,0 +1,50 @@ +/* + * + * Copyright 2015, 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 +#include + +#include + +#include "src/core/surface/api_trace.h" + +void grpc_call_details_init(grpc_call_details* cd) { + GRPC_API_TRACE("grpc_call_details_init(cd=%p)", 1, (cd)); + memset(cd, 0, sizeof(*cd)); +} + +void grpc_call_details_destroy(grpc_call_details* cd) { + GRPC_API_TRACE("grpc_call_details_destroy(cd=%p)", 1, (cd)); + gpr_free(cd->method); + gpr_free(cd->host); +} diff --git a/src/core/lib/surface/call_log_batch.c b/src/core/lib/surface/call_log_batch.c new file mode 100644 index 0000000000..044211616c --- /dev/null +++ b/src/core/lib/surface/call_log_batch.c @@ -0,0 +1,118 @@ +/* + * + * Copyright 2015-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/surface/call.h" + +#include +#include +#include "src/core/support/string.h" + +static void add_metadata(gpr_strvec *b, const grpc_metadata *md, size_t count) { + size_t i; + for (i = 0; i < count; i++) { + gpr_strvec_add(b, gpr_strdup("\nkey=")); + gpr_strvec_add(b, gpr_strdup(md[i].key)); + + gpr_strvec_add(b, gpr_strdup(" value=")); + gpr_strvec_add(b, gpr_dump(md[i].value, md[i].value_length, + GPR_DUMP_HEX | GPR_DUMP_ASCII)); + } +} + +char *grpc_op_string(const grpc_op *op) { + char *tmp; + char *out; + + gpr_strvec b; + gpr_strvec_init(&b); + + switch (op->op) { + case GRPC_OP_SEND_INITIAL_METADATA: + gpr_strvec_add(&b, gpr_strdup("SEND_INITIAL_METADATA")); + add_metadata(&b, op->data.send_initial_metadata.metadata, + op->data.send_initial_metadata.count); + break; + case GRPC_OP_SEND_MESSAGE: + gpr_asprintf(&tmp, "SEND_MESSAGE ptr=%p", op->data.send_message); + gpr_strvec_add(&b, tmp); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + gpr_strvec_add(&b, gpr_strdup("SEND_CLOSE_FROM_CLIENT")); + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + gpr_asprintf(&tmp, "SEND_STATUS_FROM_SERVER status=%d details=%s", + op->data.send_status_from_server.status, + op->data.send_status_from_server.status_details); + gpr_strvec_add(&b, tmp); + add_metadata(&b, op->data.send_status_from_server.trailing_metadata, + op->data.send_status_from_server.trailing_metadata_count); + break; + case GRPC_OP_RECV_INITIAL_METADATA: + gpr_asprintf(&tmp, "RECV_INITIAL_METADATA ptr=%p", + op->data.recv_initial_metadata); + gpr_strvec_add(&b, tmp); + break; + case GRPC_OP_RECV_MESSAGE: + gpr_asprintf(&tmp, "RECV_MESSAGE ptr=%p", op->data.recv_message); + gpr_strvec_add(&b, tmp); + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + gpr_asprintf(&tmp, + "RECV_STATUS_ON_CLIENT metadata=%p status=%p details=%p", + op->data.recv_status_on_client.trailing_metadata, + op->data.recv_status_on_client.status, + op->data.recv_status_on_client.status_details); + gpr_strvec_add(&b, tmp); + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + gpr_asprintf(&tmp, "RECV_CLOSE_ON_SERVER cancelled=%p", + op->data.recv_close_on_server.cancelled); + gpr_strvec_add(&b, tmp); + } + out = gpr_strvec_flatten(&b, NULL); + gpr_strvec_destroy(&b); + + return out; +} + +void grpc_call_log_batch(char *file, int line, gpr_log_severity severity, + grpc_call *call, const grpc_op *ops, size_t nops, + void *tag) { + char *tmp; + size_t i; + for (i = 0; i < nops; i++) { + tmp = grpc_op_string(&ops[i]); + gpr_log(file, line, severity, "ops[%d]: %s", i, tmp); + gpr_free(tmp); + } +} diff --git a/src/core/lib/surface/call_test_only.h b/src/core/lib/surface/call_test_only.h new file mode 100644 index 0000000000..fdc43a383b --- /dev/null +++ b/src/core/lib/surface/call_test_only.h @@ -0,0 +1,64 @@ +/* + * + * Copyright 2015-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_SURFACE_CALL_TEST_ONLY_H +#define GRPC_CORE_SURFACE_CALL_TEST_ONLY_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Return the compression algorithm from \a call. + * + * \warning This function should \b only be used in test code. */ +grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm( + grpc_call *call); + +/** Return the message flags from \a call. + * + * \warning This function should \b only be used in test code. */ +uint32_t grpc_call_test_only_get_message_flags(grpc_call *call); + +/** Returns a bitset for the encodings (compression algorithms) supported by \a + * call's peer. + * + * To be indexed by grpc_compression_algorithm enum values. */ +uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call); + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_SURFACE_CALL_TEST_ONLY_H */ diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c new file mode 100644 index 0000000000..0010b64c7d --- /dev/null +++ b/src/core/lib/surface/channel.c @@ -0,0 +1,324 @@ +/* + * + * Copyright 2015-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/surface/channel.h" + +#include +#include + +#include +#include +#include + +#include "src/core/client_config/resolver_registry.h" +#include "src/core/iomgr/iomgr.h" +#include "src/core/support/string.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/call.h" +#include "src/core/surface/channel_init.h" +#include "src/core/surface/init.h" +#include "src/core/transport/static_metadata.h" + +/** Cache grpc-status: X mdelems for X = 0..NUM_CACHED_STATUS_ELEMS. + * Avoids needing to take a metadata context lock for sending status + * if the status code is <= NUM_CACHED_STATUS_ELEMS. + * Sized to allow the most commonly used codes to fit in + * (OK, Cancelled, Unknown). */ +#define NUM_CACHED_STATUS_ELEMS 3 + +typedef struct registered_call { + grpc_mdelem *path; + grpc_mdelem *authority; + struct registered_call *next; +} registered_call; + +struct grpc_channel { + int is_client; + uint32_t max_message_length; + grpc_mdelem *default_authority; + + gpr_mu registered_call_mu; + registered_call *registered_calls; + char *target; +}; + +#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c) + 1)) +#define CHANNEL_FROM_CHANNEL_STACK(channel_stack) \ + (((grpc_channel *)(channel_stack)) - 1) +#define CHANNEL_FROM_TOP_ELEM(top_elem) \ + CHANNEL_FROM_CHANNEL_STACK(grpc_channel_stack_from_top_element(top_elem)) + +/* the protobuf library will (by default) start warning at 100megs */ +#define DEFAULT_MAX_MESSAGE_LENGTH (100 * 1024 * 1024) + +static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg, bool success); + +grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, + const grpc_channel_args *args, + grpc_channel_stack_type channel_stack_type, + grpc_transport *optional_transport) { + bool is_client = grpc_channel_stack_type_is_client(channel_stack_type); + + grpc_channel *channel = grpc_channel_init_create_stack( + exec_ctx, channel_stack_type, sizeof(grpc_channel), args, 1, + destroy_channel, NULL, optional_transport); + + memset(channel, 0, sizeof(*channel)); + channel->target = gpr_strdup(target); + channel->is_client = is_client; + gpr_mu_init(&channel->registered_call_mu); + channel->registered_calls = NULL; + + channel->max_message_length = DEFAULT_MAX_MESSAGE_LENGTH; + if (args) { + for (size_t i = 0; i < args->num_args; i++) { + if (0 == strcmp(args->args[i].key, GRPC_ARG_MAX_MESSAGE_LENGTH)) { + if (args->args[i].type != GRPC_ARG_INTEGER) { + gpr_log(GPR_ERROR, "%s ignored: it must be an integer", + GRPC_ARG_MAX_MESSAGE_LENGTH); + } else if (args->args[i].value.integer < 0) { + gpr_log(GPR_ERROR, "%s ignored: it must be >= 0", + GRPC_ARG_MAX_MESSAGE_LENGTH); + } else { + channel->max_message_length = (uint32_t)args->args[i].value.integer; + } + } else if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) { + if (args->args[i].type != GRPC_ARG_STRING) { + gpr_log(GPR_ERROR, "%s ignored: it must be a string", + GRPC_ARG_DEFAULT_AUTHORITY); + } else { + if (channel->default_authority) { + /* setting this takes precedence over anything else */ + GRPC_MDELEM_UNREF(channel->default_authority); + } + channel->default_authority = grpc_mdelem_from_strings( + ":authority", args->args[i].value.string); + } + } else if (0 == + strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) { + if (args->args[i].type != GRPC_ARG_STRING) { + gpr_log(GPR_ERROR, "%s ignored: it must be a string", + GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); + } else { + if (channel->default_authority) { + /* other ways of setting this (notably ssl) take precedence */ + gpr_log(GPR_ERROR, + "%s ignored: default host already set some other way", + GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); + } else { + channel->default_authority = grpc_mdelem_from_strings( + ":authority", args->args[i].value.string); + } + } + } + } + } + + if (channel->is_client && channel->default_authority == NULL && + target != NULL) { + char *default_authority = grpc_get_default_authority(target); + if (default_authority) { + channel->default_authority = + grpc_mdelem_from_strings(":authority", default_authority); + } + gpr_free(default_authority); + } + + return channel; +} + +char *grpc_channel_get_target(grpc_channel *channel) { + GRPC_API_TRACE("grpc_channel_get_target(channel=%p)", 1, (channel)); + return gpr_strdup(channel->target); +} + +static grpc_call *grpc_channel_create_call_internal( + grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, + grpc_completion_queue *cq, grpc_mdelem *path_mdelem, + grpc_mdelem *authority_mdelem, gpr_timespec deadline) { + grpc_mdelem *send_metadata[2]; + size_t num_metadata = 0; + + GPR_ASSERT(channel->is_client); + + send_metadata[num_metadata++] = path_mdelem; + if (authority_mdelem != NULL) { + send_metadata[num_metadata++] = authority_mdelem; + } else if (channel->default_authority != NULL) { + send_metadata[num_metadata++] = GRPC_MDELEM_REF(channel->default_authority); + } + + return grpc_call_create(channel, parent_call, propagation_mask, cq, NULL, + send_metadata, num_metadata, deadline); +} + +grpc_call *grpc_channel_create_call(grpc_channel *channel, + grpc_call *parent_call, + uint32_t propagation_mask, + grpc_completion_queue *cq, + const char *method, const char *host, + gpr_timespec deadline, void *reserved) { + GRPC_API_TRACE( + "grpc_channel_create_call(" + "channel=%p, parent_call=%p, propagation_mask=%x, cq=%p, method=%s, " + "host=%s, " + "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " + "reserved=%p)", + 10, (channel, parent_call, (unsigned)propagation_mask, cq, method, host, + (long long)deadline.tv_sec, (int)deadline.tv_nsec, + (int)deadline.clock_type, reserved)); + GPR_ASSERT(!reserved); + return grpc_channel_create_call_internal( + channel, parent_call, propagation_mask, cq, + grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH, + grpc_mdstr_from_string(method)), + host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY, + grpc_mdstr_from_string(host)) + : NULL, + deadline); +} + +void *grpc_channel_register_call(grpc_channel *channel, const char *method, + const char *host, void *reserved) { + registered_call *rc = gpr_malloc(sizeof(registered_call)); + GRPC_API_TRACE( + "grpc_channel_register_call(channel=%p, method=%s, host=%s, reserved=%p)", + 4, (channel, method, host, reserved)); + GPR_ASSERT(!reserved); + rc->path = grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH, + grpc_mdstr_from_string(method)); + rc->authority = host ? grpc_mdelem_from_metadata_strings( + GRPC_MDSTR_AUTHORITY, grpc_mdstr_from_string(host)) + : NULL; + gpr_mu_lock(&channel->registered_call_mu); + rc->next = channel->registered_calls; + channel->registered_calls = rc; + gpr_mu_unlock(&channel->registered_call_mu); + return rc; +} + +grpc_call *grpc_channel_create_registered_call( + grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, + grpc_completion_queue *completion_queue, void *registered_call_handle, + gpr_timespec deadline, void *reserved) { + registered_call *rc = registered_call_handle; + GRPC_API_TRACE( + "grpc_channel_create_registered_call(" + "channel=%p, parent_call=%p, propagation_mask=%x, completion_queue=%p, " + "registered_call_handle=%p, " + "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " + "reserved=%p)", + 9, (channel, parent_call, (unsigned)propagation_mask, completion_queue, + registered_call_handle, (long long)deadline.tv_sec, + (int)deadline.tv_nsec, (int)deadline.clock_type, reserved)); + GPR_ASSERT(!reserved); + return grpc_channel_create_call_internal( + channel, parent_call, propagation_mask, completion_queue, + GRPC_MDELEM_REF(rc->path), + rc->authority ? GRPC_MDELEM_REF(rc->authority) : NULL, deadline); +} + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +#define REF_REASON reason +#define REF_ARG , const char *reason +#else +#define REF_REASON "" +#define REF_ARG +#endif +void grpc_channel_internal_ref(grpc_channel *c REF_ARG) { + GRPC_CHANNEL_STACK_REF(CHANNEL_STACK_FROM_CHANNEL(c), REF_REASON); +} + +void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, + grpc_channel *c REF_ARG) { + GRPC_CHANNEL_STACK_UNREF(exec_ctx, CHANNEL_STACK_FROM_CHANNEL(c), REF_REASON); +} + +static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg, + bool iomgr_success) { + grpc_channel *channel = arg; + grpc_channel_stack_destroy(exec_ctx, CHANNEL_STACK_FROM_CHANNEL(channel)); + while (channel->registered_calls) { + registered_call *rc = channel->registered_calls; + channel->registered_calls = rc->next; + GRPC_MDELEM_UNREF(rc->path); + if (rc->authority) { + GRPC_MDELEM_UNREF(rc->authority); + } + gpr_free(rc); + } + if (channel->default_authority != NULL) { + GRPC_MDELEM_UNREF(channel->default_authority); + } + gpr_mu_destroy(&channel->registered_call_mu); + gpr_free(channel->target); + gpr_free(channel); +} + +void grpc_channel_destroy(grpc_channel *channel) { + grpc_transport_op op; + grpc_channel_element *elem; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GRPC_API_TRACE("grpc_channel_destroy(channel=%p)", 1, (channel)); + memset(&op, 0, sizeof(op)); + op.disconnect = 1; + elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CHANNEL(channel), 0); + elem->filter->start_transport_op(&exec_ctx, elem, &op); + + GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, channel, "channel"); + + grpc_exec_ctx_finish(&exec_ctx); +} + +grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel) { + return CHANNEL_STACK_FROM_CHANNEL(channel); +} + +grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) { + char tmp[GPR_LTOA_MIN_BUFSIZE]; + switch (i) { + case 0: + return GRPC_MDELEM_GRPC_STATUS_0; + case 1: + return GRPC_MDELEM_GRPC_STATUS_1; + case 2: + return GRPC_MDELEM_GRPC_STATUS_2; + } + gpr_ltoa(i, tmp); + return grpc_mdelem_from_metadata_strings(GRPC_MDSTR_GRPC_STATUS, + grpc_mdstr_from_string(tmp)); +} + +uint32_t grpc_channel_get_max_message_length(grpc_channel *channel) { + return channel->max_message_length; +} diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h new file mode 100644 index 0000000000..6a803ffe23 --- /dev/null +++ b/src/core/lib/surface/channel.h @@ -0,0 +1,75 @@ +/* + * + * Copyright 2015-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_SURFACE_CHANNEL_H +#define GRPC_CORE_SURFACE_CHANNEL_H + +#include "src/core/channel/channel_stack.h" +#include "src/core/client_config/subchannel_factory.h" +#include "src/core/surface/channel_stack_type.h" + +grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, + const grpc_channel_args *args, + grpc_channel_stack_type channel_stack_type, + grpc_transport *optional_transport); + +/** Get a (borrowed) pointer to this channels underlying channel stack */ +grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel); + +/** Get a grpc_mdelem of grpc-status: X where X is the numeric value of + status_code. + + The returned elem is owned by the caller. */ +grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, + int status_code); +uint32_t grpc_channel_get_max_message_length(grpc_channel *channel); + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +void grpc_channel_internal_ref(grpc_channel *channel, const char *reason); +void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, grpc_channel *channel, + const char *reason); +#define GRPC_CHANNEL_INTERNAL_REF(channel, reason) \ + grpc_channel_internal_ref(channel, reason) +#define GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, reason) \ + grpc_channel_internal_unref(exec_ctx, channel, reason) +#else +void grpc_channel_internal_ref(grpc_channel *channel); +void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, + grpc_channel *channel); +#define GRPC_CHANNEL_INTERNAL_REF(channel, reason) \ + grpc_channel_internal_ref(channel) +#define GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, reason) \ + grpc_channel_internal_unref(exec_ctx, channel) +#endif + +#endif /* GRPC_CORE_SURFACE_CHANNEL_H */ diff --git a/src/core/lib/surface/channel_connectivity.c b/src/core/lib/surface/channel_connectivity.c new file mode 100644 index 0000000000..18267939ed --- /dev/null +++ b/src/core/lib/surface/channel_connectivity.c @@ -0,0 +1,207 @@ +/* + * + * Copyright 2015-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/surface/channel.h" + +#include +#include + +#include "src/core/channel/client_channel.h" +#include "src/core/iomgr/timer.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/completion_queue.h" + +grpc_connectivity_state grpc_channel_check_connectivity_state( + grpc_channel *channel, int try_to_connect) { + /* forward through to the underlying client channel */ + grpc_channel_element *client_channel_elem = + grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_connectivity_state state; + GRPC_API_TRACE( + "grpc_channel_check_connectivity_state(channel=%p, try_to_connect=%d)", 2, + (channel, try_to_connect)); + if (client_channel_elem->filter == &grpc_client_channel_filter) { + state = grpc_client_channel_check_connectivity_state( + &exec_ctx, client_channel_elem, try_to_connect); + grpc_exec_ctx_finish(&exec_ctx); + return state; + } + gpr_log(GPR_ERROR, + "grpc_channel_check_connectivity_state called on something that is " + "not a (u)client channel, but '%s'", + client_channel_elem->filter->name); + grpc_exec_ctx_finish(&exec_ctx); + return GRPC_CHANNEL_FATAL_FAILURE; +} + +typedef enum { + WAITING, + CALLING_BACK, + CALLING_BACK_AND_FINISHED, + CALLED_BACK +} callback_phase; + +typedef struct { + gpr_mu mu; + callback_phase phase; + int success; + grpc_closure on_complete; + grpc_timer alarm; + grpc_connectivity_state state; + grpc_completion_queue *cq; + grpc_cq_completion completion_storage; + grpc_channel *channel; + void *tag; +} state_watcher; + +static void delete_state_watcher(grpc_exec_ctx *exec_ctx, state_watcher *w) { + grpc_channel_element *client_channel_elem = grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(w->channel)); + if (client_channel_elem->filter == &grpc_client_channel_filter) { + GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, w->channel, + "watch_channel_connectivity"); + } else { + abort(); + } + gpr_mu_destroy(&w->mu); + gpr_free(w); +} + +static void finished_completion(grpc_exec_ctx *exec_ctx, void *pw, + grpc_cq_completion *ignored) { + int delete = 0; + state_watcher *w = pw; + gpr_mu_lock(&w->mu); + switch (w->phase) { + case WAITING: + case CALLED_BACK: + GPR_UNREACHABLE_CODE(return ); + case CALLING_BACK: + w->phase = CALLED_BACK; + break; + case CALLING_BACK_AND_FINISHED: + delete = 1; + break; + } + gpr_mu_unlock(&w->mu); + + if (delete) { + delete_state_watcher(exec_ctx, w); + } +} + +static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w, + int due_to_completion) { + int delete = 0; + + if (due_to_completion) { + grpc_timer_cancel(exec_ctx, &w->alarm); + } + + gpr_mu_lock(&w->mu); + if (due_to_completion) { + w->success = 1; + } + switch (w->phase) { + case WAITING: + w->phase = CALLING_BACK; + grpc_cq_end_op(exec_ctx, w->cq, w->tag, w->success, finished_completion, + w, &w->completion_storage); + break; + case CALLING_BACK: + w->phase = CALLING_BACK_AND_FINISHED; + break; + case CALLING_BACK_AND_FINISHED: + GPR_UNREACHABLE_CODE(return ); + case CALLED_BACK: + delete = 1; + break; + } + gpr_mu_unlock(&w->mu); + + if (delete) { + delete_state_watcher(exec_ctx, w); + } +} + +static void watch_complete(grpc_exec_ctx *exec_ctx, void *pw, bool success) { + partly_done(exec_ctx, pw, 1); +} + +static void timeout_complete(grpc_exec_ctx *exec_ctx, void *pw, bool success) { + partly_done(exec_ctx, pw, 0); +} + +void grpc_channel_watch_connectivity_state( + grpc_channel *channel, grpc_connectivity_state last_observed_state, + gpr_timespec deadline, grpc_completion_queue *cq, void *tag) { + grpc_channel_element *client_channel_elem = + grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + state_watcher *w = gpr_malloc(sizeof(*w)); + + GRPC_API_TRACE( + "grpc_channel_watch_connectivity_state(" + "channel=%p, last_observed_state=%d, " + "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " + "cq=%p, tag=%p)", + 7, (channel, (int)last_observed_state, (long long)deadline.tv_sec, + (int)deadline.tv_nsec, (int)deadline.clock_type, cq, tag)); + + grpc_cq_begin_op(cq, tag); + + gpr_mu_init(&w->mu); + grpc_closure_init(&w->on_complete, watch_complete, w); + w->phase = WAITING; + w->state = last_observed_state; + w->success = 0; + w->cq = cq; + w->tag = tag; + w->channel = channel; + + grpc_timer_init(&exec_ctx, &w->alarm, + gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC), + timeout_complete, w, gpr_now(GPR_CLOCK_MONOTONIC)); + + if (client_channel_elem->filter == &grpc_client_channel_filter) { + GRPC_CHANNEL_INTERNAL_REF(channel, "watch_channel_connectivity"); + grpc_client_channel_watch_connectivity_state(&exec_ctx, client_channel_elem, + grpc_cq_pollset(cq), &w->state, + &w->on_complete); + } else { + abort(); + } + + grpc_exec_ctx_finish(&exec_ctx); +} diff --git a/src/core/lib/surface/channel_create.c b/src/core/lib/surface/channel_create.c new file mode 100644 index 0000000000..123447c8ed --- /dev/null +++ b/src/core/lib/surface/channel_create.c @@ -0,0 +1,223 @@ +/* + * + * Copyright 2015-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 + +#include +#include + +#include +#include +#include + +#include "src/core/census/grpc_filter.h" +#include "src/core/channel/channel_args.h" +#include "src/core/channel/client_channel.h" +#include "src/core/channel/compress_filter.h" +#include "src/core/channel/http_client_filter.h" +#include "src/core/client_config/resolver_registry.h" +#include "src/core/iomgr/tcp_client.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/channel.h" +#include "src/core/transport/chttp2_transport.h" + +typedef struct { + grpc_connector base; + gpr_refcount refs; + + grpc_closure *notify; + grpc_connect_in_args args; + grpc_connect_out_args *result; + grpc_closure initial_string_sent; + gpr_slice_buffer initial_string_buffer; + + grpc_endpoint *tcp; + + grpc_closure connected; +} connector; + +static void connector_ref(grpc_connector *con) { + connector *c = (connector *)con; + gpr_ref(&c->refs); +} + +static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { + connector *c = (connector *)con; + if (gpr_unref(&c->refs)) { + /* c->initial_string_buffer does not need to be destroyed */ + gpr_free(c); + } +} + +static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, + bool success) { + connector_unref(exec_ctx, arg); +} + +static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + connector *c = arg; + grpc_closure *notify; + grpc_endpoint *tcp = c->tcp; + if (tcp != NULL) { + if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) { + grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent, + c); + gpr_slice_buffer_init(&c->initial_string_buffer); + gpr_slice_buffer_add(&c->initial_string_buffer, + c->args.initial_connect_string); + connector_ref(arg); + grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, + &c->initial_string_sent); + } + c->result->transport = + grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, tcp, 1); + grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, + 0); + GPR_ASSERT(c->result->transport); + c->result->channel_args = c->args.channel_args; + } else { + memset(c->result, 0, sizeof(*c->result)); + } + notify = c->notify; + c->notify = NULL; + notify->cb(exec_ctx, notify->cb_arg, 1); +} + +static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) {} + +static void connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *con, + const grpc_connect_in_args *args, + grpc_connect_out_args *result, + grpc_closure *notify) { + connector *c = (connector *)con; + GPR_ASSERT(c->notify == NULL); + GPR_ASSERT(notify->cb); + c->notify = notify; + c->args = *args; + c->result = result; + c->tcp = NULL; + grpc_closure_init(&c->connected, connected, c); + grpc_tcp_client_connect(exec_ctx, &c->connected, &c->tcp, + args->interested_parties, args->addr, args->addr_len, + args->deadline); +} + +static const grpc_connector_vtable connector_vtable = { + connector_ref, connector_unref, connector_shutdown, connector_connect}; + +typedef struct { + grpc_subchannel_factory base; + gpr_refcount refs; + grpc_channel_args *merge_args; + grpc_channel *master; +} subchannel_factory; + +static void subchannel_factory_ref(grpc_subchannel_factory *scf) { + subchannel_factory *f = (subchannel_factory *)scf; + gpr_ref(&f->refs); +} + +static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx, + grpc_subchannel_factory *scf) { + subchannel_factory *f = (subchannel_factory *)scf; + if (gpr_unref(&f->refs)) { + GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory"); + grpc_channel_args_destroy(f->merge_args); + gpr_free(f); + } +} + +static grpc_subchannel *subchannel_factory_create_subchannel( + grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *scf, + grpc_subchannel_args *args) { + subchannel_factory *f = (subchannel_factory *)scf; + connector *c = gpr_malloc(sizeof(*c)); + grpc_channel_args *final_args = + grpc_channel_args_merge(args->args, f->merge_args); + grpc_subchannel *s; + memset(c, 0, sizeof(*c)); + c->base.vtable = &connector_vtable; + gpr_ref_init(&c->refs, 1); + args->args = final_args; + s = grpc_subchannel_create(exec_ctx, &c->base, args); + grpc_connector_unref(exec_ctx, &c->base); + grpc_channel_args_destroy(final_args); + return s; +} + +static const grpc_subchannel_factory_vtable subchannel_factory_vtable = { + subchannel_factory_ref, subchannel_factory_unref, + subchannel_factory_create_subchannel}; + +/* Create a client channel: + Asynchronously: - resolve target + - connect to it (trying alternatives as presented) + - perform handshakes */ +grpc_channel *grpc_insecure_channel_create(const char *target, + const grpc_channel_args *args, + void *reserved) { + grpc_channel *channel = NULL; + grpc_resolver *resolver; + subchannel_factory *f; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GRPC_API_TRACE( + "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3, + (target, args, reserved)); + GPR_ASSERT(!reserved); + + channel = + grpc_channel_create(&exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL); + + f = gpr_malloc(sizeof(*f)); + f->base.vtable = &subchannel_factory_vtable; + gpr_ref_init(&f->refs, 1); + f->merge_args = grpc_channel_args_copy(args); + f->master = channel; + GRPC_CHANNEL_INTERNAL_REF(f->master, "subchannel_factory"); + resolver = grpc_resolver_create(target, &f->base); + if (!resolver) { + GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, f->master, "subchannel_factory"); + grpc_subchannel_factory_unref(&exec_ctx, &f->base); + grpc_exec_ctx_finish(&exec_ctx); + return NULL; + } + + grpc_client_channel_set_resolver( + &exec_ctx, grpc_channel_get_channel_stack(channel), resolver); + GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create"); + grpc_subchannel_factory_unref(&exec_ctx, &f->base); + + grpc_exec_ctx_finish(&exec_ctx); + + return channel; +} diff --git a/src/core/lib/surface/channel_init.c b/src/core/lib/surface/channel_init.c new file mode 100644 index 0000000000..ac962f3972 --- /dev/null +++ b/src/core/lib/surface/channel_init.c @@ -0,0 +1,146 @@ +/* + * + * 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/surface/channel_init.h" + +#include +#include + +typedef struct stage_slot { + grpc_channel_init_stage fn; + void *arg; + int priority; + size_t insertion_order; +} stage_slot; + +typedef struct stage_slots { + stage_slot *slots; + size_t num_slots; + size_t cap_slots; +} stage_slots; + +static stage_slots g_slots[GRPC_NUM_CHANNEL_STACK_TYPES]; +static bool g_finalized; + +void grpc_channel_init_init(void) { + for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) { + g_slots[i].slots = NULL; + g_slots[i].num_slots = 0; + g_slots[i].cap_slots = 0; + } + g_finalized = false; +} + +void grpc_channel_init_register_stage(grpc_channel_stack_type type, + int priority, + grpc_channel_init_stage stage, + void *stage_arg) { + GPR_ASSERT(!g_finalized); + if (g_slots[type].cap_slots == g_slots[type].num_slots) { + g_slots[type].cap_slots = GPR_MAX(8, 3 * g_slots[type].cap_slots / 2); + g_slots[type].slots = + gpr_realloc(g_slots[type].slots, + g_slots[type].cap_slots * sizeof(*g_slots[type].slots)); + } + stage_slot *s = &g_slots[type].slots[g_slots[type].num_slots++]; + s->insertion_order = g_slots[type].num_slots; + s->priority = priority; + s->fn = stage; + s->arg = stage_arg; +} + +static int compare_slots(const void *a, const void *b) { + const stage_slot *sa = a; + const stage_slot *sb = b; + + int c = GPR_ICMP(sa->priority, sb->priority); + if (c != 0) return c; + return GPR_ICMP(sa->insertion_order, sb->insertion_order); +} + +void grpc_channel_init_finalize(void) { + GPR_ASSERT(!g_finalized); + for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) { + qsort(g_slots[i].slots, g_slots[i].num_slots, sizeof(*g_slots[i].slots), + compare_slots); + } + g_finalized = true; +} + +void grpc_channel_init_shutdown(void) { + for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) { + gpr_free(g_slots[i].slots); + g_slots[i].slots = (void *)(uintptr_t)0xdeadbeef; + } +} + +static const char *name_for_type(grpc_channel_stack_type type) { + switch (type) { + case GRPC_CLIENT_CHANNEL: + return "CLIENT_CHANNEL"; + case GRPC_CLIENT_SUBCHANNEL: + return "CLIENT_SUBCHANNEL"; + case GRPC_SERVER_CHANNEL: + return "SERVER_CHANNEL"; + case GRPC_CLIENT_LAME_CHANNEL: + return "CLIENT_LAME_CHANNEL"; + case GRPC_CLIENT_DIRECT_CHANNEL: + return "CLIENT_DIRECT_CHANNEL"; + case GRPC_NUM_CHANNEL_STACK_TYPES: + break; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +void *grpc_channel_init_create_stack( + grpc_exec_ctx *exec_ctx, grpc_channel_stack_type type, size_t prefix_bytes, + const grpc_channel_args *args, int initial_refs, grpc_iomgr_cb_func destroy, + void *destroy_arg, grpc_transport *transport) { + GPR_ASSERT(g_finalized); + + grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create(); + grpc_channel_stack_builder_set_name(builder, name_for_type(type)); + grpc_channel_stack_builder_set_channel_arguments(builder, args); + grpc_channel_stack_builder_set_transport(builder, transport); + + for (size_t i = 0; i < g_slots[type].num_slots; i++) { + const stage_slot *slot = &g_slots[type].slots[i]; + if (!slot->fn(builder, slot->arg)) { + grpc_channel_stack_builder_destroy(builder); + return NULL; + } + } + + return grpc_channel_stack_builder_finish(exec_ctx, builder, prefix_bytes, + initial_refs, destroy, destroy_arg); +} diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h new file mode 100644 index 0000000000..06faef6ddb --- /dev/null +++ b/src/core/lib/surface/channel_init.h @@ -0,0 +1,86 @@ +/* + * + * 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_SURFACE_CHANNEL_INIT_H +#define GRPC_CORE_SURFACE_CHANNEL_INIT_H + +#include "src/core/channel/channel_stack_builder.h" +#include "src/core/surface/channel_stack_type.h" +#include "src/core/transport/transport.h" + +/// This module provides a way for plugins (and the grpc core library itself) +/// to register mutators for channel stacks. +/// It also provides a universal entry path to run those mutators to build +/// a channel stack for various subsystems. + +/// One stage of mutation: call functions against \a builder to influence the +/// finally constructed channel stack +typedef bool (*grpc_channel_init_stage)(grpc_channel_stack_builder *builder, + void *arg); + +/// Global initialization of the system +void grpc_channel_init_init(void); + +/// Register one stage of mutators. +/// Stages are run in priority order (lowest to highest), and then in +/// registration order (in the case of a tie). +/// Stages are registered against one of the pre-determined channel stack +/// types. +void grpc_channel_init_register_stage(grpc_channel_stack_type type, + int priority, + grpc_channel_init_stage stage_fn, + void *stage_arg); + +/// Finalize registration. No more calls to grpc_channel_init_register_stage are +/// allowed. +void grpc_channel_init_finalize(void); +/// Shutdown the channel init system +void grpc_channel_init_shutdown(void); + +/// Construct a channel stack of some sort: see channel_stack.h for details +/// \a type is the type of channel stack to create +/// \a prefix_bytes is the number of bytes before the channel stack to allocate +/// \a args are configuration arguments for the channel stack +/// \a initial_refs is the initial refcount to give the channel stack +/// \a destroy and \a destroy_arg specify how to destroy the channel stack +/// if destroy_arg is NULL, the returned value from this function will be +/// substituted +/// \a optional_transport is either NULL or a constructed transport object +/// Returns a pointer to the base of the memory allocated (the actual channel +/// stack object will be prefix_bytes past that pointer) +void *grpc_channel_init_create_stack( + grpc_exec_ctx *exec_ctx, grpc_channel_stack_type type, size_t prefix_bytes, + const grpc_channel_args *args, int initial_refs, grpc_iomgr_cb_func destroy, + void *destroy_arg, grpc_transport *optional_transport); + +#endif /* GRPC_CORE_SURFACE_CHANNEL_INIT_H */ diff --git a/src/core/lib/surface/channel_ping.c b/src/core/lib/surface/channel_ping.c new file mode 100644 index 0000000000..983f1c8a66 --- /dev/null +++ b/src/core/lib/surface/channel_ping.c @@ -0,0 +1,79 @@ +/* + * + * Copyright 2015-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/surface/channel.h" + +#include + +#include +#include + +#include "src/core/surface/api_trace.h" +#include "src/core/surface/completion_queue.h" + +typedef struct { + grpc_closure closure; + void *tag; + grpc_completion_queue *cq; + grpc_cq_completion completion_storage; +} ping_result; + +static void ping_destroy(grpc_exec_ctx *exec_ctx, void *arg, + grpc_cq_completion *storage) { + gpr_free(arg); +} + +static void ping_done(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + ping_result *pr = arg; + grpc_cq_end_op(exec_ctx, pr->cq, pr->tag, success, ping_destroy, pr, + &pr->completion_storage); +} + +void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq, + void *tag, void *reserved) { + grpc_transport_op op; + ping_result *pr = gpr_malloc(sizeof(*pr)); + grpc_channel_element *top_elem = + grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GPR_ASSERT(reserved == NULL); + memset(&op, 0, sizeof(op)); + pr->tag = tag; + pr->cq = cq; + grpc_closure_init(&pr->closure, ping_done, pr); + op.send_ping = &pr->closure; + op.bind_pollset = grpc_cq_pollset(cq); + grpc_cq_begin_op(cq, tag); + top_elem->filter->start_transport_op(&exec_ctx, top_elem, &op); + grpc_exec_ctx_finish(&exec_ctx); +} diff --git a/src/core/lib/surface/channel_stack_type.c b/src/core/lib/surface/channel_stack_type.c new file mode 100644 index 0000000000..1a6e949ffe --- /dev/null +++ b/src/core/lib/surface/channel_stack_type.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/surface/channel_stack_type.h" +#include +#include + +bool grpc_channel_stack_type_is_client(grpc_channel_stack_type type) { + switch (type) { + case GRPC_CLIENT_CHANNEL: + return true; + case GRPC_CLIENT_SUBCHANNEL: + return true; + case GRPC_CLIENT_LAME_CHANNEL: + return true; + case GRPC_CLIENT_DIRECT_CHANNEL: + return true; + case GRPC_SERVER_CHANNEL: + return false; + case GRPC_NUM_CHANNEL_STACK_TYPES: + break; + } + GPR_UNREACHABLE_CODE(return true;); +} diff --git a/src/core/lib/surface/channel_stack_type.h b/src/core/lib/surface/channel_stack_type.h new file mode 100644 index 0000000000..75a1b9c072 --- /dev/null +++ b/src/core/lib/surface/channel_stack_type.h @@ -0,0 +1,58 @@ +/* + * + * Copyright 2015-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_SURFACE_CHANNEL_STACK_TYPE_H +#define GRPC_CORE_SURFACE_CHANNEL_STACK_TYPE_H + +#include + +typedef enum { + // normal top-half client channel with load-balancing, connection management + GRPC_CLIENT_CHANNEL, + // bottom-half of a client channel: everything that happens post-load + // balancing (bound to a specific transport) + GRPC_CLIENT_SUBCHANNEL, + // a permanently broken client channel + GRPC_CLIENT_LAME_CHANNEL, + // a directly connected client channel (without load-balancing, directly talks + // to a transport) + GRPC_CLIENT_DIRECT_CHANNEL, + // server side channel + GRPC_SERVER_CHANNEL, + // must be last + GRPC_NUM_CHANNEL_STACK_TYPES +} grpc_channel_stack_type; + +bool grpc_channel_stack_type_is_client(grpc_channel_stack_type type); + +#endif /* GRPC_CORE_SURFACE_CHANNEL_STACK_TYPE_H */ diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c new file mode 100644 index 0000000000..b22818ea87 --- /dev/null +++ b/src/core/lib/surface/completion_queue.c @@ -0,0 +1,512 @@ +/* + * + * Copyright 2015-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/surface/completion_queue.h" + +#include +#include + +#include +#include +#include +#include + +#include "src/core/iomgr/pollset.h" +#include "src/core/iomgr/timer.h" +#include "src/core/profiling/timers.h" +#include "src/core/support/string.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/call.h" +#include "src/core/surface/event_string.h" +#include "src/core/surface/surface_trace.h" + +typedef struct { + grpc_pollset_worker **worker; + void *tag; +} plucker; + +/* Completion queue structure */ +struct grpc_completion_queue { + /** owned by pollset */ + gpr_mu *mu; + /** completed events */ + grpc_cq_completion completed_head; + grpc_cq_completion *completed_tail; + /** Number of pending events (+1 if we're not shutdown) */ + gpr_refcount pending_events; + /** Once owning_refs drops to zero, we will destroy the cq */ + gpr_refcount owning_refs; + /** 0 initially, 1 once we've begun shutting down */ + int shutdown; + int shutdown_called; + int is_server_cq; + int num_pluckers; + plucker pluckers[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS]; + grpc_closure pollset_shutdown_done; + +#ifndef NDEBUG + void **outstanding_tags; + size_t outstanding_tag_count; + size_t outstanding_tag_capacity; +#endif + + grpc_completion_queue *next_free; +}; + +#define POLLSET_FROM_CQ(cq) ((grpc_pollset *)(cq + 1)) + +static gpr_mu g_freelist_mu; +static grpc_completion_queue *g_freelist; + +static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *cc, + bool success); + +void grpc_cq_global_init(void) { gpr_mu_init(&g_freelist_mu); } + +void grpc_cq_global_shutdown(void) { + gpr_mu_destroy(&g_freelist_mu); + while (g_freelist) { + grpc_completion_queue *next = g_freelist->next_free; + grpc_pollset_destroy(POLLSET_FROM_CQ(g_freelist)); +#ifndef NDEBUG + gpr_free(g_freelist->outstanding_tags); +#endif + gpr_free(g_freelist); + g_freelist = next; + } +} + +struct grpc_cq_alarm { + grpc_timer alarm; + grpc_cq_completion completion; + /** completion queue where events about this alarm will be posted */ + grpc_completion_queue *cq; + /** user supplied tag */ + void *tag; +}; + +grpc_completion_queue *grpc_completion_queue_create(void *reserved) { + grpc_completion_queue *cc; + GPR_ASSERT(!reserved); + + GPR_TIMER_BEGIN("grpc_completion_queue_create", 0); + + GRPC_API_TRACE("grpc_completion_queue_create(reserved=%p)", 1, (reserved)); + + gpr_mu_lock(&g_freelist_mu); + if (g_freelist == NULL) { + gpr_mu_unlock(&g_freelist_mu); + + cc = gpr_malloc(sizeof(grpc_completion_queue) + grpc_pollset_size()); + grpc_pollset_init(POLLSET_FROM_CQ(cc), &cc->mu); +#ifndef NDEBUG + cc->outstanding_tags = NULL; + cc->outstanding_tag_capacity = 0; +#endif + } else { + cc = g_freelist; + g_freelist = g_freelist->next_free; + gpr_mu_unlock(&g_freelist_mu); + /* pollset already initialized */ + } + + /* Initial ref is dropped by grpc_completion_queue_shutdown */ + gpr_ref_init(&cc->pending_events, 1); + /* One for destroy(), one for pollset_shutdown */ + gpr_ref_init(&cc->owning_refs, 2); + cc->completed_tail = &cc->completed_head; + cc->completed_head.next = (uintptr_t)cc->completed_tail; + cc->shutdown = 0; + cc->shutdown_called = 0; + cc->is_server_cq = 0; + cc->num_pluckers = 0; +#ifndef NDEBUG + cc->outstanding_tag_count = 0; +#endif + grpc_closure_init(&cc->pollset_shutdown_done, on_pollset_shutdown_done, cc); + + GPR_TIMER_END("grpc_completion_queue_create", 0); + + return cc; +} + +#ifdef GRPC_CQ_REF_COUNT_DEBUG +void grpc_cq_internal_ref(grpc_completion_queue *cc, const char *reason, + const char *file, int line) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p ref %d -> %d %s", cc, + (int)cc->owning_refs.count, (int)cc->owning_refs.count + 1, reason); +#else +void grpc_cq_internal_ref(grpc_completion_queue *cc) { +#endif + gpr_ref(&cc->owning_refs); +} + +static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *arg, + bool success) { + grpc_completion_queue *cc = arg; + GRPC_CQ_INTERNAL_UNREF(cc, "pollset_destroy"); +} + +#ifdef GRPC_CQ_REF_COUNT_DEBUG +void grpc_cq_internal_unref(grpc_completion_queue *cc, const char *reason, + const char *file, int line) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p unref %d -> %d %s", cc, + (int)cc->owning_refs.count, (int)cc->owning_refs.count - 1, reason); +#else +void grpc_cq_internal_unref(grpc_completion_queue *cc) { +#endif + if (gpr_unref(&cc->owning_refs)) { + GPR_ASSERT(cc->completed_head.next == (uintptr_t)&cc->completed_head); + grpc_pollset_reset(POLLSET_FROM_CQ(cc)); + gpr_mu_lock(&g_freelist_mu); + cc->next_free = g_freelist; + g_freelist = cc; + gpr_mu_unlock(&g_freelist_mu); + } +} + +void grpc_cq_begin_op(grpc_completion_queue *cc, void *tag) { +#ifndef NDEBUG + gpr_mu_lock(cc->mu); + GPR_ASSERT(!cc->shutdown_called); + if (cc->outstanding_tag_count == cc->outstanding_tag_capacity) { + cc->outstanding_tag_capacity = GPR_MAX(4, 2 * cc->outstanding_tag_capacity); + cc->outstanding_tags = + gpr_realloc(cc->outstanding_tags, sizeof(*cc->outstanding_tags) * + cc->outstanding_tag_capacity); + } + cc->outstanding_tags[cc->outstanding_tag_count++] = tag; + gpr_mu_unlock(cc->mu); +#endif + gpr_ref(&cc->pending_events); +} + +/* Signal the end of an operation - if this is the last waiting-to-be-queued + event, then enter shutdown mode */ +/* Queue a GRPC_OP_COMPLETED operation */ +void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, + void *tag, int success, + void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg, + grpc_cq_completion *storage), + void *done_arg, grpc_cq_completion *storage) { + int shutdown; + int i; + grpc_pollset_worker *pluck_worker; +#ifndef NDEBUG + int found = 0; +#endif + + GPR_TIMER_BEGIN("grpc_cq_end_op", 0); + + storage->tag = tag; + storage->done = done; + storage->done_arg = done_arg; + storage->next = + ((uintptr_t)&cc->completed_head) | ((uintptr_t)(success != 0)); + + gpr_mu_lock(cc->mu); +#ifndef NDEBUG + for (i = 0; i < (int)cc->outstanding_tag_count; i++) { + if (cc->outstanding_tags[i] == tag) { + cc->outstanding_tag_count--; + GPR_SWAP(void *, cc->outstanding_tags[i], + cc->outstanding_tags[cc->outstanding_tag_count]); + found = 1; + break; + } + } + GPR_ASSERT(found); +#endif + shutdown = gpr_unref(&cc->pending_events); + if (!shutdown) { + cc->completed_tail->next = + ((uintptr_t)storage) | (1u & (uintptr_t)cc->completed_tail->next); + cc->completed_tail = storage; + pluck_worker = NULL; + for (i = 0; i < cc->num_pluckers; i++) { + if (cc->pluckers[i].tag == tag) { + pluck_worker = *cc->pluckers[i].worker; + break; + } + } + grpc_pollset_kick(POLLSET_FROM_CQ(cc), pluck_worker); + gpr_mu_unlock(cc->mu); + } else { + cc->completed_tail->next = + ((uintptr_t)storage) | (1u & (uintptr_t)cc->completed_tail->next); + cc->completed_tail = storage; + GPR_ASSERT(!cc->shutdown); + GPR_ASSERT(cc->shutdown_called); + cc->shutdown = 1; + grpc_pollset_shutdown(exec_ctx, POLLSET_FROM_CQ(cc), + &cc->pollset_shutdown_done); + gpr_mu_unlock(cc->mu); + } + + GPR_TIMER_END("grpc_cq_end_op", 0); +} + +grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, + gpr_timespec deadline, void *reserved) { + grpc_event ret; + grpc_pollset_worker *worker = NULL; + int first_loop = 1; + gpr_timespec now; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + GPR_TIMER_BEGIN("grpc_completion_queue_next", 0); + + GRPC_API_TRACE( + "grpc_completion_queue_next(" + "cc=%p, " + "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " + "reserved=%p)", + 5, (cc, (long long)deadline.tv_sec, (int)deadline.tv_nsec, + (int)deadline.clock_type, reserved)); + GPR_ASSERT(!reserved); + + deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); + + GRPC_CQ_INTERNAL_REF(cc, "next"); + gpr_mu_lock(cc->mu); + for (;;) { + if (cc->completed_tail != &cc->completed_head) { + grpc_cq_completion *c = (grpc_cq_completion *)cc->completed_head.next; + cc->completed_head.next = c->next & ~(uintptr_t)1; + if (c == cc->completed_tail) { + cc->completed_tail = &cc->completed_head; + } + gpr_mu_unlock(cc->mu); + ret.type = GRPC_OP_COMPLETE; + ret.success = c->next & 1u; + ret.tag = c->tag; + c->done(&exec_ctx, c->done_arg, c); + break; + } + if (cc->shutdown) { + gpr_mu_unlock(cc->mu); + memset(&ret, 0, sizeof(ret)); + ret.type = GRPC_QUEUE_SHUTDOWN; + break; + } + now = gpr_now(GPR_CLOCK_MONOTONIC); + if (!first_loop && gpr_time_cmp(now, deadline) >= 0) { + gpr_mu_unlock(cc->mu); + memset(&ret, 0, sizeof(ret)); + ret.type = GRPC_QUEUE_TIMEOUT; + break; + } + first_loop = 0; + /* Check alarms - these are a global resource so we just ping + each time through on every pollset. + May update deadline to ensure timely wakeups. + TODO(ctiller): can this work be localized? */ + gpr_timespec iteration_deadline = deadline; + if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) { + GPR_TIMER_MARK("alarm_triggered", 0); + gpr_mu_unlock(cc->mu); + grpc_exec_ctx_flush(&exec_ctx); + gpr_mu_lock(cc->mu); + continue; + } else { + grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc), &worker, now, + iteration_deadline); + } + } + GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret); + GRPC_CQ_INTERNAL_UNREF(cc, "next"); + grpc_exec_ctx_finish(&exec_ctx); + + GPR_TIMER_END("grpc_completion_queue_next", 0); + + return ret; +} + +static int add_plucker(grpc_completion_queue *cc, void *tag, + grpc_pollset_worker **worker) { + if (cc->num_pluckers == GRPC_MAX_COMPLETION_QUEUE_PLUCKERS) { + return 0; + } + cc->pluckers[cc->num_pluckers].tag = tag; + cc->pluckers[cc->num_pluckers].worker = worker; + cc->num_pluckers++; + return 1; +} + +static void del_plucker(grpc_completion_queue *cc, void *tag, + grpc_pollset_worker **worker) { + int i; + for (i = 0; i < cc->num_pluckers; i++) { + if (cc->pluckers[i].tag == tag && cc->pluckers[i].worker == worker) { + cc->num_pluckers--; + GPR_SWAP(plucker, cc->pluckers[i], cc->pluckers[cc->num_pluckers]); + return; + } + } + GPR_UNREACHABLE_CODE(return ); +} + +grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, + gpr_timespec deadline, void *reserved) { + grpc_event ret; + grpc_cq_completion *c; + grpc_cq_completion *prev; + grpc_pollset_worker *worker = NULL; + gpr_timespec now; + int first_loop = 1; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + GPR_TIMER_BEGIN("grpc_completion_queue_pluck", 0); + + GRPC_API_TRACE( + "grpc_completion_queue_pluck(" + "cc=%p, tag=%p, " + "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " + "reserved=%p)", + 6, (cc, tag, (long long)deadline.tv_sec, (int)deadline.tv_nsec, + (int)deadline.clock_type, reserved)); + GPR_ASSERT(!reserved); + + deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); + + GRPC_CQ_INTERNAL_REF(cc, "pluck"); + gpr_mu_lock(cc->mu); + for (;;) { + prev = &cc->completed_head; + while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) != + &cc->completed_head) { + if (c->tag == tag) { + prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1); + if (c == cc->completed_tail) { + cc->completed_tail = prev; + } + gpr_mu_unlock(cc->mu); + ret.type = GRPC_OP_COMPLETE; + ret.success = c->next & 1u; + ret.tag = c->tag; + c->done(&exec_ctx, c->done_arg, c); + goto done; + } + prev = c; + } + if (cc->shutdown) { + gpr_mu_unlock(cc->mu); + memset(&ret, 0, sizeof(ret)); + ret.type = GRPC_QUEUE_SHUTDOWN; + break; + } + if (!add_plucker(cc, tag, &worker)) { + gpr_log(GPR_DEBUG, + "Too many outstanding grpc_completion_queue_pluck calls: maximum " + "is %d", + GRPC_MAX_COMPLETION_QUEUE_PLUCKERS); + gpr_mu_unlock(cc->mu); + memset(&ret, 0, sizeof(ret)); + /* TODO(ctiller): should we use a different result here */ + ret.type = GRPC_QUEUE_TIMEOUT; + break; + } + now = gpr_now(GPR_CLOCK_MONOTONIC); + if (!first_loop && gpr_time_cmp(now, deadline) >= 0) { + del_plucker(cc, tag, &worker); + gpr_mu_unlock(cc->mu); + memset(&ret, 0, sizeof(ret)); + ret.type = GRPC_QUEUE_TIMEOUT; + break; + } + first_loop = 0; + /* Check alarms - these are a global resource so we just ping + each time through on every pollset. + May update deadline to ensure timely wakeups. + TODO(ctiller): can this work be localized? */ + gpr_timespec iteration_deadline = deadline; + if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) { + GPR_TIMER_MARK("alarm_triggered", 0); + gpr_mu_unlock(cc->mu); + grpc_exec_ctx_flush(&exec_ctx); + gpr_mu_lock(cc->mu); + } else { + grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc), &worker, now, + iteration_deadline); + } + del_plucker(cc, tag, &worker); + } +done: + GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret); + GRPC_CQ_INTERNAL_UNREF(cc, "pluck"); + grpc_exec_ctx_finish(&exec_ctx); + + GPR_TIMER_END("grpc_completion_queue_pluck", 0); + + return ret; +} + +/* Shutdown simply drops a ref that we reserved at creation time; if we drop + to zero here, then enter shutdown mode and wake up any waiters */ +void grpc_completion_queue_shutdown(grpc_completion_queue *cc) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GPR_TIMER_BEGIN("grpc_completion_queue_shutdown", 0); + GRPC_API_TRACE("grpc_completion_queue_shutdown(cc=%p)", 1, (cc)); + gpr_mu_lock(cc->mu); + if (cc->shutdown_called) { + gpr_mu_unlock(cc->mu); + GPR_TIMER_END("grpc_completion_queue_shutdown", 0); + return; + } + cc->shutdown_called = 1; + if (gpr_unref(&cc->pending_events)) { + GPR_ASSERT(!cc->shutdown); + cc->shutdown = 1; + grpc_pollset_shutdown(&exec_ctx, POLLSET_FROM_CQ(cc), + &cc->pollset_shutdown_done); + } + gpr_mu_unlock(cc->mu); + grpc_exec_ctx_finish(&exec_ctx); + GPR_TIMER_END("grpc_completion_queue_shutdown", 0); +} + +void grpc_completion_queue_destroy(grpc_completion_queue *cc) { + GRPC_API_TRACE("grpc_completion_queue_destroy(cc=%p)", 1, (cc)); + GPR_TIMER_BEGIN("grpc_completion_queue_destroy", 0); + grpc_completion_queue_shutdown(cc); + GRPC_CQ_INTERNAL_UNREF(cc, "destroy"); + GPR_TIMER_END("grpc_completion_queue_destroy", 0); +} + +grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) { + return POLLSET_FROM_CQ(cc); +} + +void grpc_cq_mark_server_cq(grpc_completion_queue *cc) { cc->is_server_cq = 1; } + +int grpc_cq_is_server_cq(grpc_completion_queue *cc) { return cc->is_server_cq; } diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h new file mode 100644 index 0000000000..213d89c079 --- /dev/null +++ b/src/core/lib/surface/completion_queue.h @@ -0,0 +1,91 @@ +/* + * + * Copyright 2015-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_SURFACE_COMPLETION_QUEUE_H +#define GRPC_CORE_SURFACE_COMPLETION_QUEUE_H + +/* Internal API for completion queues */ + +#include +#include "src/core/iomgr/pollset.h" + +typedef struct grpc_cq_completion { + /** user supplied tag */ + void *tag; + /** done callback - called when this queue element is no longer + needed by the completion queue */ + void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg, + struct grpc_cq_completion *c); + void *done_arg; + /** next pointer; low bit is used to indicate success or not */ + uintptr_t next; +} grpc_cq_completion; + +#ifdef GRPC_CQ_REF_COUNT_DEBUG +void grpc_cq_internal_ref(grpc_completion_queue *cc, const char *reason, + const char *file, int line); +void grpc_cq_internal_unref(grpc_completion_queue *cc, const char *reason, + const char *file, int line); +#define GRPC_CQ_INTERNAL_REF(cc, reason) \ + grpc_cq_internal_ref(cc, reason, __FILE__, __LINE__) +#define GRPC_CQ_INTERNAL_UNREF(cc, reason) \ + grpc_cq_internal_unref(cc, reason, __FILE__, __LINE__) +#else +void grpc_cq_internal_ref(grpc_completion_queue *cc); +void grpc_cq_internal_unref(grpc_completion_queue *cc); +#define GRPC_CQ_INTERNAL_REF(cc, reason) grpc_cq_internal_ref(cc) +#define GRPC_CQ_INTERNAL_UNREF(cc, reason) grpc_cq_internal_unref(cc) +#endif + +/* Flag that an operation is beginning: the completion channel will not finish + shutdown until a corrensponding grpc_cq_end_* call is made. + \a tag is currently used only in debug builds. */ +void grpc_cq_begin_op(grpc_completion_queue *cc, void *tag); + +/* Queue a GRPC_OP_COMPLETED operation; tag must correspond to the tag passed to + grpc_cq_begin_op */ +void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, + void *tag, int success, + void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg, + grpc_cq_completion *storage), + void *done_arg, grpc_cq_completion *storage); + +grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc); + +void grpc_cq_mark_server_cq(grpc_completion_queue *cc); +int grpc_cq_is_server_cq(grpc_completion_queue *cc); + +void grpc_cq_global_init(void); +void grpc_cq_global_shutdown(void); + +#endif /* GRPC_CORE_SURFACE_COMPLETION_QUEUE_H */ diff --git a/src/core/lib/surface/event_string.c b/src/core/lib/surface/event_string.c new file mode 100644 index 0000000000..85a372b9ad --- /dev/null +++ b/src/core/lib/surface/event_string.c @@ -0,0 +1,81 @@ +/* + * + * Copyright 2015-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/surface/event_string.h" + +#include + +#include +#include +#include "src/core/support/string.h" + +static void addhdr(gpr_strvec *buf, grpc_event *ev) { + char *tmp; + gpr_asprintf(&tmp, "tag:%p", ev->tag); + gpr_strvec_add(buf, tmp); +} + +static const char *errstr(int success) { return success ? "OK" : "ERROR"; } + +static void adderr(gpr_strvec *buf, int success) { + char *tmp; + gpr_asprintf(&tmp, " %s", errstr(success)); + gpr_strvec_add(buf, tmp); +} + +char *grpc_event_string(grpc_event *ev) { + char *out; + gpr_strvec buf; + + if (ev == NULL) return gpr_strdup("null"); + + gpr_strvec_init(&buf); + + switch (ev->type) { + case GRPC_QUEUE_TIMEOUT: + gpr_strvec_add(&buf, gpr_strdup("QUEUE_TIMEOUT")); + break; + case GRPC_QUEUE_SHUTDOWN: + gpr_strvec_add(&buf, gpr_strdup("QUEUE_SHUTDOWN")); + break; + case GRPC_OP_COMPLETE: + gpr_strvec_add(&buf, gpr_strdup("OP_COMPLETE: ")); + addhdr(&buf, ev); + adderr(&buf, ev->success); + break; + } + + out = gpr_strvec_flatten(&buf, NULL); + gpr_strvec_destroy(&buf); + return out; +} diff --git a/src/core/lib/surface/event_string.h b/src/core/lib/surface/event_string.h new file mode 100644 index 0000000000..d0598cecca --- /dev/null +++ b/src/core/lib/surface/event_string.h @@ -0,0 +1,42 @@ +/* + * + * Copyright 2015-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_SURFACE_EVENT_STRING_H +#define GRPC_CORE_SURFACE_EVENT_STRING_H + +#include + +/* Returns a string describing an event. Must be later freed with gpr_free() */ +char *grpc_event_string(grpc_event *ev); + +#endif /* GRPC_CORE_SURFACE_EVENT_STRING_H */ diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c new file mode 100644 index 0000000000..3c4db3e6cc --- /dev/null +++ b/src/core/lib/surface/init.c @@ -0,0 +1,239 @@ +/* + * + * Copyright 2015-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 + +#include +#include + +#include +#include +#include +/* TODO(ctiller): find another way? - better not to include census here */ +#include "src/core/census/grpc_plugin.h" +#include "src/core/channel/channel_stack.h" +#include "src/core/channel/client_channel.h" +#include "src/core/channel/compress_filter.h" +#include "src/core/channel/connected_channel.h" +#include "src/core/channel/http_client_filter.h" +#include "src/core/channel/http_server_filter.h" +#include "src/core/client_config/lb_policies/pick_first.h" +#include "src/core/client_config/lb_policies/round_robin.h" +#include "src/core/client_config/lb_policy_registry.h" +#include "src/core/client_config/resolver_registry.h" +#include "src/core/client_config/resolvers/dns_resolver.h" +#include "src/core/client_config/resolvers/sockaddr_resolver.h" +#include "src/core/client_config/subchannel.h" +#include "src/core/client_config/subchannel_index.h" +#include "src/core/debug/trace.h" +#include "src/core/iomgr/executor.h" +#include "src/core/iomgr/iomgr.h" +#include "src/core/profiling/timers.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/call.h" +#include "src/core/surface/channel_init.h" +#include "src/core/surface/completion_queue.h" +#include "src/core/surface/init.h" +#include "src/core/surface/lame_client.h" +#include "src/core/surface/server.h" +#include "src/core/surface/surface_trace.h" +#include "src/core/transport/chttp2_transport.h" +#include "src/core/transport/connectivity_state.h" +#include "src/core/transport/transport_impl.h" + +#ifndef GRPC_DEFAULT_NAME_PREFIX +#define GRPC_DEFAULT_NAME_PREFIX "dns:///" +#endif + +#define MAX_PLUGINS 128 + +static gpr_once g_basic_init = GPR_ONCE_INIT; +static gpr_mu g_init_mu; +static int g_initializations; + +static void do_basic_init(void) { + gpr_mu_init(&g_init_mu); + /* TODO(ctiller): ideally remove this strict linkage */ + grpc_register_plugin(census_grpc_plugin_init, census_grpc_plugin_destroy); + g_initializations = 0; +} + +static bool append_filter(grpc_channel_stack_builder *builder, void *arg) { + return grpc_channel_stack_builder_append_filter( + builder, (const grpc_channel_filter *)arg, NULL, NULL); +} + +static bool prepend_filter(grpc_channel_stack_builder *builder, void *arg) { + return grpc_channel_stack_builder_prepend_filter( + builder, (const grpc_channel_filter *)arg, NULL, NULL); +} + +static bool maybe_add_http_filter(grpc_channel_stack_builder *builder, + void *arg) { + grpc_transport *t = grpc_channel_stack_builder_get_transport(builder); + if (t && strstr(t->vtable->name, "http")) { + return grpc_channel_stack_builder_prepend_filter( + builder, (const grpc_channel_filter *)arg, NULL, NULL); + } + return true; +} + +static void register_builtin_channel_init() { + grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, prepend_filter, + (void *)&grpc_compress_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, + prepend_filter, + (void *)&grpc_compress_filter); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter, + (void *)&grpc_compress_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX, + maybe_add_http_filter, + (void *)&grpc_http_client_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX, + grpc_add_connected_filter, NULL); + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, + maybe_add_http_filter, + (void *)&grpc_http_client_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, + grpc_add_connected_filter, NULL); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, + maybe_add_http_filter, + (void *)&grpc_http_server_filter); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, + grpc_add_connected_filter, NULL); + grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, append_filter, + (void *)&grpc_client_channel_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_LAME_CHANNEL, INT_MAX, + append_filter, (void *)&grpc_lame_filter); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter, + (void *)&grpc_server_top_filter); +} + +typedef struct grpc_plugin { + void (*init)(); + void (*destroy)(); +} grpc_plugin; + +static grpc_plugin g_all_of_the_plugins[MAX_PLUGINS]; +static int g_number_of_plugins = 0; + +void grpc_register_plugin(void (*init)(void), void (*destroy)(void)) { + GRPC_API_TRACE("grpc_register_plugin(init=%p, destroy=%p)", 2, + ((void *)(intptr_t)init, (void *)(intptr_t)destroy)); + GPR_ASSERT(g_number_of_plugins != MAX_PLUGINS); + g_all_of_the_plugins[g_number_of_plugins].init = init; + g_all_of_the_plugins[g_number_of_plugins].destroy = destroy; + g_number_of_plugins++; +} + +void grpc_init(void) { + int i; + gpr_once_init(&g_basic_init, do_basic_init); + + gpr_mu_lock(&g_init_mu); + if (++g_initializations == 1) { + gpr_time_init(); + grpc_mdctx_global_init(); + grpc_channel_init_init(); + grpc_lb_policy_registry_init(grpc_pick_first_lb_factory_create()); + grpc_register_lb_policy(grpc_pick_first_lb_factory_create()); + grpc_register_lb_policy(grpc_round_robin_lb_factory_create()); + grpc_resolver_registry_init(GRPC_DEFAULT_NAME_PREFIX); + grpc_register_resolver_type(grpc_dns_resolver_factory_create()); + grpc_register_resolver_type(grpc_ipv4_resolver_factory_create()); + grpc_register_resolver_type(grpc_ipv6_resolver_factory_create()); +#ifdef GPR_POSIX_SOCKET + grpc_register_resolver_type(grpc_unix_resolver_factory_create()); +#endif + grpc_register_tracer("api", &grpc_api_trace); + grpc_register_tracer("channel", &grpc_trace_channel); + grpc_register_tracer("http", &grpc_http_trace); + grpc_register_tracer("flowctl", &grpc_flowctl_trace); + grpc_register_tracer("connectivity_state", &grpc_connectivity_state_trace); + grpc_register_tracer("channel_stack_builder", + &grpc_trace_channel_stack_builder); + grpc_security_pre_init(); + grpc_iomgr_init(); + grpc_executor_init(); + grpc_tracer_init("GRPC_TRACE"); + gpr_timers_global_init(); + grpc_cq_global_init(); + grpc_subchannel_index_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(); + } + } + /* register channel finalization AFTER all plugins, to ensure that it's run + * at the appropriate time */ + grpc_register_security_filters(); + register_builtin_channel_init(); + /* no more changes to channel init pipelines */ + grpc_channel_init_finalize(); + } + gpr_mu_unlock(&g_init_mu); + GRPC_API_TRACE("grpc_init(void)", 0, ()); +} + +void grpc_shutdown(void) { + int i; + GRPC_API_TRACE("grpc_shutdown(void)", 0, ()); + gpr_mu_lock(&g_init_mu); + if (--g_initializations == 0) { + grpc_executor_shutdown(); + grpc_cq_global_shutdown(); + grpc_iomgr_shutdown(); + grpc_subchannel_index_shutdown(); + gpr_timers_global_destroy(); + grpc_tracer_shutdown(); + grpc_resolver_registry_shutdown(); + grpc_lb_policy_registry_shutdown(); + for (i = 0; i < g_number_of_plugins; i++) { + if (g_all_of_the_plugins[i].destroy != NULL) { + g_all_of_the_plugins[i].destroy(); + } + } + grpc_channel_init_shutdown(); + grpc_mdctx_global_shutdown(); + } + gpr_mu_unlock(&g_init_mu); +} + +int grpc_is_initialized(void) { + int r; + gpr_once_init(&g_basic_init, do_basic_init); + gpr_mu_lock(&g_init_mu); + r = g_initializations > 0; + gpr_mu_unlock(&g_init_mu); + return r; +} diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h new file mode 100644 index 0000000000..5e358c7022 --- /dev/null +++ b/src/core/lib/surface/init.h @@ -0,0 +1,41 @@ +/* + * + * Copyright 2015-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_SURFACE_INIT_H +#define GRPC_CORE_SURFACE_INIT_H + +void grpc_register_security_filters(void); +void grpc_security_pre_init(void); +int grpc_is_initialized(void); + +#endif /* GRPC_CORE_SURFACE_INIT_H */ diff --git a/src/core/lib/surface/init_secure.c b/src/core/lib/surface/init_secure.c new file mode 100644 index 0000000000..e0d66a8d46 --- /dev/null +++ b/src/core/lib/surface/init_secure.c @@ -0,0 +1,89 @@ +/* + * + * Copyright 2015-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/surface/init.h" + +#include +#include + +#include "src/core/debug/trace.h" +#include "src/core/security/auth_filters.h" +#include "src/core/security/credentials.h" +#include "src/core/security/secure_endpoint.h" +#include "src/core/security/security_connector.h" +#include "src/core/surface/channel_init.h" +#include "src/core/tsi/transport_security_interface.h" + +void grpc_security_pre_init(void) { + grpc_register_tracer("secure_endpoint", &grpc_trace_secure_endpoint); + grpc_register_tracer("transport_security", &tsi_tracing_enabled); +} + +static bool maybe_prepend_client_auth_filter( + grpc_channel_stack_builder *builder, void *arg) { + const grpc_channel_args *args = + grpc_channel_stack_builder_get_channel_arguments(builder); + if (args) { + for (size_t i = 0; i < args->num_args; i++) { + if (0 == strcmp(GRPC_SECURITY_CONNECTOR_ARG, args->args[i].key)) { + return grpc_channel_stack_builder_prepend_filter( + builder, &grpc_client_auth_filter, NULL, NULL); + } + } + } + return true; +} + +static bool maybe_prepend_server_auth_filter( + grpc_channel_stack_builder *builder, void *arg) { + const grpc_channel_args *args = + grpc_channel_stack_builder_get_channel_arguments(builder); + if (args) { + for (size_t i = 0; i < args->num_args; i++) { + if (0 == strcmp(GRPC_SERVER_CREDENTIALS_ARG, args->args[i].key)) { + return grpc_channel_stack_builder_prepend_filter( + builder, &grpc_server_auth_filter, NULL, NULL); + } + } + } + return true; +} + +void grpc_register_security_filters(void) { + grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX, + maybe_prepend_client_auth_filter, NULL); + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, + maybe_prepend_client_auth_filter, NULL); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, + maybe_prepend_server_auth_filter, NULL); +} diff --git a/src/core/lib/surface/init_unsecure.c b/src/core/lib/surface/init_unsecure.c new file mode 100644 index 0000000000..278fcc83ac --- /dev/null +++ b/src/core/lib/surface/init_unsecure.c @@ -0,0 +1,38 @@ +/* + * + * Copyright 2015-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/surface/init.h" + +void grpc_security_pre_init(void) {} + +void grpc_register_security_filters(void) {} diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c new file mode 100644 index 0000000000..25f3a74349 --- /dev/null +++ b/src/core/lib/surface/lame_client.c @@ -0,0 +1,155 @@ +/* + * + * Copyright 2015-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/surface/lame_client.h" + +#include + +#include + +#include +#include +#include "src/core/channel/channel_stack.h" +#include "src/core/support/string.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/call.h" +#include "src/core/surface/channel.h" + +typedef struct { + grpc_linked_mdelem status; + grpc_linked_mdelem details; +} call_data; + +typedef struct { + grpc_status_code error_code; + const char *error_message; +} channel_data; + +static void fill_metadata(grpc_call_element *elem, grpc_metadata_batch *mdb) { + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + char tmp[GPR_LTOA_MIN_BUFSIZE]; + gpr_ltoa(chand->error_code, tmp); + calld->status.md = grpc_mdelem_from_strings("grpc-status", tmp); + calld->details.md = + grpc_mdelem_from_strings("grpc-message", chand->error_message); + calld->status.prev = calld->details.next = NULL; + calld->status.next = &calld->details; + calld->details.prev = &calld->status; + mdb->list.head = &calld->status; + mdb->list.tail = &calld->details; + mdb->deadline = gpr_inf_future(GPR_CLOCK_REALTIME); +} + +static void lame_start_transport_stream_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + GRPC_CALL_LOG_OP(GPR_INFO, elem, op); + if (op->recv_initial_metadata != NULL) { + fill_metadata(elem, op->recv_initial_metadata); + } else if (op->recv_trailing_metadata != NULL) { + fill_metadata(elem, op->recv_trailing_metadata); + } + grpc_transport_stream_op_finish_with_failure(exec_ctx, op); +} + +static char *lame_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { + return NULL; +} + +static void lame_start_transport_op(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_transport_op *op) { + if (op->on_connectivity_state_change) { + GPR_ASSERT(*op->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE); + *op->connectivity_state = GRPC_CHANNEL_FATAL_FAILURE; + op->on_connectivity_state_change->cb( + exec_ctx, op->on_connectivity_state_change->cb_arg, 1); + } + if (op->on_consumed != NULL) { + op->on_consumed->cb(exec_ctx, op->on_consumed->cb_arg, 1); + } +} + +static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args) {} + +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) {} + +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + GPR_ASSERT(args->is_first); + GPR_ASSERT(args->is_last); +} + +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) {} + +const grpc_channel_filter grpc_lame_filter = { + lame_start_transport_stream_op, + lame_start_transport_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + lame_get_peer, + "lame-client", +}; + +#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c) + 1)) + +grpc_channel *grpc_lame_client_channel_create(const char *target, + grpc_status_code error_code, + const char *error_message) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_channel_element *elem; + channel_data *chand; + grpc_channel *channel = grpc_channel_create(&exec_ctx, target, NULL, + GRPC_CLIENT_LAME_CHANNEL, NULL); + elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0); + GRPC_API_TRACE( + "grpc_lame_client_channel_create(target=%s, error_code=%d, " + "error_message=%s)", + 3, (target, (int)error_code, error_message)); + GPR_ASSERT(elem->filter == &grpc_lame_filter); + chand = (channel_data *)elem->channel_data; + chand->error_code = error_code; + chand->error_message = error_message; + grpc_exec_ctx_finish(&exec_ctx); + return channel; +} diff --git a/src/core/lib/surface/lame_client.h b/src/core/lib/surface/lame_client.h new file mode 100644 index 0000000000..3f3abd2ffe --- /dev/null +++ b/src/core/lib/surface/lame_client.h @@ -0,0 +1,41 @@ +/* + * + * 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_SURFACE_LAME_CLIENT_H +#define GRPC_CORE_SURFACE_LAME_CLIENT_H + +#include "src/core/channel/channel_stack.h" + +extern const grpc_channel_filter grpc_lame_filter; + +#endif /* GRPC_CORE_SURFACE_LAME_CLIENT_H */ diff --git a/src/core/lib/surface/metadata_array.c b/src/core/lib/surface/metadata_array.c new file mode 100644 index 0000000000..4c7bf17835 --- /dev/null +++ b/src/core/lib/surface/metadata_array.c @@ -0,0 +1,49 @@ +/* + * + * Copyright 2015, 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 +#include + +#include + +#include "src/core/surface/api_trace.h" + +void grpc_metadata_array_init(grpc_metadata_array* array) { + GRPC_API_TRACE("grpc_metadata_array_init(array=%p)", 1, (array)); + memset(array, 0, sizeof(*array)); +} + +void grpc_metadata_array_destroy(grpc_metadata_array* array) { + GRPC_API_TRACE("grpc_metadata_array_destroy(array=%p)", 1, (array)); + gpr_free(array->metadata); +} diff --git a/src/core/lib/surface/secure_channel_create.c b/src/core/lib/surface/secure_channel_create.c new file mode 100644 index 0000000000..cc752227ee --- /dev/null +++ b/src/core/lib/surface/secure_channel_create.c @@ -0,0 +1,319 @@ +/* + * + * Copyright 2015-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 + +#include +#include + +#include +#include +#include + +#include "src/core/channel/channel_args.h" +#include "src/core/channel/client_channel.h" +#include "src/core/client_config/resolver_registry.h" +#include "src/core/iomgr/tcp_client.h" +#include "src/core/security/auth_filters.h" +#include "src/core/security/credentials.h" +#include "src/core/security/security_context.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/channel.h" +#include "src/core/transport/chttp2_transport.h" +#include "src/core/tsi/transport_security_interface.h" + +typedef struct { + grpc_connector base; + gpr_refcount refs; + + grpc_channel_security_connector *security_connector; + + grpc_closure *notify; + grpc_connect_in_args args; + grpc_connect_out_args *result; + grpc_closure initial_string_sent; + gpr_slice_buffer initial_string_buffer; + + gpr_mu mu; + grpc_endpoint *connecting_endpoint; + grpc_endpoint *newly_connecting_endpoint; + + grpc_closure connected_closure; +} connector; + +static void connector_ref(grpc_connector *con) { + connector *c = (connector *)con; + gpr_ref(&c->refs); +} + +static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { + connector *c = (connector *)con; + if (gpr_unref(&c->refs)) { + /* c->initial_string_buffer does not need to be destroyed */ + gpr_free(c); + } +} + +static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, + grpc_security_status status, + grpc_endpoint *secure_endpoint, + grpc_auth_context *auth_context) { + connector *c = arg; + grpc_closure *notify; + grpc_channel_args *args_copy = NULL; + gpr_mu_lock(&c->mu); + if (c->connecting_endpoint == NULL) { + memset(c->result, 0, sizeof(*c->result)); + gpr_mu_unlock(&c->mu); + } else if (status != GRPC_SECURITY_OK) { + gpr_log(GPR_ERROR, "Secure handshake failed with error %d.", status); + memset(c->result, 0, sizeof(*c->result)); + c->connecting_endpoint = NULL; + gpr_mu_unlock(&c->mu); + } else { + grpc_arg auth_context_arg; + c->connecting_endpoint = NULL; + gpr_mu_unlock(&c->mu); + c->result->transport = grpc_create_chttp2_transport( + exec_ctx, c->args.channel_args, secure_endpoint, 1); + grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, + 0); + auth_context_arg = grpc_auth_context_to_arg(auth_context); + args_copy = grpc_channel_args_copy_and_add(c->args.channel_args, + &auth_context_arg, 1); + c->result->channel_args = args_copy; + } + notify = c->notify; + c->notify = NULL; + /* look at c->args which are connector args. */ + notify->cb(exec_ctx, notify->cb_arg, 1); + if (args_copy != NULL) grpc_channel_args_destroy(args_copy); +} + +static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, + bool success) { + connector *c = arg; + grpc_channel_security_connector_do_handshake(exec_ctx, c->security_connector, + c->connecting_endpoint, + on_secure_handshake_done, c); +} + +static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + connector *c = arg; + grpc_closure *notify; + grpc_endpoint *tcp = c->newly_connecting_endpoint; + if (tcp != NULL) { + gpr_mu_lock(&c->mu); + GPR_ASSERT(c->connecting_endpoint == NULL); + c->connecting_endpoint = tcp; + gpr_mu_unlock(&c->mu); + if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) { + grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent, + c); + gpr_slice_buffer_init(&c->initial_string_buffer); + gpr_slice_buffer_add(&c->initial_string_buffer, + c->args.initial_connect_string); + grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, + &c->initial_string_sent); + } else { + grpc_channel_security_connector_do_handshake( + exec_ctx, c->security_connector, tcp, on_secure_handshake_done, c); + } + } else { + memset(c->result, 0, sizeof(*c->result)); + notify = c->notify; + c->notify = NULL; + notify->cb(exec_ctx, notify->cb_arg, 1); + } +} + +static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) { + connector *c = (connector *)con; + grpc_endpoint *ep; + gpr_mu_lock(&c->mu); + ep = c->connecting_endpoint; + c->connecting_endpoint = NULL; + gpr_mu_unlock(&c->mu); + if (ep) { + grpc_endpoint_shutdown(exec_ctx, ep); + } +} + +static void connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *con, + const grpc_connect_in_args *args, + grpc_connect_out_args *result, + grpc_closure *notify) { + connector *c = (connector *)con; + GPR_ASSERT(c->notify == NULL); + GPR_ASSERT(notify->cb); + c->notify = notify; + c->args = *args; + c->result = result; + gpr_mu_lock(&c->mu); + GPR_ASSERT(c->connecting_endpoint == NULL); + gpr_mu_unlock(&c->mu); + grpc_closure_init(&c->connected_closure, connected, c); + grpc_tcp_client_connect( + exec_ctx, &c->connected_closure, &c->newly_connecting_endpoint, + args->interested_parties, args->addr, args->addr_len, args->deadline); +} + +static const grpc_connector_vtable connector_vtable = { + connector_ref, connector_unref, connector_shutdown, connector_connect}; + +typedef struct { + grpc_subchannel_factory base; + gpr_refcount refs; + grpc_channel_args *merge_args; + grpc_channel_security_connector *security_connector; + grpc_channel *master; +} subchannel_factory; + +static void subchannel_factory_ref(grpc_subchannel_factory *scf) { + subchannel_factory *f = (subchannel_factory *)scf; + gpr_ref(&f->refs); +} + +static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx, + grpc_subchannel_factory *scf) { + subchannel_factory *f = (subchannel_factory *)scf; + if (gpr_unref(&f->refs)) { + GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base, + "subchannel_factory"); + GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory"); + grpc_channel_args_destroy(f->merge_args); + gpr_free(f); + } +} + +static grpc_subchannel *subchannel_factory_create_subchannel( + grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *scf, + grpc_subchannel_args *args) { + subchannel_factory *f = (subchannel_factory *)scf; + connector *c = gpr_malloc(sizeof(*c)); + grpc_channel_args *final_args = + grpc_channel_args_merge(args->args, f->merge_args); + grpc_subchannel *s; + memset(c, 0, sizeof(*c)); + c->base.vtable = &connector_vtable; + c->security_connector = f->security_connector; + gpr_mu_init(&c->mu); + gpr_ref_init(&c->refs, 1); + args->args = final_args; + s = grpc_subchannel_create(exec_ctx, &c->base, args); + grpc_connector_unref(exec_ctx, &c->base); + grpc_channel_args_destroy(final_args); + return s; +} + +static const grpc_subchannel_factory_vtable subchannel_factory_vtable = { + subchannel_factory_ref, subchannel_factory_unref, + subchannel_factory_create_subchannel}; + +/* Create a secure client channel: + Asynchronously: - resolve target + - connect to it (trying alternatives as presented) + - perform handshakes */ +grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds, + const char *target, + const grpc_channel_args *args, + void *reserved) { + grpc_channel *channel; + grpc_arg connector_arg; + grpc_channel_args *args_copy; + grpc_channel_args *new_args_from_connector; + grpc_channel_security_connector *security_connector; + grpc_resolver *resolver; + subchannel_factory *f; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + GRPC_API_TRACE( + "grpc_secure_channel_create(creds=%p, target=%s, args=%p, " + "reserved=%p)", + 4, (creds, target, args, reserved)); + GPR_ASSERT(reserved == NULL); + + if (grpc_find_security_connector_in_args(args) != NULL) { + gpr_log(GPR_ERROR, "Cannot set security context in channel args."); + grpc_exec_ctx_finish(&exec_ctx); + return grpc_lame_client_channel_create( + target, GRPC_STATUS_INVALID_ARGUMENT, + "Security connector exists in channel args."); + } + + if (grpc_channel_credentials_create_security_connector( + creds, target, args, &security_connector, &new_args_from_connector) != + GRPC_SECURITY_OK) { + grpc_exec_ctx_finish(&exec_ctx); + return grpc_lame_client_channel_create( + target, GRPC_STATUS_INVALID_ARGUMENT, + "Failed to create security connector."); + } + + connector_arg = grpc_security_connector_to_arg(&security_connector->base); + args_copy = grpc_channel_args_copy_and_add( + new_args_from_connector != NULL ? new_args_from_connector : args, + &connector_arg, 1); + + channel = grpc_channel_create(&exec_ctx, target, args_copy, + GRPC_CLIENT_CHANNEL, NULL); + + f = gpr_malloc(sizeof(*f)); + f->base.vtable = &subchannel_factory_vtable; + gpr_ref_init(&f->refs, 1); + GRPC_SECURITY_CONNECTOR_REF(&security_connector->base, "subchannel_factory"); + f->security_connector = security_connector; + f->merge_args = grpc_channel_args_copy(args_copy); + f->master = channel; + GRPC_CHANNEL_INTERNAL_REF(channel, "subchannel_factory"); + resolver = grpc_resolver_create(target, &f->base); + if (resolver) { + grpc_client_channel_set_resolver( + &exec_ctx, grpc_channel_get_channel_stack(channel), resolver); + GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create"); + } + grpc_subchannel_factory_unref(&exec_ctx, &f->base); + GRPC_SECURITY_CONNECTOR_UNREF(&security_connector->base, "channel_create"); + grpc_channel_args_destroy(args_copy); + if (new_args_from_connector != NULL) { + grpc_channel_args_destroy(new_args_from_connector); + } + + if (!resolver) { + GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, channel, "subchannel_factory"); + channel = NULL; + } + grpc_exec_ctx_finish(&exec_ctx); + + return channel; +} diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c new file mode 100644 index 0000000000..a92f2b3e38 --- /dev/null +++ b/src/core/lib/surface/server.c @@ -0,0 +1,1319 @@ +/* + * + * Copyright 2015-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/surface/server.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include "src/core/channel/channel_args.h" +#include "src/core/channel/connected_channel.h" +#include "src/core/iomgr/iomgr.h" +#include "src/core/support/stack_lockfree.h" +#include "src/core/support/string.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/call.h" +#include "src/core/surface/channel.h" +#include "src/core/surface/completion_queue.h" +#include "src/core/surface/init.h" +#include "src/core/transport/metadata.h" +#include "src/core/transport/static_metadata.h" + +typedef struct listener { + void *arg; + void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, + grpc_pollset **pollsets, size_t pollset_count); + void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, + grpc_closure *closure); + struct listener *next; + grpc_closure destroy_done; +} listener; + +typedef struct call_data call_data; +typedef struct channel_data channel_data; +typedef struct registered_method registered_method; + +typedef struct { + call_data *next; + call_data *prev; +} call_link; + +typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type; + +typedef struct requested_call { + requested_call_type type; + void *tag; + grpc_server *server; + grpc_completion_queue *cq_bound_to_call; + grpc_completion_queue *cq_for_notification; + grpc_call **call; + grpc_cq_completion completion; + grpc_metadata_array *initial_metadata; + union { + struct { + grpc_call_details *details; + } batch; + struct { + registered_method *registered_method; + gpr_timespec *deadline; + grpc_byte_buffer **optional_payload; + } registered; + } data; + grpc_closure publish; +} requested_call; + +typedef struct channel_registered_method { + registered_method *server_registered_method; + grpc_mdstr *method; + grpc_mdstr *host; +} channel_registered_method; + +struct channel_data { + grpc_server *server; + grpc_connectivity_state connectivity_state; + grpc_channel *channel; + /* linked list of all channels on a server */ + channel_data *next; + channel_data *prev; + channel_registered_method *registered_methods; + uint32_t registered_method_slots; + uint32_t registered_method_max_probes; + grpc_closure finish_destroy_channel_closure; + grpc_closure channel_connectivity_changed; +}; + +typedef struct shutdown_tag { + void *tag; + grpc_completion_queue *cq; + grpc_cq_completion completion; +} shutdown_tag; + +typedef enum { + /* waiting for metadata */ + NOT_STARTED, + /* inital metadata read, not flow controlled in yet */ + PENDING, + /* flow controlled in, on completion queue */ + ACTIVATED, + /* cancelled before being queued */ + ZOMBIED +} call_state; + +typedef struct request_matcher request_matcher; + +struct call_data { + grpc_call *call; + + /** protects state */ + gpr_mu mu_state; + /** the current state of a call - see call_state */ + call_state state; + + grpc_mdstr *path; + grpc_mdstr *host; + gpr_timespec deadline; + + grpc_completion_queue *cq_new; + + grpc_metadata_batch *recv_initial_metadata; + grpc_metadata_array initial_metadata; + + grpc_closure got_initial_metadata; + grpc_closure server_on_recv_initial_metadata; + grpc_closure kill_zombie_closure; + grpc_closure *on_done_recv_initial_metadata; + + call_data *pending_next; +}; + +struct request_matcher { + call_data *pending_head; + call_data *pending_tail; + gpr_stack_lockfree *requests; +}; + +struct registered_method { + char *method; + char *host; + request_matcher request_matcher; + registered_method *next; +}; + +typedef struct { + grpc_channel **channels; + size_t num_channels; +} channel_broadcaster; + +struct grpc_server { + grpc_channel_args *channel_args; + + grpc_completion_queue **cqs; + grpc_pollset **pollsets; + size_t cq_count; + + /* The two following mutexes control access to server-state + mu_global controls access to non-call-related state (e.g., channel state) + mu_call controls access to call-related state (e.g., the call lists) + + If they are ever required to be nested, you must lock mu_global + before mu_call. This is currently used in shutdown processing + (grpc_server_shutdown_and_notify and maybe_finish_shutdown) */ + gpr_mu mu_global; /* mutex for server and channel state */ + gpr_mu mu_call; /* mutex for call-specific state */ + + registered_method *registered_methods; + request_matcher unregistered_request_matcher; + /** free list of available requested_calls indices */ + gpr_stack_lockfree *request_freelist; + /** requested call backing data */ + requested_call *requested_calls; + size_t max_requested_calls; + + gpr_atm shutdown_flag; + uint8_t shutdown_published; + size_t num_shutdown_tags; + shutdown_tag *shutdown_tags; + + channel_data root_channel_data; + + listener *listeners; + int listeners_destroyed; + gpr_refcount internal_refcount; + + /** when did we print the last shutdown progress message */ + gpr_timespec last_shutdown_message_time; +}; + +#define SERVER_FROM_CALL_ELEM(elem) \ + (((channel_data *)(elem)->channel_data)->server) + +static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server, + call_data *calld, requested_call *rc); +static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server, + requested_call *rc); +/* Before calling maybe_finish_shutdown, we must hold mu_global and not + hold mu_call */ +static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_server *server); + +/* + * channel broadcaster + */ + +/* assumes server locked */ +static void channel_broadcaster_init(grpc_server *s, channel_broadcaster *cb) { + channel_data *c; + size_t count = 0; + for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { + count++; + } + cb->num_channels = count; + cb->channels = gpr_malloc(sizeof(*cb->channels) * cb->num_channels); + count = 0; + for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { + cb->channels[count++] = c->channel; + GRPC_CHANNEL_INTERNAL_REF(c->channel, "broadcast"); + } +} + +struct shutdown_cleanup_args { + grpc_closure closure; + gpr_slice slice; +}; + +static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg, + bool iomgr_status_ignored) { + struct shutdown_cleanup_args *a = arg; + gpr_slice_unref(a->slice); + gpr_free(a); +} + +static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel, + int send_goaway, int send_disconnect) { + grpc_transport_op op; + struct shutdown_cleanup_args *sc; + grpc_channel_element *elem; + + memset(&op, 0, sizeof(op)); + op.send_goaway = send_goaway; + sc = gpr_malloc(sizeof(*sc)); + sc->slice = gpr_slice_from_copied_string("Server shutdown"); + op.goaway_message = &sc->slice; + op.goaway_status = GRPC_STATUS_OK; + op.disconnect = send_disconnect; + grpc_closure_init(&sc->closure, shutdown_cleanup, sc); + op.on_consumed = &sc->closure; + + elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0); + elem->filter->start_transport_op(exec_ctx, elem, &op); +} + +static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx, + channel_broadcaster *cb, + int send_goaway, + int force_disconnect) { + size_t i; + + for (i = 0; i < cb->num_channels; i++) { + send_shutdown(exec_ctx, cb->channels[i], send_goaway, force_disconnect); + GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, cb->channels[i], "broadcast"); + } + gpr_free(cb->channels); +} + +/* + * request_matcher + */ + +static void request_matcher_init(request_matcher *rm, size_t entries) { + memset(rm, 0, sizeof(*rm)); + rm->requests = gpr_stack_lockfree_create(entries); +} + +static void request_matcher_destroy(request_matcher *rm) { + GPR_ASSERT(gpr_stack_lockfree_pop(rm->requests) == -1); + gpr_stack_lockfree_destroy(rm->requests); +} + +static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, bool success) { + grpc_call_destroy(grpc_call_from_top_element(elem)); +} + +static void request_matcher_zombify_all_pending_calls(grpc_exec_ctx *exec_ctx, + request_matcher *rm) { + while (rm->pending_head) { + call_data *calld = rm->pending_head; + rm->pending_head = calld->pending_next; + gpr_mu_lock(&calld->mu_state); + calld->state = ZOMBIED; + gpr_mu_unlock(&calld->mu_state); + grpc_closure_init( + &calld->kill_zombie_closure, kill_zombie, + grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0)); + grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL); + } +} + +static void request_matcher_kill_requests(grpc_exec_ctx *exec_ctx, + grpc_server *server, + request_matcher *rm) { + int request_id; + while ((request_id = gpr_stack_lockfree_pop(rm->requests)) != -1) { + fail_call(exec_ctx, server, &server->requested_calls[request_id]); + } +} + +/* + * server proper + */ + +static void server_ref(grpc_server *server) { + gpr_ref(&server->internal_refcount); +} + +static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) { + registered_method *rm; + size_t i; + grpc_channel_args_destroy(server->channel_args); + gpr_mu_destroy(&server->mu_global); + gpr_mu_destroy(&server->mu_call); + while ((rm = server->registered_methods) != NULL) { + server->registered_methods = rm->next; + request_matcher_destroy(&rm->request_matcher); + gpr_free(rm->method); + gpr_free(rm->host); + gpr_free(rm); + } + for (i = 0; i < server->cq_count; i++) { + GRPC_CQ_INTERNAL_UNREF(server->cqs[i], "server"); + } + request_matcher_destroy(&server->unregistered_request_matcher); + gpr_stack_lockfree_destroy(server->request_freelist); + gpr_free(server->cqs); + gpr_free(server->pollsets); + gpr_free(server->shutdown_tags); + gpr_free(server->requested_calls); + gpr_free(server); +} + +static void server_unref(grpc_exec_ctx *exec_ctx, grpc_server *server) { + if (gpr_unref(&server->internal_refcount)) { + server_delete(exec_ctx, server); + } +} + +static int is_channel_orphaned(channel_data *chand) { + return chand->next == chand; +} + +static void orphan_channel(channel_data *chand) { + chand->next->prev = chand->prev; + chand->prev->next = chand->next; + chand->next = chand->prev = chand; +} + +static void finish_destroy_channel(grpc_exec_ctx *exec_ctx, void *cd, + bool success) { + channel_data *chand = cd; + grpc_server *server = chand->server; + GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "server"); + server_unref(exec_ctx, server); +} + +static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand) { + if (is_channel_orphaned(chand)) return; + GPR_ASSERT(chand->server != NULL); + orphan_channel(chand); + server_ref(chand->server); + maybe_finish_shutdown(exec_ctx, chand->server); + chand->finish_destroy_channel_closure.cb = finish_destroy_channel; + chand->finish_destroy_channel_closure.cb_arg = chand; + + grpc_transport_op op; + memset(&op, 0, sizeof(op)); + op.set_accept_stream = true; + op.on_consumed = &chand->finish_destroy_channel_closure; + grpc_channel_next_op(exec_ctx, + grpc_channel_stack_element( + grpc_channel_get_channel_stack(chand->channel), 0), + &op); +} + +static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server, + grpc_call_element *elem, request_matcher *rm) { + call_data *calld = elem->call_data; + int request_id; + + if (gpr_atm_acq_load(&server->shutdown_flag)) { + gpr_mu_lock(&calld->mu_state); + calld->state = ZOMBIED; + gpr_mu_unlock(&calld->mu_state); + grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem); + grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL); + return; + } + + request_id = gpr_stack_lockfree_pop(rm->requests); + if (request_id == -1) { + gpr_mu_lock(&server->mu_call); + gpr_mu_lock(&calld->mu_state); + calld->state = PENDING; + gpr_mu_unlock(&calld->mu_state); + if (rm->pending_head == NULL) { + rm->pending_tail = rm->pending_head = calld; + } else { + rm->pending_tail->pending_next = calld; + rm->pending_tail = calld; + } + calld->pending_next = NULL; + gpr_mu_unlock(&server->mu_call); + } else { + gpr_mu_lock(&calld->mu_state); + calld->state = ACTIVATED; + gpr_mu_unlock(&calld->mu_state); + begin_call(exec_ctx, server, calld, &server->requested_calls[request_id]); + } +} + +static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { + channel_data *chand = elem->channel_data; + call_data *calld = elem->call_data; + grpc_server *server = chand->server; + uint32_t i; + uint32_t hash; + channel_registered_method *rm; + + if (chand->registered_methods && calld->path && calld->host) { + /* TODO(ctiller): unify these two searches */ + /* check for an exact match with host */ + hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash); + for (i = 0; i <= chand->registered_method_max_probes; i++) { + rm = &chand->registered_methods[(hash + i) % + chand->registered_method_slots]; + if (!rm) break; + if (rm->host != calld->host) continue; + if (rm->method != calld->path) continue; + finish_start_new_rpc(exec_ctx, server, elem, + &rm->server_registered_method->request_matcher); + return; + } + /* check for a wildcard method definition (no host set) */ + hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash); + for (i = 0; i <= chand->registered_method_max_probes; i++) { + rm = &chand->registered_methods[(hash + i) % + chand->registered_method_slots]; + if (!rm) break; + if (rm->host != NULL) continue; + if (rm->method != calld->path) continue; + finish_start_new_rpc(exec_ctx, server, elem, + &rm->server_registered_method->request_matcher); + return; + } + } + finish_start_new_rpc(exec_ctx, server, elem, + &server->unregistered_request_matcher); +} + +static int num_listeners(grpc_server *server) { + listener *l; + int n = 0; + for (l = server->listeners; l; l = l->next) { + n++; + } + return n; +} + +static void done_shutdown_event(grpc_exec_ctx *exec_ctx, void *server, + grpc_cq_completion *completion) { + server_unref(exec_ctx, server); +} + +static int num_channels(grpc_server *server) { + channel_data *chand; + int n = 0; + for (chand = server->root_channel_data.next; + chand != &server->root_channel_data; chand = chand->next) { + n++; + } + return n; +} + +static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx, + grpc_server *server) { + registered_method *rm; + request_matcher_kill_requests(exec_ctx, server, + &server->unregistered_request_matcher); + request_matcher_zombify_all_pending_calls( + exec_ctx, &server->unregistered_request_matcher); + for (rm = server->registered_methods; rm; rm = rm->next) { + request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher); + request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher); + } +} + +static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, + grpc_server *server) { + size_t i; + if (!gpr_atm_acq_load(&server->shutdown_flag) || server->shutdown_published) { + return; + } + + kill_pending_work_locked(exec_ctx, server); + + if (server->root_channel_data.next != &server->root_channel_data || + server->listeners_destroyed < num_listeners(server)) { + if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), + server->last_shutdown_message_time), + gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) { + server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME); + gpr_log(GPR_DEBUG, + "Waiting for %d channels and %d/%d listeners to be destroyed" + " before shutting down server", + num_channels(server), + num_listeners(server) - server->listeners_destroyed, + num_listeners(server)); + } + return; + } + server->shutdown_published = 1; + for (i = 0; i < server->num_shutdown_tags; i++) { + server_ref(server); + grpc_cq_end_op(exec_ctx, server->shutdown_tags[i].cq, + server->shutdown_tags[i].tag, 1, done_shutdown_event, server, + &server->shutdown_tags[i].completion); + } +} + +static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) { + grpc_call_element *elem = user_data; + call_data *calld = elem->call_data; + if (md->key == GRPC_MDSTR_PATH) { + calld->path = GRPC_MDSTR_REF(md->value); + return NULL; + } else if (md->key == GRPC_MDSTR_AUTHORITY) { + calld->host = GRPC_MDSTR_REF(md->value); + return NULL; + } + return md; +} + +static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr, + bool success) { + grpc_call_element *elem = ptr; + call_data *calld = elem->call_data; + gpr_timespec op_deadline; + + grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem); + op_deadline = calld->recv_initial_metadata->deadline; + if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) { + calld->deadline = op_deadline; + } + if (calld->host && calld->path) { + /* do nothing */ + } else { + success = 0; + } + + calld->on_done_recv_initial_metadata->cb( + exec_ctx, calld->on_done_recv_initial_metadata->cb_arg, success); +} + +static void server_mutate_op(grpc_call_element *elem, + grpc_transport_stream_op *op) { + call_data *calld = elem->call_data; + + if (op->recv_initial_metadata != NULL) { + calld->recv_initial_metadata = op->recv_initial_metadata; + calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata; + } +} + +static void server_start_transport_stream_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + GRPC_CALL_LOG_OP(GPR_INFO, elem, op); + server_mutate_op(elem, op); + grpc_call_next_op(exec_ctx, elem, op); +} + +static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr, + bool success) { + grpc_call_element *elem = ptr; + call_data *calld = elem->call_data; + if (success) { + start_new_rpc(exec_ctx, elem); + } else { + gpr_mu_lock(&calld->mu_state); + if (calld->state == NOT_STARTED) { + calld->state = ZOMBIED; + gpr_mu_unlock(&calld->mu_state); + grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem); + grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL); + } else if (calld->state == PENDING) { + calld->state = ZOMBIED; + gpr_mu_unlock(&calld->mu_state); + /* zombied call will be destroyed when it's removed from the pending + queue... later */ + } else { + gpr_mu_unlock(&calld->mu_state); + } + } +} + +static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd, + grpc_transport *transport, + const void *transport_server_data) { + channel_data *chand = cd; + /* create a call */ + grpc_call *call = + grpc_call_create(chand->channel, NULL, 0, NULL, transport_server_data, + NULL, 0, gpr_inf_future(GPR_CLOCK_MONOTONIC)); + grpc_call_element *elem = + grpc_call_stack_element(grpc_call_get_call_stack(call), 0); + call_data *calld = elem->call_data; + grpc_op op; + memset(&op, 0, sizeof(op)); + op.op = GRPC_OP_RECV_INITIAL_METADATA; + op.data.recv_initial_metadata = &calld->initial_metadata; + grpc_closure_init(&calld->got_initial_metadata, got_initial_metadata, elem); + grpc_call_start_batch_and_execute(exec_ctx, call, &op, 1, + &calld->got_initial_metadata); +} + +static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd, + bool iomgr_status_ignored) { + channel_data *chand = cd; + grpc_server *server = chand->server; + if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) { + grpc_transport_op op; + memset(&op, 0, sizeof(op)); + op.on_connectivity_state_change = &chand->channel_connectivity_changed, + op.connectivity_state = &chand->connectivity_state; + grpc_channel_next_op(exec_ctx, + grpc_channel_stack_element( + grpc_channel_get_channel_stack(chand->channel), 0), + &op); + } else { + gpr_mu_lock(&server->mu_global); + destroy_channel(exec_ctx, chand); + gpr_mu_unlock(&server->mu_global); + GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "connectivity"); + } +} + +static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args) { + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + memset(calld, 0, sizeof(call_data)); + calld->deadline = gpr_inf_future(GPR_CLOCK_REALTIME); + calld->call = grpc_call_from_top_element(elem); + gpr_mu_init(&calld->mu_state); + + grpc_closure_init(&calld->server_on_recv_initial_metadata, + server_on_recv_initial_metadata, elem); + + server_ref(chand->server); +} + +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + channel_data *chand = elem->channel_data; + call_data *calld = elem->call_data; + + GPR_ASSERT(calld->state != PENDING); + + if (calld->host) { + GRPC_MDSTR_UNREF(calld->host); + } + if (calld->path) { + GRPC_MDSTR_UNREF(calld->path); + } + grpc_metadata_array_destroy(&calld->initial_metadata); + + gpr_mu_destroy(&calld->mu_state); + + server_unref(exec_ctx, chand->server); +} + +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + channel_data *chand = elem->channel_data; + GPR_ASSERT(args->is_first); + GPR_ASSERT(!args->is_last); + chand->server = NULL; + chand->channel = NULL; + chand->next = chand->prev = chand; + chand->registered_methods = NULL; + chand->connectivity_state = GRPC_CHANNEL_IDLE; + grpc_closure_init(&chand->channel_connectivity_changed, + channel_connectivity_changed, chand); +} + +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) { + size_t i; + channel_data *chand = elem->channel_data; + if (chand->registered_methods) { + for (i = 0; i < chand->registered_method_slots; i++) { + if (chand->registered_methods[i].method) { + GRPC_MDSTR_UNREF(chand->registered_methods[i].method); + } + if (chand->registered_methods[i].host) { + GRPC_MDSTR_UNREF(chand->registered_methods[i].host); + } + } + gpr_free(chand->registered_methods); + } + if (chand->server) { + gpr_mu_lock(&chand->server->mu_global); + chand->next->prev = chand->prev; + chand->prev->next = chand->next; + chand->next = chand->prev = chand; + maybe_finish_shutdown(exec_ctx, chand->server); + gpr_mu_unlock(&chand->server->mu_global); + server_unref(exec_ctx, chand->server); + } +} + +const grpc_channel_filter grpc_server_top_filter = { + server_start_transport_stream_op, + grpc_channel_next_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "server", +}; + +void grpc_server_register_completion_queue(grpc_server *server, + grpc_completion_queue *cq, + void *reserved) { + size_t i, n; + GRPC_API_TRACE( + "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3, + (server, cq, reserved)); + GPR_ASSERT(!reserved); + for (i = 0; i < server->cq_count; i++) { + if (server->cqs[i] == cq) return; + } + GRPC_CQ_INTERNAL_REF(cq, "server"); + grpc_cq_mark_server_cq(cq); + n = server->cq_count++; + server->cqs = gpr_realloc(server->cqs, + server->cq_count * sizeof(grpc_completion_queue *)); + server->cqs[n] = cq; +} + +grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) { + size_t i; + + GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved)); + + grpc_server *server = gpr_malloc(sizeof(grpc_server)); + + GPR_ASSERT(grpc_is_initialized() && "call grpc_init()"); + + memset(server, 0, sizeof(grpc_server)); + + gpr_mu_init(&server->mu_global); + gpr_mu_init(&server->mu_call); + + /* decremented by grpc_server_destroy */ + gpr_ref_init(&server->internal_refcount, 1); + server->root_channel_data.next = server->root_channel_data.prev = + &server->root_channel_data; + + /* TODO(ctiller): expose a channel_arg for this */ + server->max_requested_calls = 32768; + server->request_freelist = + gpr_stack_lockfree_create(server->max_requested_calls); + for (i = 0; i < (size_t)server->max_requested_calls; i++) { + gpr_stack_lockfree_push(server->request_freelist, (int)i); + } + request_matcher_init(&server->unregistered_request_matcher, + server->max_requested_calls); + server->requested_calls = gpr_malloc(server->max_requested_calls * + sizeof(*server->requested_calls)); + + server->channel_args = grpc_channel_args_copy(args); + + return server; +} + +static int streq(const char *a, const char *b) { + if (a == NULL && b == NULL) return 1; + if (a == NULL) return 0; + if (b == NULL) return 0; + return 0 == strcmp(a, b); +} + +void *grpc_server_register_method(grpc_server *server, const char *method, + const char *host) { + registered_method *m; + GRPC_API_TRACE("grpc_server_register_method(server=%p, method=%s, host=%s)", + 3, (server, method, host)); + if (!method) { + gpr_log(GPR_ERROR, + "grpc_server_register_method method string cannot be NULL"); + return NULL; + } + for (m = server->registered_methods; m; m = m->next) { + if (streq(m->method, method) && streq(m->host, host)) { + gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method, + host ? host : "*"); + return NULL; + } + } + m = gpr_malloc(sizeof(registered_method)); + memset(m, 0, sizeof(*m)); + request_matcher_init(&m->request_matcher, server->max_requested_calls); + m->method = gpr_strdup(method); + m->host = gpr_strdup(host); + m->next = server->registered_methods; + server->registered_methods = m; + return m; +} + +void grpc_server_start(grpc_server *server) { + listener *l; + size_t i; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server)); + + server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count); + for (i = 0; i < server->cq_count; i++) { + server->pollsets[i] = grpc_cq_pollset(server->cqs[i]); + } + + for (l = server->listeners; l; l = l->next) { + l->start(&exec_ctx, server, l->arg, server->pollsets, server->cq_count); + } + + grpc_exec_ctx_finish(&exec_ctx); +} + +void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s, + grpc_transport *transport, + const grpc_channel_args *args) { + size_t i; + size_t num_registered_methods; + size_t alloc; + registered_method *rm; + channel_registered_method *crm; + grpc_channel *channel; + channel_data *chand; + grpc_mdstr *host; + grpc_mdstr *method; + uint32_t hash; + size_t slots; + uint32_t probes; + uint32_t max_probes = 0; + grpc_transport_op op; + + for (i = 0; i < s->cq_count; i++) { + memset(&op, 0, sizeof(op)); + op.bind_pollset = grpc_cq_pollset(s->cqs[i]); + grpc_transport_perform_op(exec_ctx, transport, &op); + } + + channel = + grpc_channel_create(exec_ctx, NULL, args, GRPC_SERVER_CHANNEL, transport); + chand = (channel_data *)grpc_channel_stack_element( + grpc_channel_get_channel_stack(channel), 0) + ->channel_data; + chand->server = s; + server_ref(s); + chand->channel = channel; + + num_registered_methods = 0; + for (rm = s->registered_methods; rm; rm = rm->next) { + num_registered_methods++; + } + /* build a lookup table phrased in terms of mdstr's in this channels context + to quickly find registered methods */ + if (num_registered_methods > 0) { + slots = 2 * num_registered_methods; + alloc = sizeof(channel_registered_method) * slots; + chand->registered_methods = gpr_malloc(alloc); + memset(chand->registered_methods, 0, alloc); + for (rm = s->registered_methods; rm; rm = rm->next) { + host = rm->host ? grpc_mdstr_from_string(rm->host) : NULL; + method = grpc_mdstr_from_string(rm->method); + hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash); + for (probes = 0; chand->registered_methods[(hash + probes) % slots] + .server_registered_method != NULL; + probes++) + ; + if (probes > max_probes) max_probes = probes; + crm = &chand->registered_methods[(hash + probes) % slots]; + crm->server_registered_method = rm; + crm->host = host; + crm->method = method; + } + GPR_ASSERT(slots <= UINT32_MAX); + chand->registered_method_slots = (uint32_t)slots; + chand->registered_method_max_probes = max_probes; + } + + gpr_mu_lock(&s->mu_global); + chand->next = &s->root_channel_data; + chand->prev = chand->next->prev; + chand->next->prev = chand->prev->next = chand; + gpr_mu_unlock(&s->mu_global); + + GRPC_CHANNEL_INTERNAL_REF(channel, "connectivity"); + memset(&op, 0, sizeof(op)); + op.set_accept_stream = true; + op.set_accept_stream_fn = accept_stream; + op.set_accept_stream_user_data = chand; + op.on_connectivity_state_change = &chand->channel_connectivity_changed; + op.connectivity_state = &chand->connectivity_state; + op.disconnect = gpr_atm_acq_load(&s->shutdown_flag) != 0; + grpc_transport_perform_op(exec_ctx, transport, &op); +} + +void done_published_shutdown(grpc_exec_ctx *exec_ctx, void *done_arg, + grpc_cq_completion *storage) { + (void)done_arg; + gpr_free(storage); +} + +static void listener_destroy_done(grpc_exec_ctx *exec_ctx, void *s, + bool success) { + grpc_server *server = s; + gpr_mu_lock(&server->mu_global); + server->listeners_destroyed++; + maybe_finish_shutdown(exec_ctx, server); + gpr_mu_unlock(&server->mu_global); +} + +void grpc_server_shutdown_and_notify(grpc_server *server, + grpc_completion_queue *cq, void *tag) { + listener *l; + shutdown_tag *sdt; + channel_broadcaster broadcaster; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3, + (server, cq, tag)); + + /* lock, and gather up some stuff to do */ + gpr_mu_lock(&server->mu_global); + grpc_cq_begin_op(cq, tag); + if (server->shutdown_published) { + grpc_cq_end_op(&exec_ctx, cq, tag, 1, done_published_shutdown, NULL, + gpr_malloc(sizeof(grpc_cq_completion))); + gpr_mu_unlock(&server->mu_global); + goto done; + } + server->shutdown_tags = + gpr_realloc(server->shutdown_tags, + sizeof(shutdown_tag) * (server->num_shutdown_tags + 1)); + sdt = &server->shutdown_tags[server->num_shutdown_tags++]; + sdt->tag = tag; + sdt->cq = cq; + if (gpr_atm_acq_load(&server->shutdown_flag)) { + gpr_mu_unlock(&server->mu_global); + goto done; + } + + server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME); + + channel_broadcaster_init(server, &broadcaster); + + gpr_atm_rel_store(&server->shutdown_flag, 1); + + /* collect all unregistered then registered calls */ + gpr_mu_lock(&server->mu_call); + kill_pending_work_locked(&exec_ctx, server); + gpr_mu_unlock(&server->mu_call); + + maybe_finish_shutdown(&exec_ctx, server); + gpr_mu_unlock(&server->mu_global); + + /* Shutdown listeners */ + for (l = server->listeners; l; l = l->next) { + grpc_closure_init(&l->destroy_done, listener_destroy_done, server); + l->destroy(&exec_ctx, server, l->arg, &l->destroy_done); + } + + channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0); + +done: + grpc_exec_ctx_finish(&exec_ctx); +} + +void grpc_server_cancel_all_calls(grpc_server *server) { + channel_broadcaster broadcaster; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + GRPC_API_TRACE("grpc_server_cancel_all_calls(server=%p)", 1, (server)); + + gpr_mu_lock(&server->mu_global); + channel_broadcaster_init(server, &broadcaster); + gpr_mu_unlock(&server->mu_global); + + channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, 1); + grpc_exec_ctx_finish(&exec_ctx); +} + +void grpc_server_destroy(grpc_server *server) { + listener *l; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + GRPC_API_TRACE("grpc_server_destroy(server=%p)", 1, (server)); + + gpr_mu_lock(&server->mu_global); + GPR_ASSERT(gpr_atm_acq_load(&server->shutdown_flag) || !server->listeners); + GPR_ASSERT(server->listeners_destroyed == num_listeners(server)); + + while (server->listeners) { + l = server->listeners; + server->listeners = l->next; + gpr_free(l); + } + + gpr_mu_unlock(&server->mu_global); + + server_unref(&exec_ctx, server); + grpc_exec_ctx_finish(&exec_ctx); +} + +void grpc_server_add_listener( + grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, + void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, + grpc_pollset **pollsets, size_t pollset_count), + void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, + grpc_closure *on_done)) { + listener *l = gpr_malloc(sizeof(listener)); + l->arg = arg; + l->start = start; + l->destroy = destroy; + l->next = server->listeners; + server->listeners = l; +} + +static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx, + grpc_server *server, + requested_call *rc) { + call_data *calld = NULL; + request_matcher *rm = NULL; + int request_id; + if (gpr_atm_acq_load(&server->shutdown_flag)) { + fail_call(exec_ctx, server, rc); + return GRPC_CALL_OK; + } + request_id = gpr_stack_lockfree_pop(server->request_freelist); + if (request_id == -1) { + /* out of request ids: just fail this one */ + fail_call(exec_ctx, server, rc); + return GRPC_CALL_OK; + } + switch (rc->type) { + case BATCH_CALL: + rm = &server->unregistered_request_matcher; + break; + case REGISTERED_CALL: + rm = &rc->data.registered.registered_method->request_matcher; + break; + } + server->requested_calls[request_id] = *rc; + gpr_free(rc); + if (gpr_stack_lockfree_push(rm->requests, request_id)) { + /* this was the first queued request: we need to lock and start + matching calls */ + gpr_mu_lock(&server->mu_call); + while ((calld = rm->pending_head) != NULL) { + request_id = gpr_stack_lockfree_pop(rm->requests); + if (request_id == -1) break; + rm->pending_head = calld->pending_next; + gpr_mu_unlock(&server->mu_call); + gpr_mu_lock(&calld->mu_state); + if (calld->state == ZOMBIED) { + gpr_mu_unlock(&calld->mu_state); + grpc_closure_init( + &calld->kill_zombie_closure, kill_zombie, + grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0)); + grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, + NULL); + } else { + GPR_ASSERT(calld->state == PENDING); + calld->state = ACTIVATED; + gpr_mu_unlock(&calld->mu_state); + begin_call(exec_ctx, server, calld, + &server->requested_calls[request_id]); + } + gpr_mu_lock(&server->mu_call); + } + gpr_mu_unlock(&server->mu_call); + } + return GRPC_CALL_OK; +} + +grpc_call_error grpc_server_request_call( + grpc_server *server, grpc_call **call, grpc_call_details *details, + grpc_metadata_array *initial_metadata, + grpc_completion_queue *cq_bound_to_call, + grpc_completion_queue *cq_for_notification, void *tag) { + grpc_call_error error; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + requested_call *rc = gpr_malloc(sizeof(*rc)); + GRPC_API_TRACE( + "grpc_server_request_call(" + "server=%p, call=%p, details=%p, initial_metadata=%p, " + "cq_bound_to_call=%p, cq_for_notification=%p, tag=%p)", + 7, (server, call, details, initial_metadata, cq_bound_to_call, + cq_for_notification, tag)); + if (!grpc_cq_is_server_cq(cq_for_notification)) { + gpr_free(rc); + error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE; + goto done; + } + grpc_cq_begin_op(cq_for_notification, tag); + details->reserved = NULL; + rc->type = BATCH_CALL; + rc->server = server; + rc->tag = tag; + rc->cq_bound_to_call = cq_bound_to_call; + rc->cq_for_notification = cq_for_notification; + rc->call = call; + rc->data.batch.details = details; + rc->initial_metadata = initial_metadata; + error = queue_call_request(&exec_ctx, server, rc); +done: + grpc_exec_ctx_finish(&exec_ctx); + return error; +} + +grpc_call_error grpc_server_request_registered_call( + grpc_server *server, void *rmp, grpc_call **call, gpr_timespec *deadline, + grpc_metadata_array *initial_metadata, grpc_byte_buffer **optional_payload, + grpc_completion_queue *cq_bound_to_call, + grpc_completion_queue *cq_for_notification, void *tag) { + grpc_call_error error; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + requested_call *rc = gpr_malloc(sizeof(*rc)); + registered_method *rm = rmp; + GRPC_API_TRACE( + "grpc_server_request_registered_call(" + "server=%p, rmp=%p, call=%p, deadline=%p, initial_metadata=%p, " + "optional_payload=%p, cq_bound_to_call=%p, cq_for_notification=%p, " + "tag=%p)", + 9, (server, rmp, call, deadline, initial_metadata, optional_payload, + cq_bound_to_call, cq_for_notification, tag)); + if (!grpc_cq_is_server_cq(cq_for_notification)) { + gpr_free(rc); + error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE; + goto done; + } + grpc_cq_begin_op(cq_for_notification, tag); + rc->type = REGISTERED_CALL; + rc->server = server; + rc->tag = tag; + rc->cq_bound_to_call = cq_bound_to_call; + rc->cq_for_notification = cq_for_notification; + rc->call = call; + rc->data.registered.registered_method = rm; + rc->data.registered.deadline = deadline; + rc->initial_metadata = initial_metadata; + rc->data.registered.optional_payload = optional_payload; + error = queue_call_request(&exec_ctx, server, rc); +done: + grpc_exec_ctx_finish(&exec_ctx); + return error; +} + +static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, + void *user_data, bool success); + +static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) { + gpr_slice slice = value->slice; + size_t len = GPR_SLICE_LENGTH(slice); + + if (len + 1 > *capacity) { + *capacity = GPR_MAX(len + 1, *capacity * 2); + *dest = gpr_realloc(*dest, *capacity); + } + memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1); +} + +static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server, + call_data *calld, requested_call *rc) { + grpc_op ops[1]; + grpc_op *op = ops; + + memset(ops, 0, sizeof(ops)); + + /* called once initial metadata has been read by the call, but BEFORE + the ioreq to fetch it out of the call has been executed. + This means metadata related fields can be relied on in calld, but to + fill in the metadata array passed by the client, we need to perform + an ioreq op, that should complete immediately. */ + + grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call); + grpc_closure_init(&rc->publish, publish_registered_or_batch, rc); + *rc->call = calld->call; + calld->cq_new = rc->cq_for_notification; + GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata); + switch (rc->type) { + case BATCH_CALL: + GPR_ASSERT(calld->host != NULL); + GPR_ASSERT(calld->path != NULL); + cpstr(&rc->data.batch.details->host, + &rc->data.batch.details->host_capacity, calld->host); + cpstr(&rc->data.batch.details->method, + &rc->data.batch.details->method_capacity, calld->path); + rc->data.batch.details->deadline = calld->deadline; + break; + case REGISTERED_CALL: + *rc->data.registered.deadline = calld->deadline; + if (rc->data.registered.optional_payload) { + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = rc->data.registered.optional_payload; + op++; + } + break; + default: + GPR_UNREACHABLE_CODE(return ); + } + + GRPC_CALL_INTERNAL_REF(calld->call, "server"); + grpc_call_start_batch_and_execute(exec_ctx, calld->call, ops, + (size_t)(op - ops), &rc->publish); +} + +static void done_request_event(grpc_exec_ctx *exec_ctx, void *req, + grpc_cq_completion *c) { + requested_call *rc = req; + grpc_server *server = rc->server; + + if (rc >= server->requested_calls && + rc < server->requested_calls + server->max_requested_calls) { + GPR_ASSERT(rc - server->requested_calls <= INT_MAX); + gpr_stack_lockfree_push(server->request_freelist, + (int)(rc - server->requested_calls)); + } else { + gpr_free(req); + } + + server_unref(exec_ctx, server); +} + +static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server, + requested_call *rc) { + *rc->call = NULL; + rc->initial_metadata->count = 0; + + server_ref(server); + grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0, + done_request_event, rc, &rc->completion); +} + +static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, void *prc, + bool success) { + requested_call *rc = prc; + grpc_call *call = *rc->call; + grpc_call_element *elem = + grpc_call_stack_element(grpc_call_get_call_stack(call), 0); + call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; + server_ref(chand->server); + grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, success, done_request_event, + rc, &rc->completion); + GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "server"); +} + +const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) { + return server->channel_args; +} + +int grpc_server_has_open_connections(grpc_server *server) { + int r; + gpr_mu_lock(&server->mu_global); + r = server->root_channel_data.next != &server->root_channel_data; + gpr_mu_unlock(&server->mu_global); + return r; +} diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h new file mode 100644 index 0000000000..cd62eadd7f --- /dev/null +++ b/src/core/lib/surface/server.h @@ -0,0 +1,62 @@ +/* + * + * Copyright 2015-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_SURFACE_SERVER_H +#define GRPC_CORE_SURFACE_SERVER_H + +#include +#include "src/core/channel/channel_stack.h" +#include "src/core/transport/transport.h" + +extern const grpc_channel_filter grpc_server_top_filter; + +/* Add a listener to the server: when the server starts, it will call start, + and when it shuts down, it will call destroy */ +void grpc_server_add_listener( + grpc_exec_ctx *exec_ctx, grpc_server *server, void *listener, + void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, + grpc_pollset **pollsets, size_t npollsets), + void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, + grpc_closure *on_done)); + +/* Setup a transport - creates a channel stack, binds the transport to the + server */ +void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *server, + grpc_transport *transport, + const grpc_channel_args *args); + +const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server); + +int grpc_server_has_open_connections(grpc_server *server); + +#endif /* GRPC_CORE_SURFACE_SERVER_H */ diff --git a/src/core/lib/surface/server_chttp2.c b/src/core/lib/surface/server_chttp2.c new file mode 100644 index 0000000000..546760ecfa --- /dev/null +++ b/src/core/lib/surface/server_chttp2.c @@ -0,0 +1,146 @@ +/* + * + * Copyright 2015-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 + +#include +#include +#include +#include "src/core/channel/http_server_filter.h" +#include "src/core/iomgr/resolve_address.h" +#include "src/core/iomgr/tcp_server.h" +#include "src/core/surface/api_trace.h" +#include "src/core/surface/server.h" +#include "src/core/transport/chttp2_transport.h" + +static void setup_transport(grpc_exec_ctx *exec_ctx, void *server, + grpc_transport *transport) { + grpc_server_setup_transport(exec_ctx, server, transport, + grpc_server_get_channel_args(server)); +} + +static void new_transport(grpc_exec_ctx *exec_ctx, void *server, + grpc_endpoint *tcp, + grpc_tcp_server_acceptor *acceptor) { + /* + * Beware that the call to grpc_create_chttp2_transport() has to happen before + * grpc_tcp_server_destroy(). This is fine here, but similar code + * asynchronously doing a handshake instead of calling grpc_tcp_server_start() + * (as in server_secure_chttp2.c) needs to add synchronization to avoid this + * case. + */ + grpc_transport *transport = grpc_create_chttp2_transport( + exec_ctx, grpc_server_get_channel_args(server), tcp, 0); + setup_transport(exec_ctx, server, transport); + grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); +} + +/* Server callback: start listening on our ports */ +static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, + grpc_pollset **pollsets, size_t pollset_count) { + grpc_tcp_server *tcp = tcpp; + grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, new_transport, + server); +} + +/* Server callback: destroy the tcp listener (so we don't generate further + callbacks) */ +static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, + grpc_closure *destroy_done) { + grpc_tcp_server *tcp = tcpp; + grpc_tcp_server_unref(exec_ctx, tcp); + grpc_exec_ctx_enqueue(exec_ctx, destroy_done, true, NULL); +} + +int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) { + grpc_resolved_addresses *resolved = NULL; + grpc_tcp_server *tcp = NULL; + size_t i; + unsigned count = 0; + int port_num = -1; + int port_temp; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + GRPC_API_TRACE("grpc_server_add_insecure_http2_port(server=%p, addr=%s)", 2, + (server, addr)); + + resolved = grpc_blocking_resolve_address(addr, "http"); + if (!resolved) { + goto error; + } + + tcp = grpc_tcp_server_create(NULL); + GPR_ASSERT(tcp); + + for (i = 0; i < resolved->naddrs; i++) { + port_temp = grpc_tcp_server_add_port( + tcp, (struct sockaddr *)&resolved->addrs[i].addr, + resolved->addrs[i].len); + if (port_temp > 0) { + if (port_num == -1) { + port_num = port_temp; + } else { + GPR_ASSERT(port_num == port_temp); + } + count++; + } + } + if (count == 0) { + gpr_log(GPR_ERROR, "No address added out of total %d resolved", + resolved->naddrs); + goto error; + } + if (count != resolved->naddrs) { + gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved", + count, resolved->naddrs); + } + grpc_resolved_addresses_destroy(resolved); + + /* Register with the server only upon success */ + grpc_server_add_listener(&exec_ctx, server, tcp, start, destroy); + goto done; + +/* Error path: cleanup and return */ +error: + if (resolved) { + grpc_resolved_addresses_destroy(resolved); + } + if (tcp) { + grpc_tcp_server_unref(&exec_ctx, tcp); + } + port_num = 0; + +done: + grpc_exec_ctx_finish(&exec_ctx); + return port_num; +} diff --git a/src/core/lib/surface/surface_trace.h b/src/core/lib/surface/surface_trace.h new file mode 100644 index 0000000000..a55a88e44d --- /dev/null +++ b/src/core/lib/surface/surface_trace.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2015-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_SURFACE_SURFACE_TRACE_H +#define GRPC_CORE_SURFACE_SURFACE_TRACE_H + +#include +#include "src/core/debug/trace.h" +#include "src/core/surface/api_trace.h" + +#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \ + if (grpc_api_trace) { \ + char *_ev = grpc_event_string(event); \ + gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \ + gpr_free(_ev); \ + } + +#endif /* GRPC_CORE_SURFACE_SURFACE_TRACE_H */ diff --git a/src/core/lib/surface/validate_metadata.c b/src/core/lib/surface/validate_metadata.c new file mode 100644 index 0000000000..bf4126867f --- /dev/null +++ b/src/core/lib/surface/validate_metadata.c @@ -0,0 +1,73 @@ +/* + * + * 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 +#include + +#include + +static int conforms_to(const char *s, size_t len, const uint8_t *legal_bits) { + const char *p = s; + const char *e = s + len; + for (; p != e; p++) { + int idx = *p; + int byte = idx / 8; + int bit = idx % 8; + if ((legal_bits[byte] & (1 << bit)) == 0) return 0; + } + return 1; +} + +int grpc_header_key_is_legal(const char *key, size_t length) { + static const uint8_t legal_header_bits[256 / 8] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0x00, 0x00, 0x00, + 0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + if (length == 0) { + return 0; + } + return conforms_to(key, length, legal_header_bits); +} + +int grpc_header_nonbin_value_is_legal(const char *value, size_t length) { + static const uint8_t legal_header_bits[256 / 8] = { + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + return conforms_to(value, length, legal_header_bits); +} + +int grpc_is_binary_header(const char *key, size_t length) { + if (length < 5) return 0; + return 0 == memcmp(key + length - 4, "-bin", 4); +} diff --git a/src/core/lib/surface/version.c b/src/core/lib/surface/version.c new file mode 100644 index 0000000000..7723f39401 --- /dev/null +++ b/src/core/lib/surface/version.c @@ -0,0 +1,39 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* This file is autogenerated from: + templates/src/core/surface/version.c.template */ + +#include + +const char *grpc_version_string(void) { return "0.14.0-dev"; } diff --git a/src/core/lib/transport/byte_stream.c b/src/core/lib/transport/byte_stream.c new file mode 100644 index 0000000000..8e6fb2cbef --- /dev/null +++ b/src/core/lib/transport/byte_stream.c @@ -0,0 +1,78 @@ +/* + * + * Copyright 2015, 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/transport/byte_stream.h" + +#include + +#include + +int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, gpr_slice *slice, + size_t max_size_hint, grpc_closure *on_complete) { + return byte_stream->next(exec_ctx, byte_stream, slice, max_size_hint, + on_complete); +} + +void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream) { + byte_stream->destroy(exec_ctx, byte_stream); +} + +/* slice_buffer_stream */ + +static int slice_buffer_stream_next(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, + gpr_slice *slice, size_t max_size_hint, + grpc_closure *on_complete) { + grpc_slice_buffer_stream *stream = (grpc_slice_buffer_stream *)byte_stream; + GPR_ASSERT(stream->cursor < stream->backing_buffer->count); + *slice = gpr_slice_ref(stream->backing_buffer->slices[stream->cursor]); + stream->cursor++; + return 1; +} + +static void slice_buffer_stream_destroy(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream) {} + +void grpc_slice_buffer_stream_init(grpc_slice_buffer_stream *stream, + gpr_slice_buffer *slice_buffer, + uint32_t flags) { + GPR_ASSERT(slice_buffer->length <= UINT32_MAX); + stream->base.length = (uint32_t)slice_buffer->length; + stream->base.flags = flags; + stream->base.next = slice_buffer_stream_next; + stream->base.destroy = slice_buffer_stream_destroy; + stream->backing_buffer = slice_buffer; + stream->cursor = 0; +} diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h new file mode 100644 index 0000000000..ab42d07e7e --- /dev/null +++ b/src/core/lib/transport/byte_stream.h @@ -0,0 +1,89 @@ +/* + * + * Copyright 2015-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_TRANSPORT_BYTE_STREAM_H +#define GRPC_CORE_TRANSPORT_BYTE_STREAM_H + +#include +#include "src/core/iomgr/exec_ctx.h" + +/** Internal bit flag for grpc_begin_message's \a flags signaling the use of + * compression for the message */ +#define GRPC_WRITE_INTERNAL_COMPRESS (0x80000000u) +/** Mask of all valid internal flags. */ +#define GRPC_WRITE_INTERNAL_USED_MASK (GRPC_WRITE_INTERNAL_COMPRESS) + +struct grpc_byte_stream; +typedef struct grpc_byte_stream grpc_byte_stream; + +struct grpc_byte_stream { + uint32_t length; + uint32_t flags; + int (*next)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, + gpr_slice *slice, size_t max_size_hint, + grpc_closure *on_complete); + void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream); +}; + +/* returns 1 if the bytes are available immediately (in which case + * on_complete will not be called), 0 if the bytes will be available + * asynchronously. + * + * on entry, *remaining can be set as a hint as to the maximum number + * of bytes that would be acceptable to read. + * + * fills *buffer, *length, *remaining with the bytes, length of bytes + * and length of data remaining to be read before either returning 1 + * or calling on_complete. + * + * once a slice is returned into *slice, it is owned by the caller. + */ +int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, gpr_slice *slice, + size_t max_size_hint, grpc_closure *on_complete); + +void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream); + +/* grpc_byte_stream that wraps a slice buffer */ +typedef struct grpc_slice_buffer_stream { + grpc_byte_stream base; + gpr_slice_buffer *backing_buffer; + size_t cursor; +} grpc_slice_buffer_stream; + +void grpc_slice_buffer_stream_init(grpc_slice_buffer_stream *stream, + gpr_slice_buffer *slice_buffer, + uint32_t flags); + +#endif /* GRPC_CORE_TRANSPORT_BYTE_STREAM_H */ diff --git a/src/core/lib/transport/chttp2/alpn.c b/src/core/lib/transport/chttp2/alpn.c new file mode 100644 index 0000000000..69da4e6718 --- /dev/null +++ b/src/core/lib/transport/chttp2/alpn.c @@ -0,0 +1,56 @@ +/* + * + * Copyright 2015, 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/transport/chttp2/alpn.h" +#include +#include + +/* in order of preference */ +static const char *const supported_versions[] = {"h2"}; + +int grpc_chttp2_is_alpn_version_supported(const char *version, size_t size) { + size_t i; + for (i = 0; i < GPR_ARRAY_SIZE(supported_versions); i++) { + if (!strncmp(version, supported_versions[i], size)) return 1; + } + return 0; +} + +size_t grpc_chttp2_num_alpn_versions(void) { + return GPR_ARRAY_SIZE(supported_versions); +} + +const char *grpc_chttp2_get_alpn_version_index(size_t i) { + GPR_ASSERT(i < GPR_ARRAY_SIZE(supported_versions)); + return supported_versions[i]; +} diff --git a/src/core/lib/transport/chttp2/alpn.h b/src/core/lib/transport/chttp2/alpn.h new file mode 100644 index 0000000000..68010e3155 --- /dev/null +++ b/src/core/lib/transport/chttp2/alpn.h @@ -0,0 +1,49 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_ALPN_H +#define GRPC_CORE_TRANSPORT_CHTTP2_ALPN_H + +#include + +/* Retuns 1 if the version is supported, 0 otherwise. */ +int grpc_chttp2_is_alpn_version_supported(const char *version, size_t size); + +/* Returns the number of protocol versions to advertise */ +size_t grpc_chttp2_num_alpn_versions(void); + +/* Returns the protocol version at index i (0 <= i < + * grpc_chttp2_num_alpn_versions()) */ +const char *grpc_chttp2_get_alpn_version_index(size_t i); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_ALPN_H */ diff --git a/src/core/lib/transport/chttp2/bin_encoder.c b/src/core/lib/transport/chttp2/bin_encoder.c new file mode 100644 index 0000000000..3d31162499 --- /dev/null +++ b/src/core/lib/transport/chttp2/bin_encoder.c @@ -0,0 +1,233 @@ +/* + * + * Copyright 2015-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/transport/chttp2/bin_encoder.h" + +#include + +#include +#include "src/core/transport/chttp2/huffsyms.h" + +static const char alphabet[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +typedef struct { + uint16_t bits; + uint8_t length; +} b64_huff_sym; + +static const b64_huff_sym huff_alphabet[64] = { + {0x21, 6}, {0x5d, 7}, {0x5e, 7}, {0x5f, 7}, {0x60, 7}, {0x61, 7}, + {0x62, 7}, {0x63, 7}, {0x64, 7}, {0x65, 7}, {0x66, 7}, {0x67, 7}, + {0x68, 7}, {0x69, 7}, {0x6a, 7}, {0x6b, 7}, {0x6c, 7}, {0x6d, 7}, + {0x6e, 7}, {0x6f, 7}, {0x70, 7}, {0x71, 7}, {0x72, 7}, {0xfc, 8}, + {0x73, 7}, {0xfd, 8}, {0x3, 5}, {0x23, 6}, {0x4, 5}, {0x24, 6}, + {0x5, 5}, {0x25, 6}, {0x26, 6}, {0x27, 6}, {0x6, 5}, {0x74, 7}, + {0x75, 7}, {0x28, 6}, {0x29, 6}, {0x2a, 6}, {0x7, 5}, {0x2b, 6}, + {0x76, 7}, {0x2c, 6}, {0x8, 5}, {0x9, 5}, {0x2d, 6}, {0x77, 7}, + {0x78, 7}, {0x79, 7}, {0x7a, 7}, {0x7b, 7}, {0x0, 5}, {0x1, 5}, + {0x2, 5}, {0x19, 6}, {0x1a, 6}, {0x1b, 6}, {0x1c, 6}, {0x1d, 6}, + {0x1e, 6}, {0x1f, 6}, {0x7fb, 11}, {0x18, 6}}; + +static const uint8_t tail_xtra[3] = {0, 2, 3}; + +gpr_slice grpc_chttp2_base64_encode(gpr_slice input) { + size_t input_length = GPR_SLICE_LENGTH(input); + size_t input_triplets = input_length / 3; + size_t tail_case = input_length % 3; + size_t output_length = input_triplets * 4 + tail_xtra[tail_case]; + gpr_slice output = gpr_slice_malloc(output_length); + uint8_t *in = GPR_SLICE_START_PTR(input); + char *out = (char *)GPR_SLICE_START_PTR(output); + size_t i; + + /* encode full triplets */ + for (i = 0; i < input_triplets; i++) { + out[0] = alphabet[in[0] >> 2]; + out[1] = alphabet[((in[0] & 0x3) << 4) | (in[1] >> 4)]; + out[2] = alphabet[((in[1] & 0xf) << 2) | (in[2] >> 6)]; + out[3] = alphabet[in[2] & 0x3f]; + out += 4; + in += 3; + } + + /* encode the remaining bytes */ + switch (tail_case) { + case 0: + break; + case 1: + out[0] = alphabet[in[0] >> 2]; + out[1] = alphabet[(in[0] & 0x3) << 4]; + out += 2; + in += 1; + break; + case 2: + out[0] = alphabet[in[0] >> 2]; + out[1] = alphabet[((in[0] & 0x3) << 4) | (in[1] >> 4)]; + out[2] = alphabet[(in[1] & 0xf) << 2]; + out += 3; + in += 2; + break; + } + + GPR_ASSERT(out == (char *)GPR_SLICE_END_PTR(output)); + GPR_ASSERT(in == GPR_SLICE_END_PTR(input)); + return output; +} + +gpr_slice grpc_chttp2_huffman_compress(gpr_slice input) { + size_t nbits; + uint8_t *in; + uint8_t *out; + gpr_slice output; + uint32_t temp = 0; + uint32_t temp_length = 0; + + nbits = 0; + for (in = GPR_SLICE_START_PTR(input); in != GPR_SLICE_END_PTR(input); ++in) { + nbits += grpc_chttp2_huffsyms[*in].length; + } + + output = gpr_slice_malloc(nbits / 8 + (nbits % 8 != 0)); + out = GPR_SLICE_START_PTR(output); + for (in = GPR_SLICE_START_PTR(input); in != GPR_SLICE_END_PTR(input); ++in) { + int sym = *in; + temp <<= grpc_chttp2_huffsyms[sym].length; + temp |= grpc_chttp2_huffsyms[sym].bits; + temp_length += grpc_chttp2_huffsyms[sym].length; + + while (temp_length > 8) { + temp_length -= 8; + *out++ = (uint8_t)(temp >> temp_length); + } + } + + if (temp_length) { + /* NB: the following integer arithmetic operation needs to be in its + * expanded form due to the "integral promotion" performed (see section + * 3.2.1.1 of the C89 draft standard). A cast to the smaller container type + * is then required to avoid the compiler warning */ + *out++ = (uint8_t)((uint8_t)(temp << (8u - temp_length)) | + (uint8_t)(0xffu >> temp_length)); + } + + GPR_ASSERT(out == GPR_SLICE_END_PTR(output)); + + return output; +} + +typedef struct { + uint32_t temp; + uint32_t temp_length; + uint8_t *out; +} huff_out; + +static void enc_flush_some(huff_out *out) { + while (out->temp_length > 8) { + out->temp_length -= 8; + *out->out++ = (uint8_t)(out->temp >> out->temp_length); + } +} + +static void enc_add2(huff_out *out, uint8_t a, uint8_t b) { + b64_huff_sym sa = huff_alphabet[a]; + b64_huff_sym sb = huff_alphabet[b]; + out->temp = (out->temp << (sa.length + sb.length)) | + ((uint32_t)sa.bits << sb.length) | sb.bits; + out->temp_length += (uint32_t)sa.length + (uint32_t)sb.length; + enc_flush_some(out); +} + +static void enc_add1(huff_out *out, uint8_t a) { + b64_huff_sym sa = huff_alphabet[a]; + out->temp = (out->temp << sa.length) | sa.bits; + out->temp_length += sa.length; + enc_flush_some(out); +} + +gpr_slice grpc_chttp2_base64_encode_and_huffman_compress(gpr_slice input) { + size_t input_length = GPR_SLICE_LENGTH(input); + size_t input_triplets = input_length / 3; + size_t tail_case = input_length % 3; + size_t output_syms = input_triplets * 4 + tail_xtra[tail_case]; + size_t max_output_bits = 11 * output_syms; + size_t max_output_length = max_output_bits / 8 + (max_output_bits % 8 != 0); + gpr_slice output = gpr_slice_malloc(max_output_length); + uint8_t *in = GPR_SLICE_START_PTR(input); + uint8_t *start_out = GPR_SLICE_START_PTR(output); + huff_out out; + size_t i; + + out.temp = 0; + out.temp_length = 0; + out.out = start_out; + + /* encode full triplets */ + for (i = 0; i < input_triplets; i++) { + enc_add2(&out, in[0] >> 2, (uint8_t)((in[0] & 0x3) << 4) | (in[1] >> 4)); + enc_add2(&out, (uint8_t)((in[1] & 0xf) << 2) | (in[2] >> 6), + (uint8_t)(in[2] & 0x3f)); + in += 3; + } + + /* encode the remaining bytes */ + switch (tail_case) { + case 0: + break; + case 1: + enc_add2(&out, in[0] >> 2, (uint8_t)((in[0] & 0x3) << 4)); + in += 1; + break; + case 2: + enc_add2(&out, in[0] >> 2, + (uint8_t)((in[0] & 0x3) << 4) | (uint8_t)(in[1] >> 4)); + enc_add1(&out, (uint8_t)((in[1] & 0xf) << 2)); + in += 2; + break; + } + + if (out.temp_length) { + /* NB: the following integer arithmetic operation needs to be in its + * expanded form due to the "integral promotion" performed (see section + * 3.2.1.1 of the C89 draft standard). A cast to the smaller container type + * is then required to avoid the compiler warning */ + *out.out++ = (uint8_t)((uint8_t)(out.temp << (8u - out.temp_length)) | + (uint8_t)(0xffu >> out.temp_length)); + } + + GPR_ASSERT(out.out <= GPR_SLICE_END_PTR(output)); + GPR_SLICE_SET_LENGTH(output, out.out - start_out); + + GPR_ASSERT(in == GPR_SLICE_END_PTR(input)); + return output; +} diff --git a/src/core/lib/transport/chttp2/bin_encoder.h b/src/core/lib/transport/chttp2/bin_encoder.h new file mode 100644 index 0000000000..edb6f2dad1 --- /dev/null +++ b/src/core/lib/transport/chttp2/bin_encoder.h @@ -0,0 +1,54 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_BIN_ENCODER_H +#define GRPC_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H + +#include + +/* base64 encode a slice. Returns a new slice, does not take ownership of the + input */ +gpr_slice grpc_chttp2_base64_encode(gpr_slice input); + +/* Compress a slice with the static huffman encoder detailed in the hpack + standard. Returns a new slice, does not take ownership of the input */ +gpr_slice grpc_chttp2_huffman_compress(gpr_slice input); + +/* equivalent to: + gpr_slice x = grpc_chttp2_base64_encode(input); + gpr_slice y = grpc_chttp2_huffman_compress(x); + gpr_slice_unref(x); + return y; */ +gpr_slice grpc_chttp2_base64_encode_and_huffman_compress(gpr_slice input); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H */ diff --git a/src/core/lib/transport/chttp2/frame.h b/src/core/lib/transport/chttp2/frame.h new file mode 100644 index 0000000000..560a6675af --- /dev/null +++ b/src/core/lib/transport/chttp2/frame.h @@ -0,0 +1,69 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_H +#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_H + +#include +#include + +/* Common definitions for frame handling in the chttp2 transport */ + +typedef enum { + GRPC_CHTTP2_PARSE_OK, + GRPC_CHTTP2_STREAM_ERROR, + GRPC_CHTTP2_CONNECTION_ERROR +} grpc_chttp2_parse_error; + +/* defined in internal.h */ +typedef struct grpc_chttp2_stream_parsing grpc_chttp2_stream_parsing; +typedef struct grpc_chttp2_transport_parsing grpc_chttp2_transport_parsing; + +#define GRPC_CHTTP2_FRAME_DATA 0 +#define GRPC_CHTTP2_FRAME_HEADER 1 +#define GRPC_CHTTP2_FRAME_CONTINUATION 9 +#define GRPC_CHTTP2_FRAME_RST_STREAM 3 +#define GRPC_CHTTP2_FRAME_SETTINGS 4 +#define GRPC_CHTTP2_FRAME_PING 6 +#define GRPC_CHTTP2_FRAME_GOAWAY 7 +#define GRPC_CHTTP2_FRAME_WINDOW_UPDATE 8 + +#define GRPC_CHTTP2_MAX_PAYLOAD_LENGTH ((1 << 14) - 1) + +#define GRPC_CHTTP2_DATA_FLAG_END_STREAM 1 +#define GRPC_CHTTP2_FLAG_ACK 1 +#define GRPC_CHTTP2_DATA_FLAG_END_HEADERS 4 +#define GRPC_CHTTP2_DATA_FLAG_PADDED 8 +#define GRPC_CHTTP2_FLAG_HAS_PRIORITY 0x20 + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_H */ diff --git a/src/core/lib/transport/chttp2/frame_data.c b/src/core/lib/transport/chttp2/frame_data.c new file mode 100644 index 0000000000..6cc6d4eaf2 --- /dev/null +++ b/src/core/lib/transport/chttp2/frame_data.c @@ -0,0 +1,248 @@ +/* + * + * Copyright 2015-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/transport/chttp2/frame_data.h" + +#include + +#include +#include +#include +#include "src/core/support/string.h" +#include "src/core/transport/chttp2/internal.h" +#include "src/core/transport/transport.h" + +grpc_chttp2_parse_error grpc_chttp2_data_parser_init( + grpc_chttp2_data_parser *parser) { + parser->state = GRPC_CHTTP2_DATA_FH_0; + parser->parsing_frame = NULL; + return GRPC_CHTTP2_PARSE_OK; +} + +void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, + grpc_chttp2_data_parser *parser) { + grpc_byte_stream *bs; + if (parser->parsing_frame) { + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, parser->parsing_frame, + 0, 1); + } + while ( + (bs = grpc_chttp2_incoming_frame_queue_pop(&parser->incoming_frames))) { + grpc_byte_stream_destroy(exec_ctx, bs); + } +} + +grpc_chttp2_parse_error grpc_chttp2_data_parser_begin_frame( + grpc_chttp2_data_parser *parser, uint8_t flags) { + if (flags & ~GRPC_CHTTP2_DATA_FLAG_END_STREAM) { + gpr_log(GPR_ERROR, "unsupported data flags: 0x%02x", flags); + return GRPC_CHTTP2_STREAM_ERROR; + } + + if (flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) { + parser->is_last_frame = 1; + } else { + parser->is_last_frame = 0; + } + + return GRPC_CHTTP2_PARSE_OK; +} + +void grpc_chttp2_incoming_frame_queue_merge( + grpc_chttp2_incoming_frame_queue *head_dst, + grpc_chttp2_incoming_frame_queue *tail_src) { + if (tail_src->head == NULL) { + return; + } + + if (head_dst->head == NULL) { + *head_dst = *tail_src; + memset(tail_src, 0, sizeof(*tail_src)); + return; + } + + head_dst->tail->next_message = tail_src->head; + head_dst->tail = tail_src->tail; + memset(tail_src, 0, sizeof(*tail_src)); +} + +grpc_byte_stream *grpc_chttp2_incoming_frame_queue_pop( + grpc_chttp2_incoming_frame_queue *q) { + grpc_byte_stream *out; + if (q->head == NULL) { + return NULL; + } + out = &q->head->base; + if (q->head == q->tail) { + memset(q, 0, sizeof(*q)); + } else { + q->head = q->head->next_message; + } + return out; +} + +void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf, + uint32_t write_bytes, int is_eof, + gpr_slice_buffer *outbuf) { + gpr_slice hdr; + uint8_t *p; + + hdr = gpr_slice_malloc(9); + p = GPR_SLICE_START_PTR(hdr); + GPR_ASSERT(write_bytes < (1 << 24)); + *p++ = (uint8_t)(write_bytes >> 16); + *p++ = (uint8_t)(write_bytes >> 8); + *p++ = (uint8_t)(write_bytes); + *p++ = GRPC_CHTTP2_FRAME_DATA; + *p++ = is_eof ? GRPC_CHTTP2_DATA_FLAG_END_STREAM : 0; + *p++ = (uint8_t)(id >> 24); + *p++ = (uint8_t)(id >> 16); + *p++ = (uint8_t)(id >> 8); + *p++ = (uint8_t)(id); + gpr_slice_buffer_add(outbuf, hdr); + + gpr_slice_buffer_move_first(inbuf, write_bytes, outbuf); +} + +grpc_chttp2_parse_error grpc_chttp2_data_parser_parse( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + uint8_t *const beg = GPR_SLICE_START_PTR(slice); + uint8_t *const end = GPR_SLICE_END_PTR(slice); + uint8_t *cur = beg; + grpc_chttp2_data_parser *p = parser; + uint32_t message_flags; + grpc_chttp2_incoming_byte_stream *incoming_byte_stream; + + if (is_last && p->is_last_frame) { + stream_parsing->received_close = 1; + } + + if (cur == end) { + return GRPC_CHTTP2_PARSE_OK; + } + + switch (p->state) { + fh_0: + case GRPC_CHTTP2_DATA_FH_0: + p->frame_type = *cur; + switch (p->frame_type) { + case 0: + p->is_frame_compressed = 0; /* GPR_FALSE */ + break; + case 1: + p->is_frame_compressed = 1; /* GPR_TRUE */ + break; + default: + gpr_log(GPR_ERROR, "Bad GRPC frame type 0x%02x", p->frame_type); + return GRPC_CHTTP2_STREAM_ERROR; + } + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_1; + return GRPC_CHTTP2_PARSE_OK; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_1: + p->frame_size = ((uint32_t)*cur) << 24; + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_2; + return GRPC_CHTTP2_PARSE_OK; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_2: + p->frame_size |= ((uint32_t)*cur) << 16; + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_3; + return GRPC_CHTTP2_PARSE_OK; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_3: + p->frame_size |= ((uint32_t)*cur) << 8; + if (++cur == end) { + p->state = GRPC_CHTTP2_DATA_FH_4; + return GRPC_CHTTP2_PARSE_OK; + } + /* fallthrough */ + case GRPC_CHTTP2_DATA_FH_4: + p->frame_size |= ((uint32_t)*cur); + p->state = GRPC_CHTTP2_DATA_FRAME; + ++cur; + message_flags = 0; + if (p->is_frame_compressed) { + message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; + } + p->parsing_frame = incoming_byte_stream = + grpc_chttp2_incoming_byte_stream_create( + exec_ctx, transport_parsing, stream_parsing, p->frame_size, + message_flags, &p->incoming_frames); + /* fallthrough */ + case GRPC_CHTTP2_DATA_FRAME: + if (cur == end) { + grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, + stream_parsing); + return GRPC_CHTTP2_PARSE_OK; + } + grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, + stream_parsing); + if ((uint32_t)(end - cur) == p->frame_size) { + grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + gpr_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, 1, + 1); + p->parsing_frame = NULL; + p->state = GRPC_CHTTP2_DATA_FH_0; + return GRPC_CHTTP2_PARSE_OK; + } else if ((uint32_t)(end - cur) > p->frame_size) { + grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + gpr_slice_sub(slice, (size_t)(cur - beg), + (size_t)(cur + p->frame_size - beg))); + grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, 1, + 1); + p->parsing_frame = NULL; + cur += p->frame_size; + goto fh_0; /* loop */ + } else { + grpc_chttp2_incoming_byte_stream_push( + exec_ctx, p->parsing_frame, + gpr_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); + GPR_ASSERT((size_t)(end - cur) <= p->frame_size); + p->frame_size -= (uint32_t)(end - cur); + return GRPC_CHTTP2_PARSE_OK; + } + } + + GPR_UNREACHABLE_CODE(return GRPC_CHTTP2_CONNECTION_ERROR); +} diff --git a/src/core/lib/transport/chttp2/frame_data.h b/src/core/lib/transport/chttp2/frame_data.h new file mode 100644 index 0000000000..9dbaa60d44 --- /dev/null +++ b/src/core/lib/transport/chttp2/frame_data.h @@ -0,0 +1,101 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_DATA_H +#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H + +/* Parser for GRPC streams embedded in DATA frames */ + +#include +#include +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/transport/byte_stream.h" +#include "src/core/transport/chttp2/frame.h" + +typedef enum { + GRPC_CHTTP2_DATA_FH_0, + GRPC_CHTTP2_DATA_FH_1, + GRPC_CHTTP2_DATA_FH_2, + GRPC_CHTTP2_DATA_FH_3, + GRPC_CHTTP2_DATA_FH_4, + GRPC_CHTTP2_DATA_FRAME +} grpc_chttp2_stream_state; + +typedef struct grpc_chttp2_incoming_byte_stream + grpc_chttp2_incoming_byte_stream; + +typedef struct grpc_chttp2_incoming_frame_queue { + grpc_chttp2_incoming_byte_stream *head; + grpc_chttp2_incoming_byte_stream *tail; +} grpc_chttp2_incoming_frame_queue; + +typedef struct { + grpc_chttp2_stream_state state; + uint8_t is_last_frame; + uint8_t frame_type; + uint32_t frame_size; + + int is_frame_compressed; + grpc_chttp2_incoming_frame_queue incoming_frames; + grpc_chttp2_incoming_byte_stream *parsing_frame; +} grpc_chttp2_data_parser; + +void grpc_chttp2_incoming_frame_queue_merge( + grpc_chttp2_incoming_frame_queue *head_dst, + grpc_chttp2_incoming_frame_queue *tail_src); +grpc_byte_stream *grpc_chttp2_incoming_frame_queue_pop( + grpc_chttp2_incoming_frame_queue *q); + +/* initialize per-stream state for data frame parsing */ +grpc_chttp2_parse_error grpc_chttp2_data_parser_init( + grpc_chttp2_data_parser *parser); + +void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, + grpc_chttp2_data_parser *parser); + +/* start processing a new data frame */ +grpc_chttp2_parse_error grpc_chttp2_data_parser_begin_frame( + grpc_chttp2_data_parser *parser, uint8_t flags); + +/* handle a slice of a data frame - is_last indicates the last slice of a + frame */ +grpc_chttp2_parse_error grpc_chttp2_data_parser_parse( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + +void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf, + uint32_t write_bytes, int is_eof, + gpr_slice_buffer *outbuf); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H */ diff --git a/src/core/lib/transport/chttp2/frame_goaway.c b/src/core/lib/transport/chttp2/frame_goaway.c new file mode 100644 index 0000000000..2fa525e989 --- /dev/null +++ b/src/core/lib/transport/chttp2/frame_goaway.c @@ -0,0 +1,193 @@ +/* + * + * Copyright 2015, 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/transport/chttp2/frame_goaway.h" +#include "src/core/transport/chttp2/internal.h" + +#include + +#include +#include + +void grpc_chttp2_goaway_parser_init(grpc_chttp2_goaway_parser *p) { + p->debug_data = NULL; +} + +void grpc_chttp2_goaway_parser_destroy(grpc_chttp2_goaway_parser *p) { + gpr_free(p->debug_data); +} + +grpc_chttp2_parse_error grpc_chttp2_goaway_parser_begin_frame( + grpc_chttp2_goaway_parser *p, uint32_t length, uint8_t flags) { + if (length < 8) { + gpr_log(GPR_ERROR, "goaway frame too short (%d bytes)", length); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + + gpr_free(p->debug_data); + p->debug_length = length - 8; + p->debug_data = gpr_malloc(p->debug_length); + p->debug_pos = 0; + p->state = GRPC_CHTTP2_GOAWAY_LSI0; + return GRPC_CHTTP2_PARSE_OK; +} + +grpc_chttp2_parse_error grpc_chttp2_goaway_parser_parse( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + uint8_t *const beg = GPR_SLICE_START_PTR(slice); + uint8_t *const end = GPR_SLICE_END_PTR(slice); + uint8_t *cur = beg; + grpc_chttp2_goaway_parser *p = parser; + + switch (p->state) { + case GRPC_CHTTP2_GOAWAY_LSI0: + if (cur == end) { + p->state = GRPC_CHTTP2_GOAWAY_LSI0; + return GRPC_CHTTP2_PARSE_OK; + } + p->last_stream_id = ((uint32_t)*cur) << 24; + ++cur; + /* fallthrough */ + case GRPC_CHTTP2_GOAWAY_LSI1: + if (cur == end) { + p->state = GRPC_CHTTP2_GOAWAY_LSI1; + return GRPC_CHTTP2_PARSE_OK; + } + p->last_stream_id |= ((uint32_t)*cur) << 16; + ++cur; + /* fallthrough */ + case GRPC_CHTTP2_GOAWAY_LSI2: + if (cur == end) { + p->state = GRPC_CHTTP2_GOAWAY_LSI2; + return GRPC_CHTTP2_PARSE_OK; + } + p->last_stream_id |= ((uint32_t)*cur) << 8; + ++cur; + /* fallthrough */ + case GRPC_CHTTP2_GOAWAY_LSI3: + if (cur == end) { + p->state = GRPC_CHTTP2_GOAWAY_LSI3; + return GRPC_CHTTP2_PARSE_OK; + } + p->last_stream_id |= ((uint32_t)*cur); + ++cur; + /* fallthrough */ + case GRPC_CHTTP2_GOAWAY_ERR0: + if (cur == end) { + p->state = GRPC_CHTTP2_GOAWAY_ERR0; + return GRPC_CHTTP2_PARSE_OK; + } + p->error_code = ((uint32_t)*cur) << 24; + ++cur; + /* fallthrough */ + case GRPC_CHTTP2_GOAWAY_ERR1: + if (cur == end) { + p->state = GRPC_CHTTP2_GOAWAY_ERR1; + return GRPC_CHTTP2_PARSE_OK; + } + p->error_code |= ((uint32_t)*cur) << 16; + ++cur; + /* fallthrough */ + case GRPC_CHTTP2_GOAWAY_ERR2: + if (cur == end) { + p->state = GRPC_CHTTP2_GOAWAY_ERR2; + return GRPC_CHTTP2_PARSE_OK; + } + p->error_code |= ((uint32_t)*cur) << 8; + ++cur; + /* fallthrough */ + case GRPC_CHTTP2_GOAWAY_ERR3: + if (cur == end) { + p->state = GRPC_CHTTP2_GOAWAY_ERR3; + return GRPC_CHTTP2_PARSE_OK; + } + p->error_code |= ((uint32_t)*cur); + ++cur; + /* fallthrough */ + case GRPC_CHTTP2_GOAWAY_DEBUG: + memcpy(p->debug_data + p->debug_pos, cur, (size_t)(end - cur)); + GPR_ASSERT((size_t)(end - cur) < UINT32_MAX - p->debug_pos); + p->debug_pos += (uint32_t)(end - cur); + p->state = GRPC_CHTTP2_GOAWAY_DEBUG; + if (is_last) { + transport_parsing->goaway_received = 1; + transport_parsing->goaway_last_stream_index = p->last_stream_id; + gpr_slice_unref(transport_parsing->goaway_text); + transport_parsing->goaway_error = (grpc_status_code)p->error_code; + transport_parsing->goaway_text = + gpr_slice_new(p->debug_data, p->debug_length, gpr_free); + p->debug_data = NULL; + } + return GRPC_CHTTP2_PARSE_OK; + } + GPR_UNREACHABLE_CODE(return GRPC_CHTTP2_CONNECTION_ERROR); +} + +void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code, + gpr_slice debug_data, + gpr_slice_buffer *slice_buffer) { + gpr_slice header = gpr_slice_malloc(9 + 4 + 4); + uint8_t *p = GPR_SLICE_START_PTR(header); + uint32_t frame_length; + GPR_ASSERT(GPR_SLICE_LENGTH(debug_data) < UINT32_MAX - 4 - 4); + frame_length = 4 + 4 + (uint32_t)GPR_SLICE_LENGTH(debug_data); + + /* frame header: length */ + *p++ = (uint8_t)(frame_length >> 16); + *p++ = (uint8_t)(frame_length >> 8); + *p++ = (uint8_t)(frame_length); + /* frame header: type */ + *p++ = GRPC_CHTTP2_FRAME_GOAWAY; + /* frame header: flags */ + *p++ = 0; + /* frame header: stream id */ + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + /* payload: last stream id */ + *p++ = (uint8_t)(last_stream_id >> 24); + *p++ = (uint8_t)(last_stream_id >> 16); + *p++ = (uint8_t)(last_stream_id >> 8); + *p++ = (uint8_t)(last_stream_id); + /* payload: error code */ + *p++ = (uint8_t)(error_code >> 24); + *p++ = (uint8_t)(error_code >> 16); + *p++ = (uint8_t)(error_code >> 8); + *p++ = (uint8_t)(error_code); + GPR_ASSERT(p == GPR_SLICE_END_PTR(header)); + gpr_slice_buffer_add(slice_buffer, header); + gpr_slice_buffer_add(slice_buffer, debug_data); +} diff --git a/src/core/lib/transport/chttp2/frame_goaway.h b/src/core/lib/transport/chttp2/frame_goaway.h new file mode 100644 index 0000000000..b980e47723 --- /dev/null +++ b/src/core/lib/transport/chttp2/frame_goaway.h @@ -0,0 +1,77 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_GOAWAY_H +#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H + +#include +#include +#include +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/transport/chttp2/frame.h" + +typedef enum { + GRPC_CHTTP2_GOAWAY_LSI0, + GRPC_CHTTP2_GOAWAY_LSI1, + GRPC_CHTTP2_GOAWAY_LSI2, + GRPC_CHTTP2_GOAWAY_LSI3, + GRPC_CHTTP2_GOAWAY_ERR0, + GRPC_CHTTP2_GOAWAY_ERR1, + GRPC_CHTTP2_GOAWAY_ERR2, + GRPC_CHTTP2_GOAWAY_ERR3, + GRPC_CHTTP2_GOAWAY_DEBUG +} grpc_chttp2_goaway_parse_state; + +typedef struct { + grpc_chttp2_goaway_parse_state state; + uint32_t last_stream_id; + uint32_t error_code; + char *debug_data; + uint32_t debug_length; + uint32_t debug_pos; +} grpc_chttp2_goaway_parser; + +void grpc_chttp2_goaway_parser_init(grpc_chttp2_goaway_parser *p); +void grpc_chttp2_goaway_parser_destroy(grpc_chttp2_goaway_parser *p); +grpc_chttp2_parse_error grpc_chttp2_goaway_parser_begin_frame( + grpc_chttp2_goaway_parser *parser, uint32_t length, uint8_t flags); +grpc_chttp2_parse_error grpc_chttp2_goaway_parser_parse( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + +void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code, + gpr_slice debug_data, + gpr_slice_buffer *slice_buffer); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H */ diff --git a/src/core/lib/transport/chttp2/frame_ping.c b/src/core/lib/transport/chttp2/frame_ping.c new file mode 100644 index 0000000000..c6ab522283 --- /dev/null +++ b/src/core/lib/transport/chttp2/frame_ping.c @@ -0,0 +1,97 @@ +/* + * + * Copyright 2015, 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/transport/chttp2/frame_ping.h" +#include "src/core/transport/chttp2/internal.h" + +#include + +#include +#include + +gpr_slice grpc_chttp2_ping_create(uint8_t ack, uint8_t *opaque_8bytes) { + gpr_slice slice = gpr_slice_malloc(9 + 8); + uint8_t *p = GPR_SLICE_START_PTR(slice); + + *p++ = 0; + *p++ = 0; + *p++ = 8; + *p++ = GRPC_CHTTP2_FRAME_PING; + *p++ = ack ? 1 : 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + memcpy(p, opaque_8bytes, 8); + + return slice; +} + +grpc_chttp2_parse_error grpc_chttp2_ping_parser_begin_frame( + grpc_chttp2_ping_parser *parser, uint32_t length, uint8_t flags) { + if (flags & 0xfe || length != 8) { + gpr_log(GPR_ERROR, "invalid ping: length=%d, flags=%02x", length, flags); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + parser->byte = 0; + parser->is_ack = flags; + return GRPC_CHTTP2_PARSE_OK; +} + +grpc_chttp2_parse_error grpc_chttp2_ping_parser_parse( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + uint8_t *const beg = GPR_SLICE_START_PTR(slice); + uint8_t *const end = GPR_SLICE_END_PTR(slice); + uint8_t *cur = beg; + grpc_chttp2_ping_parser *p = parser; + + while (p->byte != 8 && cur != end) { + p->opaque_8bytes[p->byte] = *cur; + cur++; + p->byte++; + } + + if (p->byte == 8) { + GPR_ASSERT(is_last); + if (p->is_ack) { + grpc_chttp2_ack_ping(exec_ctx, transport_parsing, p->opaque_8bytes); + } else { + gpr_slice_buffer_add(&transport_parsing->qbuf, + grpc_chttp2_ping_create(1, p->opaque_8bytes)); + } + } + + return GRPC_CHTTP2_PARSE_OK; +} diff --git a/src/core/lib/transport/chttp2/frame_ping.h b/src/core/lib/transport/chttp2/frame_ping.h new file mode 100644 index 0000000000..2412cd7a6f --- /dev/null +++ b/src/core/lib/transport/chttp2/frame_ping.h @@ -0,0 +1,56 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_PING_H +#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_PING_H + +#include +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/transport/chttp2/frame.h" + +typedef struct { + uint8_t byte; + uint8_t is_ack; + uint8_t opaque_8bytes[8]; +} grpc_chttp2_ping_parser; + +gpr_slice grpc_chttp2_ping_create(uint8_t ack, uint8_t *opaque_8bytes); + +grpc_chttp2_parse_error grpc_chttp2_ping_parser_begin_frame( + grpc_chttp2_ping_parser *parser, uint32_t length, uint8_t flags); +grpc_chttp2_parse_error grpc_chttp2_ping_parser_parse( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_PING_H */ diff --git a/src/core/lib/transport/chttp2/frame_rst_stream.c b/src/core/lib/transport/chttp2/frame_rst_stream.c new file mode 100644 index 0000000000..754529e4b9 --- /dev/null +++ b/src/core/lib/transport/chttp2/frame_rst_stream.c @@ -0,0 +1,99 @@ +/* + * + * Copyright 2015, 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/transport/chttp2/frame_rst_stream.h" +#include "src/core/transport/chttp2/internal.h" + +#include + +#include "src/core/transport/chttp2/frame.h" + +gpr_slice grpc_chttp2_rst_stream_create(uint32_t id, uint32_t code) { + gpr_slice slice = gpr_slice_malloc(13); + uint8_t *p = GPR_SLICE_START_PTR(slice); + + *p++ = 0; + *p++ = 0; + *p++ = 4; + *p++ = GRPC_CHTTP2_FRAME_RST_STREAM; + *p++ = 0; + *p++ = (uint8_t)(id >> 24); + *p++ = (uint8_t)(id >> 16); + *p++ = (uint8_t)(id >> 8); + *p++ = (uint8_t)(id); + *p++ = (uint8_t)(code >> 24); + *p++ = (uint8_t)(code >> 16); + *p++ = (uint8_t)(code >> 8); + *p++ = (uint8_t)(code); + + return slice; +} + +grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_begin_frame( + grpc_chttp2_rst_stream_parser *parser, uint32_t length, uint8_t flags) { + if (length != 4) { + gpr_log(GPR_ERROR, "invalid rst_stream: length=%d, flags=%02x", length, + flags); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + parser->byte = 0; + return GRPC_CHTTP2_PARSE_OK; +} + +grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_parse( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + uint8_t *const beg = GPR_SLICE_START_PTR(slice); + uint8_t *const end = GPR_SLICE_END_PTR(slice); + uint8_t *cur = beg; + grpc_chttp2_rst_stream_parser *p = parser; + + while (p->byte != 4 && cur != end) { + p->reason_bytes[p->byte] = *cur; + cur++; + p->byte++; + } + + if (p->byte == 4) { + GPR_ASSERT(is_last); + stream_parsing->received_close = 1; + stream_parsing->saw_rst_stream = 1; + stream_parsing->rst_stream_reason = (((uint32_t)p->reason_bytes[0]) << 24) | + (((uint32_t)p->reason_bytes[1]) << 16) | + (((uint32_t)p->reason_bytes[2]) << 8) | + (((uint32_t)p->reason_bytes[3])); + } + + return GRPC_CHTTP2_PARSE_OK; +} diff --git a/src/core/lib/transport/chttp2/frame_rst_stream.h b/src/core/lib/transport/chttp2/frame_rst_stream.h new file mode 100644 index 0000000000..f725c5d767 --- /dev/null +++ b/src/core/lib/transport/chttp2/frame_rst_stream.h @@ -0,0 +1,55 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H +#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H + +#include +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/transport/chttp2/frame.h" + +typedef struct { + uint8_t byte; + uint8_t reason_bytes[4]; +} grpc_chttp2_rst_stream_parser; + +gpr_slice grpc_chttp2_rst_stream_create(uint32_t stream_id, uint32_t code); + +grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_begin_frame( + grpc_chttp2_rst_stream_parser *parser, uint32_t length, uint8_t flags); +grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_parse( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H */ diff --git a/src/core/lib/transport/chttp2/frame_settings.c b/src/core/lib/transport/chttp2/frame_settings.c new file mode 100644 index 0000000000..cc49dd4f69 --- /dev/null +++ b/src/core/lib/transport/chttp2/frame_settings.c @@ -0,0 +1,259 @@ +/* + * + * Copyright 2015, 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/transport/chttp2/frame_settings.h" +#include "src/core/transport/chttp2/internal.h" + +#include + +#include +#include + +#include "src/core/debug/trace.h" +#include "src/core/transport/chttp2/frame.h" +#include "src/core/transport/chttp2/http2_errors.h" +#include "src/core/transport/chttp2_transport.h" + +#define MAX_MAX_HEADER_LIST_SIZE (1024 * 1024 * 1024) + +/* HTTP/2 mandated initial connection settings */ +const grpc_chttp2_setting_parameters + grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = { + {NULL, 0, 0, 0, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, + GRPC_CHTTP2_PROTOCOL_ERROR}, + {"HEADER_TABLE_SIZE", 4096, 0, 0xffffffff, + GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_CHTTP2_PROTOCOL_ERROR}, + {"ENABLE_PUSH", 1, 0, 1, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, + GRPC_CHTTP2_PROTOCOL_ERROR}, + {"MAX_CONCURRENT_STREAMS", 0xffffffffu, 0, 0xffffffffu, + GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_CHTTP2_PROTOCOL_ERROR}, + {"INITIAL_WINDOW_SIZE", 65535, 0, 0x7fffffffu, + GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, + GRPC_CHTTP2_FLOW_CONTROL_ERROR}, + {"MAX_FRAME_SIZE", 16384, 16384, 16777215, + GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_CHTTP2_PROTOCOL_ERROR}, + {"MAX_HEADER_LIST_SIZE", MAX_MAX_HEADER_LIST_SIZE, 0, + MAX_MAX_HEADER_LIST_SIZE, GRPC_CHTTP2_CLAMP_INVALID_VALUE, + GRPC_CHTTP2_PROTOCOL_ERROR}, +}; + +static uint8_t *fill_header(uint8_t *out, uint32_t length, uint8_t flags) { + *out++ = (uint8_t)(length >> 16); + *out++ = (uint8_t)(length >> 8); + *out++ = (uint8_t)(length); + *out++ = GRPC_CHTTP2_FRAME_SETTINGS; + *out++ = flags; + *out++ = 0; + *out++ = 0; + *out++ = 0; + *out++ = 0; + return out; +} + +gpr_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *new, + uint32_t force_mask, size_t count) { + size_t i; + uint32_t n = 0; + gpr_slice output; + uint8_t *p; + + for (i = 0; i < count; i++) { + n += (new[i] != old[i] || (force_mask & (1u << i)) != 0); + } + + output = gpr_slice_malloc(9 + 6 * n); + p = fill_header(GPR_SLICE_START_PTR(output), 6 * n, 0); + + for (i = 0; i < count; i++) { + if (new[i] != old[i] || (force_mask & (1u << i)) != 0) { + GPR_ASSERT(i); + *p++ = (uint8_t)(i >> 8); + *p++ = (uint8_t)(i); + *p++ = (uint8_t)(new[i] >> 24); + *p++ = (uint8_t)(new[i] >> 16); + *p++ = (uint8_t)(new[i] >> 8); + *p++ = (uint8_t)(new[i]); + old[i] = new[i]; + } + } + + GPR_ASSERT(p == GPR_SLICE_END_PTR(output)); + + return output; +} + +gpr_slice grpc_chttp2_settings_ack_create(void) { + gpr_slice output = gpr_slice_malloc(9); + fill_header(GPR_SLICE_START_PTR(output), 0, GRPC_CHTTP2_FLAG_ACK); + return output; +} + +grpc_chttp2_parse_error grpc_chttp2_settings_parser_begin_frame( + grpc_chttp2_settings_parser *parser, uint32_t length, uint8_t flags, + uint32_t *settings) { + parser->target_settings = settings; + memcpy(parser->incoming_settings, settings, + GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); + parser->is_ack = 0; + parser->state = GRPC_CHTTP2_SPS_ID0; + if (flags == GRPC_CHTTP2_FLAG_ACK) { + parser->is_ack = 1; + if (length != 0) { + gpr_log(GPR_ERROR, "non-empty settings ack frame received"); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + return GRPC_CHTTP2_PARSE_OK; + } else if (flags != 0) { + gpr_log(GPR_ERROR, "invalid flags on settings frame"); + return GRPC_CHTTP2_CONNECTION_ERROR; + } else if (length % 6 != 0) { + gpr_log(GPR_ERROR, "settings frames must be a multiple of six bytes"); + return GRPC_CHTTP2_CONNECTION_ERROR; + } else { + return GRPC_CHTTP2_PARSE_OK; + } +} + +grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse( + grpc_exec_ctx *exec_ctx, void *p, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + grpc_chttp2_settings_parser *parser = p; + const uint8_t *cur = GPR_SLICE_START_PTR(slice); + const uint8_t *end = GPR_SLICE_END_PTR(slice); + + if (parser->is_ack) { + return GRPC_CHTTP2_PARSE_OK; + } + + for (;;) { + switch (parser->state) { + case GRPC_CHTTP2_SPS_ID0: + if (cur == end) { + parser->state = GRPC_CHTTP2_SPS_ID0; + if (is_last) { + transport_parsing->settings_updated = 1; + memcpy(parser->target_settings, parser->incoming_settings, + GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); + gpr_slice_buffer_add(&transport_parsing->qbuf, + grpc_chttp2_settings_ack_create()); + } + return GRPC_CHTTP2_PARSE_OK; + } + parser->id = (uint16_t)(((uint16_t)*cur) << 8); + cur++; + /* fallthrough */ + case GRPC_CHTTP2_SPS_ID1: + if (cur == end) { + parser->state = GRPC_CHTTP2_SPS_ID1; + return GRPC_CHTTP2_PARSE_OK; + } + parser->id = (uint16_t)(parser->id | (*cur)); + cur++; + /* fallthrough */ + case GRPC_CHTTP2_SPS_VAL0: + if (cur == end) { + parser->state = GRPC_CHTTP2_SPS_VAL0; + return GRPC_CHTTP2_PARSE_OK; + } + parser->value = ((uint32_t)*cur) << 24; + cur++; + /* fallthrough */ + case GRPC_CHTTP2_SPS_VAL1: + if (cur == end) { + parser->state = GRPC_CHTTP2_SPS_VAL1; + return GRPC_CHTTP2_PARSE_OK; + } + parser->value |= ((uint32_t)*cur) << 16; + cur++; + /* fallthrough */ + case GRPC_CHTTP2_SPS_VAL2: + if (cur == end) { + parser->state = GRPC_CHTTP2_SPS_VAL2; + return GRPC_CHTTP2_PARSE_OK; + } + parser->value |= ((uint32_t)*cur) << 8; + cur++; + /* fallthrough */ + case GRPC_CHTTP2_SPS_VAL3: + if (cur == end) { + parser->state = GRPC_CHTTP2_SPS_VAL3; + return GRPC_CHTTP2_PARSE_OK; + } else { + parser->state = GRPC_CHTTP2_SPS_ID0; + } + parser->value |= *cur; + cur++; + + if (parser->id > 0 && parser->id < GRPC_CHTTP2_NUM_SETTINGS) { + const grpc_chttp2_setting_parameters *sp = + &grpc_chttp2_settings_parameters[parser->id]; + if (parser->value < sp->min_value || parser->value > sp->max_value) { + switch (sp->invalid_value_behavior) { + case GRPC_CHTTP2_CLAMP_INVALID_VALUE: + parser->value = + GPR_CLAMP(parser->value, sp->min_value, sp->max_value); + break; + case GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE: + grpc_chttp2_goaway_append( + transport_parsing->last_incoming_stream_id, sp->error_value, + gpr_slice_from_static_string("HTTP2 settings error"), + &transport_parsing->qbuf); + gpr_log(GPR_ERROR, "invalid value %u passed for %s", + parser->value, sp->name); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + } + if (parser->id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE && + parser->incoming_settings[parser->id] != parser->value) { + transport_parsing->initial_window_update = + (int64_t)parser->value - parser->incoming_settings[parser->id]; + if (grpc_http_trace) { + gpr_log(GPR_DEBUG, "adding %d for initial_window change", + (int)transport_parsing->initial_window_update); + } + } + parser->incoming_settings[parser->id] = parser->value; + if (grpc_http_trace) { + gpr_log(GPR_DEBUG, "CHTTP2:%s: got setting %d = %d", + transport_parsing->is_client ? "CLI" : "SVR", parser->id, + parser->value); + } + } else { + gpr_log(GPR_ERROR, "CHTTP2: Ignoring unknown setting %d (value %d)", + parser->id, parser->value); + } + break; + } + } +} diff --git a/src/core/lib/transport/chttp2/frame_settings.h b/src/core/lib/transport/chttp2/frame_settings.h new file mode 100644 index 0000000000..59dbff9b40 --- /dev/null +++ b/src/core/lib/transport/chttp2/frame_settings.h @@ -0,0 +1,103 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_SETTINGS_H +#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H + +#include +#include +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/transport/chttp2/frame.h" + +typedef enum { + GRPC_CHTTP2_SPS_ID0, + GRPC_CHTTP2_SPS_ID1, + GRPC_CHTTP2_SPS_VAL0, + GRPC_CHTTP2_SPS_VAL1, + GRPC_CHTTP2_SPS_VAL2, + GRPC_CHTTP2_SPS_VAL3 +} grpc_chttp2_settings_parse_state; + +/* The things HTTP/2 defines as connection level settings */ +typedef enum { + GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE = 1, + GRPC_CHTTP2_SETTINGS_ENABLE_PUSH = 2, + GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 3, + GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 4, + GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE = 5, + GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 6, + GRPC_CHTTP2_NUM_SETTINGS +} grpc_chttp2_setting_id; + +typedef struct { + grpc_chttp2_settings_parse_state state; + uint32_t *target_settings; + uint8_t is_ack; + uint16_t id; + uint32_t value; + uint32_t incoming_settings[GRPC_CHTTP2_NUM_SETTINGS]; +} grpc_chttp2_settings_parser; + +typedef enum { + GRPC_CHTTP2_CLAMP_INVALID_VALUE, + GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE +} grpc_chttp2_invalid_value_behavior; + +typedef struct { + const char *name; + uint32_t default_value; + uint32_t min_value; + uint32_t max_value; + grpc_chttp2_invalid_value_behavior invalid_value_behavior; + uint32_t error_value; +} grpc_chttp2_setting_parameters; + +/* HTTP/2 mandated connection setting parameters */ +extern const grpc_chttp2_setting_parameters + grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS]; + +/* Create a settings frame by diffing old & new, and updating old to be new */ +gpr_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *new, + uint32_t force_mask, size_t count); +/* Create an ack settings frame */ +gpr_slice grpc_chttp2_settings_ack_create(void); + +grpc_chttp2_parse_error grpc_chttp2_settings_parser_begin_frame( + grpc_chttp2_settings_parser *parser, uint32_t length, uint8_t flags, + uint32_t *settings); +grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H */ diff --git a/src/core/lib/transport/chttp2/frame_window_update.c b/src/core/lib/transport/chttp2/frame_window_update.c new file mode 100644 index 0000000000..62d9bac117 --- /dev/null +++ b/src/core/lib/transport/chttp2/frame_window_update.c @@ -0,0 +1,113 @@ +/* + * + * Copyright 2015, 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/transport/chttp2/frame_window_update.h" +#include "src/core/transport/chttp2/internal.h" + +#include + +gpr_slice grpc_chttp2_window_update_create(uint32_t id, + uint32_t window_update) { + gpr_slice slice = gpr_slice_malloc(13); + uint8_t *p = GPR_SLICE_START_PTR(slice); + + GPR_ASSERT(window_update); + + *p++ = 0; + *p++ = 0; + *p++ = 4; + *p++ = GRPC_CHTTP2_FRAME_WINDOW_UPDATE; + *p++ = 0; + *p++ = (uint8_t)(id >> 24); + *p++ = (uint8_t)(id >> 16); + *p++ = (uint8_t)(id >> 8); + *p++ = (uint8_t)(id); + *p++ = (uint8_t)(window_update >> 24); + *p++ = (uint8_t)(window_update >> 16); + *p++ = (uint8_t)(window_update >> 8); + *p++ = (uint8_t)(window_update); + + return slice; +} + +grpc_chttp2_parse_error grpc_chttp2_window_update_parser_begin_frame( + grpc_chttp2_window_update_parser *parser, uint32_t length, uint8_t flags) { + if (flags || length != 4) { + gpr_log(GPR_ERROR, "invalid window update: length=%d, flags=%02x", length, + flags); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + parser->byte = 0; + parser->amount = 0; + return GRPC_CHTTP2_PARSE_OK; +} + +grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + uint8_t *const beg = GPR_SLICE_START_PTR(slice); + uint8_t *const end = GPR_SLICE_END_PTR(slice); + uint8_t *cur = beg; + grpc_chttp2_window_update_parser *p = parser; + + while (p->byte != 4 && cur != end) { + p->amount |= ((uint32_t)*cur) << (8 * (3 - p->byte)); + cur++; + p->byte++; + } + + if (p->byte == 4) { + uint32_t received_update = p->amount; + if (received_update == 0 || (received_update & 0x80000000u)) { + gpr_log(GPR_ERROR, "invalid window update bytes: %d", p->amount); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + GPR_ASSERT(is_last); + + if (transport_parsing->incoming_stream_id != 0) { + if (stream_parsing != NULL) { + GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", transport_parsing, + stream_parsing, outgoing_window, + received_update); + grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, + stream_parsing); + } + } else { + GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parse", transport_parsing, + outgoing_window, received_update); + } + } + + return GRPC_CHTTP2_PARSE_OK; +} diff --git a/src/core/lib/transport/chttp2/frame_window_update.h b/src/core/lib/transport/chttp2/frame_window_update.h new file mode 100644 index 0000000000..9b7ca3ce63 --- /dev/null +++ b/src/core/lib/transport/chttp2/frame_window_update.h @@ -0,0 +1,56 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H +#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H + +#include +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/transport/chttp2/frame.h" + +typedef struct { + uint8_t byte; + uint8_t is_connection_update; + uint32_t amount; +} grpc_chttp2_window_update_parser; + +gpr_slice grpc_chttp2_window_update_create(uint32_t id, uint32_t window_delta); + +grpc_chttp2_parse_error grpc_chttp2_window_update_parser_begin_frame( + grpc_chttp2_window_update_parser *parser, uint32_t length, uint8_t flags); +grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H */ diff --git a/src/core/lib/transport/chttp2/hpack_encoder.c b/src/core/lib/transport/chttp2/hpack_encoder.c new file mode 100644 index 0000000000..f30f574d06 --- /dev/null +++ b/src/core/lib/transport/chttp2/hpack_encoder.c @@ -0,0 +1,568 @@ +/* + * + * Copyright 2015-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/transport/chttp2/hpack_encoder.h" + +#include +#include + +/* This is here for grpc_is_binary_header + * TODO(murgatroid99): Remove this + */ +#include + +#include +#include +#include + +#include "src/core/transport/chttp2/bin_encoder.h" +#include "src/core/transport/chttp2/hpack_table.h" +#include "src/core/transport/chttp2/timeout_encoding.h" +#include "src/core/transport/chttp2/varint.h" +#include "src/core/transport/static_metadata.h" + +#define HASH_FRAGMENT_1(x) ((x)&255) +#define HASH_FRAGMENT_2(x) ((x >> 8) & 255) +#define HASH_FRAGMENT_3(x) ((x >> 16) & 255) +#define HASH_FRAGMENT_4(x) ((x >> 24) & 255) + +/* if the probability of this item being seen again is < 1/x then don't add + it to the table */ +#define ONE_ON_ADD_PROBABILITY 128 +/* don't consider adding anything bigger than this to the hpack table */ +#define MAX_DECODER_SPACE_USAGE 512 + +typedef struct { + int is_first_frame; + /* number of bytes in 'output' when we started the frame - used to calculate + frame length */ + size_t output_length_at_start_of_frame; + /* index (in output) of the header for the current frame */ + size_t header_idx; + /* have we seen a regular (non-colon-prefixed) header yet? */ + uint8_t seen_regular_header; + /* output stream id */ + uint32_t stream_id; + gpr_slice_buffer *output; +} framer_state; + +/* fills p (which is expected to be 9 bytes long) with a data frame header */ +static void fill_header(uint8_t *p, uint8_t type, uint32_t id, size_t len, + uint8_t flags) { + GPR_ASSERT(len < 16777316); + *p++ = (uint8_t)(len >> 16); + *p++ = (uint8_t)(len >> 8); + *p++ = (uint8_t)(len); + *p++ = type; + *p++ = flags; + *p++ = (uint8_t)(id >> 24); + *p++ = (uint8_t)(id >> 16); + *p++ = (uint8_t)(id >> 8); + *p++ = (uint8_t)(id); +} + +/* finish a frame - fill in the previously reserved header */ +static void finish_frame(framer_state *st, int is_header_boundary, + int is_last_in_stream) { + uint8_t type = 0xff; + type = st->is_first_frame ? GRPC_CHTTP2_FRAME_HEADER + : GRPC_CHTTP2_FRAME_CONTINUATION; + fill_header( + GPR_SLICE_START_PTR(st->output->slices[st->header_idx]), type, + st->stream_id, st->output->length - st->output_length_at_start_of_frame, + (uint8_t)((is_last_in_stream ? GRPC_CHTTP2_DATA_FLAG_END_STREAM : 0) | + (is_header_boundary ? GRPC_CHTTP2_DATA_FLAG_END_HEADERS : 0))); + st->is_first_frame = 0; +} + +/* begin a new frame: reserve off header space, remember how many bytes we'd + output before beginning */ +static void begin_frame(framer_state *st) { + st->header_idx = + gpr_slice_buffer_add_indexed(st->output, gpr_slice_malloc(9)); + st->output_length_at_start_of_frame = st->output->length; +} + +/* make sure that the current frame is of the type desired, and has sufficient + space to add at least about_to_add bytes -- finishes the current frame if + needed */ +static void ensure_space(framer_state *st, size_t need_bytes) { + if (st->output->length - st->output_length_at_start_of_frame + need_bytes <= + GRPC_CHTTP2_MAX_PAYLOAD_LENGTH) { + return; + } + finish_frame(st, 0, 0); + begin_frame(st); +} + +/* increment a filter count, halve all counts if one element reaches max */ +static void inc_filter(uint8_t idx, uint32_t *sum, uint8_t *elems) { + elems[idx]++; + if (elems[idx] < 255) { + (*sum)++; + } else { + int i; + *sum = 0; + for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_FILTERS; i++) { + elems[i] /= 2; + (*sum) += elems[i]; + } + } +} + +static void add_header_data(framer_state *st, gpr_slice slice) { + size_t len = GPR_SLICE_LENGTH(slice); + size_t remaining; + if (len == 0) return; + remaining = GRPC_CHTTP2_MAX_PAYLOAD_LENGTH + + st->output_length_at_start_of_frame - st->output->length; + if (len <= remaining) { + gpr_slice_buffer_add(st->output, slice); + } else { + gpr_slice_buffer_add(st->output, gpr_slice_split_head(&slice, remaining)); + finish_frame(st, 0, 0); + begin_frame(st); + add_header_data(st, slice); + } +} + +static uint8_t *add_tiny_header_data(framer_state *st, size_t len) { + ensure_space(st, len); + return gpr_slice_buffer_tiny_add(st->output, len); +} + +static void evict_entry(grpc_chttp2_hpack_compressor *c) { + c->tail_remote_index++; + GPR_ASSERT(c->tail_remote_index > 0); + GPR_ASSERT(c->table_size >= + c->table_elem_size[c->tail_remote_index % c->cap_table_elems]); + GPR_ASSERT(c->table_elems > 0); + c->table_size = + (uint16_t)(c->table_size - + c->table_elem_size[c->tail_remote_index % c->cap_table_elems]); + c->table_elems--; +} + +/* add an element to the decoder table */ +static void add_elem(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem) { + uint32_t key_hash = elem->key->hash; + uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash); + uint32_t new_index = c->tail_remote_index + c->table_elems + 1; + size_t elem_size = 32 + GPR_SLICE_LENGTH(elem->key->slice) + + GPR_SLICE_LENGTH(elem->value->slice); + + GPR_ASSERT(elem_size < 65536); + + if (elem_size > c->max_table_size) { + while (c->table_size > 0) { + evict_entry(c); + } + return; + } + + /* Reserve space for this element in the remote table: if this overflows + the current table, drop elements until it fits, matching the decompressor + algorithm */ + while (c->table_size + elem_size > c->max_table_size) { + evict_entry(c); + } + GPR_ASSERT(c->table_elems < c->max_table_size); + c->table_elem_size[new_index % c->cap_table_elems] = (uint16_t)elem_size; + c->table_size = (uint16_t)(c->table_size + elem_size); + c->table_elems++; + + /* Store this element into {entries,indices}_elem */ + if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == elem) { + /* already there: update with new index */ + c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index; + } else if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == elem) { + /* already there (cuckoo): update with new index */ + c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index; + } else if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == NULL) { + /* not there, but a free element: add */ + c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem); + c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index; + } else if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == NULL) { + /* not there (cuckoo), but a free element: add */ + c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem); + c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index; + } else if (c->indices_elems[HASH_FRAGMENT_2(elem_hash)] < + c->indices_elems[HASH_FRAGMENT_3(elem_hash)]) { + /* not there: replace oldest */ + GRPC_MDELEM_UNREF(c->entries_elems[HASH_FRAGMENT_2(elem_hash)]); + c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem); + c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index; + } else { + /* not there: replace oldest */ + GRPC_MDELEM_UNREF(c->entries_elems[HASH_FRAGMENT_3(elem_hash)]); + c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem); + c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index; + } + + /* do exactly the same for the key (so we can find by that again too) */ + + if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == elem->key) { + c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index; + } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == elem->key) { + c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index; + } else if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == NULL) { + c->entries_keys[HASH_FRAGMENT_2(key_hash)] = GRPC_MDSTR_REF(elem->key); + c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index; + } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == NULL) { + c->entries_keys[HASH_FRAGMENT_3(key_hash)] = GRPC_MDSTR_REF(elem->key); + c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index; + } else if (c->indices_keys[HASH_FRAGMENT_2(key_hash)] < + c->indices_keys[HASH_FRAGMENT_3(key_hash)]) { + GRPC_MDSTR_UNREF(c->entries_keys[HASH_FRAGMENT_2(key_hash)]); + c->entries_keys[HASH_FRAGMENT_2(key_hash)] = GRPC_MDSTR_REF(elem->key); + c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index; + } else { + GRPC_MDSTR_UNREF(c->entries_keys[HASH_FRAGMENT_3(key_hash)]); + c->entries_keys[HASH_FRAGMENT_3(key_hash)] = GRPC_MDSTR_REF(elem->key); + c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index; + } +} + +static void emit_indexed(grpc_chttp2_hpack_compressor *c, uint32_t elem_index, + framer_state *st) { + uint32_t len = GRPC_CHTTP2_VARINT_LENGTH(elem_index, 1); + GRPC_CHTTP2_WRITE_VARINT(elem_index, 1, 0x80, add_tiny_header_data(st, len), + len); +} + +static gpr_slice get_wire_value(grpc_mdelem *elem, uint8_t *huffman_prefix) { + if (grpc_is_binary_header((const char *)GPR_SLICE_START_PTR(elem->key->slice), + GPR_SLICE_LENGTH(elem->key->slice))) { + *huffman_prefix = 0x80; + return grpc_mdstr_as_base64_encoded_and_huffman_compressed(elem->value); + } + /* TODO(ctiller): opportunistically compress non-binary headers */ + *huffman_prefix = 0x00; + return elem->value->slice; +} + +static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor *c, + uint32_t key_index, grpc_mdelem *elem, + framer_state *st) { + uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 2); + uint8_t huffman_prefix; + gpr_slice value_slice = get_wire_value(elem, &huffman_prefix); + size_t len_val = GPR_SLICE_LENGTH(value_slice); + uint32_t len_val_len; + GPR_ASSERT(len_val <= UINT32_MAX); + len_val_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)len_val, 1); + GRPC_CHTTP2_WRITE_VARINT(key_index, 2, 0x40, + add_tiny_header_data(st, len_pfx), len_pfx); + GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix, + add_tiny_header_data(st, len_val_len), len_val_len); + add_header_data(st, gpr_slice_ref(value_slice)); +} + +static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor *c, + uint32_t key_index, grpc_mdelem *elem, + framer_state *st) { + uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 4); + uint8_t huffman_prefix; + gpr_slice value_slice = get_wire_value(elem, &huffman_prefix); + size_t len_val = GPR_SLICE_LENGTH(value_slice); + uint32_t len_val_len; + GPR_ASSERT(len_val <= UINT32_MAX); + len_val_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)len_val, 1); + GRPC_CHTTP2_WRITE_VARINT(key_index, 4, 0x00, + add_tiny_header_data(st, len_pfx), len_pfx); + GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix, + add_tiny_header_data(st, len_val_len), len_val_len); + add_header_data(st, gpr_slice_ref(value_slice)); +} + +static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c, + grpc_mdelem *elem, framer_state *st) { + uint32_t len_key = (uint32_t)GPR_SLICE_LENGTH(elem->key->slice); + uint8_t huffman_prefix; + gpr_slice value_slice = get_wire_value(elem, &huffman_prefix); + uint32_t len_val = (uint32_t)GPR_SLICE_LENGTH(value_slice); + uint32_t len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1); + uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1); + GPR_ASSERT(len_key <= UINT32_MAX); + GPR_ASSERT(GPR_SLICE_LENGTH(value_slice) <= UINT32_MAX); + *add_tiny_header_data(st, 1) = 0x40; + GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, + add_tiny_header_data(st, len_key_len), len_key_len); + add_header_data(st, gpr_slice_ref(elem->key->slice)); + GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix, + add_tiny_header_data(st, len_val_len), len_val_len); + add_header_data(st, gpr_slice_ref(value_slice)); +} + +static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c, + grpc_mdelem *elem, framer_state *st) { + uint32_t len_key = (uint32_t)GPR_SLICE_LENGTH(elem->key->slice); + uint8_t huffman_prefix; + gpr_slice value_slice = get_wire_value(elem, &huffman_prefix); + uint32_t len_val = (uint32_t)GPR_SLICE_LENGTH(value_slice); + uint32_t len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1); + uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1); + GPR_ASSERT(len_key <= UINT32_MAX); + GPR_ASSERT(GPR_SLICE_LENGTH(value_slice) <= UINT32_MAX); + *add_tiny_header_data(st, 1) = 0x00; + GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, + add_tiny_header_data(st, len_key_len), len_key_len); + add_header_data(st, gpr_slice_ref(elem->key->slice)); + GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix, + add_tiny_header_data(st, len_val_len), len_val_len); + add_header_data(st, gpr_slice_ref(value_slice)); +} + +static void emit_advertise_table_size_change(grpc_chttp2_hpack_compressor *c, + framer_state *st) { + uint32_t len = GRPC_CHTTP2_VARINT_LENGTH(c->max_table_size, 3); + GRPC_CHTTP2_WRITE_VARINT(c->max_table_size, 3, 0x20, + add_tiny_header_data(st, len), len); + c->advertise_table_size_change = 0; +} + +static uint32_t dynidx(grpc_chttp2_hpack_compressor *c, uint32_t elem_index) { + return 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY + c->tail_remote_index + + c->table_elems - elem_index; +} + +/* encode an mdelem */ +static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem, + framer_state *st) { + uint32_t key_hash = elem->key->hash; + uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash); + size_t decoder_space_usage; + uint32_t indices_key; + int should_add_elem; + + GPR_ASSERT(GPR_SLICE_LENGTH(elem->key->slice) > 0); + if (GPR_SLICE_START_PTR(elem->key->slice)[0] != ':') { /* regular header */ + st->seen_regular_header = 1; + } else { + GPR_ASSERT( + st->seen_regular_header == 0 && + "Reserved header (colon-prefixed) happening after regular ones."); + } + + inc_filter(HASH_FRAGMENT_1(elem_hash), &c->filter_elems_sum, c->filter_elems); + + /* is this elem currently in the decoders table? */ + + if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == elem && + c->indices_elems[HASH_FRAGMENT_2(elem_hash)] > c->tail_remote_index) { + /* HIT: complete element (first cuckoo hash) */ + emit_indexed(c, dynidx(c, c->indices_elems[HASH_FRAGMENT_2(elem_hash)]), + st); + return; + } + + if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == elem && + c->indices_elems[HASH_FRAGMENT_3(elem_hash)] > c->tail_remote_index) { + /* HIT: complete element (second cuckoo hash) */ + emit_indexed(c, dynidx(c, c->indices_elems[HASH_FRAGMENT_3(elem_hash)]), + st); + return; + } + + /* should this elem be in the table? */ + decoder_space_usage = 32 + GPR_SLICE_LENGTH(elem->key->slice) + + GPR_SLICE_LENGTH(elem->value->slice); + should_add_elem = decoder_space_usage < MAX_DECODER_SPACE_USAGE && + c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >= + c->filter_elems_sum / ONE_ON_ADD_PROBABILITY; + + /* no hits for the elem... maybe there's a key? */ + + indices_key = c->indices_keys[HASH_FRAGMENT_2(key_hash)]; + if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == elem->key && + indices_key > c->tail_remote_index) { + /* HIT: key (first cuckoo hash) */ + if (should_add_elem) { + emit_lithdr_incidx(c, dynidx(c, indices_key), elem, st); + add_elem(c, elem); + return; + } else { + emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st); + return; + } + GPR_UNREACHABLE_CODE(return ); + } + + indices_key = c->indices_keys[HASH_FRAGMENT_3(key_hash)]; + if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == elem->key && + indices_key > c->tail_remote_index) { + /* HIT: key (first cuckoo hash) */ + if (should_add_elem) { + emit_lithdr_incidx(c, dynidx(c, indices_key), elem, st); + add_elem(c, elem); + return; + } else { + emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st); + return; + } + GPR_UNREACHABLE_CODE(return ); + } + + /* no elem, key in the table... fall back to literal emission */ + + if (should_add_elem) { + emit_lithdr_incidx_v(c, elem, st); + add_elem(c, elem); + return; + } else { + emit_lithdr_noidx_v(c, elem, st); + return; + } + GPR_UNREACHABLE_CODE(return ); +} + +#define STRLEN_LIT(x) (sizeof(x) - 1) +#define TIMEOUT_KEY "grpc-timeout" + +static void deadline_enc(grpc_chttp2_hpack_compressor *c, gpr_timespec deadline, + framer_state *st) { + char timeout_str[GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; + grpc_mdelem *mdelem; + grpc_chttp2_encode_timeout( + gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str); + mdelem = grpc_mdelem_from_metadata_strings( + GRPC_MDSTR_GRPC_TIMEOUT, grpc_mdstr_from_string(timeout_str)); + hpack_enc(c, mdelem, st); + GRPC_MDELEM_UNREF(mdelem); +} + +static uint32_t elems_for_bytes(uint32_t bytes) { return (bytes + 31) / 32; } + +void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c) { + memset(c, 0, sizeof(*c)); + c->max_table_size = GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE; + c->cap_table_elems = elems_for_bytes(c->max_table_size); + c->max_table_elems = c->cap_table_elems; + c->max_usable_size = GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE; + c->table_elem_size = + gpr_malloc(sizeof(*c->table_elem_size) * c->cap_table_elems); + memset(c->table_elem_size, 0, + sizeof(*c->table_elem_size) * c->cap_table_elems); +} + +void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) { + int i; + for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_VALUES; i++) { + if (c->entries_keys[i]) GRPC_MDSTR_UNREF(c->entries_keys[i]); + if (c->entries_elems[i]) GRPC_MDELEM_UNREF(c->entries_elems[i]); + } + gpr_free(c->table_elem_size); +} + +void grpc_chttp2_hpack_compressor_set_max_usable_size( + grpc_chttp2_hpack_compressor *c, uint32_t max_table_size) { + c->max_usable_size = max_table_size; + grpc_chttp2_hpack_compressor_set_max_table_size( + c, GPR_MIN(c->max_table_size, max_table_size)); +} + +static void rebuild_elems(grpc_chttp2_hpack_compressor *c, uint32_t new_cap) { + uint16_t *table_elem_size = gpr_malloc(sizeof(*table_elem_size) * new_cap); + uint32_t i; + + memset(table_elem_size, 0, sizeof(*table_elem_size) * new_cap); + GPR_ASSERT(c->table_elems <= new_cap); + + for (i = 0; i < c->table_elems; i++) { + uint32_t ofs = c->tail_remote_index + i + 1; + table_elem_size[ofs % new_cap] = + c->table_elem_size[ofs % c->cap_table_elems]; + } + + c->cap_table_elems = new_cap; + gpr_free(c->table_elem_size); + c->table_elem_size = table_elem_size; +} + +void grpc_chttp2_hpack_compressor_set_max_table_size( + grpc_chttp2_hpack_compressor *c, uint32_t max_table_size) { + max_table_size = GPR_MIN(max_table_size, c->max_usable_size); + if (max_table_size == c->max_table_size) { + return; + } + while (c->table_size > 0 && c->table_size > max_table_size) { + evict_entry(c); + } + c->max_table_size = max_table_size; + c->max_table_elems = elems_for_bytes(max_table_size); + if (c->max_table_elems > c->cap_table_elems) { + rebuild_elems(c, GPR_MAX(c->max_table_elems, 2 * c->cap_table_elems)); + } else if (c->max_table_elems < c->cap_table_elems / 3) { + uint32_t new_cap = GPR_MAX(c->max_table_elems, 16); + if (new_cap != c->cap_table_elems) { + rebuild_elems(c, new_cap); + } + } + c->advertise_table_size_change = 1; + gpr_log(GPR_DEBUG, "set max table size from encoder to %d", max_table_size); +} + +void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, + uint32_t stream_id, + grpc_metadata_batch *metadata, int is_eof, + gpr_slice_buffer *outbuf) { + framer_state st; + grpc_linked_mdelem *l; + gpr_timespec deadline; + + GPR_ASSERT(stream_id != 0); + + st.seen_regular_header = 0; + st.stream_id = stream_id; + st.output = outbuf; + st.is_first_frame = 1; + + /* Encode a metadata batch; store the returned values, representing + a metadata element that needs to be unreffed back into the metadata + slot. THIS MAY NOT BE THE SAME ELEMENT (if a decoder table slot got + updated). After this loop, we'll do a batch unref of elements. */ + begin_frame(&st); + if (c->advertise_table_size_change != 0) { + emit_advertise_table_size_change(c, &st); + } + grpc_metadata_batch_assert_ok(metadata); + for (l = metadata->list.head; l; l = l->next) { + hpack_enc(c, l->md, &st); + } + deadline = metadata->deadline; + if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) != 0) { + deadline_enc(c, deadline, &st); + } + + finish_frame(&st, 1, is_eof); +} diff --git a/src/core/lib/transport/chttp2/hpack_encoder.h b/src/core/lib/transport/chttp2/hpack_encoder.h new file mode 100644 index 0000000000..6d86eb7c83 --- /dev/null +++ b/src/core/lib/transport/chttp2/hpack_encoder.h @@ -0,0 +1,95 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_HPACK_ENCODER_H +#define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H + +#include +#include +#include +#include "src/core/transport/chttp2/frame.h" +#include "src/core/transport/metadata.h" +#include "src/core/transport/metadata_batch.h" + +#define GRPC_CHTTP2_HPACKC_NUM_FILTERS 256 +#define GRPC_CHTTP2_HPACKC_NUM_VALUES 256 +/* initial table size, per spec */ +#define GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE 4096 +/* maximum table size we'll actually use */ +#define GRPC_CHTTP2_HPACKC_MAX_TABLE_SIZE (1024 * 1024) + +typedef struct { + uint32_t filter_elems_sum; + uint32_t max_table_size; + uint32_t max_table_elems; + uint32_t cap_table_elems; + /** if non-zero, advertise to the decoder that we'll start using a table + of this size */ + uint8_t advertise_table_size_change; + /** maximum number of bytes we'll use for the decode table (to guard against + peers ooming us by setting decode table size high) */ + uint32_t max_usable_size; + /* one before the lowest usable table index */ + uint32_t tail_remote_index; + uint32_t table_size; + uint32_t table_elems; + + /* filter tables for elems: this tables provides an approximate + popularity count for particular hashes, and are used to determine whether + a new literal should be added to the compression table or not. + They track a single integer that counts how often a particular value has + been seen. When that count reaches max (255), all values are halved. */ + uint8_t filter_elems[GRPC_CHTTP2_HPACKC_NUM_FILTERS]; + + /* entry tables for keys & elems: these tables track values that have been + seen and *may* be in the decompressor table */ + grpc_mdstr *entries_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES]; + grpc_mdelem *entries_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES]; + uint32_t indices_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES]; + uint32_t indices_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES]; + + uint16_t *table_elem_size; +} grpc_chttp2_hpack_compressor; + +void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c); +void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c); +void grpc_chttp2_hpack_compressor_set_max_table_size( + grpc_chttp2_hpack_compressor *c, uint32_t max_table_size); +void grpc_chttp2_hpack_compressor_set_max_usable_size( + grpc_chttp2_hpack_compressor *c, uint32_t max_table_size); + +void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, uint32_t id, + grpc_metadata_batch *metadata, int is_eof, + gpr_slice_buffer *outbuf); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H */ diff --git a/src/core/lib/transport/chttp2/hpack_parser.c b/src/core/lib/transport/chttp2/hpack_parser.c new file mode 100644 index 0000000000..b6e36923cb --- /dev/null +++ b/src/core/lib/transport/chttp2/hpack_parser.c @@ -0,0 +1,1449 @@ +/* + * + * Copyright 2015-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/transport/chttp2/hpack_parser.h" +#include "src/core/transport/chttp2/internal.h" + +#include +#include +#include + +/* This is here for grpc_is_binary_header + * TODO(murgatroid99): Remove this + */ +#include + +#include +#include +#include +#include + +#include "src/core/profiling/timers.h" +#include "src/core/support/string.h" +#include "src/core/transport/chttp2/bin_encoder.h" + +typedef enum { + NOT_BINARY, + B64_BYTE0, + B64_BYTE1, + B64_BYTE2, + B64_BYTE3 +} binary_state; + +/* How parsing works: + + The parser object keeps track of a function pointer which represents the + current parse state. + + Each time new bytes are presented, we call into the current state, which + recursively parses until all bytes in the given chunk are exhausted. + + The parse state that terminates then saves its function pointer to be the + current state so that it can resume when more bytes are available. + + It's expected that most optimizing compilers will turn this code into + a set of indirect jumps, and so not waste stack space. */ + +/* forward declarations for parsing states */ +static int parse_begin(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_error(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_illegal_op(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); + +static int parse_string_prefix(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_key_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_value_string_with_indexed_key(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, + const uint8_t *end); +static int parse_value_string_with_literal_key(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, + const uint8_t *end); + +static int parse_value0(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_value1(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_value2(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_value3(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_value4(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_value5up(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); + +static int parse_indexed_field(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_indexed_field_x(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end); +static int parse_lithdr_incidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end); +static int parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end); +static int parse_lithdr_notidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end); +static int parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end); +static int parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end); +static int parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end); +static int parse_max_tbl_size(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); +static int parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end); + +/* we translate the first byte of a hpack field into one of these decoding + cases, then use a lookup table to jump directly to the appropriate parser. + + _X => the integer index is all ones, meaning we need to do varint decoding + _V => the integer index is all zeros, meaning we need to decode an additional + string value */ +typedef enum { + INDEXED_FIELD, + INDEXED_FIELD_X, + LITHDR_INCIDX, + LITHDR_INCIDX_X, + LITHDR_INCIDX_V, + LITHDR_NOTIDX, + LITHDR_NOTIDX_X, + LITHDR_NOTIDX_V, + LITHDR_NVRIDX, + LITHDR_NVRIDX_X, + LITHDR_NVRIDX_V, + MAX_TBL_SIZE, + MAX_TBL_SIZE_X, + ILLEGAL +} first_byte_type; + +/* jump table of parse state functions -- order must match first_byte_type + above */ +static const grpc_chttp2_hpack_parser_state first_byte_action[] = { + parse_indexed_field, parse_indexed_field_x, parse_lithdr_incidx, + parse_lithdr_incidx_x, parse_lithdr_incidx_v, parse_lithdr_notidx, + parse_lithdr_notidx_x, parse_lithdr_notidx_v, parse_lithdr_nvridx, + parse_lithdr_nvridx_x, parse_lithdr_nvridx_v, parse_max_tbl_size, + parse_max_tbl_size_x, parse_illegal_op}; + +/* indexes the first byte to a parse state function - generated by + gen_hpack_tables.c */ +static const uint8_t first_byte_lut[256] = { + LITHDR_NOTIDX_V, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, + LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, + LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, + LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX_X, + LITHDR_NVRIDX_V, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, + LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, + LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, + LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX_X, + MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, + MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, + MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, + MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, + MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, + MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, + MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, + MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE_X, + LITHDR_INCIDX_V, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, + LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX_X, + ILLEGAL, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, + INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD_X, +}; + +/* state table for huffman decoding: given a state, gives an index/16 into + next_sub_tbl. Taking that index and adding the value of the nibble being + considered returns the next state. + + generated by gen_hpack_tables.c */ +static const uint8_t next_tbl[256] = { + 0, 1, 2, 3, 4, 1, 2, 5, 6, 1, 7, 8, 1, 3, 3, 9, 10, 11, 1, 1, + 1, 12, 1, 2, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 14, 1, 15, 16, 1, 17, 1, 15, 2, 7, 3, 18, 19, 1, 1, 1, 1, 20, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 15, 2, 2, 7, 21, 1, 22, 1, 1, 1, 1, 1, + 1, 1, 1, 15, 2, 2, 2, 2, 2, 2, 23, 24, 25, 1, 1, 1, 1, 2, 2, 2, + 26, 3, 3, 27, 10, 28, 1, 1, 1, 1, 1, 1, 2, 3, 29, 10, 30, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 2, 2, 32, 1, 1, 15, 33, 1, 34, 35, 9, 36, 1, 1, 1, + 1, 1, 1, 1, 37, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 26, 9, + 38, 1, 1, 1, 1, 1, 1, 1, 15, 2, 2, 2, 2, 26, 3, 3, 39, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 7, 3, 3, 3, 40, 2, + 41, 1, 1, 1, 42, 43, 1, 1, 44, 1, 1, 1, 1, 15, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 45, 46, 1, 1, 2, 2, 2, 35, 3, 3, 18, 47, 2, +}; + +/* next state, based upon current state and the current nibble: see above. + generated by gen_hpack_tables.c */ +static const int16_t next_sub_tbl[48 * 16] = { + 1, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 2, 6, 10, 13, 14, 15, 16, 17, 2, 6, 10, 13, 14, 15, + 16, 17, 3, 7, 11, 24, 3, 7, 11, 24, 3, 7, 11, 24, 3, + 7, 11, 24, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, + 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 199, 200, 201, 202, 203, 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 3, 7, 11, 24, 3, 7, 11, 24, + 4, 8, 4, 8, 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 12, 132, 4, 8, 4, 8, 4, 8, + 4, 8, 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 21, 4, 8, 4, + 8, 4, 8, 4, 8, 4, 8, 0, 0, 0, 22, 23, 91, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 3, + 7, 11, 24, 3, 7, 11, 24, 0, 0, 0, 0, 0, 41, 42, 43, + 2, 6, 10, 13, 14, 15, 16, 17, 3, 7, 11, 24, 3, 7, 11, + 24, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 0, 0, + 44, 45, 2, 6, 10, 13, 14, 15, 16, 17, 46, 47, 48, 49, 50, + 51, 52, 57, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 53, 54, 55, 56, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 73, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 3, 7, 11, 24, 3, 7, 11, + 24, 3, 7, 11, 24, 0, 0, 0, 0, 3, 7, 11, 24, 3, 7, + 11, 24, 4, 8, 4, 8, 0, 0, 0, 92, 0, 0, 0, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 3, 7, 11, 24, + 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, + 8, 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 4, + 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 0, 0, + 0, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 2, 6, 10, 13, 14, 15, 16, 17, 4, 8, 4, 8, 4, 8, + 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 148, + 149, 150, 151, 3, 7, 11, 24, 4, 8, 4, 8, 0, 0, 0, 0, + 0, 0, 152, 153, 3, 7, 11, 24, 3, 7, 11, 24, 3, 7, 11, + 24, 154, 155, 156, 164, 3, 7, 11, 24, 3, 7, 11, 24, 3, 7, + 11, 24, 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 157, 158, 159, 160, 161, 162, 163, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 4, 8, 4, 8, 4, 8, + 4, 8, 4, 8, 4, 8, 4, 8, 197, 198, 4, 8, 4, 8, 4, + 8, 4, 8, 0, 0, 0, 0, 0, 0, 219, 220, 3, 7, 11, 24, + 4, 8, 4, 8, 4, 8, 0, 0, 221, 222, 223, 224, 3, 7, 11, + 24, 3, 7, 11, 24, 4, 8, 4, 8, 4, 8, 225, 228, 4, 8, + 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 226, 227, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 255, +}; + +/* emission table: indexed like next_tbl, ultimately gives the byte to be + emitted, or -1 for no byte, or 256 for end of stream + + generated by gen_hpack_tables.c */ +static const uint16_t emit_tbl[256] = { + 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 0, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 0, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 0, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 0, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 0, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, +}; + +/* generated by gen_hpack_tables.c */ +static const int16_t emit_sub_tbl[249 * 16] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, + 49, 49, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 97, + 97, 97, 97, 48, 48, 49, 49, 50, 50, 97, 97, 99, 99, 101, 101, + 105, 105, 111, 111, 48, 49, 50, 97, 99, 101, 105, 111, 115, 116, -1, + -1, -1, -1, -1, -1, 32, 32, 32, 32, 32, 32, 32, 32, 37, 37, + 37, 37, 37, 37, 37, 37, 99, 99, 99, 99, 101, 101, 101, 101, 105, + 105, 105, 105, 111, 111, 111, 111, 115, 115, 116, 116, 32, 37, 45, 46, + 47, 51, 52, 53, 54, 55, 56, 57, 61, 61, 61, 61, 61, 61, 61, + 61, 65, 65, 65, 65, 65, 65, 65, 65, 115, 115, 115, 115, 116, 116, + 116, 116, 32, 32, 37, 37, 45, 45, 46, 46, 61, 65, 95, 98, 100, + 102, 103, 104, 108, 109, 110, 112, 114, 117, -1, -1, 58, 58, 58, 58, + 58, 58, 58, 58, 66, 66, 66, 66, 66, 66, 66, 66, 47, 47, 51, + 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 61, 61, + 65, 65, 95, 95, 98, 98, 100, 100, 102, 102, 103, 103, 104, 104, 108, + 108, 109, 109, 110, 110, 112, 112, 114, 114, 117, 117, 58, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 89, 106, 107, 113, 118, 119, 120, 121, 122, -1, -1, + -1, -1, 38, 38, 38, 38, 38, 38, 38, 38, 42, 42, 42, 42, 42, + 42, 42, 42, 44, 44, 44, 44, 44, 44, 44, 44, 59, 59, 59, 59, + 59, 59, 59, 59, 88, 88, 88, 88, 88, 88, 88, 88, 90, 90, 90, + 90, 90, 90, 90, 90, 33, 33, 34, 34, 40, 40, 41, 41, 63, 63, + 39, 43, 124, -1, -1, -1, 35, 35, 35, 35, 35, 35, 35, 35, 62, + 62, 62, 62, 62, 62, 62, 62, 0, 0, 0, 0, 36, 36, 36, 36, + 64, 64, 64, 64, 91, 91, 91, 91, 69, 69, 69, 69, 69, 69, 69, + 69, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, + 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, + 73, 73, 73, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, + 75, 75, 75, 75, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, + 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, + 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, 80, 80, 80, 80, 81, + 81, 81, 81, 81, 81, 81, 81, 82, 82, 82, 82, 82, 82, 82, 82, + 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, 84, 84, 84, + 84, 85, 85, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 86, 86, + 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 89, 89, 89, 89, 89, + 89, 89, 89, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, + 107, 107, 107, 107, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118, + 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 120, 120, + 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 122, + 122, 122, 122, 122, 122, 122, 122, 38, 38, 38, 38, 42, 42, 42, 42, + 44, 44, 44, 44, 59, 59, 59, 59, 88, 88, 88, 88, 90, 90, 90, + 90, 33, 34, 40, 41, 63, -1, -1, -1, 39, 39, 39, 39, 39, 39, + 39, 39, 43, 43, 43, 43, 43, 43, 43, 43, 124, 124, 124, 124, 124, + 124, 124, 124, 35, 35, 35, 35, 62, 62, 62, 62, 0, 0, 36, 36, + 64, 64, 91, 91, 93, 93, 126, 126, 94, 125, -1, -1, 60, 60, 60, + 60, 60, 60, 60, 60, 96, 96, 96, 96, 96, 96, 96, 96, 123, 123, + 123, 123, 123, 123, 123, 123, -1, -1, -1, -1, -1, -1, -1, -1, 92, + 92, 92, 92, 92, 92, 92, 92, 195, 195, 195, 195, 195, 195, 195, 195, + 208, 208, 208, 208, 208, 208, 208, 208, 128, 128, 128, 128, 130, 130, 130, + 130, 131, 131, 131, 131, 162, 162, 162, 162, 184, 184, 184, 184, 194, 194, + 194, 194, 224, 224, 224, 224, 226, 226, 226, 226, 153, 153, 161, 161, 167, + 167, 172, 172, 176, 176, 177, 177, 179, 179, 209, 209, 216, 216, 217, 217, + 227, 227, 229, 229, 230, 230, 129, 132, 133, 134, 136, 146, 154, 156, 160, + 163, 164, 169, 170, 173, 178, 181, 185, 186, 187, 189, 190, 196, 198, 228, + 232, 233, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 135, + 135, 135, 135, 135, 135, 135, 135, 137, 137, 137, 137, 137, 137, 137, 137, + 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139, 139, 139, 139, + 139, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141, 141, + 141, 141, 143, 143, 143, 143, 143, 143, 143, 143, 147, 147, 147, 147, 147, + 147, 147, 147, 149, 149, 149, 149, 149, 149, 149, 149, 150, 150, 150, 150, + 150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 151, 151, 152, 152, 152, + 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 157, 157, + 157, 157, 157, 157, 157, 157, 158, 158, 158, 158, 158, 158, 158, 158, 165, + 165, 165, 165, 165, 165, 165, 165, 166, 166, 166, 166, 166, 166, 166, 166, + 168, 168, 168, 168, 168, 168, 168, 168, 174, 174, 174, 174, 174, 174, 174, + 174, 175, 175, 175, 175, 175, 175, 175, 175, 180, 180, 180, 180, 180, 180, + 180, 180, 182, 182, 182, 182, 182, 182, 182, 182, 183, 183, 183, 183, 183, + 183, 183, 183, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191, + 191, 191, 191, 191, 197, 197, 197, 197, 197, 197, 197, 197, 231, 231, 231, + 231, 231, 231, 231, 231, 239, 239, 239, 239, 239, 239, 239, 239, 9, 9, + 9, 9, 142, 142, 142, 142, 144, 144, 144, 144, 145, 145, 145, 145, 148, + 148, 148, 148, 159, 159, 159, 159, 171, 171, 171, 171, 206, 206, 206, 206, + 215, 215, 215, 215, 225, 225, 225, 225, 236, 236, 236, 236, 237, 237, 237, + 237, 199, 199, 207, 207, 234, 234, 235, 235, 192, 193, 200, 201, 202, 205, + 210, 213, 218, 219, 238, 240, 242, 243, 255, -1, 203, 203, 203, 203, 203, + 203, 203, 203, 204, 204, 204, 204, 204, 204, 204, 204, 211, 211, 211, 211, + 211, 211, 211, 211, 212, 212, 212, 212, 212, 212, 212, 212, 214, 214, 214, + 214, 214, 214, 214, 214, 221, 221, 221, 221, 221, 221, 221, 221, 222, 222, + 222, 222, 222, 222, 222, 222, 223, 223, 223, 223, 223, 223, 223, 223, 241, + 241, 241, 241, 241, 241, 241, 241, 244, 244, 244, 244, 244, 244, 244, 244, + 245, 245, 245, 245, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, + 246, 247, 247, 247, 247, 247, 247, 247, 247, 248, 248, 248, 248, 248, 248, + 248, 248, 250, 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, 251, 251, + 251, 251, 251, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, + 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 2, 2, 2, + 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, + 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 11, 11, 11, 11, 12, + 12, 12, 12, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, + 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, + 20, 21, 21, 21, 21, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, + 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, + 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 127, 127, 127, 127, + 220, 220, 220, 220, 249, 249, 249, 249, 10, 13, 22, 256, 93, 93, 93, + 93, 126, 126, 126, 126, 94, 94, 125, 125, 60, 96, 123, -1, 92, 195, + 208, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 128, + 128, 128, 128, 128, 128, 128, 128, 130, 130, 130, 130, 130, 130, 130, 130, + 131, 131, 131, 131, 131, 131, 131, 131, 162, 162, 162, 162, 162, 162, 162, + 162, 184, 184, 184, 184, 184, 184, 184, 184, 194, 194, 194, 194, 194, 194, + 194, 194, 224, 224, 224, 224, 224, 224, 224, 224, 226, 226, 226, 226, 226, + 226, 226, 226, 153, 153, 153, 153, 161, 161, 161, 161, 167, 167, 167, 167, + 172, 172, 172, 172, 176, 176, 176, 176, 177, 177, 177, 177, 179, 179, 179, + 179, 209, 209, 209, 209, 216, 216, 216, 216, 217, 217, 217, 217, 227, 227, + 227, 227, 229, 229, 229, 229, 230, 230, 230, 230, 129, 129, 132, 132, 133, + 133, 134, 134, 136, 136, 146, 146, 154, 154, 156, 156, 160, 160, 163, 163, + 164, 164, 169, 169, 170, 170, 173, 173, 178, 178, 181, 181, 185, 185, 186, + 186, 187, 187, 189, 189, 190, 190, 196, 196, 198, 198, 228, 228, 232, 232, + 233, 233, 1, 135, 137, 138, 139, 140, 141, 143, 147, 149, 150, 151, 152, + 155, 157, 158, 165, 166, 168, 174, 175, 180, 182, 183, 188, 191, 197, 231, + 239, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 9, 9, + 9, 9, 9, 9, 9, 142, 142, 142, 142, 142, 142, 142, 142, 144, 144, + 144, 144, 144, 144, 144, 144, 145, 145, 145, 145, 145, 145, 145, 145, 148, + 148, 148, 148, 148, 148, 148, 148, 159, 159, 159, 159, 159, 159, 159, 159, + 171, 171, 171, 171, 171, 171, 171, 171, 206, 206, 206, 206, 206, 206, 206, + 206, 215, 215, 215, 215, 215, 215, 215, 215, 225, 225, 225, 225, 225, 225, + 225, 225, 236, 236, 236, 236, 236, 236, 236, 236, 237, 237, 237, 237, 237, + 237, 237, 237, 199, 199, 199, 199, 207, 207, 207, 207, 234, 234, 234, 234, + 235, 235, 235, 235, 192, 192, 193, 193, 200, 200, 201, 201, 202, 202, 205, + 205, 210, 210, 213, 213, 218, 218, 219, 219, 238, 238, 240, 240, 242, 242, + 243, 243, 255, 255, 203, 204, 211, 212, 214, 221, 222, 223, 241, 244, 245, + 246, 247, 248, 250, 251, 252, 253, 254, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, + 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, + 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, + 12, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, + 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, + 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, + 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, + 20, 21, 21, 21, 21, 21, 21, 21, 21, 23, 23, 23, 23, 23, 23, + 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, + 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, + 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, + 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, + 31, 31, 31, 31, 31, 31, 127, 127, 127, 127, 127, 127, 127, 127, 220, + 220, 220, 220, 220, 220, 220, 220, 249, 249, 249, 249, 249, 249, 249, 249, + 10, 10, 13, 13, 22, 22, 256, 256, 67, 67, 67, 67, 67, 67, 67, + 67, 68, 68, 68, 68, 68, 68, 68, 68, 95, 95, 95, 95, 95, 95, + 95, 95, 98, 98, 98, 98, 98, 98, 98, 98, 100, 100, 100, 100, 100, + 100, 100, 100, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, + 103, 103, 103, 103, 104, 104, 104, 104, 104, 104, 104, 104, 108, 108, 108, + 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 110, 110, + 110, 110, 110, 110, 110, 110, 112, 112, 112, 112, 112, 112, 112, 112, 114, + 114, 114, 114, 114, 114, 114, 114, 117, 117, 117, 117, 117, 117, 117, 117, + 58, 58, 58, 58, 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, + 68, 69, 69, 69, 69, 70, 70, 70, 70, 71, 71, 71, 71, 72, 72, + 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 76, + 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 79, + 80, 80, 80, 80, 81, 81, 81, 81, 82, 82, 82, 82, 83, 83, 83, + 83, 84, 84, 84, 84, 85, 85, 85, 85, 86, 86, 86, 86, 87, 87, + 87, 87, 89, 89, 89, 89, 106, 106, 106, 106, 107, 107, 107, 107, 113, + 113, 113, 113, 118, 118, 118, 118, 119, 119, 119, 119, 120, 120, 120, 120, + 121, 121, 121, 121, 122, 122, 122, 122, 38, 38, 42, 42, 44, 44, 59, + 59, 88, 88, 90, 90, -1, -1, -1, -1, 33, 33, 33, 33, 33, 33, + 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 40, 40, 40, 40, 40, + 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 63, 63, 63, 63, + 63, 63, 63, 63, 39, 39, 39, 39, 43, 43, 43, 43, 124, 124, 124, + 124, 35, 35, 62, 62, 0, 36, 64, 91, 93, 126, -1, -1, 94, 94, + 94, 94, 94, 94, 94, 94, 125, 125, 125, 125, 125, 125, 125, 125, 60, + 60, 60, 60, 96, 96, 96, 96, 123, 123, 123, 123, -1, -1, -1, -1, + 92, 92, 92, 92, 195, 195, 195, 195, 208, 208, 208, 208, 128, 128, 130, + 130, 131, 131, 162, 162, 184, 184, 194, 194, 224, 224, 226, 226, 153, 161, + 167, 172, 176, 177, 179, 209, 216, 217, 227, 229, 230, -1, -1, -1, -1, + -1, -1, -1, 129, 129, 129, 129, 129, 129, 129, 129, 132, 132, 132, 132, + 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 134, 134, 134, + 134, 134, 134, 134, 134, 136, 136, 136, 136, 136, 136, 136, 136, 146, 146, + 146, 146, 146, 146, 146, 146, 154, 154, 154, 154, 154, 154, 154, 154, 156, + 156, 156, 156, 156, 156, 156, 156, 160, 160, 160, 160, 160, 160, 160, 160, + 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, + 164, 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, + 170, 170, 173, 173, 173, 173, 173, 173, 173, 173, 178, 178, 178, 178, 178, + 178, 178, 178, 181, 181, 181, 181, 181, 181, 181, 181, 185, 185, 185, 185, + 185, 185, 185, 185, 186, 186, 186, 186, 186, 186, 186, 186, 187, 187, 187, + 187, 187, 187, 187, 187, 189, 189, 189, 189, 189, 189, 189, 189, 190, 190, + 190, 190, 190, 190, 190, 190, 196, 196, 196, 196, 196, 196, 196, 196, 198, + 198, 198, 198, 198, 198, 198, 198, 228, 228, 228, 228, 228, 228, 228, 228, + 232, 232, 232, 232, 232, 232, 232, 232, 233, 233, 233, 233, 233, 233, 233, + 233, 1, 1, 1, 1, 135, 135, 135, 135, 137, 137, 137, 137, 138, 138, + 138, 138, 139, 139, 139, 139, 140, 140, 140, 140, 141, 141, 141, 141, 143, + 143, 143, 143, 147, 147, 147, 147, 149, 149, 149, 149, 150, 150, 150, 150, + 151, 151, 151, 151, 152, 152, 152, 152, 155, 155, 155, 155, 157, 157, 157, + 157, 158, 158, 158, 158, 165, 165, 165, 165, 166, 166, 166, 166, 168, 168, + 168, 168, 174, 174, 174, 174, 175, 175, 175, 175, 180, 180, 180, 180, 182, + 182, 182, 182, 183, 183, 183, 183, 188, 188, 188, 188, 191, 191, 191, 191, + 197, 197, 197, 197, 231, 231, 231, 231, 239, 239, 239, 239, 9, 9, 142, + 142, 144, 144, 145, 145, 148, 148, 159, 159, 171, 171, 206, 206, 215, 215, + 225, 225, 236, 236, 237, 237, 199, 207, 234, 235, 192, 192, 192, 192, 192, + 192, 192, 192, 193, 193, 193, 193, 193, 193, 193, 193, 200, 200, 200, 200, + 200, 200, 200, 200, 201, 201, 201, 201, 201, 201, 201, 201, 202, 202, 202, + 202, 202, 202, 202, 202, 205, 205, 205, 205, 205, 205, 205, 205, 210, 210, + 210, 210, 210, 210, 210, 210, 213, 213, 213, 213, 213, 213, 213, 213, 218, + 218, 218, 218, 218, 218, 218, 218, 219, 219, 219, 219, 219, 219, 219, 219, + 238, 238, 238, 238, 238, 238, 238, 238, 240, 240, 240, 240, 240, 240, 240, + 240, 242, 242, 242, 242, 242, 242, 242, 242, 243, 243, 243, 243, 243, 243, + 243, 243, 255, 255, 255, 255, 255, 255, 255, 255, 203, 203, 203, 203, 204, + 204, 204, 204, 211, 211, 211, 211, 212, 212, 212, 212, 214, 214, 214, 214, + 221, 221, 221, 221, 222, 222, 222, 222, 223, 223, 223, 223, 241, 241, 241, + 241, 244, 244, 244, 244, 245, 245, 245, 245, 246, 246, 246, 246, 247, 247, + 247, 247, 248, 248, 248, 248, 250, 250, 250, 250, 251, 251, 251, 251, 252, + 252, 252, 252, 253, 253, 253, 253, 254, 254, 254, 254, 2, 2, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 11, 11, 12, 12, 14, + 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, + 30, 31, 31, 127, 127, 220, 220, 249, 249, -1, -1, 10, 10, 10, 10, + 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 22, 22, 22, + 22, 22, 22, 22, 22, 256, 256, 256, 256, 256, 256, 256, 256, 45, 45, + 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 47, + 47, 47, 47, 47, 47, 47, 47, 51, 51, 51, 51, 51, 51, 51, 51, + 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, + 53, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, + 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, + 57, 57, 57, 50, 50, 50, 50, 50, 50, 50, 50, 97, 97, 97, 97, + 97, 97, 97, 97, 99, 99, 99, 99, 99, 99, 99, 99, 101, 101, 101, + 101, 101, 101, 101, 101, 105, 105, 105, 105, 105, 105, 105, 105, 111, 111, + 111, 111, 111, 111, 111, 111, 115, 115, 115, 115, 115, 115, 115, 115, 116, + 116, 116, 116, 116, 116, 116, 116, 32, 32, 32, 32, 37, 37, 37, 37, + 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 51, 51, 51, + 51, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, + 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, 61, 61, 61, 61, 65, + 65, 65, 65, 95, 95, 95, 95, 98, 98, 98, 98, 100, 100, 100, 100, + 102, 102, 102, 102, 103, 103, 103, 103, 104, 104, 104, 104, 108, 108, 108, + 108, 109, 109, 109, 109, 110, 110, 110, 110, 112, 112, 112, 112, 114, 114, + 114, 114, 117, 117, 117, 117, 58, 58, 66, 66, 67, 67, 68, 68, 69, + 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, + 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, + 84, 85, 85, 86, 86, 87, 87, 89, 89, 106, 106, 107, 107, 113, 113, + 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 38, 42, 44, 59, 88, + 90, -1, -1, 33, 33, 33, 33, 34, 34, 34, 34, 40, 40, 40, 40, + 41, 41, 41, 41, 63, 63, 63, 63, 39, 39, 43, 43, 124, 124, 35, + 62, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36, + 36, 36, 36, 36, 36, 36, 64, 64, 64, 64, 64, 64, 64, 64, 91, + 91, 91, 91, 91, 91, 91, 91, 93, 93, 93, 93, 93, 93, 93, 93, + 126, 126, 126, 126, 126, 126, 126, 126, 94, 94, 94, 94, 125, 125, 125, + 125, 60, 60, 96, 96, 123, 123, -1, -1, 92, 92, 195, 195, 208, 208, + 128, 130, 131, 162, 184, 194, 224, 226, -1, -1, 153, 153, 153, 153, 153, + 153, 153, 153, 161, 161, 161, 161, 161, 161, 161, 161, 167, 167, 167, 167, + 167, 167, 167, 167, 172, 172, 172, 172, 172, 172, 172, 172, 176, 176, 176, + 176, 176, 176, 176, 176, 177, 177, 177, 177, 177, 177, 177, 177, 179, 179, + 179, 179, 179, 179, 179, 179, 209, 209, 209, 209, 209, 209, 209, 209, 216, + 216, 216, 216, 216, 216, 216, 216, 217, 217, 217, 217, 217, 217, 217, 217, + 227, 227, 227, 227, 227, 227, 227, 227, 229, 229, 229, 229, 229, 229, 229, + 229, 230, 230, 230, 230, 230, 230, 230, 230, 129, 129, 129, 129, 132, 132, + 132, 132, 133, 133, 133, 133, 134, 134, 134, 134, 136, 136, 136, 136, 146, + 146, 146, 146, 154, 154, 154, 154, 156, 156, 156, 156, 160, 160, 160, 160, + 163, 163, 163, 163, 164, 164, 164, 164, 169, 169, 169, 169, 170, 170, 170, + 170, 173, 173, 173, 173, 178, 178, 178, 178, 181, 181, 181, 181, 185, 185, + 185, 185, 186, 186, 186, 186, 187, 187, 187, 187, 189, 189, 189, 189, 190, + 190, 190, 190, 196, 196, 196, 196, 198, 198, 198, 198, 228, 228, 228, 228, + 232, 232, 232, 232, 233, 233, 233, 233, 1, 1, 135, 135, 137, 137, 138, + 138, 139, 139, 140, 140, 141, 141, 143, 143, 147, 147, 149, 149, 150, 150, + 151, 151, 152, 152, 155, 155, 157, 157, 158, 158, 165, 165, 166, 166, 168, + 168, 174, 174, 175, 175, 180, 180, 182, 182, 183, 183, 188, 188, 191, 191, + 197, 197, 231, 231, 239, 239, 9, 142, 144, 145, 148, 159, 171, 206, 215, + 225, 236, 237, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 199, 199, + 199, 199, 199, 199, 199, 199, 207, 207, 207, 207, 207, 207, 207, 207, 234, + 234, 234, 234, 234, 234, 234, 234, 235, 235, 235, 235, 235, 235, 235, 235, + 192, 192, 192, 192, 193, 193, 193, 193, 200, 200, 200, 200, 201, 201, 201, + 201, 202, 202, 202, 202, 205, 205, 205, 205, 210, 210, 210, 210, 213, 213, + 213, 213, 218, 218, 218, 218, 219, 219, 219, 219, 238, 238, 238, 238, 240, + 240, 240, 240, 242, 242, 242, 242, 243, 243, 243, 243, 255, 255, 255, 255, + 203, 203, 204, 204, 211, 211, 212, 212, 214, 214, 221, 221, 222, 222, 223, + 223, 241, 241, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 250, 250, + 251, 251, 252, 252, 253, 253, 254, 254, 2, 3, 4, 5, 6, 7, 8, + 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 127, 220, 249, -1, 10, 10, 10, 10, 13, 13, 13, + 13, 22, 22, 22, 22, 256, 256, 256, 256, +}; + +static const uint8_t inverse_base64[256] = { + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, + 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, + 255, 64, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, +}; + +/* emission helpers */ +static int on_hdr(grpc_chttp2_hpack_parser *p, grpc_mdelem *md, + int add_to_table) { + if (add_to_table) { + if (!grpc_chttp2_hptbl_add(&p->table, md)) { + return 0; + } + } + p->on_header(p->on_header_user_data, md); + return 1; +} + +static grpc_mdstr *take_string(grpc_chttp2_hpack_parser *p, + grpc_chttp2_hpack_parser_string *str) { + grpc_mdstr *s = grpc_mdstr_from_buffer((uint8_t *)str->str, str->length); + str->length = 0; + return s; +} + +/* jump to the next state */ +static int parse_next(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + p->state = *p->next_state++; + return p->state(p, cur, end); +} + +/* begin parsing a header: all functionality is encoded into lookup tables + above */ +static int parse_begin(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (cur == end) { + p->state = parse_begin; + return 1; + } + + return first_byte_action[first_byte_lut[*cur]](p, cur, end); +} + +/* stream dependency and prioritization data: we just skip it */ +static int parse_stream_weight(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (cur == end) { + p->state = parse_stream_weight; + return 1; + } + + return p->after_prioritization(p, cur + 1, end); +} + +static int parse_stream_dep3(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (cur == end) { + p->state = parse_stream_dep3; + return 1; + } + + return parse_stream_weight(p, cur + 1, end); +} + +static int parse_stream_dep2(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (cur == end) { + p->state = parse_stream_dep2; + return 1; + } + + return parse_stream_dep3(p, cur + 1, end); +} + +static int parse_stream_dep1(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (cur == end) { + p->state = parse_stream_dep1; + return 1; + } + + return parse_stream_dep2(p, cur + 1, end); +} + +static int parse_stream_dep0(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (cur == end) { + p->state = parse_stream_dep0; + return 1; + } + + return parse_stream_dep1(p, cur + 1, end); +} + +/* emit an indexed field; for now just logs it to console; jumps to + begin the next field on completion */ +static int finish_indexed_field(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); + if (md == NULL) { + gpr_log(GPR_ERROR, "Invalid HPACK index received: %d", p->index); + return 0; + } + GRPC_MDELEM_REF(md); + return on_hdr(p, md, 0) && parse_begin(p, cur, end); +} + +/* parse an indexed field with index < 127 */ +static int parse_indexed_field(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + p->dynamic_table_update_allowed = 0; + p->index = (*cur) & 0x7f; + return finish_indexed_field(p, cur + 1, end); +} + +/* parse an indexed field with index >= 127 */ +static int parse_indexed_field_x(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end) { + static const grpc_chttp2_hpack_parser_state and_then[] = { + finish_indexed_field}; + p->dynamic_table_update_allowed = 0; + p->next_state = and_then; + p->index = 0x7f; + p->parsing.value = &p->index; + return parse_value0(p, cur + 1, end); +} + +/* finish a literal header with incremental indexing: just log, and jump to ' + begin */ +static int finish_lithdr_incidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); + GPR_ASSERT(md != NULL); /* handled in string parsing */ + return on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key), + take_string(p, &p->value)), + 1) && + parse_begin(p, cur, end); +} + +/* finish a literal header with incremental indexing with no index */ +static int finish_lithdr_incidx_v(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end) { + return on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key), + take_string(p, &p->value)), + 1) && + parse_begin(p, cur, end); +} + +/* parse a literal header with incremental indexing; index < 63 */ +static int parse_lithdr_incidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + static const grpc_chttp2_hpack_parser_state and_then[] = { + parse_value_string_with_indexed_key, finish_lithdr_incidx}; + p->dynamic_table_update_allowed = 0; + p->next_state = and_then; + p->index = (*cur) & 0x3f; + return parse_string_prefix(p, cur + 1, end); +} + +/* parse a literal header with incremental indexing; index >= 63 */ +static int parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end) { + static const grpc_chttp2_hpack_parser_state and_then[] = { + parse_string_prefix, parse_value_string_with_indexed_key, + finish_lithdr_incidx}; + p->dynamic_table_update_allowed = 0; + p->next_state = and_then; + p->index = 0x3f; + p->parsing.value = &p->index; + return parse_value0(p, cur + 1, end); +} + +/* parse a literal header with incremental indexing; index = 0 */ +static int parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end) { + static const grpc_chttp2_hpack_parser_state and_then[] = { + parse_key_string, parse_string_prefix, + parse_value_string_with_literal_key, finish_lithdr_incidx_v}; + p->dynamic_table_update_allowed = 0; + p->next_state = and_then; + return parse_string_prefix(p, cur + 1, end); +} + +/* finish a literal header without incremental indexing */ +static int finish_lithdr_notidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); + GPR_ASSERT(md != NULL); /* handled in string parsing */ + return on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key), + take_string(p, &p->value)), + 0) && + parse_begin(p, cur, end); +} + +/* finish a literal header without incremental indexing with index = 0 */ +static int finish_lithdr_notidx_v(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end) { + return on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key), + take_string(p, &p->value)), + 0) && + parse_begin(p, cur, end); +} + +/* parse a literal header without incremental indexing; index < 15 */ +static int parse_lithdr_notidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + static const grpc_chttp2_hpack_parser_state and_then[] = { + parse_value_string_with_indexed_key, finish_lithdr_notidx}; + p->dynamic_table_update_allowed = 0; + p->next_state = and_then; + p->index = (*cur) & 0xf; + return parse_string_prefix(p, cur + 1, end); +} + +/* parse a literal header without incremental indexing; index >= 15 */ +static int parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end) { + static const grpc_chttp2_hpack_parser_state and_then[] = { + parse_string_prefix, parse_value_string_with_indexed_key, + finish_lithdr_notidx}; + p->dynamic_table_update_allowed = 0; + p->next_state = and_then; + p->index = 0xf; + p->parsing.value = &p->index; + return parse_value0(p, cur + 1, end); +} + +/* parse a literal header without incremental indexing; index == 0 */ +static int parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end) { + static const grpc_chttp2_hpack_parser_state and_then[] = { + parse_key_string, parse_string_prefix, + parse_value_string_with_literal_key, finish_lithdr_notidx_v}; + p->dynamic_table_update_allowed = 0; + p->next_state = and_then; + return parse_string_prefix(p, cur + 1, end); +} + +/* finish a literal header that is never indexed */ +static int finish_lithdr_nvridx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); + GPR_ASSERT(md != NULL); /* handled in string parsing */ + return on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key), + take_string(p, &p->value)), + 0) && + parse_begin(p, cur, end); +} + +/* finish a literal header that is never indexed with an extra value */ +static int finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end) { + return on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key), + take_string(p, &p->value)), + 0) && + parse_begin(p, cur, end); +} + +/* parse a literal header that is never indexed; index < 15 */ +static int parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + static const grpc_chttp2_hpack_parser_state and_then[] = { + parse_value_string_with_indexed_key, finish_lithdr_nvridx}; + p->dynamic_table_update_allowed = 0; + p->next_state = and_then; + p->index = (*cur) & 0xf; + return parse_string_prefix(p, cur + 1, end); +} + +/* parse a literal header that is never indexed; index >= 15 */ +static int parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end) { + static const grpc_chttp2_hpack_parser_state and_then[] = { + parse_string_prefix, parse_value_string_with_indexed_key, + finish_lithdr_nvridx}; + p->dynamic_table_update_allowed = 0; + p->next_state = and_then; + p->index = 0xf; + p->parsing.value = &p->index; + return parse_value0(p, cur + 1, end); +} + +/* parse a literal header that is never indexed; index == 0 */ +static int parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, const uint8_t *end) { + static const grpc_chttp2_hpack_parser_state and_then[] = { + parse_key_string, parse_string_prefix, + parse_value_string_with_literal_key, finish_lithdr_nvridx_v}; + p->dynamic_table_update_allowed = 0; + p->next_state = and_then; + return parse_string_prefix(p, cur + 1, end); +} + +/* finish parsing a max table size change */ +static int finish_max_tbl_size(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", p->index); + return grpc_chttp2_hptbl_set_current_table_size(&p->table, p->index) && + parse_begin(p, cur, end); +} + +/* parse a max table size change, max size < 15 */ +static int parse_max_tbl_size(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (p->dynamic_table_update_allowed == 0) { + return 0; + } + p->dynamic_table_update_allowed--; + p->index = (*cur) & 0x1f; + return finish_max_tbl_size(p, cur + 1, end); +} + +/* parse a max table size change, max size >= 15 */ +static int parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + static const grpc_chttp2_hpack_parser_state and_then[] = { + finish_max_tbl_size}; + if (p->dynamic_table_update_allowed == 0) { + return 0; + } + p->dynamic_table_update_allowed--; + p->next_state = and_then; + p->index = 0x1f; + p->parsing.value = &p->index; + return parse_value0(p, cur + 1, end); +} + +/* a parse error: jam the parse state into parse_error, and return error */ +static int parse_error(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + p->state = parse_error; + return 0; +} + +static int parse_illegal_op(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + GPR_ASSERT(cur != end); + gpr_log(GPR_DEBUG, "Illegal hpack op code %d", *cur); + return parse_error(p, cur, end); +} + +/* parse the 1st byte of a varint into p->parsing.value + no overflow is possible */ +static int parse_value0(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (cur == end) { + p->state = parse_value0; + return 1; + } + + *p->parsing.value += (*cur) & 0x7f; + + if ((*cur) & 0x80) { + return parse_value1(p, cur + 1, end); + } else { + return parse_next(p, cur + 1, end); + } +} + +/* parse the 2nd byte of a varint into p->parsing.value + no overflow is possible */ +static int parse_value1(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (cur == end) { + p->state = parse_value1; + return 1; + } + + *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 7; + + if ((*cur) & 0x80) { + return parse_value2(p, cur + 1, end); + } else { + return parse_next(p, cur + 1, end); + } +} + +/* parse the 3rd byte of a varint into p->parsing.value + no overflow is possible */ +static int parse_value2(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (cur == end) { + p->state = parse_value2; + return 1; + } + + *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 14; + + if ((*cur) & 0x80) { + return parse_value3(p, cur + 1, end); + } else { + return parse_next(p, cur + 1, end); + } +} + +/* parse the 4th byte of a varint into p->parsing.value + no overflow is possible */ +static int parse_value3(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (cur == end) { + p->state = parse_value3; + return 1; + } + + *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 21; + + if ((*cur) & 0x80) { + return parse_value4(p, cur + 1, end); + } else { + return parse_next(p, cur + 1, end); + } +} + +/* parse the 5th byte of a varint into p->parsing.value + depending on the byte, we may overflow, and care must be taken */ +static int parse_value4(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + uint8_t c; + uint32_t cur_value; + uint32_t add_value; + + if (cur == end) { + p->state = parse_value4; + return 1; + } + + c = (*cur) & 0x7f; + if (c > 0xf) { + goto error; + } + + cur_value = *p->parsing.value; + add_value = ((uint32_t)c) << 28; + if (add_value > 0xffffffffu - cur_value) { + goto error; + } + + *p->parsing.value = cur_value + add_value; + + if ((*cur) & 0x80) { + return parse_value5up(p, cur + 1, end); + } else { + return parse_next(p, cur + 1, end); + } + +error: + gpr_log(GPR_ERROR, + "integer overflow in hpack integer decoding: have 0x%08x, " + "got byte 0x%02x on byte 5", + *p->parsing.value, *cur); + return parse_error(p, cur, end); +} + +/* parse any trailing bytes in a varint: it's possible to append an arbitrary + number of 0x80's and not affect the value - a zero will terminate - and + anything else will overflow */ +static int parse_value5up(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + while (cur != end && *cur == 0x80) { + ++cur; + } + + if (cur == end) { + p->state = parse_value5up; + return 1; + } + + if (*cur == 0) { + return parse_next(p, cur + 1, end); + } + + gpr_log(GPR_ERROR, + "integer overflow in hpack integer decoding: have 0x%08x, " + "got byte 0x%02x sometime after byte 5", + *p->parsing.value, *cur); + return parse_error(p, cur, end); +} + +/* parse a string prefix */ +static int parse_string_prefix(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (cur == end) { + p->state = parse_string_prefix; + return 1; + } + + p->strlen = (*cur) & 0x7f; + p->huff = (*cur) >> 7; + if (p->strlen == 0x7f) { + p->parsing.value = &p->strlen; + return parse_value0(p, cur + 1, end); + } else { + return parse_next(p, cur + 1, end); + } +} + +/* append some bytes to a string */ +static void append_bytes(grpc_chttp2_hpack_parser_string *str, + const uint8_t *data, size_t length) { + if (length + str->length > str->capacity) { + GPR_ASSERT(str->length + length <= UINT32_MAX); + str->capacity = (uint32_t)(str->length + length); + str->str = gpr_realloc(str->str, str->capacity); + } + memcpy(str->str + str->length, data, length); + GPR_ASSERT(length <= UINT32_MAX - str->length); + str->length += (uint32_t)length; +} + +static int append_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + grpc_chttp2_hpack_parser_string *str = p->parsing.str; + uint32_t bits; + uint8_t decoded[3]; + switch ((binary_state)p->binary) { + case NOT_BINARY: + append_bytes(str, cur, (size_t)(end - cur)); + return 1; + b64_byte0: + case B64_BYTE0: + if (cur == end) { + p->binary = B64_BYTE0; + return 1; + } + bits = inverse_base64[*cur]; + ++cur; + if (bits == 255) + return 0; + else if (bits == 64) + goto b64_byte0; + p->base64_buffer = bits << 18; + /* fallthrough */ + b64_byte1: + case B64_BYTE1: + if (cur == end) { + p->binary = B64_BYTE1; + return 1; + } + bits = inverse_base64[*cur]; + ++cur; + if (bits == 255) + return 0; + else if (bits == 64) + goto b64_byte1; + p->base64_buffer |= bits << 12; + /* fallthrough */ + b64_byte2: + case B64_BYTE2: + if (cur == end) { + p->binary = B64_BYTE2; + return 1; + } + bits = inverse_base64[*cur]; + ++cur; + if (bits == 255) + return 0; + else if (bits == 64) + goto b64_byte2; + p->base64_buffer |= bits << 6; + /* fallthrough */ + b64_byte3: + case B64_BYTE3: + if (cur == end) { + p->binary = B64_BYTE3; + return 1; + } + bits = inverse_base64[*cur]; + ++cur; + if (bits == 255) + return 0; + else if (bits == 64) + goto b64_byte3; + p->base64_buffer |= bits; + bits = p->base64_buffer; + decoded[0] = (uint8_t)(bits >> 16); + decoded[1] = (uint8_t)(bits >> 8); + decoded[2] = (uint8_t)(bits); + append_bytes(str, decoded, 3); + goto b64_byte0; + } + GPR_UNREACHABLE_CODE(return 1); +} + +/* append a null terminator to a string */ +static int finish_str(grpc_chttp2_hpack_parser *p) { + uint8_t terminator = 0; + uint8_t decoded[2]; + uint32_t bits; + grpc_chttp2_hpack_parser_string *str = p->parsing.str; + switch ((binary_state)p->binary) { + case NOT_BINARY: + break; + case B64_BYTE0: + break; + case B64_BYTE1: + gpr_log(GPR_ERROR, "illegal base64 encoding"); + return 0; /* illegal encoding */ + case B64_BYTE2: + bits = p->base64_buffer; + if (bits & 0xffff) { + gpr_log(GPR_ERROR, "trailing bits in base64 encoding: 0x%04x", + bits & 0xffff); + return 0; + } + decoded[0] = (uint8_t)(bits >> 16); + append_bytes(str, decoded, 1); + break; + case B64_BYTE3: + bits = p->base64_buffer; + if (bits & 0xff) { + gpr_log(GPR_ERROR, "trailing bits in base64 encoding: 0x%02x", + bits & 0xff); + return 0; + } + decoded[0] = (uint8_t)(bits >> 16); + decoded[1] = (uint8_t)(bits >> 8); + append_bytes(str, decoded, 2); + break; + } + append_bytes(str, &terminator, 1); + p->parsing.str->length--; /* don't actually count the null terminator */ + return 1; +} + +/* decode a nibble from a huffman encoded stream */ +static int huff_nibble(grpc_chttp2_hpack_parser *p, uint8_t nibble) { + int16_t emit = emit_sub_tbl[16 * emit_tbl[p->huff_state] + nibble]; + int16_t next = next_sub_tbl[16 * next_tbl[p->huff_state] + nibble]; + if (emit != -1) { + if (emit >= 0 && emit < 256) { + uint8_t c = (uint8_t)emit; + if (!append_string(p, &c, (&c) + 1)) return 0; + } else { + assert(emit == 256); + } + } + p->huff_state = next; + return 1; +} + +/* decode full bytes from a huffman encoded stream */ +static int add_huff_bytes(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + for (; cur != end; ++cur) { + if (!huff_nibble(p, *cur >> 4) || !huff_nibble(p, *cur & 0xf)) return 0; + } + return 1; +} + +/* decode some string bytes based on the current decoding mode + (huffman or not) */ +static int add_str_bytes(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + if (p->huff) { + return add_huff_bytes(p, cur, end); + } else { + return append_string(p, cur, end); + } +} + +/* parse a string - tries to do large chunks at a time */ +static int parse_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + size_t remaining = p->strlen - p->strgot; + size_t given = (size_t)(end - cur); + if (remaining <= given) { + return add_str_bytes(p, cur, cur + remaining) && finish_str(p) && + parse_next(p, cur + remaining, end); + } else { + if (!add_str_bytes(p, cur, cur + given)) return 0; + GPR_ASSERT(given <= UINT32_MAX - p->strgot); + p->strgot += (uint32_t)given; + p->state = parse_string; + return 1; + } +} + +/* begin parsing a string - performs setup, calls parse_string */ +static int begin_parse_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end, uint8_t binary, + grpc_chttp2_hpack_parser_string *str) { + p->strgot = 0; + str->length = 0; + p->parsing.str = str; + p->huff_state = 0; + p->binary = binary; + return parse_string(p, cur, end); +} + +/* parse the key string */ +static int parse_key_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end) { + return begin_parse_string(p, cur, end, NOT_BINARY, &p->key); +} + +/* check if a key represents a binary header or not */ +typedef enum { BINARY_HEADER, PLAINTEXT_HEADER, ERROR_HEADER } is_binary_header; + +static is_binary_header is_binary_literal_header(grpc_chttp2_hpack_parser *p) { + return grpc_is_binary_header(p->key.str, p->key.length) ? BINARY_HEADER + : PLAINTEXT_HEADER; +} + +static is_binary_header is_binary_indexed_header(grpc_chttp2_hpack_parser *p) { + grpc_mdelem *elem = grpc_chttp2_hptbl_lookup(&p->table, p->index); + if (!elem) { + gpr_log(GPR_ERROR, "Invalid HPACK index received: %d", p->index); + return ERROR_HEADER; + } + return grpc_is_binary_header( + (const char *)GPR_SLICE_START_PTR(elem->key->slice), + GPR_SLICE_LENGTH(elem->key->slice)) + ? BINARY_HEADER + : PLAINTEXT_HEADER; +} + +/* parse the value string */ +static int parse_value_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, + const uint8_t *end, is_binary_header type) { + switch (type) { + case BINARY_HEADER: + return begin_parse_string(p, cur, end, B64_BYTE0, &p->value); + case PLAINTEXT_HEADER: + return begin_parse_string(p, cur, end, NOT_BINARY, &p->value); + case ERROR_HEADER: + return 0; + } + /* Add code to prevent return without value error */ + GPR_UNREACHABLE_CODE(return 0); +} + +static int parse_value_string_with_indexed_key(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, + const uint8_t *end) { + return parse_value_string(p, cur, end, is_binary_indexed_header(p)); +} + +static int parse_value_string_with_literal_key(grpc_chttp2_hpack_parser *p, + const uint8_t *cur, + const uint8_t *end) { + return parse_value_string(p, cur, end, is_binary_literal_header(p)); +} + +/* PUBLIC INTERFACE */ + +static void on_header_not_set(void *user_data, grpc_mdelem *md) { + GPR_UNREACHABLE_CODE(return ); +} + +void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p) { + p->on_header = on_header_not_set; + p->on_header_user_data = NULL; + p->state = parse_begin; + p->key.str = NULL; + p->key.capacity = 0; + p->key.length = 0; + p->value.str = NULL; + p->value.capacity = 0; + p->value.length = 0; + p->dynamic_table_update_allowed = 2; + grpc_chttp2_hptbl_init(&p->table); +} + +void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p) { + p->after_prioritization = p->state; + p->state = parse_stream_dep0; +} + +void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p) { + grpc_chttp2_hptbl_destroy(&p->table); + gpr_free(p->key.str); + gpr_free(p->value.str); +} + +int grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p, + const uint8_t *beg, const uint8_t *end) { + /* TODO(ctiller): limit the distance of end from beg, and perform multiple + steps in the event of a large chunk of data to limit + stack space usage when no tail call optimization is + available */ + return p->state(p, beg, end); +} + +grpc_chttp2_parse_error grpc_chttp2_header_parser_parse( + grpc_exec_ctx *exec_ctx, void *hpack_parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + grpc_chttp2_hpack_parser *parser = hpack_parser; + GPR_TIMER_BEGIN("grpc_chttp2_hpack_parser_parse", 0); + if (!grpc_chttp2_hpack_parser_parse(parser, GPR_SLICE_START_PTR(slice), + GPR_SLICE_END_PTR(slice))) { + GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + if (is_last) { + if (parser->is_boundary && parser->state != parse_begin) { + gpr_log(GPR_ERROR, + "end of header frame not aligned with a hpack record boundary"); + GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + /* need to check for null stream: this can occur if we receive an invalid + stream id on a header */ + if (stream_parsing != NULL) { + if (parser->is_boundary) { + stream_parsing + ->got_metadata_on_parse[stream_parsing->header_frames_received] = 1; + stream_parsing->header_frames_received++; + grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, + stream_parsing); + } + if (parser->is_eof) { + stream_parsing->received_close = 1; + } + } + parser->on_header = on_header_not_set; + parser->on_header_user_data = NULL; + parser->is_boundary = 0xde; + parser->is_eof = 0xde; + parser->dynamic_table_update_allowed = 2; + } + GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0); + return GRPC_CHTTP2_PARSE_OK; +} diff --git a/src/core/lib/transport/chttp2/hpack_parser.h b/src/core/lib/transport/chttp2/hpack_parser.h new file mode 100644 index 0000000000..6a6d136da2 --- /dev/null +++ b/src/core/lib/transport/chttp2/hpack_parser.h @@ -0,0 +1,116 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_HPACK_PARSER_H +#define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H + +#include + +#include +#include "src/core/iomgr/exec_ctx.h" +#include "src/core/transport/chttp2/frame.h" +#include "src/core/transport/chttp2/hpack_table.h" +#include "src/core/transport/metadata.h" + +typedef struct grpc_chttp2_hpack_parser grpc_chttp2_hpack_parser; + +typedef int (*grpc_chttp2_hpack_parser_state)(grpc_chttp2_hpack_parser *p, + const uint8_t *beg, + const uint8_t *end); + +typedef struct { + char *str; + uint32_t length; + uint32_t capacity; +} grpc_chttp2_hpack_parser_string; + +struct grpc_chttp2_hpack_parser { + /* user specified callback for each header output */ + void (*on_header)(void *user_data, grpc_mdelem *md); + void *on_header_user_data; + + /* current parse state - or a function that implements it */ + grpc_chttp2_hpack_parser_state state; + /* future states dependent on the opening op code */ + const grpc_chttp2_hpack_parser_state *next_state; + /* what to do after skipping prioritization data */ + grpc_chttp2_hpack_parser_state after_prioritization; + /* the value we're currently parsing */ + union { + uint32_t *value; + grpc_chttp2_hpack_parser_string *str; + } parsing; + /* string parameters for each chunk */ + grpc_chttp2_hpack_parser_string key; + grpc_chttp2_hpack_parser_string value; + /* parsed index */ + uint32_t index; + /* length of source bytes for the currently parsing string */ + uint32_t strlen; + /* number of source bytes read for the currently parsing string */ + uint32_t strgot; + /* huffman decoding state */ + int16_t huff_state; + /* is the string being decoded binary? */ + uint8_t binary; + /* is the current string huffman encoded? */ + uint8_t huff; + /* is a dynamic table update allowed? */ + uint8_t dynamic_table_update_allowed; + /* set by higher layers, used by grpc_chttp2_header_parser_parse to signal + it should append a metadata boundary at the end of frame */ + uint8_t is_boundary; + uint8_t is_eof; + uint32_t base64_buffer; + + /* hpack table */ + grpc_chttp2_hptbl table; +}; + +void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p); +void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p); + +void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p); + +/* returns 1 on success, 0 on error */ +int grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p, + const uint8_t *beg, const uint8_t *end); + +/* wraps grpc_chttp2_hpack_parser_parse to provide a frame level parser for + the transport */ +grpc_chttp2_parse_error grpc_chttp2_header_parser_parse( + grpc_exec_ctx *exec_ctx, void *hpack_parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H */ diff --git a/src/core/lib/transport/chttp2/hpack_table.c b/src/core/lib/transport/chttp2/hpack_table.c new file mode 100644 index 0000000000..f1ce3b84fd --- /dev/null +++ b/src/core/lib/transport/chttp2/hpack_table.c @@ -0,0 +1,361 @@ +/* + * + * Copyright 2015, 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/transport/chttp2/hpack_table.h" + +#include +#include + +#include +#include + +#include "src/core/support/murmur_hash.h" + +static struct { + const char *key; + const char *value; +} static_table[] = { + /* 0: */ + {NULL, NULL}, + /* 1: */ + {":authority", ""}, + /* 2: */ + {":method", "GET"}, + /* 3: */ + {":method", "POST"}, + /* 4: */ + {":path", "/"}, + /* 5: */ + {":path", "/index.html"}, + /* 6: */ + {":scheme", "http"}, + /* 7: */ + {":scheme", "https"}, + /* 8: */ + {":status", "200"}, + /* 9: */ + {":status", "204"}, + /* 10: */ + {":status", "206"}, + /* 11: */ + {":status", "304"}, + /* 12: */ + {":status", "400"}, + /* 13: */ + {":status", "404"}, + /* 14: */ + {":status", "500"}, + /* 15: */ + {"accept-charset", ""}, + /* 16: */ + {"accept-encoding", "gzip, deflate"}, + /* 17: */ + {"accept-language", ""}, + /* 18: */ + {"accept-ranges", ""}, + /* 19: */ + {"accept", ""}, + /* 20: */ + {"access-control-allow-origin", ""}, + /* 21: */ + {"age", ""}, + /* 22: */ + {"allow", ""}, + /* 23: */ + {"authorization", ""}, + /* 24: */ + {"cache-control", ""}, + /* 25: */ + {"content-disposition", ""}, + /* 26: */ + {"content-encoding", ""}, + /* 27: */ + {"content-language", ""}, + /* 28: */ + {"content-length", ""}, + /* 29: */ + {"content-location", ""}, + /* 30: */ + {"content-range", ""}, + /* 31: */ + {"content-type", ""}, + /* 32: */ + {"cookie", ""}, + /* 33: */ + {"date", ""}, + /* 34: */ + {"etag", ""}, + /* 35: */ + {"expect", ""}, + /* 36: */ + {"expires", ""}, + /* 37: */ + {"from", ""}, + /* 38: */ + {"host", ""}, + /* 39: */ + {"if-match", ""}, + /* 40: */ + {"if-modified-since", ""}, + /* 41: */ + {"if-none-match", ""}, + /* 42: */ + {"if-range", ""}, + /* 43: */ + {"if-unmodified-since", ""}, + /* 44: */ + {"last-modified", ""}, + /* 45: */ + {"link", ""}, + /* 46: */ + {"location", ""}, + /* 47: */ + {"max-forwards", ""}, + /* 48: */ + {"proxy-authenticate", ""}, + /* 49: */ + {"proxy-authorization", ""}, + /* 50: */ + {"range", ""}, + /* 51: */ + {"referer", ""}, + /* 52: */ + {"refresh", ""}, + /* 53: */ + {"retry-after", ""}, + /* 54: */ + {"server", ""}, + /* 55: */ + {"set-cookie", ""}, + /* 56: */ + {"strict-transport-security", ""}, + /* 57: */ + {"transfer-encoding", ""}, + /* 58: */ + {"user-agent", ""}, + /* 59: */ + {"vary", ""}, + /* 60: */ + {"via", ""}, + /* 61: */ + {"www-authenticate", ""}, +}; + +static uint32_t entries_for_bytes(uint32_t bytes) { + return (bytes + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD - 1) / + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD; +} + +void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl) { + size_t i; + + memset(tbl, 0, sizeof(*tbl)); + tbl->current_table_bytes = tbl->max_bytes = + GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE; + tbl->max_entries = tbl->cap_entries = + entries_for_bytes(tbl->current_table_bytes); + tbl->ents = gpr_malloc(sizeof(*tbl->ents) * tbl->cap_entries); + memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries); + for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { + tbl->static_ents[i - 1] = + grpc_mdelem_from_strings(static_table[i].key, static_table[i].value); + } +} + +void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl) { + size_t i; + for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { + GRPC_MDELEM_UNREF(tbl->static_ents[i]); + } + for (i = 0; i < tbl->num_ents; i++) { + GRPC_MDELEM_UNREF(tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]); + } + gpr_free(tbl->ents); +} + +grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl, + uint32_t tbl_index) { + /* Static table comes first, just return an entry from it */ + if (tbl_index <= GRPC_CHTTP2_LAST_STATIC_ENTRY) { + return tbl->static_ents[tbl_index - 1]; + } + /* Otherwise, find the value in the list of valid entries */ + tbl_index -= (GRPC_CHTTP2_LAST_STATIC_ENTRY + 1); + if (tbl_index < tbl->num_ents) { + uint32_t offset = + (tbl->num_ents - 1u - tbl_index + tbl->first_ent) % tbl->cap_entries; + return tbl->ents[offset]; + } + /* Invalid entry: return error */ + return NULL; +} + +/* Evict one element from the table */ +static void evict1(grpc_chttp2_hptbl *tbl) { + grpc_mdelem *first_ent = tbl->ents[tbl->first_ent]; + size_t elem_bytes = GPR_SLICE_LENGTH(first_ent->key->slice) + + GPR_SLICE_LENGTH(first_ent->value->slice) + + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD; + GPR_ASSERT(elem_bytes <= tbl->mem_used); + tbl->mem_used -= (uint32_t)elem_bytes; + tbl->first_ent = ((tbl->first_ent + 1) % tbl->cap_entries); + tbl->num_ents--; + GRPC_MDELEM_UNREF(first_ent); +} + +static void rebuild_ents(grpc_chttp2_hptbl *tbl, uint32_t new_cap) { + grpc_mdelem **ents = gpr_malloc(sizeof(*ents) * new_cap); + uint32_t i; + + for (i = 0; i < tbl->num_ents; i++) { + ents[i] = tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]; + } + gpr_free(tbl->ents); + tbl->ents = ents; + tbl->cap_entries = new_cap; + tbl->first_ent = 0; +} + +void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl, + uint32_t max_bytes) { + if (tbl->max_bytes == max_bytes) { + return; + } + gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes); + while (tbl->mem_used > max_bytes) { + evict1(tbl); + } + tbl->max_bytes = max_bytes; +} + +int grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl, + uint32_t bytes) { + if (tbl->current_table_bytes == bytes) { + return 1; + } + if (bytes > tbl->max_bytes) { + gpr_log(GPR_ERROR, + "Attempt to make hpack table %d bytes when max is %d bytes", bytes, + tbl->max_bytes); + return 0; + } + gpr_log(GPR_DEBUG, "Update hpack parser table size to %d", bytes); + while (tbl->mem_used > bytes) { + evict1(tbl); + } + tbl->current_table_bytes = bytes; + tbl->max_entries = entries_for_bytes(bytes); + if (tbl->max_entries > tbl->cap_entries) { + rebuild_ents(tbl, GPR_MAX(tbl->max_entries, 2 * tbl->cap_entries)); + } else if (tbl->max_entries < tbl->cap_entries / 3) { + uint32_t new_cap = GPR_MAX(tbl->max_entries, 16u); + if (new_cap != tbl->cap_entries) { + rebuild_ents(tbl, new_cap); + } + } + return 1; +} + +int grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md) { + /* determine how many bytes of buffer this entry represents */ + size_t elem_bytes = GPR_SLICE_LENGTH(md->key->slice) + + GPR_SLICE_LENGTH(md->value->slice) + + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD; + + if (tbl->current_table_bytes > tbl->max_bytes) { + gpr_log(GPR_ERROR, + "HPACK max table size reduced to %d but not reflected by hpack " + "stream (still at %d)", + tbl->max_bytes, tbl->current_table_bytes); + return 0; + } + + /* we can't add elements bigger than the max table size */ + if (elem_bytes > tbl->current_table_bytes) { + /* HPACK draft 10 section 4.4 states: + * If the size of the new entry is less than or equal to the maximum + * size, that entry is added to the table. It is not an error to + * attempt to add an entry that is larger than the maximum size; an + * attempt to add an entry larger than the entire table causes + * the table + * to be emptied of all existing entries, and results in an + * empty table. + */ + while (tbl->num_ents) { + evict1(tbl); + } + return 1; + } + + /* evict entries to ensure no overflow */ + while (elem_bytes > (size_t)tbl->current_table_bytes - tbl->mem_used) { + evict1(tbl); + } + + /* copy the finalized entry in */ + tbl->ents[(tbl->first_ent + tbl->num_ents) % tbl->cap_entries] = + GRPC_MDELEM_REF(md); + + /* update accounting values */ + tbl->num_ents++; + tbl->mem_used += (uint32_t)elem_bytes; + return 1; +} + +grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find( + const grpc_chttp2_hptbl *tbl, grpc_mdelem *md) { + grpc_chttp2_hptbl_find_result r = {0, 0}; + uint32_t i; + + /* See if the string is in the static table */ + for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { + grpc_mdelem *ent = tbl->static_ents[i]; + if (md->key != ent->key) continue; + r.index = i + 1u; + r.has_value = md->value == ent->value; + if (r.has_value) return r; + } + + /* Scan the dynamic table */ + for (i = 0; i < tbl->num_ents; i++) { + uint32_t idx = + (uint32_t)(tbl->num_ents - i + GRPC_CHTTP2_LAST_STATIC_ENTRY); + grpc_mdelem *ent = tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]; + if (md->key != ent->key) continue; + r.index = idx; + r.has_value = md->value == ent->value; + if (r.has_value) return r; + } + + return r; +} diff --git a/src/core/lib/transport/chttp2/hpack_table.h b/src/core/lib/transport/chttp2/hpack_table.h new file mode 100644 index 0000000000..c984ca35e4 --- /dev/null +++ b/src/core/lib/transport/chttp2/hpack_table.h @@ -0,0 +1,108 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_HPACK_TABLE_H +#define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H + +#include +#include +#include "src/core/transport/metadata.h" + +/* HPACK header table */ + +/* last index in the static table */ +#define GRPC_CHTTP2_LAST_STATIC_ENTRY 61 + +/* Initial table size as per the spec */ +#define GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE 4096 +/* Maximum table size that we'll use */ +#define GRPC_CHTTP2_MAX_HPACK_TABLE_SIZE GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE +/* Per entry overhead bytes as per the spec */ +#define GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD 32 +#if 0 +/* Maximum number of entries we could possibly fit in the table, given defined + overheads */ +#define GRPC_CHTTP2_MAX_TABLE_COUNT \ + ((GRPC_CHTTP2_MAX_HPACK_TABLE_SIZE + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD - 1) / \ + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD) +#endif + +/* hpack decoder table */ +typedef struct { + /* the first used entry in ents */ + uint32_t first_ent; + /* how many entries are in the table */ + uint32_t num_ents; + /* the amount of memory used by the table, according to the hpack algorithm */ + uint32_t mem_used; + /* the max memory allowed to be used by the table, according to the hpack + algorithm */ + uint32_t max_bytes; + /* the currently agreed size of the table, according to the hpack algorithm */ + uint32_t current_table_bytes; + /* Maximum number of entries we could possibly fit in the table, given defined + overheads */ + uint32_t max_entries; + /* Number of entries allocated in ents */ + uint32_t cap_entries; + /* a circular buffer of headers - this is stored in the opposite order to + what hpack specifies, in order to simplify table management a little... + meaning lookups need to SUBTRACT from the end position */ + grpc_mdelem **ents; + grpc_mdelem *static_ents[GRPC_CHTTP2_LAST_STATIC_ENTRY]; +} grpc_chttp2_hptbl; + +/* initialize a hpack table */ +void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl); +void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl); +void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl, + uint32_t max_bytes); +int grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl, + uint32_t bytes); + +/* lookup a table entry based on its hpack index */ +grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl, + uint32_t index); +/* add a table entry to the index */ +int grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, + grpc_mdelem *md) GRPC_MUST_USE_RESULT; +/* Find a key/value pair in the table... returns the index in the table of the + most similar entry, or 0 if the value was not found */ +typedef struct { + uint32_t index; + int has_value; +} grpc_chttp2_hptbl_find_result; +grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find( + const grpc_chttp2_hptbl *tbl, grpc_mdelem *md); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H */ diff --git a/src/core/lib/transport/chttp2/hpack_tables.txt b/src/core/lib/transport/chttp2/hpack_tables.txt new file mode 100644 index 0000000000..08842a0267 --- /dev/null +++ b/src/core/lib/transport/chttp2/hpack_tables.txt @@ -0,0 +1,66 @@ +Static table, from the spec: + +-------+-----------------------------+---------------+ + | Index | Header Name | Header Value | + +-------+-----------------------------+---------------+ + | 1 | :authority | | + | 2 | :method | GET | + | 3 | :method | POST | + | 4 | :path | / | + | 5 | :path | /index.html | + | 6 | :scheme | http | + | 7 | :scheme | https | + | 8 | :status | 200 | + | 9 | :status | 204 | + | 10 | :status | 206 | + | 11 | :status | 304 | + | 12 | :status | 400 | + | 13 | :status | 404 | + | 14 | :status | 500 | + | 15 | accept-charset | | + | 16 | accept-encoding | gzip, deflate | + | 17 | accept-language | | + | 18 | accept-ranges | | + | 19 | accept | | + | 20 | access-control-allow-origin | | + | 21 | age | | + | 22 | allow | | + | 23 | authorization | | + | 24 | cache-control | | + | 25 | content-disposition | | + | 26 | content-encoding | | + | 27 | content-language | | + | 28 | content-length | | + | 29 | content-location | | + | 30 | content-range | | + | 31 | content-type | | + | 32 | cookie | | + | 33 | date | | + | 34 | etag | | + | 35 | expect | | + | 36 | expires | | + | 37 | from | | + | 38 | host | | + | 39 | if-match | | + | 40 | if-modified-since | | + | 41 | if-none-match | | + | 42 | if-range | | + | 43 | if-unmodified-since | | + | 44 | last-modified | | + | 45 | link | | + | 46 | location | | + | 47 | max-forwards | | + | 48 | proxy-authenticate | | + | 49 | proxy-authorization | | + | 50 | range | | + | 51 | referer | | + | 52 | refresh | | + | 53 | retry-after | | + | 54 | server | | + | 55 | set-cookie | | + | 56 | strict-transport-security | | + | 57 | transfer-encoding | | + | 58 | user-agent | | + | 59 | vary | | + | 60 | via | | + | 61 | www-authenticate | | + +-------+-----------------------------+---------------+ diff --git a/src/core/lib/transport/chttp2/http2_errors.h b/src/core/lib/transport/chttp2/http2_errors.h new file mode 100644 index 0000000000..4290df3d89 --- /dev/null +++ b/src/core/lib/transport/chttp2/http2_errors.h @@ -0,0 +1,56 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_HTTP2_ERRORS_H +#define GRPC_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H + +/* error codes for RST_STREAM from http2 draft 14 section 7 */ +typedef enum { + GRPC_CHTTP2_NO_ERROR = 0x0, + GRPC_CHTTP2_PROTOCOL_ERROR = 0x1, + GRPC_CHTTP2_INTERNAL_ERROR = 0x2, + GRPC_CHTTP2_FLOW_CONTROL_ERROR = 0x3, + GRPC_CHTTP2_SETTINGS_TIMEOUT = 0x4, + GRPC_CHTTP2_STREAM_CLOSED = 0x5, + GRPC_CHTTP2_FRAME_SIZE_ERROR = 0x6, + GRPC_CHTTP2_REFUSED_STREAM = 0x7, + GRPC_CHTTP2_CANCEL = 0x8, + GRPC_CHTTP2_COMPRESSION_ERROR = 0x9, + GRPC_CHTTP2_CONNECT_ERROR = 0xa, + GRPC_CHTTP2_ENHANCE_YOUR_CALM = 0xb, + GRPC_CHTTP2_INADEQUATE_SECURITY = 0xc, + /* force use of a default clause */ + GRPC_CHTTP2__ERROR_DO_NOT_USE = -1 +} grpc_chttp2_error_code; + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H */ diff --git a/src/core/lib/transport/chttp2/huffsyms.c b/src/core/lib/transport/chttp2/huffsyms.c new file mode 100644 index 0000000000..ebc85d3378 --- /dev/null +++ b/src/core/lib/transport/chttp2/huffsyms.c @@ -0,0 +1,105 @@ +/* + * + * Copyright 2015-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/transport/chttp2/huffsyms.h" + +/* Constants pulled from the HPACK spec, and converted to C using the vim + command: + :%s/.* \([0-9a-f]\+\) \[ *\([0-9]\+\)\]/{0x\1, \2},/g */ +const grpc_chttp2_huffsym grpc_chttp2_huffsyms[GRPC_CHTTP2_NUM_HUFFSYMS] = { + {0x1ff8, 13}, {0x7fffd8, 23}, {0xfffffe2, 28}, {0xfffffe3, 28}, + {0xfffffe4, 28}, {0xfffffe5, 28}, {0xfffffe6, 28}, {0xfffffe7, 28}, + {0xfffffe8, 28}, {0xffffea, 24}, {0x3ffffffc, 30}, {0xfffffe9, 28}, + {0xfffffea, 28}, {0x3ffffffd, 30}, {0xfffffeb, 28}, {0xfffffec, 28}, + {0xfffffed, 28}, {0xfffffee, 28}, {0xfffffef, 28}, {0xffffff0, 28}, + {0xffffff1, 28}, {0xffffff2, 28}, {0x3ffffffe, 30}, {0xffffff3, 28}, + {0xffffff4, 28}, {0xffffff5, 28}, {0xffffff6, 28}, {0xffffff7, 28}, + {0xffffff8, 28}, {0xffffff9, 28}, {0xffffffa, 28}, {0xffffffb, 28}, + {0x14, 6}, {0x3f8, 10}, {0x3f9, 10}, {0xffa, 12}, + {0x1ff9, 13}, {0x15, 6}, {0xf8, 8}, {0x7fa, 11}, + {0x3fa, 10}, {0x3fb, 10}, {0xf9, 8}, {0x7fb, 11}, + {0xfa, 8}, {0x16, 6}, {0x17, 6}, {0x18, 6}, + {0x0, 5}, {0x1, 5}, {0x2, 5}, {0x19, 6}, + {0x1a, 6}, {0x1b, 6}, {0x1c, 6}, {0x1d, 6}, + {0x1e, 6}, {0x1f, 6}, {0x5c, 7}, {0xfb, 8}, + {0x7ffc, 15}, {0x20, 6}, {0xffb, 12}, {0x3fc, 10}, + {0x1ffa, 13}, {0x21, 6}, {0x5d, 7}, {0x5e, 7}, + {0x5f, 7}, {0x60, 7}, {0x61, 7}, {0x62, 7}, + {0x63, 7}, {0x64, 7}, {0x65, 7}, {0x66, 7}, + {0x67, 7}, {0x68, 7}, {0x69, 7}, {0x6a, 7}, + {0x6b, 7}, {0x6c, 7}, {0x6d, 7}, {0x6e, 7}, + {0x6f, 7}, {0x70, 7}, {0x71, 7}, {0x72, 7}, + {0xfc, 8}, {0x73, 7}, {0xfd, 8}, {0x1ffb, 13}, + {0x7fff0, 19}, {0x1ffc, 13}, {0x3ffc, 14}, {0x22, 6}, + {0x7ffd, 15}, {0x3, 5}, {0x23, 6}, {0x4, 5}, + {0x24, 6}, {0x5, 5}, {0x25, 6}, {0x26, 6}, + {0x27, 6}, {0x6, 5}, {0x74, 7}, {0x75, 7}, + {0x28, 6}, {0x29, 6}, {0x2a, 6}, {0x7, 5}, + {0x2b, 6}, {0x76, 7}, {0x2c, 6}, {0x8, 5}, + {0x9, 5}, {0x2d, 6}, {0x77, 7}, {0x78, 7}, + {0x79, 7}, {0x7a, 7}, {0x7b, 7}, {0x7ffe, 15}, + {0x7fc, 11}, {0x3ffd, 14}, {0x1ffd, 13}, {0xffffffc, 28}, + {0xfffe6, 20}, {0x3fffd2, 22}, {0xfffe7, 20}, {0xfffe8, 20}, + {0x3fffd3, 22}, {0x3fffd4, 22}, {0x3fffd5, 22}, {0x7fffd9, 23}, + {0x3fffd6, 22}, {0x7fffda, 23}, {0x7fffdb, 23}, {0x7fffdc, 23}, + {0x7fffdd, 23}, {0x7fffde, 23}, {0xffffeb, 24}, {0x7fffdf, 23}, + {0xffffec, 24}, {0xffffed, 24}, {0x3fffd7, 22}, {0x7fffe0, 23}, + {0xffffee, 24}, {0x7fffe1, 23}, {0x7fffe2, 23}, {0x7fffe3, 23}, + {0x7fffe4, 23}, {0x1fffdc, 21}, {0x3fffd8, 22}, {0x7fffe5, 23}, + {0x3fffd9, 22}, {0x7fffe6, 23}, {0x7fffe7, 23}, {0xffffef, 24}, + {0x3fffda, 22}, {0x1fffdd, 21}, {0xfffe9, 20}, {0x3fffdb, 22}, + {0x3fffdc, 22}, {0x7fffe8, 23}, {0x7fffe9, 23}, {0x1fffde, 21}, + {0x7fffea, 23}, {0x3fffdd, 22}, {0x3fffde, 22}, {0xfffff0, 24}, + {0x1fffdf, 21}, {0x3fffdf, 22}, {0x7fffeb, 23}, {0x7fffec, 23}, + {0x1fffe0, 21}, {0x1fffe1, 21}, {0x3fffe0, 22}, {0x1fffe2, 21}, + {0x7fffed, 23}, {0x3fffe1, 22}, {0x7fffee, 23}, {0x7fffef, 23}, + {0xfffea, 20}, {0x3fffe2, 22}, {0x3fffe3, 22}, {0x3fffe4, 22}, + {0x7ffff0, 23}, {0x3fffe5, 22}, {0x3fffe6, 22}, {0x7ffff1, 23}, + {0x3ffffe0, 26}, {0x3ffffe1, 26}, {0xfffeb, 20}, {0x7fff1, 19}, + {0x3fffe7, 22}, {0x7ffff2, 23}, {0x3fffe8, 22}, {0x1ffffec, 25}, + {0x3ffffe2, 26}, {0x3ffffe3, 26}, {0x3ffffe4, 26}, {0x7ffffde, 27}, + {0x7ffffdf, 27}, {0x3ffffe5, 26}, {0xfffff1, 24}, {0x1ffffed, 25}, + {0x7fff2, 19}, {0x1fffe3, 21}, {0x3ffffe6, 26}, {0x7ffffe0, 27}, + {0x7ffffe1, 27}, {0x3ffffe7, 26}, {0x7ffffe2, 27}, {0xfffff2, 24}, + {0x1fffe4, 21}, {0x1fffe5, 21}, {0x3ffffe8, 26}, {0x3ffffe9, 26}, + {0xffffffd, 28}, {0x7ffffe3, 27}, {0x7ffffe4, 27}, {0x7ffffe5, 27}, + {0xfffec, 20}, {0xfffff3, 24}, {0xfffed, 20}, {0x1fffe6, 21}, + {0x3fffe9, 22}, {0x1fffe7, 21}, {0x1fffe8, 21}, {0x7ffff3, 23}, + {0x3fffea, 22}, {0x3fffeb, 22}, {0x1ffffee, 25}, {0x1ffffef, 25}, + {0xfffff4, 24}, {0xfffff5, 24}, {0x3ffffea, 26}, {0x7ffff4, 23}, + {0x3ffffeb, 26}, {0x7ffffe6, 27}, {0x3ffffec, 26}, {0x3ffffed, 26}, + {0x7ffffe7, 27}, {0x7ffffe8, 27}, {0x7ffffe9, 27}, {0x7ffffea, 27}, + {0x7ffffeb, 27}, {0xffffffe, 28}, {0x7ffffec, 27}, {0x7ffffed, 27}, + {0x7ffffee, 27}, {0x7ffffef, 27}, {0x7fffff0, 27}, {0x3ffffee, 26}, + {0x3fffffff, 30}, +}; diff --git a/src/core/lib/transport/chttp2/huffsyms.h b/src/core/lib/transport/chttp2/huffsyms.h new file mode 100644 index 0000000000..9c4f09dcf6 --- /dev/null +++ b/src/core/lib/transport/chttp2/huffsyms.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_HUFFSYMS_H +#define GRPC_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H + +/* HPACK static huffman table */ + +#define GRPC_CHTTP2_NUM_HUFFSYMS 257 + +typedef struct { + unsigned bits; + unsigned length; +} grpc_chttp2_huffsym; + +extern const grpc_chttp2_huffsym grpc_chttp2_huffsyms[GRPC_CHTTP2_NUM_HUFFSYMS]; + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H */ diff --git a/src/core/lib/transport/chttp2/incoming_metadata.c b/src/core/lib/transport/chttp2/incoming_metadata.c new file mode 100644 index 0000000000..315bc2faa1 --- /dev/null +++ b/src/core/lib/transport/chttp2/incoming_metadata.c @@ -0,0 +1,96 @@ +/* + * + * Copyright 2015, 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/transport/chttp2/incoming_metadata.h" + +#include + +#include "src/core/transport/chttp2/internal.h" + +#include +#include + +void grpc_chttp2_incoming_metadata_buffer_init( + grpc_chttp2_incoming_metadata_buffer *buffer) { + buffer->deadline = gpr_inf_future(GPR_CLOCK_REALTIME); +} + +void grpc_chttp2_incoming_metadata_buffer_destroy( + grpc_chttp2_incoming_metadata_buffer *buffer) { + size_t i; + if (!buffer->published) { + for (i = 0; i < buffer->count; i++) { + GRPC_MDELEM_UNREF(buffer->elems[i].md); + } + } + gpr_free(buffer->elems); +} + +void grpc_chttp2_incoming_metadata_buffer_add( + grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem *elem) { + GPR_ASSERT(!buffer->published); + if (buffer->capacity == buffer->count) { + buffer->capacity = GPR_MAX(8, 2 * buffer->capacity); + buffer->elems = + gpr_realloc(buffer->elems, sizeof(*buffer->elems) * buffer->capacity); + } + buffer->elems[buffer->count++].md = elem; +} + +void grpc_chttp2_incoming_metadata_buffer_set_deadline( + grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline) { + GPR_ASSERT(!buffer->published); + buffer->deadline = deadline; +} + +void grpc_chttp2_incoming_metadata_buffer_publish( + grpc_chttp2_incoming_metadata_buffer *buffer, grpc_metadata_batch *batch) { + GPR_ASSERT(!buffer->published); + buffer->published = 1; + if (buffer->count > 0) { + size_t i; + for (i = 1; i < buffer->count; i++) { + buffer->elems[i].prev = &buffer->elems[i - 1]; + } + for (i = 0; i < buffer->count - 1; i++) { + buffer->elems[i].next = &buffer->elems[i + 1]; + } + buffer->elems[0].prev = NULL; + buffer->elems[buffer->count - 1].next = NULL; + batch->list.head = &buffer->elems[0]; + batch->list.tail = &buffer->elems[buffer->count - 1]; + } else { + batch->list.head = batch->list.tail = NULL; + } + batch->deadline = buffer->deadline; +} diff --git a/src/core/lib/transport/chttp2/incoming_metadata.h b/src/core/lib/transport/chttp2/incoming_metadata.h new file mode 100644 index 0000000000..52454f348c --- /dev/null +++ b/src/core/lib/transport/chttp2/incoming_metadata.h @@ -0,0 +1,60 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_INCOMING_METADATA_H +#define GRPC_CORE_TRANSPORT_CHTTP2_INCOMING_METADATA_H + +#include "src/core/transport/transport.h" + +typedef struct { + grpc_linked_mdelem *elems; + size_t count; + size_t capacity; + gpr_timespec deadline; + int published; +} grpc_chttp2_incoming_metadata_buffer; + +/** assumes everything initially zeroed */ +void grpc_chttp2_incoming_metadata_buffer_init( + grpc_chttp2_incoming_metadata_buffer *buffer); +void grpc_chttp2_incoming_metadata_buffer_destroy( + grpc_chttp2_incoming_metadata_buffer *buffer); +void grpc_chttp2_incoming_metadata_buffer_publish( + grpc_chttp2_incoming_metadata_buffer *buffer, grpc_metadata_batch *batch); + +void grpc_chttp2_incoming_metadata_buffer_add( + grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem *elem); +void grpc_chttp2_incoming_metadata_buffer_set_deadline( + grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_INCOMING_METADATA_H */ diff --git a/src/core/lib/transport/chttp2/internal.h b/src/core/lib/transport/chttp2/internal.h new file mode 100644 index 0000000000..0690cb37cd --- /dev/null +++ b/src/core/lib/transport/chttp2/internal.h @@ -0,0 +1,780 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_INTERNAL_H +#define GRPC_CORE_TRANSPORT_CHTTP2_INTERNAL_H + +#include +#include + +#include "src/core/iomgr/endpoint.h" +#include "src/core/transport/chttp2/frame.h" +#include "src/core/transport/chttp2/frame_data.h" +#include "src/core/transport/chttp2/frame_goaway.h" +#include "src/core/transport/chttp2/frame_ping.h" +#include "src/core/transport/chttp2/frame_rst_stream.h" +#include "src/core/transport/chttp2/frame_settings.h" +#include "src/core/transport/chttp2/frame_window_update.h" +#include "src/core/transport/chttp2/hpack_encoder.h" +#include "src/core/transport/chttp2/hpack_parser.h" +#include "src/core/transport/chttp2/incoming_metadata.h" +#include "src/core/transport/chttp2/stream_map.h" +#include "src/core/transport/connectivity_state.h" +#include "src/core/transport/transport_impl.h" + +typedef struct grpc_chttp2_transport grpc_chttp2_transport; +typedef struct grpc_chttp2_stream grpc_chttp2_stream; + +/* streams are kept in various linked lists depending on what things need to + happen to them... this enum labels each list */ +typedef enum { + GRPC_CHTTP2_LIST_ALL_STREAMS, + GRPC_CHTTP2_LIST_CHECK_READ_OPS, + GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE, + GRPC_CHTTP2_LIST_WRITABLE, + GRPC_CHTTP2_LIST_WRITING, + GRPC_CHTTP2_LIST_WRITTEN, + GRPC_CHTTP2_LIST_PARSING_SEEN, + GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING, + GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING, + GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT, + /* streams waiting for the outgoing window in the writing path, they will be + * merged to the stalled list or writable list under transport lock. */ + GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT, + /** streams that are waiting to start because there are too many concurrent + streams on the connection */ + GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY, + STREAM_LIST_COUNT /* must be last */ +} grpc_chttp2_stream_list_id; + +/* deframer state for the overall http2 stream of bytes */ +typedef enum { + /* prefix: one entry per http2 connection prefix byte */ + GRPC_DTS_CLIENT_PREFIX_0 = 0, + GRPC_DTS_CLIENT_PREFIX_1, + GRPC_DTS_CLIENT_PREFIX_2, + GRPC_DTS_CLIENT_PREFIX_3, + GRPC_DTS_CLIENT_PREFIX_4, + GRPC_DTS_CLIENT_PREFIX_5, + GRPC_DTS_CLIENT_PREFIX_6, + GRPC_DTS_CLIENT_PREFIX_7, + GRPC_DTS_CLIENT_PREFIX_8, + GRPC_DTS_CLIENT_PREFIX_9, + GRPC_DTS_CLIENT_PREFIX_10, + GRPC_DTS_CLIENT_PREFIX_11, + GRPC_DTS_CLIENT_PREFIX_12, + GRPC_DTS_CLIENT_PREFIX_13, + GRPC_DTS_CLIENT_PREFIX_14, + GRPC_DTS_CLIENT_PREFIX_15, + GRPC_DTS_CLIENT_PREFIX_16, + GRPC_DTS_CLIENT_PREFIX_17, + GRPC_DTS_CLIENT_PREFIX_18, + GRPC_DTS_CLIENT_PREFIX_19, + GRPC_DTS_CLIENT_PREFIX_20, + GRPC_DTS_CLIENT_PREFIX_21, + GRPC_DTS_CLIENT_PREFIX_22, + GRPC_DTS_CLIENT_PREFIX_23, + /* frame header byte 0... */ + /* must follow from the prefix states */ + GRPC_DTS_FH_0, + GRPC_DTS_FH_1, + GRPC_DTS_FH_2, + GRPC_DTS_FH_3, + GRPC_DTS_FH_4, + GRPC_DTS_FH_5, + GRPC_DTS_FH_6, + GRPC_DTS_FH_7, + /* ... frame header byte 8 */ + GRPC_DTS_FH_8, + /* inside a http2 frame */ + GRPC_DTS_FRAME +} grpc_chttp2_deframe_transport_state; + +typedef struct { + grpc_chttp2_stream *head; + grpc_chttp2_stream *tail; +} grpc_chttp2_stream_list; + +typedef struct { + grpc_chttp2_stream *next; + grpc_chttp2_stream *prev; +} grpc_chttp2_stream_link; + +/* We keep several sets of connection wide parameters */ +typedef enum { + /* The settings our peer has asked for (and we have acked) */ + GRPC_PEER_SETTINGS = 0, + /* The settings we'd like to have */ + GRPC_LOCAL_SETTINGS, + /* The settings we've published to our peer */ + GRPC_SENT_SETTINGS, + /* The settings the peer has acked */ + GRPC_ACKED_SETTINGS, + GRPC_NUM_SETTING_SETS +} grpc_chttp2_setting_set; + +/* Outstanding ping request data */ +typedef struct grpc_chttp2_outstanding_ping { + uint8_t id[8]; + grpc_closure *on_recv; + struct grpc_chttp2_outstanding_ping *next; + struct grpc_chttp2_outstanding_ping *prev; +} grpc_chttp2_outstanding_ping; + +/* forward declared in frame_data.h */ +struct grpc_chttp2_incoming_byte_stream { + grpc_byte_stream base; + gpr_refcount refs; + struct grpc_chttp2_incoming_byte_stream *next_message; + int failed; + + grpc_chttp2_transport *transport; + grpc_chttp2_stream *stream; + int is_tail; + gpr_slice_buffer slices; + grpc_closure *on_next; + gpr_slice *next; +}; + +typedef struct { + /** data to write next write */ + gpr_slice_buffer qbuf; + + /** window available for us to send to peer */ + int64_t outgoing_window; + /** window available to announce to peer */ + int64_t announce_incoming_window; + /** how much window would we like to have for incoming_window */ + uint32_t connection_window_target; + + /** have we seen a goaway */ + uint8_t seen_goaway; + /** have we sent a goaway */ + uint8_t sent_goaway; + + /** is this transport a client? */ + uint8_t is_client; + /** are the local settings dirty and need to be sent? */ + uint8_t dirtied_local_settings; + /** have local settings been sent? */ + uint8_t sent_local_settings; + /** bitmask of setting indexes to send out */ + uint32_t force_send_settings; + /** settings values */ + uint32_t settings[GRPC_NUM_SETTING_SETS][GRPC_CHTTP2_NUM_SETTINGS]; + + /** what is the next stream id to be allocated by this peer? + copied to next_stream_id in parsing when parsing commences */ + uint32_t next_stream_id; + + /** how far to lookahead in a stream? */ + uint32_t stream_lookahead; + + /** last received stream id */ + uint32_t last_incoming_stream_id; + + /** pings awaiting responses */ + grpc_chttp2_outstanding_ping pings; + /** next payload for an outgoing ping */ + uint64_t ping_counter; + + /** concurrent stream count: updated when not parsing, + so this is a strict over-estimation on the client */ + uint32_t concurrent_stream_count; +} grpc_chttp2_transport_global; + +typedef struct { + /** data to write now */ + gpr_slice_buffer outbuf; + /** hpack encoding */ + grpc_chttp2_hpack_compressor hpack_compressor; + int64_t outgoing_window; + /** is this a client? */ + uint8_t is_client; + /** callback for when writing is done */ + grpc_closure done_cb; +} grpc_chttp2_transport_writing; + +struct grpc_chttp2_transport_parsing { + /** is this transport a client? (boolean) */ + uint8_t is_client; + + /** were settings updated? */ + uint8_t settings_updated; + /** was a settings ack received? */ + uint8_t settings_ack_received; + /** was a goaway frame received? */ + uint8_t goaway_received; + + /** the last sent max_table_size setting */ + uint32_t last_sent_max_table_size; + + /** initial window change */ + int64_t initial_window_update; + + /** data to write later - after parsing */ + gpr_slice_buffer qbuf; + /** parser for headers */ + grpc_chttp2_hpack_parser hpack_parser; + /** simple one shot parsers */ + union { + grpc_chttp2_window_update_parser window_update; + grpc_chttp2_settings_parser settings; + grpc_chttp2_ping_parser ping; + grpc_chttp2_rst_stream_parser rst_stream; + } simple; + /** parser for goaway frames */ + grpc_chttp2_goaway_parser goaway_parser; + + /** window available for peer to send to us */ + int64_t incoming_window; + + /** next stream id available at the time of beginning parsing */ + uint32_t next_stream_id; + uint32_t last_incoming_stream_id; + + /* deframing */ + grpc_chttp2_deframe_transport_state deframe_state; + uint8_t incoming_frame_type; + uint8_t incoming_frame_flags; + uint8_t header_eof; + uint32_t expect_continuation_stream_id; + uint32_t incoming_frame_size; + uint32_t incoming_stream_id; + + /* active parser */ + void *parser_data; + grpc_chttp2_stream_parsing *incoming_stream; + grpc_chttp2_parse_error (*parser)( + grpc_exec_ctx *exec_ctx, void *parser_user_data, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); + + /* received settings */ + uint32_t settings[GRPC_CHTTP2_NUM_SETTINGS]; + + /* goaway data */ + grpc_status_code goaway_error; + uint32_t goaway_last_stream_index; + gpr_slice goaway_text; + + int64_t outgoing_window; +}; + +struct grpc_chttp2_transport { + grpc_transport base; /* must be first */ + grpc_endpoint *ep; + gpr_refcount refs; + char *peer_string; + + /** when this drops to zero it's safe to shutdown the endpoint */ + gpr_refcount shutdown_ep_refs; + + gpr_mu mu; + + /** is the transport destroying itself? */ + uint8_t destroying; + /** has the upper layer closed the transport? */ + uint8_t closed; + + /** is a thread currently writing */ + uint8_t writing_active; + /** is a thread currently parsing */ + uint8_t parsing_active; + + /** is there a read request to the endpoint outstanding? */ + uint8_t endpoint_reading; + + /** various lists of streams */ + grpc_chttp2_stream_list lists[STREAM_LIST_COUNT]; + + /** global state for reading/writing */ + grpc_chttp2_transport_global global; + /** state only accessible by the chain of execution that + set writing_active=1 */ + grpc_chttp2_transport_writing writing; + /** state only accessible by the chain of execution that + set parsing_active=1 */ + grpc_chttp2_transport_parsing parsing; + + /** maps stream id to grpc_chttp2_stream objects; + owned by the parsing thread when parsing */ + grpc_chttp2_stream_map parsing_stream_map; + + /** streams created by the client (possibly during parsing); + merged with parsing_stream_map during unlock when no + parsing is occurring */ + grpc_chttp2_stream_map new_stream_map; + + /** closure to execute writing */ + grpc_closure writing_action; + /** closure to finish reading from the endpoint */ + grpc_closure recv_data; + + /** incoming read bytes */ + gpr_slice_buffer read_buffer; + + /** address to place a newly accepted stream - set and unset by + grpc_chttp2_parsing_accept_stream; used by init_stream to + publish the accepted server stream */ + grpc_chttp2_stream **accepting_stream; + + struct { + /* accept stream callback */ + void (*accept_stream)(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_transport *transport, const void *server_data); + void *accept_stream_user_data; + + /** connectivity tracking */ + grpc_connectivity_state_tracker state_tracker; + } channel_callback; + + /** Transport op to be applied post-parsing */ + grpc_transport_op *post_parsing_op; +}; + +typedef struct { + /** HTTP2 stream id for this stream, or zero if one has not been assigned */ + uint32_t id; + + /** window available for us to send to peer */ + int64_t outgoing_window; + /** The number of bytes the upper layers have offered to receive. + As the upper layer offers more bytes, this value increases. + As bytes are read, this value decreases. */ + uint32_t max_recv_bytes; + /** The number of bytes the upper layer has offered to read but we have + not yet announced to HTTP2 flow control. + As the upper layers offer to read more bytes, this value increases. + As we advertise incoming flow control window, this value decreases. */ + uint32_t unannounced_incoming_window_for_parse; + uint32_t unannounced_incoming_window_for_writing; + /** things the upper layers would like to send */ + grpc_metadata_batch *send_initial_metadata; + grpc_closure *send_initial_metadata_finished; + grpc_byte_stream *send_message; + grpc_closure *send_message_finished; + grpc_metadata_batch *send_trailing_metadata; + grpc_closure *send_trailing_metadata_finished; + + grpc_metadata_batch *recv_initial_metadata; + grpc_closure *recv_initial_metadata_ready; + grpc_byte_stream **recv_message; + grpc_closure *recv_message_ready; + grpc_metadata_batch *recv_trailing_metadata; + grpc_closure *recv_trailing_metadata_finished; + + /** when the application requests writes be closed, the write_closed is + 'queued'; when the close is flow controlled into the send path, we are + 'sending' it; when the write has been performed it is 'sent' */ + uint8_t write_closed; + /** is this stream reading half-closed (boolean) */ + uint8_t read_closed; + /** is this stream in the stream map? (boolean) */ + uint8_t in_stream_map; + /** has this stream seen an error? if 1, then pending incoming frames + can be thrown away */ + uint8_t seen_error; + + uint8_t published_initial_metadata; + uint8_t published_trailing_metadata; + uint8_t faked_trailing_metadata; + + grpc_chttp2_incoming_metadata_buffer received_initial_metadata; + grpc_chttp2_incoming_metadata_buffer received_trailing_metadata; + + grpc_chttp2_incoming_frame_queue incoming_frames; +} grpc_chttp2_stream_global; + +typedef struct { + /** HTTP2 stream id for this stream, or zero if one has not been assigned */ + uint32_t id; + uint8_t fetching; + bool sent_initial_metadata; + uint8_t sent_message; + uint8_t sent_trailing_metadata; + uint8_t read_closed; + /** send this initial metadata */ + grpc_metadata_batch *send_initial_metadata; + grpc_byte_stream *send_message; + grpc_metadata_batch *send_trailing_metadata; + int64_t outgoing_window; + /** how much window should we announce? */ + uint32_t announce_window; + gpr_slice_buffer flow_controlled_buffer; + gpr_slice fetching_slice; + size_t stream_fetched; + grpc_closure finished_fetch; +} grpc_chttp2_stream_writing; + +struct grpc_chttp2_stream_parsing { + /** HTTP2 stream id for this stream, or zero if one has not been assigned */ + uint32_t id; + /** has this stream received a close */ + uint8_t received_close; + /** saw a rst_stream */ + uint8_t saw_rst_stream; + /** how many header frames have we received? */ + uint8_t header_frames_received; + /** which metadata did we get (on this parse) */ + uint8_t got_metadata_on_parse[2]; + /** should we raise the seen_error flag in transport_global */ + uint8_t seen_error; + /** window available for peer to send to us */ + int64_t incoming_window; + /** parsing state for data frames */ + grpc_chttp2_data_parser data_parser; + /** reason give to rst_stream */ + uint32_t rst_stream_reason; + /** amount of window given */ + int64_t outgoing_window; + /** number of bytes received - reset at end of parse thread execution */ + int64_t received_bytes; + + /** incoming metadata */ + grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; +}; + +struct grpc_chttp2_stream { + grpc_stream_refcount *refcount; + grpc_chttp2_stream_global global; + grpc_chttp2_stream_writing writing; + grpc_chttp2_stream_parsing parsing; + + grpc_chttp2_stream_link links[STREAM_LIST_COUNT]; + uint8_t included[STREAM_LIST_COUNT]; +}; + +/** Transport writing call flow: + chttp2_transport.c calls grpc_chttp2_unlocking_check_writes to see if writes + are required; + if they are, chttp2_transport.c calls grpc_chttp2_perform_writes to do the + writes. + Once writes have been completed (meaning another write could potentially be + started), + grpc_chttp2_terminate_writing is called. This will call + grpc_chttp2_cleanup_writing, at which + point the write phase is complete. */ + +/** Someone is unlocking the transport mutex: check to see if writes + are required, and schedule them if so */ +int grpc_chttp2_unlocking_check_writes(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *global, + grpc_chttp2_transport_writing *writing, + int is_parsing); +void grpc_chttp2_perform_writes( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, + grpc_endpoint *endpoint); +void grpc_chttp2_terminate_writing(grpc_exec_ctx *exec_ctx, + void *transport_writing, bool success); +void grpc_chttp2_cleanup_writing(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *global, + grpc_chttp2_transport_writing *writing); + +void grpc_chttp2_prepare_to_read(grpc_chttp2_transport_global *global, + grpc_chttp2_transport_parsing *parsing); +/** Process one slice of incoming data; return 1 if the connection is still + viable after reading, or 0 if the connection should be torn down */ +int grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing, + gpr_slice slice); +void grpc_chttp2_publish_reads(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *global, + grpc_chttp2_transport_parsing *parsing); + +bool grpc_chttp2_list_add_writable_stream( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global); +/** Get a writable stream + returns non-zero if there was a stream available */ +int grpc_chttp2_list_pop_writable_stream( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_global **stream_global, + grpc_chttp2_stream_writing **stream_writing); +bool grpc_chttp2_list_remove_writable_stream( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global) GRPC_MUST_USE_RESULT; + +void grpc_chttp2_list_add_writing_stream( + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_writing *stream_writing); +int grpc_chttp2_list_have_writing_streams( + grpc_chttp2_transport_writing *transport_writing); +int grpc_chttp2_list_pop_writing_stream( + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_writing **stream_writing); + +void grpc_chttp2_list_add_written_stream( + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_writing *stream_writing); +int grpc_chttp2_list_pop_written_stream( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_global **stream_global, + grpc_chttp2_stream_writing **stream_writing); + +void grpc_chttp2_list_add_parsing_seen_stream( + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing); +int grpc_chttp2_list_pop_parsing_seen_stream( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_global **stream_global, + grpc_chttp2_stream_parsing **stream_parsing); + +void grpc_chttp2_list_add_waiting_for_concurrency( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global); +int grpc_chttp2_list_pop_waiting_for_concurrency( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global **stream_global); + +void grpc_chttp2_list_add_check_read_ops( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global); +int grpc_chttp2_list_pop_check_read_ops( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global **stream_global); + +void grpc_chttp2_list_add_writing_stalled_by_transport( + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_writing *stream_writing); +void grpc_chttp2_list_flush_writing_stalled_by_transport( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, + bool is_window_available); + +void grpc_chttp2_list_add_stalled_by_transport( + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_writing *stream_writing); +int grpc_chttp2_list_pop_stalled_by_transport( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global **stream_global); +void grpc_chttp2_list_remove_stalled_by_transport( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global); + +void grpc_chttp2_list_add_unannounced_incoming_window_available( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global); +void grpc_chttp2_list_remove_unannounced_incoming_window_available( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global); +int grpc_chttp2_list_pop_unannounced_incoming_window_available( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_global **stream_global, + grpc_chttp2_stream_parsing **stream_parsing); + +void grpc_chttp2_list_add_closed_waiting_for_parsing( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global); +int grpc_chttp2_list_pop_closed_waiting_for_parsing( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global **stream_global); + +void grpc_chttp2_list_add_closed_waiting_for_writing( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global); +int grpc_chttp2_list_pop_closed_waiting_for_writing( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global **stream_global); + +grpc_chttp2_stream_parsing *grpc_chttp2_parsing_lookup_stream( + grpc_chttp2_transport_parsing *transport_parsing, uint32_t id); +grpc_chttp2_stream_parsing *grpc_chttp2_parsing_accept_stream( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + uint32_t id); + +void grpc_chttp2_add_incoming_goaway( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + uint32_t goaway_error, gpr_slice goaway_text); + +void grpc_chttp2_register_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream *s); +/* returns 1 if this is the last stream, 0 otherwise */ +int grpc_chttp2_unregister_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream *s) GRPC_MUST_USE_RESULT; +int grpc_chttp2_has_streams(grpc_chttp2_transport *t); +void grpc_chttp2_for_all_streams( + grpc_chttp2_transport_global *transport_global, void *user_data, + void (*cb)(grpc_chttp2_transport_global *transport_global, void *user_data, + grpc_chttp2_stream_global *stream_global)); + +void grpc_chttp2_parsing_become_skip_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); + +void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, + grpc_closure **pclosure, int success); + +#define GRPC_CHTTP2_CLIENT_CONNECT_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" +#define GRPC_CHTTP2_CLIENT_CONNECT_STRLEN \ + (sizeof(GRPC_CHTTP2_CLIENT_CONNECT_STRING) - 1) + +extern int grpc_http_trace; +extern int grpc_flowctl_trace; + +#define GRPC_CHTTP2_IF_TRACING(stmt) \ + if (!(grpc_http_trace)) \ + ; \ + else \ + stmt + +typedef enum { + GRPC_CHTTP2_FLOWCTL_MOVE, + GRPC_CHTTP2_FLOWCTL_CREDIT, + GRPC_CHTTP2_FLOWCTL_DEBIT +} grpc_chttp2_flowctl_op; + +#define GRPC_CHTTP2_FLOW_MOVE_COMMON(phase, transport, id1, id2, dst_context, \ + dst_var, src_context, src_var) \ + do { \ + assert(id1 == id2); \ + if (grpc_flowctl_trace) { \ + grpc_chttp2_flowctl_trace( \ + __FILE__, __LINE__, phase, GRPC_CHTTP2_FLOWCTL_MOVE, #dst_context, \ + #dst_var, #src_context, #src_var, transport->is_client, id1, \ + dst_context->dst_var, src_context->src_var); \ + } \ + dst_context->dst_var += src_context->src_var; \ + src_context->src_var = 0; \ + } while (0) + +#define GRPC_CHTTP2_FLOW_MOVE_STREAM(phase, transport, dst_context, dst_var, \ + src_context, src_var) \ + GRPC_CHTTP2_FLOW_MOVE_COMMON(phase, transport, dst_context->id, \ + src_context->id, dst_context, dst_var, \ + src_context, src_var) +#define GRPC_CHTTP2_FLOW_MOVE_TRANSPORT(phase, dst_context, dst_var, \ + src_context, src_var) \ + GRPC_CHTTP2_FLOW_MOVE_COMMON(phase, dst_context, 0, 0, dst_context, dst_var, \ + src_context, src_var) + +#define GRPC_CHTTP2_FLOW_CREDIT_COMMON(phase, transport, id, dst_context, \ + dst_var, amount) \ + do { \ + if (grpc_flowctl_trace) { \ + grpc_chttp2_flowctl_trace(__FILE__, __LINE__, phase, \ + GRPC_CHTTP2_FLOWCTL_CREDIT, #dst_context, \ + #dst_var, NULL, #amount, transport->is_client, \ + id, dst_context->dst_var, amount); \ + } \ + dst_context->dst_var += amount; \ + } while (0) + +#define GRPC_CHTTP2_FLOW_CREDIT_STREAM(phase, transport, dst_context, dst_var, \ + amount) \ + GRPC_CHTTP2_FLOW_CREDIT_COMMON(phase, transport, dst_context->id, \ + dst_context, dst_var, amount) +#define GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT(phase, dst_context, dst_var, amount) \ + GRPC_CHTTP2_FLOW_CREDIT_COMMON(phase, dst_context, 0, dst_context, dst_var, \ + amount) + +#define GRPC_CHTTP2_FLOW_DEBIT_COMMON(phase, transport, id, dst_context, \ + dst_var, amount) \ + do { \ + if (grpc_flowctl_trace) { \ + grpc_chttp2_flowctl_trace(__FILE__, __LINE__, phase, \ + GRPC_CHTTP2_FLOWCTL_DEBIT, #dst_context, \ + #dst_var, NULL, #amount, transport->is_client, \ + id, dst_context->dst_var, amount); \ + } \ + dst_context->dst_var -= amount; \ + } while (0) + +#define GRPC_CHTTP2_FLOW_DEBIT_STREAM(phase, transport, dst_context, dst_var, \ + amount) \ + GRPC_CHTTP2_FLOW_DEBIT_COMMON(phase, transport, dst_context->id, \ + dst_context, dst_var, amount) +#define GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT(phase, dst_context, dst_var, amount) \ + GRPC_CHTTP2_FLOW_DEBIT_COMMON(phase, dst_context, 0, dst_context, dst_var, \ + amount) + +void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase, + grpc_chttp2_flowctl_op op, const char *context1, + const char *var1, const char *context2, + const char *var2, int is_client, + uint32_t stream_id, int64_t val1, int64_t val2); + +void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream, + grpc_status_code status, gpr_slice *details); +void grpc_chttp2_mark_stream_closed( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, int close_reads, + int close_writes); +void grpc_chttp2_start_writing(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global); + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +#define GRPC_CHTTP2_STREAM_REF(stream_global, reason) \ + grpc_chttp2_stream_ref(stream_global, reason) +#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, reason) \ + grpc_chttp2_stream_unref(exec_ctx, stream_global, reason) +void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global, + const char *reason); +void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, + grpc_chttp2_stream_global *stream_global, + const char *reason); +#else +#define GRPC_CHTTP2_STREAM_REF(stream_global, reason) \ + grpc_chttp2_stream_ref(stream_global) +#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, reason) \ + grpc_chttp2_stream_unref(exec_ctx, stream_global) +void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global); +void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, + grpc_chttp2_stream_global *stream_global); +#endif + +grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, uint32_t frame_size, + uint32_t flags, grpc_chttp2_incoming_frame_queue *add_to_queue); +void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, + grpc_chttp2_incoming_byte_stream *bs, + gpr_slice slice); +void grpc_chttp2_incoming_byte_stream_finished( + grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, int success, + int from_parsing_thread); + +void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *parsing, + const uint8_t *opaque_8bytes); + +/** add a ref to the stream and add it to the writable list; + ref will be dropped in writing.c */ +void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_INTERNAL_H */ diff --git a/src/core/lib/transport/chttp2/parsing.c b/src/core/lib/transport/chttp2/parsing.c new file mode 100644 index 0000000000..0516f39fa9 --- /dev/null +++ b/src/core/lib/transport/chttp2/parsing.c @@ -0,0 +1,866 @@ +/* + * + * Copyright 2015-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/transport/chttp2/internal.h" + +#include + +#include +#include +#include + +#include "src/core/profiling/timers.h" +#include "src/core/transport/chttp2/http2_errors.h" +#include "src/core/transport/chttp2/status_conversion.h" +#include "src/core/transport/chttp2/timeout_encoding.h" +#include "src/core/transport/static_metadata.h" + +static int init_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing); +static int init_header_frame_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + int is_continuation); +static int init_data_frame_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); +static int init_rst_stream_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); +static int init_settings_frame_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); +static int init_window_update_frame_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); +static int init_ping_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing); +static int init_goaway_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing); +static int init_skip_frame_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + int is_header); + +static int parse_frame_slice(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing, + gpr_slice slice, int is_last); + +void grpc_chttp2_prepare_to_read( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_parsing *transport_parsing) { + grpc_chttp2_stream_global *stream_global; + grpc_chttp2_stream_parsing *stream_parsing; + + GPR_TIMER_BEGIN("grpc_chttp2_prepare_to_read", 0); + + transport_parsing->next_stream_id = transport_global->next_stream_id; + transport_parsing->last_sent_max_table_size = + transport_global->settings[GRPC_SENT_SETTINGS] + [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]; + + /* update the parsing view of incoming window */ + while (grpc_chttp2_list_pop_unannounced_incoming_window_available( + transport_global, transport_parsing, &stream_global, &stream_parsing)) { + GRPC_CHTTP2_FLOW_MOVE_STREAM("parse", transport_parsing, stream_parsing, + incoming_window, stream_global, + unannounced_incoming_window_for_parse); + } + + GPR_TIMER_END("grpc_chttp2_prepare_to_read", 0); +} + +void grpc_chttp2_publish_reads( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_parsing *transport_parsing) { + grpc_chttp2_stream_global *stream_global; + grpc_chttp2_stream_parsing *stream_parsing; + int was_zero; + int is_zero; + + /* transport_parsing->last_incoming_stream_id is used as + last-grpc_chttp2_stream-id when + sending GOAWAY frame. + https://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-6.8 + says that last-grpc_chttp2_stream-id is peer-initiated grpc_chttp2_stream + ID. So, + since we don't have server pushed streams, client should send + GOAWAY last-grpc_chttp2_stream-id=0 in this case. */ + if (!transport_parsing->is_client) { + transport_global->last_incoming_stream_id = + transport_parsing->incoming_stream_id; + } + + /* update global settings */ + if (transport_parsing->settings_updated) { + memcpy(transport_global->settings[GRPC_PEER_SETTINGS], + transport_parsing->settings, sizeof(transport_parsing->settings)); + transport_parsing->settings_updated = 0; + } + + /* update settings based on ack if received */ + if (transport_parsing->settings_ack_received) { + memcpy(transport_global->settings[GRPC_ACKED_SETTINGS], + transport_global->settings[GRPC_SENT_SETTINGS], + GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); + transport_parsing->settings_ack_received = 0; + transport_global->sent_local_settings = 0; + } + + /* move goaway to the global state if we received one (it will be + published later */ + if (transport_parsing->goaway_received) { + grpc_chttp2_add_incoming_goaway(exec_ctx, transport_global, + (uint32_t)transport_parsing->goaway_error, + transport_parsing->goaway_text); + transport_parsing->goaway_text = gpr_empty_slice(); + transport_parsing->goaway_received = 0; + } + + /* propagate flow control tokens to global state */ + was_zero = transport_global->outgoing_window <= 0; + GRPC_CHTTP2_FLOW_MOVE_TRANSPORT("parsed", transport_global, outgoing_window, + transport_parsing, outgoing_window); + is_zero = transport_global->outgoing_window <= 0; + if (was_zero && !is_zero) { + while (grpc_chttp2_list_pop_stalled_by_transport(transport_global, + &stream_global)) { + grpc_chttp2_become_writable(transport_global, stream_global); + } + } + + if (transport_parsing->incoming_window < + transport_global->connection_window_target * 3 / 4) { + int64_t announce_bytes = transport_global->connection_window_target - + transport_parsing->incoming_window; + GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", transport_global, + announce_incoming_window, announce_bytes); + GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", transport_parsing, + incoming_window, announce_bytes); + } + + /* for each stream that saw an update, fixup global state */ + while (grpc_chttp2_list_pop_parsing_seen_stream( + transport_global, transport_parsing, &stream_global, &stream_parsing)) { + if (stream_parsing->seen_error) { + stream_global->seen_error = 1; + grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); + } + + /* update outgoing flow control window */ + was_zero = stream_global->outgoing_window <= 0; + GRPC_CHTTP2_FLOW_MOVE_STREAM("parsed", transport_global, stream_global, + outgoing_window, stream_parsing, + outgoing_window); + is_zero = stream_global->outgoing_window <= 0; + if (was_zero && !is_zero) { + grpc_chttp2_become_writable(transport_global, stream_global); + } + + stream_global->max_recv_bytes -= (uint32_t)GPR_MIN( + stream_global->max_recv_bytes, stream_parsing->received_bytes); + stream_parsing->received_bytes = 0; + + /* publish incoming stream ops */ + if (stream_global->incoming_frames.tail != NULL) { + stream_global->incoming_frames.tail->is_tail = 0; + } + if (stream_parsing->data_parser.incoming_frames.head != NULL) { + grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); + } + grpc_chttp2_incoming_frame_queue_merge( + &stream_global->incoming_frames, + &stream_parsing->data_parser.incoming_frames); + if (stream_global->incoming_frames.tail != NULL) { + stream_global->incoming_frames.tail->is_tail = 1; + } + + if (!stream_global->published_initial_metadata && + stream_parsing->got_metadata_on_parse[0]) { + stream_parsing->got_metadata_on_parse[0] = 0; + stream_global->published_initial_metadata = 1; + GPR_SWAP(grpc_chttp2_incoming_metadata_buffer, + stream_parsing->metadata_buffer[0], + stream_global->received_initial_metadata); + grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); + } + if (!stream_global->published_trailing_metadata && + stream_parsing->got_metadata_on_parse[1]) { + stream_parsing->got_metadata_on_parse[1] = 0; + stream_global->published_trailing_metadata = 1; + GPR_SWAP(grpc_chttp2_incoming_metadata_buffer, + stream_parsing->metadata_buffer[1], + stream_global->received_trailing_metadata); + grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); + } + + if (stream_parsing->saw_rst_stream) { + if (stream_parsing->rst_stream_reason != GRPC_CHTTP2_NO_ERROR) { + grpc_status_code status_code = grpc_chttp2_http2_error_to_grpc_status( + (grpc_chttp2_error_code)stream_parsing->rst_stream_reason); + char *status_details; + gpr_slice slice_details; + gpr_asprintf(&status_details, "Received RST_STREAM err=%d", + stream_parsing->rst_stream_reason); + slice_details = gpr_slice_from_copied_string(status_details); + gpr_free(status_details); + grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, + status_code, &slice_details); + } + grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, + 1, 1); + } + + if (stream_parsing->received_close) { + grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, + 1, 0); + } + } +} + +int grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing, + gpr_slice slice) { + uint8_t *beg = GPR_SLICE_START_PTR(slice); + uint8_t *end = GPR_SLICE_END_PTR(slice); + uint8_t *cur = beg; + + if (cur == end) return 1; + + switch (transport_parsing->deframe_state) { + case GRPC_DTS_CLIENT_PREFIX_0: + case GRPC_DTS_CLIENT_PREFIX_1: + case GRPC_DTS_CLIENT_PREFIX_2: + case GRPC_DTS_CLIENT_PREFIX_3: + case GRPC_DTS_CLIENT_PREFIX_4: + case GRPC_DTS_CLIENT_PREFIX_5: + case GRPC_DTS_CLIENT_PREFIX_6: + case GRPC_DTS_CLIENT_PREFIX_7: + case GRPC_DTS_CLIENT_PREFIX_8: + case GRPC_DTS_CLIENT_PREFIX_9: + case GRPC_DTS_CLIENT_PREFIX_10: + case GRPC_DTS_CLIENT_PREFIX_11: + case GRPC_DTS_CLIENT_PREFIX_12: + case GRPC_DTS_CLIENT_PREFIX_13: + case GRPC_DTS_CLIENT_PREFIX_14: + case GRPC_DTS_CLIENT_PREFIX_15: + case GRPC_DTS_CLIENT_PREFIX_16: + case GRPC_DTS_CLIENT_PREFIX_17: + case GRPC_DTS_CLIENT_PREFIX_18: + case GRPC_DTS_CLIENT_PREFIX_19: + case GRPC_DTS_CLIENT_PREFIX_20: + case GRPC_DTS_CLIENT_PREFIX_21: + case GRPC_DTS_CLIENT_PREFIX_22: + case GRPC_DTS_CLIENT_PREFIX_23: + while (cur != end && transport_parsing->deframe_state != GRPC_DTS_FH_0) { + if (*cur != GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing + ->deframe_state]) { + gpr_log(GPR_INFO, + "Connect string mismatch: expected '%c' (%d) got '%c' (%d) " + "at byte %d", + GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing + ->deframe_state], + (int)(uint8_t)GRPC_CHTTP2_CLIENT_CONNECT_STRING + [transport_parsing->deframe_state], + *cur, (int)*cur, transport_parsing->deframe_state); + return 0; + } + ++cur; + ++transport_parsing->deframe_state; + } + if (cur == end) { + return 1; + } + /* fallthrough */ + dts_fh_0: + case GRPC_DTS_FH_0: + GPR_ASSERT(cur < end); + transport_parsing->incoming_frame_size = ((uint32_t)*cur) << 16; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_1; + return 1; + } + /* fallthrough */ + case GRPC_DTS_FH_1: + GPR_ASSERT(cur < end); + transport_parsing->incoming_frame_size |= ((uint32_t)*cur) << 8; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_2; + return 1; + } + /* fallthrough */ + case GRPC_DTS_FH_2: + GPR_ASSERT(cur < end); + transport_parsing->incoming_frame_size |= *cur; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_3; + return 1; + } + /* fallthrough */ + case GRPC_DTS_FH_3: + GPR_ASSERT(cur < end); + transport_parsing->incoming_frame_type = *cur; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_4; + return 1; + } + /* fallthrough */ + case GRPC_DTS_FH_4: + GPR_ASSERT(cur < end); + transport_parsing->incoming_frame_flags = *cur; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_5; + return 1; + } + /* fallthrough */ + case GRPC_DTS_FH_5: + GPR_ASSERT(cur < end); + transport_parsing->incoming_stream_id = (((uint32_t)*cur) & 0x7f) << 24; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_6; + return 1; + } + /* fallthrough */ + case GRPC_DTS_FH_6: + GPR_ASSERT(cur < end); + transport_parsing->incoming_stream_id |= ((uint32_t)*cur) << 16; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_7; + return 1; + } + /* fallthrough */ + case GRPC_DTS_FH_7: + GPR_ASSERT(cur < end); + transport_parsing->incoming_stream_id |= ((uint32_t)*cur) << 8; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_8; + return 1; + } + /* fallthrough */ + case GRPC_DTS_FH_8: + GPR_ASSERT(cur < end); + transport_parsing->incoming_stream_id |= ((uint32_t)*cur); + transport_parsing->deframe_state = GRPC_DTS_FRAME; + if (!init_frame_parser(exec_ctx, transport_parsing)) { + return 0; + } + if (transport_parsing->incoming_stream_id) { + transport_parsing->last_incoming_stream_id = + transport_parsing->incoming_stream_id; + } + if (transport_parsing->incoming_frame_size == 0) { + if (!parse_frame_slice(exec_ctx, transport_parsing, gpr_empty_slice(), + 1)) { + return 0; + } + transport_parsing->incoming_stream = NULL; + if (++cur == end) { + transport_parsing->deframe_state = GRPC_DTS_FH_0; + return 1; + } + goto dts_fh_0; /* loop */ + } + if (++cur == end) { + return 1; + } + /* fallthrough */ + case GRPC_DTS_FRAME: + GPR_ASSERT(cur < end); + if ((uint32_t)(end - cur) == transport_parsing->incoming_frame_size) { + if (!parse_frame_slice(exec_ctx, transport_parsing, + gpr_slice_sub_no_ref(slice, (size_t)(cur - beg), + (size_t)(end - beg)), + 1)) { + return 0; + } + transport_parsing->deframe_state = GRPC_DTS_FH_0; + transport_parsing->incoming_stream = NULL; + return 1; + } else if ((uint32_t)(end - cur) > + transport_parsing->incoming_frame_size) { + size_t cur_offset = (size_t)(cur - beg); + if (!parse_frame_slice( + exec_ctx, transport_parsing, + gpr_slice_sub_no_ref( + slice, cur_offset, + cur_offset + transport_parsing->incoming_frame_size), + 1)) { + return 0; + } + cur += transport_parsing->incoming_frame_size; + transport_parsing->incoming_stream = NULL; + goto dts_fh_0; /* loop */ + } else { + if (!parse_frame_slice(exec_ctx, transport_parsing, + gpr_slice_sub_no_ref(slice, (size_t)(cur - beg), + (size_t)(end - beg)), + 0)) { + return 0; + } + transport_parsing->incoming_frame_size -= (uint32_t)(end - cur); + return 1; + } + GPR_UNREACHABLE_CODE(return 0); + } + + GPR_UNREACHABLE_CODE(return 0); +} + +static int init_frame_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing) { + if (transport_parsing->expect_continuation_stream_id != 0) { + if (transport_parsing->incoming_frame_type != + GRPC_CHTTP2_FRAME_CONTINUATION) { + gpr_log(GPR_ERROR, "Expected CONTINUATION frame, got frame type %02x", + transport_parsing->incoming_frame_type); + return 0; + } + if (transport_parsing->expect_continuation_stream_id != + transport_parsing->incoming_stream_id) { + gpr_log(GPR_ERROR, + "Expected CONTINUATION frame for grpc_chttp2_stream %08x, got " + "grpc_chttp2_stream %08x", + transport_parsing->expect_continuation_stream_id, + transport_parsing->incoming_stream_id); + return 0; + } + return init_header_frame_parser(exec_ctx, transport_parsing, 1); + } + switch (transport_parsing->incoming_frame_type) { + case GRPC_CHTTP2_FRAME_DATA: + return init_data_frame_parser(exec_ctx, transport_parsing); + case GRPC_CHTTP2_FRAME_HEADER: + return init_header_frame_parser(exec_ctx, transport_parsing, 0); + case GRPC_CHTTP2_FRAME_CONTINUATION: + gpr_log(GPR_ERROR, "Unexpected CONTINUATION frame"); + return 0; + case GRPC_CHTTP2_FRAME_RST_STREAM: + return init_rst_stream_parser(exec_ctx, transport_parsing); + case GRPC_CHTTP2_FRAME_SETTINGS: + return init_settings_frame_parser(exec_ctx, transport_parsing); + case GRPC_CHTTP2_FRAME_WINDOW_UPDATE: + return init_window_update_frame_parser(exec_ctx, transport_parsing); + case GRPC_CHTTP2_FRAME_PING: + return init_ping_parser(exec_ctx, transport_parsing); + case GRPC_CHTTP2_FRAME_GOAWAY: + return init_goaway_parser(exec_ctx, transport_parsing); + default: + gpr_log(GPR_ERROR, "Unknown frame type %02x", + transport_parsing->incoming_frame_type); + return init_skip_frame_parser(exec_ctx, transport_parsing, 0); + } +} + +static grpc_chttp2_parse_error skip_parser( + grpc_exec_ctx *exec_ctx, void *parser, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { + return GRPC_CHTTP2_PARSE_OK; +} + +static void skip_header(void *tp, grpc_mdelem *md) { GRPC_MDELEM_UNREF(md); } + +static int init_skip_frame_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + int is_header) { + if (is_header) { + uint8_t is_eoh = transport_parsing->expect_continuation_stream_id != 0; + transport_parsing->parser = grpc_chttp2_header_parser_parse; + transport_parsing->parser_data = &transport_parsing->hpack_parser; + transport_parsing->hpack_parser.on_header = skip_header; + transport_parsing->hpack_parser.on_header_user_data = NULL; + transport_parsing->hpack_parser.is_boundary = is_eoh; + transport_parsing->hpack_parser.is_eof = + (uint8_t)(is_eoh ? transport_parsing->header_eof : 0); + } else { + transport_parsing->parser = skip_parser; + } + return 1; +} + +void grpc_chttp2_parsing_become_skip_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { + init_skip_frame_parser( + exec_ctx, transport_parsing, + transport_parsing->parser == grpc_chttp2_header_parser_parse); +} + +static grpc_chttp2_parse_error update_incoming_window( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing) { + uint32_t incoming_frame_size = transport_parsing->incoming_frame_size; + if (incoming_frame_size > transport_parsing->incoming_window) { + gpr_log(GPR_ERROR, "frame of size %d overflows incoming window of %d", + transport_parsing->incoming_frame_size, + transport_parsing->incoming_window); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + + if (incoming_frame_size > stream_parsing->incoming_window) { + gpr_log(GPR_ERROR, "frame of size %d overflows incoming window of %d", + transport_parsing->incoming_frame_size, + stream_parsing->incoming_window); + return GRPC_CHTTP2_CONNECTION_ERROR; + } + + GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", transport_parsing, incoming_window, + incoming_frame_size); + GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", transport_parsing, stream_parsing, + incoming_window, incoming_frame_size); + stream_parsing->received_bytes += incoming_frame_size; + + grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); + + return GRPC_CHTTP2_PARSE_OK; +} + +static int init_data_frame_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { + grpc_chttp2_stream_parsing *stream_parsing = + grpc_chttp2_parsing_lookup_stream(transport_parsing, + transport_parsing->incoming_stream_id); + grpc_chttp2_parse_error err = GRPC_CHTTP2_PARSE_OK; + if (!stream_parsing || stream_parsing->received_close) + return init_skip_frame_parser(exec_ctx, transport_parsing, 0); + if (err == GRPC_CHTTP2_PARSE_OK) { + err = update_incoming_window(exec_ctx, transport_parsing, stream_parsing); + } + if (err == GRPC_CHTTP2_PARSE_OK) { + err = grpc_chttp2_data_parser_begin_frame( + &stream_parsing->data_parser, transport_parsing->incoming_frame_flags); + } + switch (err) { + case GRPC_CHTTP2_PARSE_OK: + transport_parsing->incoming_stream = stream_parsing; + transport_parsing->parser = grpc_chttp2_data_parser_parse; + transport_parsing->parser_data = &stream_parsing->data_parser; + return 1; + case GRPC_CHTTP2_STREAM_ERROR: + stream_parsing->received_close = 1; + stream_parsing->saw_rst_stream = 1; + stream_parsing->rst_stream_reason = GRPC_CHTTP2_PROTOCOL_ERROR; + gpr_slice_buffer_add( + &transport_parsing->qbuf, + grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id, + GRPC_CHTTP2_PROTOCOL_ERROR)); + return init_skip_frame_parser(exec_ctx, transport_parsing, 0); + case GRPC_CHTTP2_CONNECTION_ERROR: + return 0; + } + GPR_UNREACHABLE_CODE(return 0); +} + +static void free_timeout(void *p) { gpr_free(p); } + +static void on_initial_header(void *tp, grpc_mdelem *md) { + grpc_chttp2_transport_parsing *transport_parsing = tp; + grpc_chttp2_stream_parsing *stream_parsing = + transport_parsing->incoming_stream; + + GPR_TIMER_BEGIN("on_initial_header", 0); + + GPR_ASSERT(stream_parsing); + + GRPC_CHTTP2_IF_TRACING(gpr_log( + GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", stream_parsing->id, + transport_parsing->is_client ? "CLI" : "SVR", + grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value))); + + if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) { + /* TODO(ctiller): check for a status like " 0" */ + stream_parsing->seen_error = 1; + } + + if (md->key == GRPC_MDSTR_GRPC_TIMEOUT) { + gpr_timespec *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout); + if (!cached_timeout) { + /* not already parsed: parse it now, and store the result away */ + cached_timeout = gpr_malloc(sizeof(gpr_timespec)); + if (!grpc_chttp2_decode_timeout(grpc_mdstr_as_c_string(md->value), + cached_timeout)) { + gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", + grpc_mdstr_as_c_string(md->value)); + *cached_timeout = gpr_inf_future(GPR_TIMESPAN); + } + grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); + } + grpc_chttp2_incoming_metadata_buffer_set_deadline( + &stream_parsing->metadata_buffer[0], + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout)); + GRPC_MDELEM_UNREF(md); + } else { + grpc_chttp2_incoming_metadata_buffer_add( + &stream_parsing->metadata_buffer[0], md); + } + + grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); + + GPR_TIMER_END("on_initial_header", 0); +} + +static void on_trailing_header(void *tp, grpc_mdelem *md) { + grpc_chttp2_transport_parsing *transport_parsing = tp; + grpc_chttp2_stream_parsing *stream_parsing = + transport_parsing->incoming_stream; + + GPR_TIMER_BEGIN("on_trailing_header", 0); + + GPR_ASSERT(stream_parsing); + + GRPC_CHTTP2_IF_TRACING(gpr_log( + GPR_INFO, "HTTP:%d:TRL:%s: %s: %s", stream_parsing->id, + transport_parsing->is_client ? "CLI" : "SVR", + grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value))); + + if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) { + /* TODO(ctiller): check for a status like " 0" */ + stream_parsing->seen_error = 1; + } + + grpc_chttp2_incoming_metadata_buffer_add(&stream_parsing->metadata_buffer[1], + md); + + grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); + + GPR_TIMER_END("on_trailing_header", 0); +} + +static int init_header_frame_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + int is_continuation) { + uint8_t is_eoh = (transport_parsing->incoming_frame_flags & + GRPC_CHTTP2_DATA_FLAG_END_HEADERS) != 0; + int via_accept = 0; + grpc_chttp2_stream_parsing *stream_parsing; + + /* TODO(ctiller): when to increment header_frames_received? */ + + if (is_eoh) { + transport_parsing->expect_continuation_stream_id = 0; + } else { + transport_parsing->expect_continuation_stream_id = + transport_parsing->incoming_stream_id; + } + + if (!is_continuation) { + transport_parsing->header_eof = (transport_parsing->incoming_frame_flags & + GRPC_CHTTP2_DATA_FLAG_END_STREAM) != 0; + } + + /* could be a new grpc_chttp2_stream or an existing grpc_chttp2_stream */ + stream_parsing = grpc_chttp2_parsing_lookup_stream( + transport_parsing, transport_parsing->incoming_stream_id); + if (stream_parsing == NULL) { + if (is_continuation) { + gpr_log(GPR_ERROR, + "grpc_chttp2_stream disbanded before CONTINUATION received"); + return init_skip_frame_parser(exec_ctx, transport_parsing, 1); + } + if (transport_parsing->is_client) { + if ((transport_parsing->incoming_stream_id & 1) && + transport_parsing->incoming_stream_id < + transport_parsing->next_stream_id) { + /* this is an old (probably cancelled) grpc_chttp2_stream */ + } else { + gpr_log(GPR_ERROR, + "ignoring new grpc_chttp2_stream creation on client"); + } + return init_skip_frame_parser(exec_ctx, transport_parsing, 1); + } else if (transport_parsing->last_incoming_stream_id > + transport_parsing->incoming_stream_id) { + gpr_log(GPR_ERROR, + "ignoring out of order new grpc_chttp2_stream request on server; " + "last grpc_chttp2_stream " + "id=%d, new grpc_chttp2_stream id=%d", + transport_parsing->last_incoming_stream_id, + transport_parsing->incoming_stream_id); + return init_skip_frame_parser(exec_ctx, transport_parsing, 1); + } else if ((transport_parsing->incoming_stream_id & 1) == 0) { + gpr_log(GPR_ERROR, + "ignoring grpc_chttp2_stream with non-client generated index %d", + transport_parsing->incoming_stream_id); + return init_skip_frame_parser(exec_ctx, transport_parsing, 1); + } + stream_parsing = transport_parsing->incoming_stream = + grpc_chttp2_parsing_accept_stream( + exec_ctx, transport_parsing, transport_parsing->incoming_stream_id); + if (stream_parsing == NULL) { + gpr_log(GPR_ERROR, "grpc_chttp2_stream not accepted"); + return init_skip_frame_parser(exec_ctx, transport_parsing, 1); + } + via_accept = 1; + } else { + transport_parsing->incoming_stream = stream_parsing; + } + GPR_ASSERT(stream_parsing != NULL && (via_accept == 0 || via_accept == 1)); + if (stream_parsing->received_close) { + gpr_log(GPR_ERROR, "skipping already closed grpc_chttp2_stream header"); + transport_parsing->incoming_stream = NULL; + return init_skip_frame_parser(exec_ctx, transport_parsing, 1); + } + transport_parsing->parser = grpc_chttp2_header_parser_parse; + transport_parsing->parser_data = &transport_parsing->hpack_parser; + switch (stream_parsing->header_frames_received) { + case 0: + transport_parsing->hpack_parser.on_header = on_initial_header; + break; + case 1: + transport_parsing->hpack_parser.on_header = on_trailing_header; + break; + case 2: + gpr_log(GPR_ERROR, "too many header frames received"); + return init_skip_frame_parser(exec_ctx, transport_parsing, 1); + } + transport_parsing->hpack_parser.on_header_user_data = transport_parsing; + transport_parsing->hpack_parser.is_boundary = is_eoh; + transport_parsing->hpack_parser.is_eof = + (uint8_t)(is_eoh ? transport_parsing->header_eof : 0); + if (!is_continuation && (transport_parsing->incoming_frame_flags & + GRPC_CHTTP2_FLAG_HAS_PRIORITY)) { + grpc_chttp2_hpack_parser_set_has_priority(&transport_parsing->hpack_parser); + } + return 1; +} + +static int init_window_update_frame_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { + int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_window_update_parser_begin_frame( + &transport_parsing->simple.window_update, + transport_parsing->incoming_frame_size, + transport_parsing->incoming_frame_flags); + if (transport_parsing->incoming_stream_id) { + transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream( + transport_parsing, transport_parsing->incoming_stream_id); + } + transport_parsing->parser = grpc_chttp2_window_update_parser_parse; + transport_parsing->parser_data = &transport_parsing->simple.window_update; + return ok; +} + +static int init_ping_parser(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing) { + int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_ping_parser_begin_frame( + &transport_parsing->simple.ping, + transport_parsing->incoming_frame_size, + transport_parsing->incoming_frame_flags); + transport_parsing->parser = grpc_chttp2_ping_parser_parse; + transport_parsing->parser_data = &transport_parsing->simple.ping; + return ok; +} + +static int init_rst_stream_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { + int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_rst_stream_parser_begin_frame( + &transport_parsing->simple.rst_stream, + transport_parsing->incoming_frame_size, + transport_parsing->incoming_frame_flags); + transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream( + transport_parsing, transport_parsing->incoming_stream_id); + if (!transport_parsing->incoming_stream) { + return init_skip_frame_parser(exec_ctx, transport_parsing, 0); + } + transport_parsing->parser = grpc_chttp2_rst_stream_parser_parse; + transport_parsing->parser_data = &transport_parsing->simple.rst_stream; + return ok; +} + +static int init_goaway_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { + int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_goaway_parser_begin_frame( + &transport_parsing->goaway_parser, + transport_parsing->incoming_frame_size, + transport_parsing->incoming_frame_flags); + transport_parsing->parser = grpc_chttp2_goaway_parser_parse; + transport_parsing->parser_data = &transport_parsing->goaway_parser; + return ok; +} + +static int init_settings_frame_parser( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { + int ok; + + if (transport_parsing->incoming_stream_id != 0) { + gpr_log(GPR_ERROR, "settings frame received for grpc_chttp2_stream %d", + transport_parsing->incoming_stream_id); + return 0; + } + + ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_settings_parser_begin_frame( + &transport_parsing->simple.settings, + transport_parsing->incoming_frame_size, + transport_parsing->incoming_frame_flags, + transport_parsing->settings); + if (!ok) { + return 0; + } + if (transport_parsing->incoming_frame_flags & GRPC_CHTTP2_FLAG_ACK) { + transport_parsing->settings_ack_received = 1; + grpc_chttp2_hptbl_set_max_bytes( + &transport_parsing->hpack_parser.table, + transport_parsing->last_sent_max_table_size); + } + transport_parsing->parser = grpc_chttp2_settings_parser_parse; + transport_parsing->parser_data = &transport_parsing->simple.settings; + return ok; +} + +/* +static int is_window_update_legal(int64_t window_update, int64_t window) { + return window + window_update < MAX_WINDOW; +} +*/ + +static int parse_frame_slice(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing, + gpr_slice slice, int is_last) { + grpc_chttp2_stream_parsing *stream_parsing = + transport_parsing->incoming_stream; + switch (transport_parsing->parser(exec_ctx, transport_parsing->parser_data, + transport_parsing, stream_parsing, slice, + is_last)) { + case GRPC_CHTTP2_PARSE_OK: + if (stream_parsing) { + grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, + stream_parsing); + } + return 1; + case GRPC_CHTTP2_STREAM_ERROR: + grpc_chttp2_parsing_become_skip_parser(exec_ctx, transport_parsing); + if (stream_parsing) { + stream_parsing->saw_rst_stream = 1; + stream_parsing->rst_stream_reason = GRPC_CHTTP2_PROTOCOL_ERROR; + gpr_slice_buffer_add( + &transport_parsing->qbuf, + grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id, + GRPC_CHTTP2_PROTOCOL_ERROR)); + } + return 1; + case GRPC_CHTTP2_CONNECTION_ERROR: + return 0; + } + GPR_UNREACHABLE_CODE(return 0); +} diff --git a/src/core/lib/transport/chttp2/status_conversion.c b/src/core/lib/transport/chttp2/status_conversion.c new file mode 100644 index 0000000000..bf214b017a --- /dev/null +++ b/src/core/lib/transport/chttp2/status_conversion.c @@ -0,0 +1,109 @@ +/* + * + * Copyright 2015, 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/transport/chttp2/status_conversion.h" + +int grpc_chttp2_grpc_status_to_http2_error(grpc_status_code status) { + switch (status) { + case GRPC_STATUS_OK: + return GRPC_CHTTP2_NO_ERROR; + case GRPC_STATUS_CANCELLED: + return GRPC_CHTTP2_CANCEL; + case GRPC_STATUS_RESOURCE_EXHAUSTED: + return GRPC_CHTTP2_ENHANCE_YOUR_CALM; + case GRPC_STATUS_PERMISSION_DENIED: + return GRPC_CHTTP2_INADEQUATE_SECURITY; + case GRPC_STATUS_UNAVAILABLE: + return GRPC_CHTTP2_REFUSED_STREAM; + default: + return GRPC_CHTTP2_INTERNAL_ERROR; + } +} + +grpc_status_code grpc_chttp2_http2_error_to_grpc_status( + grpc_chttp2_error_code error) { + switch (error) { + case GRPC_CHTTP2_NO_ERROR: + /* should never be received */ + return GRPC_STATUS_INTERNAL; + case GRPC_CHTTP2_CANCEL: + return GRPC_STATUS_CANCELLED; + case GRPC_CHTTP2_ENHANCE_YOUR_CALM: + return GRPC_STATUS_RESOURCE_EXHAUSTED; + case GRPC_CHTTP2_INADEQUATE_SECURITY: + return GRPC_STATUS_PERMISSION_DENIED; + case GRPC_CHTTP2_REFUSED_STREAM: + return GRPC_STATUS_UNAVAILABLE; + default: + return GRPC_STATUS_INTERNAL; + } +} + +grpc_status_code grpc_chttp2_http2_status_to_grpc_status(int status) { + switch (status) { + /* these HTTP2 status codes are called out explicitly in status.proto */ + case 200: + return GRPC_STATUS_OK; + case 400: + return GRPC_STATUS_INVALID_ARGUMENT; + case 401: + return GRPC_STATUS_UNAUTHENTICATED; + case 403: + return GRPC_STATUS_PERMISSION_DENIED; + case 404: + return GRPC_STATUS_NOT_FOUND; + case 409: + return GRPC_STATUS_ABORTED; + case 412: + return GRPC_STATUS_FAILED_PRECONDITION; + case 429: + return GRPC_STATUS_RESOURCE_EXHAUSTED; + case 499: + return GRPC_STATUS_CANCELLED; + case 500: + return GRPC_STATUS_UNKNOWN; + case 501: + return GRPC_STATUS_UNIMPLEMENTED; + case 503: + return GRPC_STATUS_UNAVAILABLE; + case 504: + return GRPC_STATUS_DEADLINE_EXCEEDED; + /* everything else is unknown */ + default: + return GRPC_STATUS_UNKNOWN; + } +} + +int grpc_chttp2_grpc_status_to_http2_status(grpc_status_code status) { + return 200; +} diff --git a/src/core/lib/transport/chttp2/status_conversion.h b/src/core/lib/transport/chttp2/status_conversion.h new file mode 100644 index 0000000000..c6e066bb5d --- /dev/null +++ b/src/core/lib/transport/chttp2/status_conversion.h @@ -0,0 +1,50 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_STATUS_CONVERSION_H +#define GRPC_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H + +#include +#include "src/core/transport/chttp2/http2_errors.h" + +/* Conversion of grpc status codes to http2 error codes (for RST_STREAM) */ +grpc_chttp2_error_code grpc_chttp2_grpc_status_to_http2_error( + grpc_status_code status); +grpc_status_code grpc_chttp2_http2_error_to_grpc_status( + grpc_chttp2_error_code error); + +/* Conversion of HTTP status codes (:status) to grpc status codes */ +grpc_status_code grpc_chttp2_http2_status_to_grpc_status(int status); +int grpc_chttp2_grpc_status_to_http2_status(grpc_status_code status); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H */ diff --git a/src/core/lib/transport/chttp2/stream_lists.c b/src/core/lib/transport/chttp2/stream_lists.c new file mode 100644 index 0000000000..60fe735cfc --- /dev/null +++ b/src/core/lib/transport/chttp2/stream_lists.c @@ -0,0 +1,442 @@ +/* + * + * Copyright 2015-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/transport/chttp2/internal.h" + +#include + +#define TRANSPORT_FROM_GLOBAL(tg) \ + ((grpc_chttp2_transport *)((char *)(tg)-offsetof(grpc_chttp2_transport, \ + global))) + +#define STREAM_FROM_GLOBAL(sg) \ + ((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, global))) + +#define TRANSPORT_FROM_WRITING(tw) \ + ((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \ + writing))) + +#define STREAM_FROM_WRITING(sw) \ + ((grpc_chttp2_stream *)((char *)(sw)-offsetof(grpc_chttp2_stream, writing))) + +#define TRANSPORT_FROM_PARSING(tp) \ + ((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \ + parsing))) + +#define STREAM_FROM_PARSING(sp) \ + ((grpc_chttp2_stream *)((char *)(sp)-offsetof(grpc_chttp2_stream, parsing))) + +/* core list management */ + +static int stream_list_empty(grpc_chttp2_transport *t, + grpc_chttp2_stream_list_id id) { + return t->lists[id].head == NULL; +} + +static int stream_list_pop(grpc_chttp2_transport *t, + grpc_chttp2_stream **stream, + grpc_chttp2_stream_list_id id) { + grpc_chttp2_stream *s = t->lists[id].head; + if (s) { + grpc_chttp2_stream *new_head = s->links[id].next; + GPR_ASSERT(s->included[id]); + if (new_head) { + t->lists[id].head = new_head; + new_head->links[id].prev = NULL; + } else { + t->lists[id].head = NULL; + t->lists[id].tail = NULL; + } + s->included[id] = 0; + } + *stream = s; + return s != 0; +} + +static void stream_list_remove(grpc_chttp2_transport *t, grpc_chttp2_stream *s, + grpc_chttp2_stream_list_id id) { + GPR_ASSERT(s->included[id]); + s->included[id] = 0; + if (s->links[id].prev) { + s->links[id].prev->links[id].next = s->links[id].next; + } else { + GPR_ASSERT(t->lists[id].head == s); + t->lists[id].head = s->links[id].next; + } + if (s->links[id].next) { + s->links[id].next->links[id].prev = s->links[id].prev; + } else { + t->lists[id].tail = s->links[id].prev; + } +} + +static bool stream_list_maybe_remove(grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + grpc_chttp2_stream_list_id id) { + if (s->included[id]) { + stream_list_remove(t, s, id); + return true; + } else { + return false; + } +} + +static void stream_list_add_tail(grpc_chttp2_transport *t, + grpc_chttp2_stream *s, + grpc_chttp2_stream_list_id id) { + grpc_chttp2_stream *old_tail; + GPR_ASSERT(!s->included[id]); + old_tail = t->lists[id].tail; + s->links[id].next = NULL; + s->links[id].prev = old_tail; + if (old_tail) { + old_tail->links[id].next = s; + } else { + t->lists[id].head = s; + } + t->lists[id].tail = s; + s->included[id] = 1; +} + +static bool stream_list_add(grpc_chttp2_transport *t, grpc_chttp2_stream *s, + grpc_chttp2_stream_list_id id) { + if (s->included[id]) { + return false; + } + stream_list_add_tail(t, s, id); + return true; +} + +/* wrappers for specializations */ + +bool grpc_chttp2_list_add_writable_stream( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global) { + GPR_ASSERT(stream_global->id != 0); + return stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), + STREAM_FROM_GLOBAL(stream_global), + GRPC_CHTTP2_LIST_WRITABLE); +} + +int grpc_chttp2_list_pop_writable_stream( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_global **stream_global, + grpc_chttp2_stream_writing **stream_writing) { + grpc_chttp2_stream *stream; + int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, + GRPC_CHTTP2_LIST_WRITABLE); + if (r != 0) { + *stream_global = &stream->global; + *stream_writing = &stream->writing; + } + return r; +} + +bool grpc_chttp2_list_remove_writable_stream( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global) { + return stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global), + STREAM_FROM_GLOBAL(stream_global), + GRPC_CHTTP2_LIST_WRITABLE); +} + +void grpc_chttp2_list_add_writing_stream( + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_writing *stream_writing) { + GPR_ASSERT(stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), + STREAM_FROM_WRITING(stream_writing), + GRPC_CHTTP2_LIST_WRITING)); +} + +int grpc_chttp2_list_have_writing_streams( + grpc_chttp2_transport_writing *transport_writing) { + return !stream_list_empty(TRANSPORT_FROM_WRITING(transport_writing), + GRPC_CHTTP2_LIST_WRITING); +} + +int grpc_chttp2_list_pop_writing_stream( + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_writing **stream_writing) { + grpc_chttp2_stream *stream; + int r = stream_list_pop(TRANSPORT_FROM_WRITING(transport_writing), &stream, + GRPC_CHTTP2_LIST_WRITING); + if (r != 0) { + *stream_writing = &stream->writing; + } + return r; +} + +void grpc_chttp2_list_add_written_stream( + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_writing *stream_writing) { + stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), + STREAM_FROM_WRITING(stream_writing), + GRPC_CHTTP2_LIST_WRITTEN); +} + +int grpc_chttp2_list_pop_written_stream( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_global **stream_global, + grpc_chttp2_stream_writing **stream_writing) { + grpc_chttp2_stream *stream; + int r = stream_list_pop(TRANSPORT_FROM_WRITING(transport_writing), &stream, + GRPC_CHTTP2_LIST_WRITTEN); + if (r != 0) { + *stream_global = &stream->global; + *stream_writing = &stream->writing; + } + return r; +} + +void grpc_chttp2_list_add_unannounced_incoming_window_available( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global) { + GPR_ASSERT(stream_global->id != 0); + stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), + STREAM_FROM_GLOBAL(stream_global), + GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE); +} + +void grpc_chttp2_list_remove_unannounced_incoming_window_available( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global) { + stream_list_maybe_remove( + TRANSPORT_FROM_GLOBAL(transport_global), + STREAM_FROM_GLOBAL(stream_global), + GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE); +} + +int grpc_chttp2_list_pop_unannounced_incoming_window_available( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_global **stream_global, + grpc_chttp2_stream_parsing **stream_parsing) { + grpc_chttp2_stream *stream; + int r = + stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, + GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE); + if (r != 0) { + *stream_global = &stream->global; + *stream_parsing = &stream->parsing; + } + return r; +} + +void grpc_chttp2_list_add_parsing_seen_stream( + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing) { + stream_list_add(TRANSPORT_FROM_PARSING(transport_parsing), + STREAM_FROM_PARSING(stream_parsing), + GRPC_CHTTP2_LIST_PARSING_SEEN); +} + +int grpc_chttp2_list_pop_parsing_seen_stream( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_global **stream_global, + grpc_chttp2_stream_parsing **stream_parsing) { + grpc_chttp2_stream *stream; + int r = stream_list_pop(TRANSPORT_FROM_PARSING(transport_parsing), &stream, + GRPC_CHTTP2_LIST_PARSING_SEEN); + if (r != 0) { + *stream_global = &stream->global; + *stream_parsing = &stream->parsing; + } + return r; +} + +void grpc_chttp2_list_add_waiting_for_concurrency( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global) { + stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), + STREAM_FROM_GLOBAL(stream_global), + GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY); +} + +int grpc_chttp2_list_pop_waiting_for_concurrency( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global **stream_global) { + grpc_chttp2_stream *stream; + int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, + GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY); + if (r != 0) { + *stream_global = &stream->global; + } + return r; +} + +void grpc_chttp2_list_add_check_read_ops( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global) { + stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), + STREAM_FROM_GLOBAL(stream_global), + GRPC_CHTTP2_LIST_CHECK_READ_OPS); +} + +int grpc_chttp2_list_pop_check_read_ops( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global **stream_global) { + grpc_chttp2_stream *stream; + int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, + GRPC_CHTTP2_LIST_CHECK_READ_OPS); + if (r != 0) { + *stream_global = &stream->global; + } + return r; +} + +void grpc_chttp2_list_add_writing_stalled_by_transport( + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_writing *stream_writing) { + grpc_chttp2_stream *stream = STREAM_FROM_WRITING(stream_writing); + if (!stream->included[GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT]) { + GRPC_CHTTP2_STREAM_REF(&stream->global, "chttp2_writing_stalled"); + } + stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), stream, + GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT); +} + +void grpc_chttp2_list_flush_writing_stalled_by_transport( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, + bool is_window_available) { + grpc_chttp2_stream *stream; + grpc_chttp2_transport *transport = TRANSPORT_FROM_WRITING(transport_writing); + while (stream_list_pop(transport, &stream, + GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT)) { + if (is_window_available) { + grpc_chttp2_become_writable(&transport->global, &stream->global); + } else { + grpc_chttp2_list_add_stalled_by_transport(transport_writing, + &stream->writing); + } + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &stream->global, + "chttp2_writing_stalled"); + } +} + +void grpc_chttp2_list_add_stalled_by_transport( + grpc_chttp2_transport_writing *transport_writing, + grpc_chttp2_stream_writing *stream_writing) { + stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), + STREAM_FROM_WRITING(stream_writing), + GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); +} + +int grpc_chttp2_list_pop_stalled_by_transport( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global **stream_global) { + grpc_chttp2_stream *stream; + int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, + GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); + if (r != 0) { + *stream_global = &stream->global; + } + return r; +} + +void grpc_chttp2_list_remove_stalled_by_transport( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global) { + stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global), + STREAM_FROM_GLOBAL(stream_global), + GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); +} + +void grpc_chttp2_list_add_closed_waiting_for_parsing( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global) { + stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), + STREAM_FROM_GLOBAL(stream_global), + GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING); +} + +int grpc_chttp2_list_pop_closed_waiting_for_parsing( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global **stream_global) { + grpc_chttp2_stream *stream; + int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, + GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING); + if (r != 0) { + *stream_global = &stream->global; + } + return r; +} + +void grpc_chttp2_list_add_closed_waiting_for_writing( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global) { + stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), + STREAM_FROM_GLOBAL(stream_global), + GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING); +} + +int grpc_chttp2_list_pop_closed_waiting_for_writing( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global **stream_global) { + grpc_chttp2_stream *stream; + int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, + GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING); + if (r != 0) { + *stream_global = &stream->global; + } + return r; +} + +void grpc_chttp2_register_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + stream_list_add_tail(t, s, GRPC_CHTTP2_LIST_ALL_STREAMS); +} + +int grpc_chttp2_unregister_stream(grpc_chttp2_transport *t, + grpc_chttp2_stream *s) { + stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_ALL_STREAMS); + return stream_list_empty(t, GRPC_CHTTP2_LIST_ALL_STREAMS); +} + +int grpc_chttp2_has_streams(grpc_chttp2_transport *t) { + return !stream_list_empty(t, GRPC_CHTTP2_LIST_ALL_STREAMS); +} + +void grpc_chttp2_for_all_streams( + grpc_chttp2_transport_global *transport_global, void *user_data, + void (*cb)(grpc_chttp2_transport_global *transport_global, void *user_data, + grpc_chttp2_stream_global *stream_global)) { + grpc_chttp2_stream *s; + grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); + for (s = t->lists[GRPC_CHTTP2_LIST_ALL_STREAMS].head; s != NULL; + s = s->links[GRPC_CHTTP2_LIST_ALL_STREAMS].next) { + cb(transport_global, user_data, &s->global); + } +} diff --git a/src/core/lib/transport/chttp2/stream_map.c b/src/core/lib/transport/chttp2/stream_map.c new file mode 100644 index 0000000000..555a16fb72 --- /dev/null +++ b/src/core/lib/transport/chttp2/stream_map.c @@ -0,0 +1,197 @@ +/* + * + * Copyright 2015, 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/transport/chttp2/stream_map.h" + +#include + +#include +#include +#include + +void grpc_chttp2_stream_map_init(grpc_chttp2_stream_map *map, + size_t initial_capacity) { + GPR_ASSERT(initial_capacity > 1); + map->keys = gpr_malloc(sizeof(uint32_t) * initial_capacity); + map->values = gpr_malloc(sizeof(void *) * initial_capacity); + map->count = 0; + map->free = 0; + map->capacity = initial_capacity; +} + +void grpc_chttp2_stream_map_destroy(grpc_chttp2_stream_map *map) { + gpr_free(map->keys); + gpr_free(map->values); +} + +static size_t compact(uint32_t *keys, void **values, size_t count) { + size_t i, out; + + for (i = 0, out = 0; i < count; i++) { + if (values[i]) { + keys[out] = keys[i]; + values[out] = values[i]; + out++; + } + } + + return out; +} + +void grpc_chttp2_stream_map_add(grpc_chttp2_stream_map *map, uint32_t key, + void *value) { + size_t count = map->count; + size_t capacity = map->capacity; + uint32_t *keys = map->keys; + void **values = map->values; + + GPR_ASSERT(count == 0 || keys[count - 1] < key); + GPR_ASSERT(value); + + if (count == capacity) { + if (map->free > capacity / 4) { + count = compact(keys, values, count); + map->free = 0; + } else { + /* resize when less than 25% of the table is free, because compaction + won't help much */ + map->capacity = capacity = 3 * capacity / 2; + map->keys = keys = gpr_realloc(keys, capacity * sizeof(uint32_t)); + map->values = values = gpr_realloc(values, capacity * sizeof(void *)); + } + } + + keys[count] = key; + values[count] = value; + map->count = count + 1; +} + +void grpc_chttp2_stream_map_move_into(grpc_chttp2_stream_map *src, + grpc_chttp2_stream_map *dst) { + /* if src is empty we dont need to do anything */ + if (src->count == src->free) { + return; + } + /* if dst is empty we simply need to swap */ + if (dst->count == dst->free) { + GPR_SWAP(grpc_chttp2_stream_map, *src, *dst); + return; + } + /* the first element of src must be greater than the last of dst... + * however the maps may need compacting for this property to hold */ + if (src->keys[0] <= dst->keys[dst->count - 1]) { + src->count = compact(src->keys, src->values, src->count); + src->free = 0; + dst->count = compact(dst->keys, dst->values, dst->count); + dst->free = 0; + } + GPR_ASSERT(src->keys[0] > dst->keys[dst->count - 1]); + /* if dst doesn't have capacity, resize */ + if (dst->count + src->count > dst->capacity) { + dst->capacity = GPR_MAX(dst->capacity * 3 / 2, dst->count + src->count); + dst->keys = gpr_realloc(dst->keys, dst->capacity * sizeof(uint32_t)); + dst->values = gpr_realloc(dst->values, dst->capacity * sizeof(void *)); + } + memcpy(dst->keys + dst->count, src->keys, src->count * sizeof(uint32_t)); + memcpy(dst->values + dst->count, src->values, src->count * sizeof(void *)); + dst->count += src->count; + dst->free += src->free; + src->count = 0; + src->free = 0; +} + +static void **find(grpc_chttp2_stream_map *map, uint32_t key) { + size_t min_idx = 0; + size_t max_idx = map->count; + size_t mid_idx; + uint32_t *keys = map->keys; + void **values = map->values; + uint32_t mid_key; + + if (max_idx == 0) return NULL; + + while (min_idx < max_idx) { + /* find the midpoint, avoiding overflow */ + mid_idx = min_idx + ((max_idx - min_idx) / 2); + mid_key = keys[mid_idx]; + + if (mid_key < key) { + min_idx = mid_idx + 1; + } else if (mid_key > key) { + max_idx = mid_idx; + } else /* mid_key == key */ + { + return &values[mid_idx]; + } + } + + return NULL; +} + +void *grpc_chttp2_stream_map_delete(grpc_chttp2_stream_map *map, uint32_t key) { + void **pvalue = find(map, key); + void *out = NULL; + if (pvalue != NULL) { + out = *pvalue; + *pvalue = NULL; + map->free += (out != NULL); + /* recognize complete emptyness and ensure we can skip + * defragmentation later */ + if (map->free == map->count) { + map->free = map->count = 0; + } + } + return out; +} + +void *grpc_chttp2_stream_map_find(grpc_chttp2_stream_map *map, uint32_t key) { + void **pvalue = find(map, key); + return pvalue != NULL ? *pvalue : NULL; +} + +size_t grpc_chttp2_stream_map_size(grpc_chttp2_stream_map *map) { + return map->count - map->free; +} + +void grpc_chttp2_stream_map_for_each(grpc_chttp2_stream_map *map, + void (*f)(void *user_data, uint32_t key, + void *value), + void *user_data) { + size_t i; + + for (i = 0; i < map->count; i++) { + if (map->values[i]) { + f(user_data, map->keys[i], map->values[i]); + } + } +} diff --git a/src/core/lib/transport/chttp2/stream_map.h b/src/core/lib/transport/chttp2/stream_map.h new file mode 100644 index 0000000000..957a58a4f2 --- /dev/null +++ b/src/core/lib/transport/chttp2/stream_map.h @@ -0,0 +1,84 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_STREAM_MAP_H +#define GRPC_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H + +#include + +#include + +/* Data structure to map a uint32_t to a data object (represented by a void*) + + Represented as a sorted array of keys, and a corresponding array of values. + Lookups are performed with binary search. + Adds are restricted to strictly higher keys than previously seen (this is + guaranteed by http2). */ +typedef struct { + uint32_t *keys; + void **values; + size_t count; + size_t free; + size_t capacity; +} grpc_chttp2_stream_map; + +void grpc_chttp2_stream_map_init(grpc_chttp2_stream_map *map, + size_t initial_capacity); +void grpc_chttp2_stream_map_destroy(grpc_chttp2_stream_map *map); + +/* Add a new key: given http2 semantics, new keys must always be greater than + existing keys - this is asserted */ +void grpc_chttp2_stream_map_add(grpc_chttp2_stream_map *map, uint32_t key, + void *value); + +/* Delete an existing key - returns the previous value of the key if it existed, + or NULL otherwise */ +void *grpc_chttp2_stream_map_delete(grpc_chttp2_stream_map *map, uint32_t key); + +/* Move all elements of src into dst */ +void grpc_chttp2_stream_map_move_into(grpc_chttp2_stream_map *src, + grpc_chttp2_stream_map *dst); + +/* Return an existing key, or NULL if it does not exist */ +void *grpc_chttp2_stream_map_find(grpc_chttp2_stream_map *map, uint32_t key); + +/* How many (populated) entries are in the stream map? */ +size_t grpc_chttp2_stream_map_size(grpc_chttp2_stream_map *map); + +/* Callback on each stream */ +void grpc_chttp2_stream_map_for_each(grpc_chttp2_stream_map *map, + void (*f)(void *user_data, uint32_t key, + void *value), + void *user_data); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H */ diff --git a/src/core/lib/transport/chttp2/timeout_encoding.c b/src/core/lib/transport/chttp2/timeout_encoding.c new file mode 100644 index 0000000000..c4802e050e --- /dev/null +++ b/src/core/lib/transport/chttp2/timeout_encoding.c @@ -0,0 +1,188 @@ +/* + * + * Copyright 2015-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/transport/chttp2/timeout_encoding.h" + +#include +#include + +#include +#include "src/core/support/string.h" + +static int64_t round_up(int64_t x, int64_t divisor) { + return (x / divisor + (x % divisor != 0)) * divisor; +} + +/* round an integer up to the next value with three significant figures */ +static int64_t round_up_to_three_sig_figs(int64_t x) { + if (x < 1000) return x; + if (x < 10000) return round_up(x, 10); + if (x < 100000) return round_up(x, 100); + if (x < 1000000) return round_up(x, 1000); + if (x < 10000000) return round_up(x, 10000); + if (x < 100000000) return round_up(x, 100000); + if (x < 1000000000) return round_up(x, 1000000); + return round_up(x, 10000000); +} + +/* encode our minimum viable timeout value */ +static void enc_tiny(char *buffer) { memcpy(buffer, "1n", 3); } + +static void enc_ext(char *buffer, int64_t value, char ext) { + int n = int64_ttoa(value, buffer); + buffer[n] = ext; + buffer[n + 1] = 0; +} + +static void enc_seconds(char *buffer, int64_t sec) { + if (sec % 3600 == 0) { + enc_ext(buffer, sec / 3600, 'H'); + } else if (sec % 60 == 0) { + enc_ext(buffer, sec / 60, 'M'); + } else { + enc_ext(buffer, sec, 'S'); + } +} + +static void enc_nanos(char *buffer, int64_t x) { + x = round_up_to_three_sig_figs(x); + if (x < 100000) { + if (x % 1000 == 0) { + enc_ext(buffer, x / 1000, 'u'); + } else { + enc_ext(buffer, x, 'n'); + } + } else if (x < 100000000) { + if (x % 1000000 == 0) { + enc_ext(buffer, x / 1000000, 'm'); + } else { + enc_ext(buffer, x / 1000, 'u'); + } + } else if (x < 1000000000) { + enc_ext(buffer, x / 1000000, 'm'); + } else { + /* note that this is only ever called with times of less than one second, + so if we reach here the time must have been rounded up to a whole second + (and no more) */ + memcpy(buffer, "1S", 3); + } +} + +static void enc_micros(char *buffer, int64_t x) { + x = round_up_to_three_sig_figs(x); + if (x < 100000) { + if (x % 1000 == 0) { + enc_ext(buffer, x / 1000, 'm'); + } else { + enc_ext(buffer, x, 'u'); + } + } else if (x < 100000000) { + if (x % 1000000 == 0) { + enc_ext(buffer, x / 1000000, 'S'); + } else { + enc_ext(buffer, x / 1000, 'm'); + } + } else { + enc_ext(buffer, x / 1000000, 'S'); + } +} + +void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer) { + if (timeout.tv_sec < 0) { + enc_tiny(buffer); + } else if (timeout.tv_sec == 0) { + enc_nanos(buffer, timeout.tv_nsec); + } else if (timeout.tv_sec < 1000 && timeout.tv_nsec != 0) { + enc_micros(buffer, + (int64_t)(timeout.tv_sec * 1000000) + + (timeout.tv_nsec / 1000 + (timeout.tv_nsec % 1000 != 0))); + } else { + enc_seconds(buffer, timeout.tv_sec + (timeout.tv_nsec != 0)); + } +} + +static int is_all_whitespace(const char *p) { + while (*p == ' ') p++; + return *p == 0; +} + +int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout) { + int32_t x = 0; + const uint8_t *p = (const uint8_t *)buffer; + int have_digit = 0; + /* skip whitespace */ + for (; *p == ' '; p++) + ; + /* decode numeric part */ + for (; *p >= '0' && *p <= '9'; p++) { + int32_t digit = (int32_t)(*p - (uint8_t)'0'); + have_digit = 1; + /* spec allows max. 8 digits, but we allow values up to 1,000,000,000 */ + if (x >= (100 * 1000 * 1000)) { + if (x != (100 * 1000 * 1000) || digit != 0) { + *timeout = gpr_inf_future(GPR_TIMESPAN); + return 1; + } + } + x = x * 10 + digit; + } + if (!have_digit) return 0; + /* skip whitespace */ + for (; *p == ' '; p++) + ; + /* decode unit specifier */ + switch (*p) { + case 'n': + *timeout = gpr_time_from_nanos(x, GPR_TIMESPAN); + break; + case 'u': + *timeout = gpr_time_from_micros(x, GPR_TIMESPAN); + break; + case 'm': + *timeout = gpr_time_from_millis(x, GPR_TIMESPAN); + break; + case 'S': + *timeout = gpr_time_from_seconds(x, GPR_TIMESPAN); + break; + case 'M': + *timeout = gpr_time_from_minutes(x, GPR_TIMESPAN); + break; + case 'H': + *timeout = gpr_time_from_hours(x, GPR_TIMESPAN); + break; + default: + return 0; + } + p++; + return is_all_whitespace((const char *)p); +} diff --git a/src/core/lib/transport/chttp2/timeout_encoding.h b/src/core/lib/transport/chttp2/timeout_encoding.h new file mode 100644 index 0000000000..f8e25226eb --- /dev/null +++ b/src/core/lib/transport/chttp2/timeout_encoding.h @@ -0,0 +1,47 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H +#define GRPC_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H + +#include +#include "src/core/support/string.h" + +#define GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1) + +/* Encode/decode timeouts to the GRPC over HTTP2 format; + encoding may round up arbitrarily */ +void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer); +int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H */ diff --git a/src/core/lib/transport/chttp2/varint.c b/src/core/lib/transport/chttp2/varint.c new file mode 100644 index 0000000000..1cc235e989 --- /dev/null +++ b/src/core/lib/transport/chttp2/varint.c @@ -0,0 +1,65 @@ +/* + * + * Copyright 2015, 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/transport/chttp2/varint.h" + +uint32_t grpc_chttp2_hpack_varint_length(uint32_t tail_value) { + if (tail_value < (1 << 7)) { + return 2; + } else if (tail_value < (1 << 14)) { + return 3; + } else if (tail_value < (1 << 21)) { + return 4; + } else if (tail_value < (1 << 28)) { + return 5; + } else { + return 6; + } +} + +void grpc_chttp2_hpack_write_varint_tail(uint32_t tail_value, uint8_t* target, + uint32_t tail_length) { + switch (tail_length) { + case 5: + target[4] = (uint8_t)((tail_value >> 28) | 0x80); + case 4: + target[3] = (uint8_t)((tail_value >> 21) | 0x80); + case 3: + target[2] = (uint8_t)((tail_value >> 14) | 0x80); + case 2: + target[1] = (uint8_t)((tail_value >> 7) | 0x80); + case 1: + target[0] = (uint8_t)((tail_value) | 0x80); + } + target[tail_length - 1] &= 0x7f; +} diff --git a/src/core/lib/transport/chttp2/varint.h b/src/core/lib/transport/chttp2/varint.h new file mode 100644 index 0000000000..7ab9d22ab5 --- /dev/null +++ b/src/core/lib/transport/chttp2/varint.h @@ -0,0 +1,75 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_VARINT_H +#define GRPC_CORE_TRANSPORT_CHTTP2_VARINT_H + +#include + +/* Helpers for hpack varint encoding */ + +/* length of a value that needs varint tail encoding (it's bigger than can be + bitpacked into the opcode byte) - returned value includes the length of the + opcode byte */ +uint32_t grpc_chttp2_hpack_varint_length(uint32_t tail_value); + +void grpc_chttp2_hpack_write_varint_tail(uint32_t tail_value, uint8_t* target, + uint32_t tail_length); + +/* maximum value that can be bitpacked with the opcode if the opcode has a + prefix + of length prefix_bits */ +#define GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits) \ + ((uint32_t)((1 << (8 - (prefix_bits))) - 1)) + +/* length required to bitpack a value */ +#define GRPC_CHTTP2_VARINT_LENGTH(n, prefix_bits) \ + ((n) < GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits) \ + ? 1u \ + : grpc_chttp2_hpack_varint_length( \ + (n)-GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits))) + +#define GRPC_CHTTP2_WRITE_VARINT(n, prefix_bits, prefix_or, target, length) \ + do { \ + uint8_t* tgt = target; \ + if ((length) == 1u) { \ + (tgt)[0] = (uint8_t)((prefix_or) | (n)); \ + } else { \ + (tgt)[0] = \ + (prefix_or) | (uint8_t)GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits); \ + grpc_chttp2_hpack_write_varint_tail( \ + (n)-GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits), (tgt) + 1, (length)-1); \ + } \ + } while (0) + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_VARINT_H */ diff --git a/src/core/lib/transport/chttp2/writing.c b/src/core/lib/transport/chttp2/writing.c new file mode 100644 index 0000000000..107725cbc7 --- /dev/null +++ b/src/core/lib/transport/chttp2/writing.c @@ -0,0 +1,350 @@ +/* + * + * Copyright 2015-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/transport/chttp2/internal.h" + +#include + +#include + +#include "src/core/profiling/timers.h" +#include "src/core/transport/chttp2/http2_errors.h" + +static void finalize_outbuf(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_writing *transport_writing); + +int grpc_chttp2_unlocking_check_writes( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_writing *transport_writing, int is_parsing) { + grpc_chttp2_stream_global *stream_global; + grpc_chttp2_stream_writing *stream_writing; + + GPR_TIMER_BEGIN("grpc_chttp2_unlocking_check_writes", 0); + + /* simple writes are queued to qbuf, and flushed here */ + gpr_slice_buffer_swap(&transport_global->qbuf, &transport_writing->outbuf); + GPR_ASSERT(transport_global->qbuf.count == 0); + + grpc_chttp2_hpack_compressor_set_max_table_size( + &transport_writing->hpack_compressor, + transport_global->settings[GRPC_PEER_SETTINGS] + [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); + + if (transport_global->dirtied_local_settings && + !transport_global->sent_local_settings && !is_parsing) { + gpr_slice_buffer_add( + &transport_writing->outbuf, + grpc_chttp2_settings_create( + transport_global->settings[GRPC_SENT_SETTINGS], + transport_global->settings[GRPC_LOCAL_SETTINGS], + transport_global->force_send_settings, GRPC_CHTTP2_NUM_SETTINGS)); + transport_global->force_send_settings = 0; + transport_global->dirtied_local_settings = 0; + transport_global->sent_local_settings = 1; + } + + GRPC_CHTTP2_FLOW_MOVE_TRANSPORT("write", transport_writing, outgoing_window, + transport_global, outgoing_window); + bool is_window_available = transport_writing->outgoing_window > 0; + grpc_chttp2_list_flush_writing_stalled_by_transport( + exec_ctx, transport_writing, is_window_available); + + /* for each grpc_chttp2_stream that's become writable, frame it's data + (according to available window sizes) and add to the output buffer */ + while (grpc_chttp2_list_pop_writable_stream( + transport_global, transport_writing, &stream_global, &stream_writing)) { + bool sent_initial_metadata = stream_writing->sent_initial_metadata; + bool become_writable = false; + + stream_writing->id = stream_global->id; + stream_writing->read_closed = stream_global->read_closed; + + GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_writing, stream_writing, + outgoing_window, stream_global, + outgoing_window); + + if (!sent_initial_metadata && stream_global->send_initial_metadata) { + stream_writing->send_initial_metadata = + stream_global->send_initial_metadata; + stream_global->send_initial_metadata = NULL; + become_writable = true; + sent_initial_metadata = true; + } + if (sent_initial_metadata) { + if (stream_global->send_message != NULL) { + gpr_slice hdr = gpr_slice_malloc(5); + uint8_t *p = GPR_SLICE_START_PTR(hdr); + uint32_t len = stream_global->send_message->length; + GPR_ASSERT(stream_writing->send_message == NULL); + p[0] = (stream_global->send_message->flags & + GRPC_WRITE_INTERNAL_COMPRESS) != 0; + p[1] = (uint8_t)(len >> 24); + p[2] = (uint8_t)(len >> 16); + p[3] = (uint8_t)(len >> 8); + p[4] = (uint8_t)(len); + gpr_slice_buffer_add(&stream_writing->flow_controlled_buffer, hdr); + if (stream_global->send_message->length > 0) { + stream_writing->send_message = stream_global->send_message; + } else { + stream_writing->send_message = NULL; + } + stream_writing->stream_fetched = 0; + stream_global->send_message = NULL; + } + if ((stream_writing->send_message != NULL || + stream_writing->flow_controlled_buffer.length > 0) && + stream_writing->outgoing_window > 0) { + if (transport_writing->outgoing_window > 0) { + become_writable = true; + } else { + grpc_chttp2_list_add_stalled_by_transport(transport_writing, + stream_writing); + } + } + if (stream_global->send_trailing_metadata) { + stream_writing->send_trailing_metadata = + stream_global->send_trailing_metadata; + stream_global->send_trailing_metadata = NULL; + become_writable = true; + } + } + + if (!stream_global->read_closed && + stream_global->unannounced_incoming_window_for_writing > 1024) { + GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_global, stream_writing, + announce_window, stream_global, + unannounced_incoming_window_for_writing); + become_writable = true; + } + + if (become_writable) { + grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing); + } else { + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); + } + } + + /* if the grpc_chttp2_transport is ready to send a window update, do so here + also; 3/4 is a magic number that will likely get tuned soon */ + if (transport_global->announce_incoming_window > 0) { + uint32_t announced = (uint32_t)GPR_MIN( + transport_global->announce_incoming_window, UINT32_MAX); + GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_global, + announce_incoming_window, announced); + gpr_slice_buffer_add(&transport_writing->outbuf, + grpc_chttp2_window_update_create(0, announced)); + } + + GPR_TIMER_END("grpc_chttp2_unlocking_check_writes", 0); + + return transport_writing->outbuf.count > 0 || + grpc_chttp2_list_have_writing_streams(transport_writing); +} + +void grpc_chttp2_perform_writes( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, + grpc_endpoint *endpoint) { + GPR_ASSERT(transport_writing->outbuf.count > 0 || + grpc_chttp2_list_have_writing_streams(transport_writing)); + + finalize_outbuf(exec_ctx, transport_writing); + + GPR_ASSERT(endpoint); + + if (transport_writing->outbuf.count > 0) { + grpc_endpoint_write(exec_ctx, endpoint, &transport_writing->outbuf, + &transport_writing->done_cb); + } else { + grpc_exec_ctx_enqueue(exec_ctx, &transport_writing->done_cb, true, NULL); + } +} + +static void finalize_outbuf(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_writing *transport_writing) { + grpc_chttp2_stream_writing *stream_writing; + + GPR_TIMER_BEGIN("finalize_outbuf", 0); + + while ( + grpc_chttp2_list_pop_writing_stream(transport_writing, &stream_writing)) { + uint32_t max_outgoing = + (uint32_t)GPR_MIN(GRPC_CHTTP2_MAX_PAYLOAD_LENGTH, + GPR_MIN(stream_writing->outgoing_window, + transport_writing->outgoing_window)); + /* send initial metadata if it's available */ + if (stream_writing->send_initial_metadata != NULL) { + grpc_chttp2_encode_header( + &transport_writing->hpack_compressor, stream_writing->id, + stream_writing->send_initial_metadata, 0, &transport_writing->outbuf); + stream_writing->send_initial_metadata = NULL; + stream_writing->sent_initial_metadata = 1; + } + /* send any window updates */ + if (stream_writing->announce_window > 0 && + stream_writing->send_initial_metadata == NULL) { + uint32_t announce = stream_writing->announce_window; + gpr_slice_buffer_add( + &transport_writing->outbuf, + grpc_chttp2_window_update_create(stream_writing->id, + stream_writing->announce_window)); + GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing, stream_writing, + announce_window, announce); + stream_writing->announce_window = 0; + } + /* fetch any body bytes */ + while (!stream_writing->fetching && stream_writing->send_message && + stream_writing->flow_controlled_buffer.length < max_outgoing && + stream_writing->stream_fetched < + stream_writing->send_message->length) { + if (grpc_byte_stream_next(exec_ctx, stream_writing->send_message, + &stream_writing->fetching_slice, max_outgoing, + &stream_writing->finished_fetch)) { + stream_writing->stream_fetched += + GPR_SLICE_LENGTH(stream_writing->fetching_slice); + if (stream_writing->stream_fetched == + stream_writing->send_message->length) { + stream_writing->send_message = NULL; + } + gpr_slice_buffer_add(&stream_writing->flow_controlled_buffer, + stream_writing->fetching_slice); + } else { + stream_writing->fetching = 1; + } + } + /* send any body bytes */ + if (stream_writing->flow_controlled_buffer.length > 0) { + if (max_outgoing > 0) { + uint32_t send_bytes = (uint32_t)GPR_MIN( + max_outgoing, stream_writing->flow_controlled_buffer.length); + int is_last_data_frame = + stream_writing->send_message == NULL && + send_bytes == stream_writing->flow_controlled_buffer.length; + int is_last_frame = is_last_data_frame && + stream_writing->send_trailing_metadata != NULL && + grpc_metadata_batch_is_empty( + stream_writing->send_trailing_metadata); + grpc_chttp2_encode_data( + stream_writing->id, &stream_writing->flow_controlled_buffer, + send_bytes, is_last_frame, &transport_writing->outbuf); + GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing, + stream_writing, outgoing_window, + send_bytes); + GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_writing, + outgoing_window, send_bytes); + if (is_last_frame) { + stream_writing->send_trailing_metadata = NULL; + stream_writing->sent_trailing_metadata = 1; + } + if (is_last_data_frame) { + GPR_ASSERT(stream_writing->send_message == NULL); + stream_writing->sent_message = 1; + } + } else if (transport_writing->outgoing_window == 0) { + grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, + stream_writing); + grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); + } + } + /* send trailing metadata if it's available and we're ready for it */ + if (stream_writing->send_message == NULL && + stream_writing->flow_controlled_buffer.length == 0 && + stream_writing->send_trailing_metadata != NULL) { + if (grpc_metadata_batch_is_empty( + stream_writing->send_trailing_metadata)) { + grpc_chttp2_encode_data(stream_writing->id, + &stream_writing->flow_controlled_buffer, 0, 1, + &transport_writing->outbuf); + } else { + grpc_chttp2_encode_header(&transport_writing->hpack_compressor, + stream_writing->id, + stream_writing->send_trailing_metadata, 1, + &transport_writing->outbuf); + } + if (!transport_writing->is_client && !stream_writing->read_closed) { + gpr_slice_buffer_add(&transport_writing->outbuf, + grpc_chttp2_rst_stream_create( + stream_writing->id, GRPC_CHTTP2_NO_ERROR)); + } + stream_writing->send_trailing_metadata = NULL; + stream_writing->sent_trailing_metadata = 1; + } + /* if there's more to write, then loop, otherwise prepare to finish the + * write */ + if ((stream_writing->flow_controlled_buffer.length > 0 || + (stream_writing->send_message && !stream_writing->fetching)) && + stream_writing->outgoing_window > 0) { + if (transport_writing->outgoing_window > 0) { + grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing); + } else { + grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, + stream_writing); + grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); + } + } else { + grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); + } + } + + GPR_TIMER_END("finalize_outbuf", 0); +} + +void grpc_chttp2_cleanup_writing( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_chttp2_transport_writing *transport_writing) { + grpc_chttp2_stream_writing *stream_writing; + grpc_chttp2_stream_global *stream_global; + + while (grpc_chttp2_list_pop_written_stream( + transport_global, transport_writing, &stream_global, &stream_writing)) { + if (stream_writing->sent_initial_metadata) { + grpc_chttp2_complete_closure_step( + exec_ctx, &stream_global->send_initial_metadata_finished, 1); + } + if (stream_writing->sent_message) { + GPR_ASSERT(stream_writing->send_message == NULL); + grpc_chttp2_complete_closure_step( + exec_ctx, &stream_global->send_message_finished, 1); + stream_writing->sent_message = 0; + } + if (stream_writing->sent_trailing_metadata) { + grpc_chttp2_complete_closure_step( + exec_ctx, &stream_global->send_trailing_metadata_finished, 1); + } + if (stream_writing->sent_trailing_metadata) { + grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, + !transport_global->is_client, 1); + } + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); + } + gpr_slice_buffer_reset_and_unref(&transport_writing->outbuf); +} diff --git a/src/core/lib/transport/chttp2_transport.c b/src/core/lib/transport/chttp2_transport.c new file mode 100644 index 0000000000..b45bf31997 --- /dev/null +++ b/src/core/lib/transport/chttp2_transport.c @@ -0,0 +1,1785 @@ +/* + * + * Copyright 2015-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/transport/chttp2_transport.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "src/core/profiling/timers.h" +#include "src/core/support/string.h" +#include "src/core/transport/chttp2/http2_errors.h" +#include "src/core/transport/chttp2/internal.h" +#include "src/core/transport/chttp2/status_conversion.h" +#include "src/core/transport/chttp2/timeout_encoding.h" +#include "src/core/transport/static_metadata.h" +#include "src/core/transport/transport_impl.h" + +#define DEFAULT_WINDOW 65535 +#define DEFAULT_CONNECTION_WINDOW_TARGET (1024 * 1024) +#define MAX_WINDOW 0x7fffffffu + +#define MAX_CLIENT_STREAM_ID 0x7fffffffu + +int grpc_http_trace = 0; +int grpc_flowctl_trace = 0; + +#define TRANSPORT_FROM_WRITING(tw) \ + ((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \ + writing))) + +#define TRANSPORT_FROM_PARSING(tw) \ + ((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \ + parsing))) + +#define TRANSPORT_FROM_GLOBAL(tg) \ + ((grpc_chttp2_transport *)((char *)(tg)-offsetof(grpc_chttp2_transport, \ + global))) + +#define STREAM_FROM_GLOBAL(sg) \ + ((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, global))) + +#define STREAM_FROM_PARSING(sg) \ + ((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, parsing))) + +static const grpc_transport_vtable vtable; + +static void lock(grpc_chttp2_transport *t); +static void unlock(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); + +/* forward declarations of various callbacks that we'll build closures around */ +static void writing_action(grpc_exec_ctx *exec_ctx, void *t, + bool iomgr_success_ignored); + +/** Set a transport level setting, and push it to our peer */ +static void push_setting(grpc_chttp2_transport *t, grpc_chttp2_setting_id id, + uint32_t value); + +/** Endpoint callback to process incoming data */ +static void recv_data(grpc_exec_ctx *exec_ctx, void *tp, bool success); + +/** Start disconnection chain */ +static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); + +/** Perform a transport_op */ +static void perform_stream_op_locked( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, grpc_transport_stream_op *op); + +/** Cancel a stream: coming from the transport API */ +static void cancel_from_api(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, + grpc_status_code status); + +static void close_from_api(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, + grpc_status_code status, + gpr_slice *optional_message); + +/** Add endpoint from this transport to pollset */ +static void add_to_pollset_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_pollset *pollset); +static void add_to_pollset_set_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_pollset_set *pollset_set); + +/** Start new streams that have been created if we can */ +static void maybe_start_some_streams( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); + +static void connectivity_state_set( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_connectivity_state state, const char *reason); + +static void check_read_ops(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global); + +static void incoming_byte_stream_update_flow_control( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, size_t max_size_hint, + size_t have_already); + +static void fail_pending_writes(grpc_exec_ctx *exec_ctx, + grpc_chttp2_stream_global *stream_global); + +/******************************************************************************* + * CONSTRUCTION/DESTRUCTION/REFCOUNTING + */ + +static void destruct_transport(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + size_t i; + + gpr_mu_lock(&t->mu); + + GPR_ASSERT(t->ep == NULL); + + gpr_slice_buffer_destroy(&t->global.qbuf); + + gpr_slice_buffer_destroy(&t->writing.outbuf); + grpc_chttp2_hpack_compressor_destroy(&t->writing.hpack_compressor); + + gpr_slice_buffer_destroy(&t->parsing.qbuf); + gpr_slice_buffer_destroy(&t->read_buffer); + grpc_chttp2_hpack_parser_destroy(&t->parsing.hpack_parser); + grpc_chttp2_goaway_parser_destroy(&t->parsing.goaway_parser); + + for (i = 0; i < STREAM_LIST_COUNT; i++) { + GPR_ASSERT(t->lists[i].head == NULL); + GPR_ASSERT(t->lists[i].tail == NULL); + } + + GPR_ASSERT(grpc_chttp2_stream_map_size(&t->parsing_stream_map) == 0); + GPR_ASSERT(grpc_chttp2_stream_map_size(&t->new_stream_map) == 0); + + grpc_chttp2_stream_map_destroy(&t->parsing_stream_map); + grpc_chttp2_stream_map_destroy(&t->new_stream_map); + grpc_connectivity_state_destroy(exec_ctx, &t->channel_callback.state_tracker); + + gpr_mu_unlock(&t->mu); + gpr_mu_destroy(&t->mu); + + /* callback remaining pings: they're not allowed to call into the transpot, + and maybe they hold resources that need to be freed */ + while (t->global.pings.next != &t->global.pings) { + grpc_chttp2_outstanding_ping *ping = t->global.pings.next; + grpc_exec_ctx_enqueue(exec_ctx, ping->on_recv, false, NULL); + ping->next->prev = ping->prev; + ping->prev->next = ping->next; + gpr_free(ping); + } + + gpr_free(t->peer_string); + gpr_free(t); +} + +#ifdef REFCOUNTING_DEBUG +#define REF_TRANSPORT(t, r) ref_transport(t, r, __FILE__, __LINE__) +#define UNREF_TRANSPORT(cl, t, r) unref_transport(cl, t, r, __FILE__, __LINE__) +static void unref_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + const char *reason, const char *file, int line) { + gpr_log(GPR_DEBUG, "chttp2:unref:%p %d->%d %s [%s:%d]", t, t->refs.count, + t->refs.count - 1, reason, file, line); + if (!gpr_unref(&t->refs)) return; + destruct_transport(exec_ctx, t); +} + +static void ref_transport(grpc_chttp2_transport *t, const char *reason, + const char *file, int line) { + gpr_log(GPR_DEBUG, "chttp2: ref:%p %d->%d %s [%s:%d]", t, t->refs.count, + t->refs.count + 1, reason, file, line); + gpr_ref(&t->refs); +} +#else +#define REF_TRANSPORT(t, r) ref_transport(t) +#define UNREF_TRANSPORT(cl, t, r) unref_transport(cl, t) +static void unref_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { + if (!gpr_unref(&t->refs)) return; + destruct_transport(exec_ctx, t); +} + +static void ref_transport(grpc_chttp2_transport *t) { gpr_ref(&t->refs); } +#endif + +static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + const grpc_channel_args *channel_args, + grpc_endpoint *ep, uint8_t is_client) { + size_t i; + int j; + + GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) == + GRPC_CHTTP2_CLIENT_CONNECT_STRLEN); + + memset(t, 0, sizeof(*t)); + + t->base.vtable = &vtable; + t->ep = ep; + /* one ref is for destroy, the other for when ep becomes NULL */ + gpr_ref_init(&t->refs, 2); + /* ref is dropped at transport close() */ + gpr_ref_init(&t->shutdown_ep_refs, 1); + gpr_mu_init(&t->mu); + t->peer_string = grpc_endpoint_get_peer(ep); + t->endpoint_reading = 1; + t->global.next_stream_id = is_client ? 1 : 2; + t->global.is_client = is_client; + t->writing.outgoing_window = DEFAULT_WINDOW; + t->parsing.incoming_window = DEFAULT_WINDOW; + t->global.stream_lookahead = DEFAULT_WINDOW; + t->global.connection_window_target = DEFAULT_CONNECTION_WINDOW_TARGET; + t->global.ping_counter = 1; + t->global.pings.next = t->global.pings.prev = &t->global.pings; + t->parsing.is_client = is_client; + t->parsing.deframe_state = + is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0; + t->writing.is_client = is_client; + grpc_connectivity_state_init( + &t->channel_callback.state_tracker, GRPC_CHANNEL_READY, + is_client ? "client_transport" : "server_transport"); + + gpr_slice_buffer_init(&t->global.qbuf); + + gpr_slice_buffer_init(&t->writing.outbuf); + grpc_chttp2_hpack_compressor_init(&t->writing.hpack_compressor); + grpc_closure_init(&t->writing_action, writing_action, t); + + gpr_slice_buffer_init(&t->parsing.qbuf); + grpc_chttp2_goaway_parser_init(&t->parsing.goaway_parser); + grpc_chttp2_hpack_parser_init(&t->parsing.hpack_parser); + + grpc_closure_init(&t->writing.done_cb, grpc_chttp2_terminate_writing, + &t->writing); + grpc_closure_init(&t->recv_data, recv_data, t); + gpr_slice_buffer_init(&t->read_buffer); + + if (is_client) { + gpr_slice_buffer_add( + &t->global.qbuf, + gpr_slice_from_copied_string(GRPC_CHTTP2_CLIENT_CONNECT_STRING)); + } + /* 8 is a random stab in the dark as to a good initial size: it's small enough + that it shouldn't waste memory for infrequently used connections, yet + large enough that the exponential growth should happen nicely when it's + needed. + TODO(ctiller): tune this */ + grpc_chttp2_stream_map_init(&t->parsing_stream_map, 8); + grpc_chttp2_stream_map_init(&t->new_stream_map, 8); + + /* copy in initial settings to all setting sets */ + for (i = 0; i < GRPC_CHTTP2_NUM_SETTINGS; i++) { + t->parsing.settings[i] = grpc_chttp2_settings_parameters[i].default_value; + for (j = 0; j < GRPC_NUM_SETTING_SETS; j++) { + t->global.settings[j][i] = + grpc_chttp2_settings_parameters[i].default_value; + } + } + t->global.dirtied_local_settings = 1; + /* Hack: it's common for implementations to assume 65536 bytes initial send + window -- this should by rights be 0 */ + t->global.force_send_settings = 1 << GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; + t->global.sent_local_settings = 0; + + /* configure http2 the way we like it */ + if (is_client) { + push_setting(t, GRPC_CHTTP2_SETTINGS_ENABLE_PUSH, 0); + push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0); + } + push_setting(t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, DEFAULT_WINDOW); + + if (channel_args) { + for (i = 0; i < channel_args->num_args; i++) { + if (0 == + strcmp(channel_args->args[i].key, GRPC_ARG_MAX_CONCURRENT_STREAMS)) { + if (is_client) { + gpr_log(GPR_ERROR, "%s: is ignored on the client", + GRPC_ARG_MAX_CONCURRENT_STREAMS); + } else if (channel_args->args[i].type != GRPC_ARG_INTEGER) { + gpr_log(GPR_ERROR, "%s: must be an integer", + GRPC_ARG_MAX_CONCURRENT_STREAMS); + } else { + push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, + (uint32_t)channel_args->args[i].value.integer); + } + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER)) { + if (channel_args->args[i].type != GRPC_ARG_INTEGER) { + gpr_log(GPR_ERROR, "%s: must be an integer", + GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER); + } else if ((t->global.next_stream_id & 1) != + (channel_args->args[i].value.integer & 1)) { + gpr_log(GPR_ERROR, "%s: low bit must be %d on %s", + GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER, + t->global.next_stream_id & 1, + is_client ? "client" : "server"); + } else { + t->global.next_stream_id = + (uint32_t)channel_args->args[i].value.integer; + } + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES)) { + if (channel_args->args[i].type != GRPC_ARG_INTEGER) { + gpr_log(GPR_ERROR, "%s: must be an integer", + GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES); + } else if (channel_args->args[i].value.integer <= 5) { + gpr_log(GPR_ERROR, "%s: must be at least 5", + GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES); + } else { + t->global.stream_lookahead = + (uint32_t)channel_args->args[i].value.integer; + } + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER)) { + if (channel_args->args[i].type != GRPC_ARG_INTEGER) { + gpr_log(GPR_ERROR, "%s: must be an integer", + GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER); + } else if (channel_args->args[i].value.integer < 0) { + gpr_log(GPR_ERROR, "%s: must be non-negative", + GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER); + } else { + push_setting(t, GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE, + (uint32_t)channel_args->args[i].value.integer); + } + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER)) { + if (channel_args->args[i].type != GRPC_ARG_INTEGER) { + gpr_log(GPR_ERROR, "%s: must be an integer", + GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER); + } else if (channel_args->args[i].value.integer < 0) { + gpr_log(GPR_ERROR, "%s: must be non-negative", + GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER); + } else { + grpc_chttp2_hpack_compressor_set_max_usable_size( + &t->writing.hpack_compressor, + (uint32_t)channel_args->args[i].value.integer); + } + } + } + } +} + +static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { + grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; + + lock(t); + t->destroying = 1; + drop_connection(exec_ctx, t); + unlock(exec_ctx, t); + + UNREF_TRANSPORT(exec_ctx, t, "destroy"); +} + +/** block grpc_endpoint_shutdown being called until a paired + allow_endpoint_shutdown is made */ +static void prevent_endpoint_shutdown(grpc_chttp2_transport *t) { + GPR_ASSERT(t->ep); + gpr_ref(&t->shutdown_ep_refs); +} + +static void allow_endpoint_shutdown_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + if (gpr_unref(&t->shutdown_ep_refs)) { + if (t->ep) { + grpc_endpoint_shutdown(exec_ctx, t->ep); + } + } +} + +static void allow_endpoint_shutdown_unlocked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + if (gpr_unref(&t->shutdown_ep_refs)) { + gpr_mu_lock(&t->mu); + if (t->ep) { + grpc_endpoint_shutdown(exec_ctx, t->ep); + } + gpr_mu_unlock(&t->mu); + } +} + +static void destroy_endpoint(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + grpc_endpoint_destroy(exec_ctx, t->ep); + t->ep = NULL; + /* safe because we'll still have the ref for write */ + UNREF_TRANSPORT(exec_ctx, t, "disconnect"); +} + +static void close_transport_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + if (!t->closed) { + t->closed = 1; + connectivity_state_set(exec_ctx, &t->global, GRPC_CHANNEL_FATAL_FAILURE, + "close_transport"); + if (t->ep) { + allow_endpoint_shutdown_locked(exec_ctx, t); + } + + /* flush writable stream list to avoid dangling references */ + grpc_chttp2_stream_global *stream_global; + grpc_chttp2_stream_writing *stream_writing; + while (grpc_chttp2_list_pop_writable_stream( + &t->global, &t->writing, &stream_global, &stream_writing)) { + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); + } + } +} + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global, + const char *reason) { + grpc_stream_ref(STREAM_FROM_GLOBAL(stream_global)->refcount, reason); +} +void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, + grpc_chttp2_stream_global *stream_global, + const char *reason) { + grpc_stream_unref(exec_ctx, STREAM_FROM_GLOBAL(stream_global)->refcount, + reason); +} +#else +void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global) { + grpc_stream_ref(STREAM_FROM_GLOBAL(stream_global)->refcount); +} +void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, + grpc_chttp2_stream_global *stream_global) { + grpc_stream_unref(exec_ctx, STREAM_FROM_GLOBAL(stream_global)->refcount); +} +#endif + +static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_stream *gs, grpc_stream_refcount *refcount, + const void *server_data) { + grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; + grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; + + memset(s, 0, sizeof(*s)); + + s->refcount = refcount; + GRPC_CHTTP2_STREAM_REF(&s->global, "chttp2"); + + grpc_chttp2_incoming_metadata_buffer_init(&s->parsing.metadata_buffer[0]); + grpc_chttp2_incoming_metadata_buffer_init(&s->parsing.metadata_buffer[1]); + grpc_chttp2_incoming_metadata_buffer_init( + &s->global.received_initial_metadata); + grpc_chttp2_incoming_metadata_buffer_init( + &s->global.received_trailing_metadata); + grpc_chttp2_data_parser_init(&s->parsing.data_parser); + gpr_slice_buffer_init(&s->writing.flow_controlled_buffer); + + REF_TRANSPORT(t, "stream"); + + lock(t); + grpc_chttp2_register_stream(t, s); + if (server_data) { + GPR_ASSERT(t->parsing_active); + s->global.id = (uint32_t)(uintptr_t)server_data; + s->parsing.id = s->global.id; + s->global.outgoing_window = + t->global.settings[GRPC_PEER_SETTINGS] + [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; + s->parsing.incoming_window = s->global.max_recv_bytes = + t->global.settings[GRPC_SENT_SETTINGS] + [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; + *t->accepting_stream = s; + grpc_chttp2_stream_map_add(&t->parsing_stream_map, s->global.id, s); + s->global.in_stream_map = 1; + } + unlock(exec_ctx, t); + + return 0; +} + +static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_stream *gs) { + grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; + grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; + int i; + grpc_byte_stream *bs; + + GPR_TIMER_BEGIN("destroy_stream", 0); + + gpr_mu_lock(&t->mu); + + GPR_ASSERT((s->global.write_closed && s->global.read_closed) || + s->global.id == 0); + GPR_ASSERT(!s->global.in_stream_map); + if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) { + close_transport_locked(exec_ctx, t); + } + if (!t->parsing_active && s->global.id) { + GPR_ASSERT(grpc_chttp2_stream_map_find(&t->parsing_stream_map, + s->global.id) == NULL); + } + + grpc_chttp2_list_remove_unannounced_incoming_window_available(&t->global, + &s->global); + grpc_chttp2_list_remove_stalled_by_transport(&t->global, &s->global); + + gpr_mu_unlock(&t->mu); + + for (i = 0; i < STREAM_LIST_COUNT; i++) { + if (s->included[i]) { + gpr_log(GPR_ERROR, "%s stream %d still included in list %d", + t->global.is_client ? "client" : "server", s->global.id, i); + abort(); + } + } + + while ( + (bs = grpc_chttp2_incoming_frame_queue_pop(&s->global.incoming_frames))) { + grpc_byte_stream_destroy(exec_ctx, bs); + } + + GPR_ASSERT(s->global.send_initial_metadata_finished == NULL); + GPR_ASSERT(s->global.send_message_finished == NULL); + GPR_ASSERT(s->global.send_trailing_metadata_finished == NULL); + GPR_ASSERT(s->global.recv_initial_metadata_ready == NULL); + GPR_ASSERT(s->global.recv_message_ready == NULL); + GPR_ASSERT(s->global.recv_trailing_metadata_finished == NULL); + grpc_chttp2_data_parser_destroy(exec_ctx, &s->parsing.data_parser); + grpc_chttp2_incoming_metadata_buffer_destroy(&s->parsing.metadata_buffer[0]); + grpc_chttp2_incoming_metadata_buffer_destroy(&s->parsing.metadata_buffer[1]); + grpc_chttp2_incoming_metadata_buffer_destroy( + &s->global.received_initial_metadata); + grpc_chttp2_incoming_metadata_buffer_destroy( + &s->global.received_trailing_metadata); + gpr_slice_buffer_destroy(&s->writing.flow_controlled_buffer); + + UNREF_TRANSPORT(exec_ctx, t, "stream"); + + GPR_TIMER_END("destroy_stream", 0); +} + +grpc_chttp2_stream_parsing *grpc_chttp2_parsing_lookup_stream( + grpc_chttp2_transport_parsing *transport_parsing, uint32_t id) { + grpc_chttp2_transport *t = TRANSPORT_FROM_PARSING(transport_parsing); + grpc_chttp2_stream *s = + grpc_chttp2_stream_map_find(&t->parsing_stream_map, id); + return s ? &s->parsing : NULL; +} + +grpc_chttp2_stream_parsing *grpc_chttp2_parsing_accept_stream( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + uint32_t id) { + grpc_chttp2_stream *accepting; + grpc_chttp2_transport *t = TRANSPORT_FROM_PARSING(transport_parsing); + GPR_ASSERT(t->accepting_stream == NULL); + t->accepting_stream = &accepting; + t->channel_callback.accept_stream(exec_ctx, + t->channel_callback.accept_stream_user_data, + &t->base, (void *)(uintptr_t)id); + t->accepting_stream = NULL; + return &accepting->parsing; +} + +/******************************************************************************* + * LOCK MANAGEMENT + */ + +/* We take a grpc_chttp2_transport-global lock in response to calls coming in + from above, + and in response to data being received from below. New data to be written + is always queued, as are callbacks to process data. During unlock() we + check our todo lists and initiate callbacks and flush writes. */ + +static void lock(grpc_chttp2_transport *t) { gpr_mu_lock(&t->mu); } + +static void unlock(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { + GPR_TIMER_BEGIN("unlock", 0); + if (!t->writing_active && !t->closed && + grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing, + t->parsing_active)) { + t->writing_active = 1; + REF_TRANSPORT(t, "writing"); + grpc_exec_ctx_enqueue(exec_ctx, &t->writing_action, true, NULL); + prevent_endpoint_shutdown(t); + } + check_read_ops(exec_ctx, &t->global); + + gpr_mu_unlock(&t->mu); + GPR_TIMER_END("unlock", 0); +} + +/******************************************************************************* + * OUTPUT PROCESSING + */ + +void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global) { + if (!TRANSPORT_FROM_GLOBAL(transport_global)->closed && + grpc_chttp2_list_add_writable_stream(transport_global, stream_global)) { + GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing"); + } +} + +static void push_setting(grpc_chttp2_transport *t, grpc_chttp2_setting_id id, + uint32_t value) { + const grpc_chttp2_setting_parameters *sp = + &grpc_chttp2_settings_parameters[id]; + uint32_t use_value = GPR_CLAMP(value, sp->min_value, sp->max_value); + if (use_value != value) { + gpr_log(GPR_INFO, "Requested parameter %s clamped from %d to %d", sp->name, + value, use_value); + } + if (use_value != t->global.settings[GRPC_LOCAL_SETTINGS][id]) { + t->global.settings[GRPC_LOCAL_SETTINGS][id] = use_value; + t->global.dirtied_local_settings = 1; + } +} + +void grpc_chttp2_terminate_writing(grpc_exec_ctx *exec_ctx, + void *transport_writing_ptr, bool success) { + grpc_chttp2_transport_writing *transport_writing = transport_writing_ptr; + grpc_chttp2_transport *t = TRANSPORT_FROM_WRITING(transport_writing); + grpc_chttp2_stream_global *stream_global; + + GPR_TIMER_BEGIN("grpc_chttp2_terminate_writing", 0); + + lock(t); + + allow_endpoint_shutdown_locked(exec_ctx, t); + + if (!success) { + drop_connection(exec_ctx, t); + } + + grpc_chttp2_cleanup_writing(exec_ctx, &t->global, &t->writing); + + while (grpc_chttp2_list_pop_closed_waiting_for_writing(&t->global, + &stream_global)) { + fail_pending_writes(exec_ctx, stream_global); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "finish_writes"); + } + + /* leave the writing flag up on shutdown to prevent further writes in unlock() + from starting */ + t->writing_active = 0; + if (t->ep && !t->endpoint_reading) { + destroy_endpoint(exec_ctx, t); + } + + unlock(exec_ctx, t); + + UNREF_TRANSPORT(exec_ctx, t, "writing"); + + GPR_TIMER_END("grpc_chttp2_terminate_writing", 0); +} + +static void writing_action(grpc_exec_ctx *exec_ctx, void *gt, + bool iomgr_success_ignored) { + grpc_chttp2_transport *t = gt; + GPR_TIMER_BEGIN("writing_action", 0); + grpc_chttp2_perform_writes(exec_ctx, &t->writing, t->ep); + GPR_TIMER_END("writing_action", 0); +} + +void grpc_chttp2_add_incoming_goaway( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + uint32_t goaway_error, gpr_slice goaway_text) { + char *msg = gpr_dump_slice(goaway_text, GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg); + gpr_free(msg); + gpr_slice_unref(goaway_text); + transport_global->seen_goaway = 1; + connectivity_state_set(exec_ctx, transport_global, GRPC_CHANNEL_FATAL_FAILURE, + "got_goaway"); +} + +static void maybe_start_some_streams( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { + grpc_chttp2_stream_global *stream_global; + uint32_t stream_incoming_window; + /* start streams where we have free grpc_chttp2_stream ids and free + * concurrency */ + while (transport_global->next_stream_id <= MAX_CLIENT_STREAM_ID && + transport_global->concurrent_stream_count < + transport_global + ->settings[GRPC_PEER_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS] && + grpc_chttp2_list_pop_waiting_for_concurrency(transport_global, + &stream_global)) { + /* safe since we can't (legally) be parsing this stream yet */ + grpc_chttp2_stream_parsing *stream_parsing = + &STREAM_FROM_GLOBAL(stream_global)->parsing; + GRPC_CHTTP2_IF_TRACING(gpr_log( + GPR_DEBUG, "HTTP:%s: Allocating new grpc_chttp2_stream %p to id %d", + transport_global->is_client ? "CLI" : "SVR", stream_global, + transport_global->next_stream_id)); + + GPR_ASSERT(stream_global->id == 0); + stream_global->id = stream_parsing->id = transport_global->next_stream_id; + transport_global->next_stream_id += 2; + + if (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID) { + connectivity_state_set(exec_ctx, transport_global, + GRPC_CHANNEL_TRANSIENT_FAILURE, + "no_more_stream_ids"); + } + + stream_global->outgoing_window = + transport_global->settings[GRPC_PEER_SETTINGS] + [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; + stream_parsing->incoming_window = stream_incoming_window = + transport_global->settings[GRPC_SENT_SETTINGS] + [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; + stream_global->max_recv_bytes = + GPR_MAX(stream_incoming_window, stream_global->max_recv_bytes); + grpc_chttp2_stream_map_add( + &TRANSPORT_FROM_GLOBAL(transport_global)->new_stream_map, + stream_global->id, STREAM_FROM_GLOBAL(stream_global)); + stream_global->in_stream_map = 1; + transport_global->concurrent_stream_count++; + grpc_chttp2_become_writable(transport_global, stream_global); + } + /* cancel out streams that will never be started */ + while (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID && + grpc_chttp2_list_pop_waiting_for_concurrency(transport_global, + &stream_global)) { + cancel_from_api(exec_ctx, transport_global, stream_global, + GRPC_STATUS_UNAVAILABLE); + } +} + +static grpc_closure *add_closure_barrier(grpc_closure *closure) { + closure->final_data += 2; + return closure; +} + +void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, + grpc_closure **pclosure, int success) { + grpc_closure *closure = *pclosure; + if (closure == NULL) { + return; + } + closure->final_data -= 2; + if (!success) { + closure->final_data |= 1; + } + if (closure->final_data < 2) { + grpc_exec_ctx_enqueue(exec_ctx, closure, closure->final_data == 0, NULL); + } + *pclosure = NULL; +} + +static int contains_non_ok_status( + grpc_chttp2_transport_global *transport_global, + grpc_metadata_batch *batch) { + grpc_linked_mdelem *l; + for (l = batch->list.head; l; l = l->next) { + if (l->md->key == GRPC_MDSTR_GRPC_STATUS && + l->md != GRPC_MDELEM_GRPC_STATUS_0) { + return 1; + } + } + return 0; +} + +static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, bool success) {} + +static void perform_stream_op_locked( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, grpc_transport_stream_op *op) { + grpc_closure *on_complete; + + GPR_TIMER_BEGIN("perform_stream_op_locked", 0); + + on_complete = op->on_complete; + if (on_complete == NULL) { + on_complete = grpc_closure_create(do_nothing, NULL); + } + /* use final_data as a barrier until enqueue time; the inital counter is + dropped at the end of this function */ + on_complete->final_data = 2; + + if (op->cancel_with_status != GRPC_STATUS_OK) { + cancel_from_api(exec_ctx, transport_global, stream_global, + op->cancel_with_status); + } + + if (op->close_with_status != GRPC_STATUS_OK) { + close_from_api(exec_ctx, transport_global, stream_global, + op->close_with_status, op->optional_close_message); + } + + if (op->send_initial_metadata != NULL) { + GPR_ASSERT(stream_global->send_initial_metadata_finished == NULL); + stream_global->send_initial_metadata_finished = + add_closure_barrier(on_complete); + stream_global->send_initial_metadata = op->send_initial_metadata; + if (contains_non_ok_status(transport_global, op->send_initial_metadata)) { + stream_global->seen_error = 1; + grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); + } + if (!stream_global->write_closed) { + if (transport_global->is_client) { + GPR_ASSERT(stream_global->id == 0); + grpc_chttp2_list_add_waiting_for_concurrency(transport_global, + stream_global); + maybe_start_some_streams(exec_ctx, transport_global); + } else { + GPR_ASSERT(stream_global->id != 0); + grpc_chttp2_become_writable(transport_global, stream_global); + } + } else { + grpc_chttp2_complete_closure_step( + exec_ctx, &stream_global->send_initial_metadata_finished, 0); + } + } + + if (op->send_message != NULL) { + GPR_ASSERT(stream_global->send_message_finished == NULL); + GPR_ASSERT(stream_global->send_message == NULL); + stream_global->send_message_finished = add_closure_barrier(on_complete); + if (stream_global->write_closed) { + grpc_chttp2_complete_closure_step( + exec_ctx, &stream_global->send_message_finished, 0); + } else { + stream_global->send_message = op->send_message; + if (stream_global->id != 0) { + grpc_chttp2_become_writable(transport_global, stream_global); + } + } + } + + if (op->send_trailing_metadata != NULL) { + GPR_ASSERT(stream_global->send_trailing_metadata_finished == NULL); + stream_global->send_trailing_metadata_finished = + add_closure_barrier(on_complete); + stream_global->send_trailing_metadata = op->send_trailing_metadata; + if (contains_non_ok_status(transport_global, op->send_trailing_metadata)) { + stream_global->seen_error = 1; + grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); + } + if (stream_global->write_closed) { + grpc_chttp2_complete_closure_step( + exec_ctx, &stream_global->send_trailing_metadata_finished, + grpc_metadata_batch_is_empty(op->send_trailing_metadata)); + } else if (stream_global->id != 0) { + /* TODO(ctiller): check if there's flow control for any outstanding + bytes before going writable */ + grpc_chttp2_become_writable(transport_global, stream_global); + } + } + + if (op->recv_initial_metadata != NULL) { + GPR_ASSERT(stream_global->recv_initial_metadata_ready == NULL); + stream_global->recv_initial_metadata_ready = + op->recv_initial_metadata_ready; + stream_global->recv_initial_metadata = op->recv_initial_metadata; + grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); + } + + if (op->recv_message != NULL) { + GPR_ASSERT(stream_global->recv_message_ready == NULL); + stream_global->recv_message_ready = op->recv_message_ready; + stream_global->recv_message = op->recv_message; + if (stream_global->id != 0 && + (stream_global->incoming_frames.head == NULL || + stream_global->incoming_frames.head->is_tail)) { + incoming_byte_stream_update_flow_control( + transport_global, stream_global, transport_global->stream_lookahead, + 0); + } + grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); + } + + if (op->recv_trailing_metadata != NULL) { + GPR_ASSERT(stream_global->recv_trailing_metadata_finished == NULL); + stream_global->recv_trailing_metadata_finished = + add_closure_barrier(on_complete); + stream_global->recv_trailing_metadata = op->recv_trailing_metadata; + grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); + } + + grpc_chttp2_complete_closure_step(exec_ctx, &on_complete, 1); + + GPR_TIMER_END("perform_stream_op_locked", 0); +} + +static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_stream *gs, grpc_transport_stream_op *op) { + grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; + grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; + + lock(t); + perform_stream_op_locked(exec_ctx, &t->global, &s->global, op); + unlock(exec_ctx, t); +} + +static void send_ping_locked(grpc_chttp2_transport *t, grpc_closure *on_recv) { + grpc_chttp2_outstanding_ping *p = gpr_malloc(sizeof(*p)); + p->next = &t->global.pings; + p->prev = p->next->prev; + p->prev->next = p->next->prev = p; + p->id[0] = (uint8_t)((t->global.ping_counter >> 56) & 0xff); + p->id[1] = (uint8_t)((t->global.ping_counter >> 48) & 0xff); + p->id[2] = (uint8_t)((t->global.ping_counter >> 40) & 0xff); + p->id[3] = (uint8_t)((t->global.ping_counter >> 32) & 0xff); + p->id[4] = (uint8_t)((t->global.ping_counter >> 24) & 0xff); + p->id[5] = (uint8_t)((t->global.ping_counter >> 16) & 0xff); + p->id[6] = (uint8_t)((t->global.ping_counter >> 8) & 0xff); + p->id[7] = (uint8_t)(t->global.ping_counter & 0xff); + p->on_recv = on_recv; + gpr_slice_buffer_add(&t->global.qbuf, grpc_chttp2_ping_create(0, p->id)); +} + +void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing, + const uint8_t *opaque_8bytes) { + grpc_chttp2_outstanding_ping *ping; + grpc_chttp2_transport *t = TRANSPORT_FROM_PARSING(transport_parsing); + grpc_chttp2_transport_global *transport_global = &t->global; + lock(t); + for (ping = transport_global->pings.next; ping != &transport_global->pings; + ping = ping->next) { + if (0 == memcmp(opaque_8bytes, ping->id, 8)) { + grpc_exec_ctx_enqueue(exec_ctx, ping->on_recv, true, NULL); + ping->next->prev = ping->prev; + ping->prev->next = ping->next; + gpr_free(ping); + break; + } + } + unlock(exec_ctx, t); +} + +static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_transport_op *op) { + bool close_transport = false; + + grpc_exec_ctx_enqueue(exec_ctx, op->on_consumed, true, NULL); + + if (op->on_connectivity_state_change != NULL) { + grpc_connectivity_state_notify_on_state_change( + exec_ctx, &t->channel_callback.state_tracker, op->connectivity_state, + op->on_connectivity_state_change); + } + + if (op->send_goaway) { + t->global.sent_goaway = 1; + grpc_chttp2_goaway_append( + t->global.last_incoming_stream_id, + (uint32_t)grpc_chttp2_grpc_status_to_http2_error(op->goaway_status), + gpr_slice_ref(*op->goaway_message), &t->global.qbuf); + close_transport = !grpc_chttp2_has_streams(t); + } + + if (op->set_accept_stream) { + t->channel_callback.accept_stream = op->set_accept_stream_fn; + t->channel_callback.accept_stream_user_data = + op->set_accept_stream_user_data; + } + + if (op->bind_pollset) { + add_to_pollset_locked(exec_ctx, t, op->bind_pollset); + } + + if (op->bind_pollset_set) { + add_to_pollset_set_locked(exec_ctx, t, op->bind_pollset_set); + } + + if (op->send_ping) { + send_ping_locked(t, op->send_ping); + } + + if (op->disconnect) { + close_transport_locked(exec_ctx, t); + } + + if (close_transport) { + close_transport_locked(exec_ctx, t); + } +} + +static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_transport_op *op) { + grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; + + lock(t); + + /* If there's a set_accept_stream ensure that we're not parsing + to avoid changing things out from underneath */ + if (t->parsing_active && op->set_accept_stream) { + GPR_ASSERT(t->post_parsing_op == NULL); + t->post_parsing_op = gpr_malloc(sizeof(*op)); + memcpy(t->post_parsing_op, op, sizeof(*op)); + } else { + perform_transport_op_locked(exec_ctx, t, op); + } + + unlock(exec_ctx, t); +} + +/******************************************************************************* + * INPUT PROCESSING + */ + +static void check_read_ops(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global) { + grpc_chttp2_stream_global *stream_global; + grpc_byte_stream *bs; + while ( + grpc_chttp2_list_pop_check_read_ops(transport_global, &stream_global)) { + if (stream_global->recv_initial_metadata_ready != NULL && + stream_global->published_initial_metadata) { + grpc_chttp2_incoming_metadata_buffer_publish( + &stream_global->received_initial_metadata, + stream_global->recv_initial_metadata); + grpc_exec_ctx_enqueue( + exec_ctx, stream_global->recv_initial_metadata_ready, true, NULL); + stream_global->recv_initial_metadata_ready = NULL; + } + if (stream_global->recv_message_ready != NULL) { + while (stream_global->seen_error && + (bs = grpc_chttp2_incoming_frame_queue_pop( + &stream_global->incoming_frames)) != NULL) { + grpc_byte_stream_destroy(exec_ctx, bs); + } + if (stream_global->incoming_frames.head != NULL) { + *stream_global->recv_message = grpc_chttp2_incoming_frame_queue_pop( + &stream_global->incoming_frames); + GPR_ASSERT(*stream_global->recv_message != NULL); + grpc_exec_ctx_enqueue(exec_ctx, stream_global->recv_message_ready, true, + NULL); + stream_global->recv_message_ready = NULL; + } else if (stream_global->published_trailing_metadata) { + *stream_global->recv_message = NULL; + grpc_exec_ctx_enqueue(exec_ctx, stream_global->recv_message_ready, true, + NULL); + stream_global->recv_message_ready = NULL; + } + } + if (stream_global->recv_trailing_metadata_finished != NULL && + stream_global->read_closed && stream_global->write_closed) { + while (stream_global->seen_error && + (bs = grpc_chttp2_incoming_frame_queue_pop( + &stream_global->incoming_frames)) != NULL) { + grpc_byte_stream_destroy(exec_ctx, bs); + } + if (stream_global->incoming_frames.head == NULL) { + grpc_chttp2_incoming_metadata_buffer_publish( + &stream_global->received_trailing_metadata, + stream_global->recv_trailing_metadata); + grpc_chttp2_complete_closure_step( + exec_ctx, &stream_global->recv_trailing_metadata_finished, 1); + } + } + } +} + +static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, + uint32_t id) { + size_t new_stream_count; + grpc_chttp2_stream *s = + grpc_chttp2_stream_map_delete(&t->parsing_stream_map, id); + if (!s) { + s = grpc_chttp2_stream_map_delete(&t->new_stream_map, id); + } + GPR_ASSERT(s); + s->global.in_stream_map = 0; + if (t->parsing.incoming_stream == &s->parsing) { + t->parsing.incoming_stream = NULL; + grpc_chttp2_parsing_become_skip_parser(exec_ctx, &t->parsing); + } + if (s->parsing.data_parser.parsing_frame != NULL) { + grpc_chttp2_incoming_byte_stream_finished( + exec_ctx, s->parsing.data_parser.parsing_frame, 0, 0); + s->parsing.data_parser.parsing_frame = NULL; + } + + if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) { + close_transport_locked(exec_ctx, t); + } + if (grpc_chttp2_list_remove_writable_stream(&t->global, &s->global)) { + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &s->global, "chttp2_writing"); + } + + new_stream_count = grpc_chttp2_stream_map_size(&t->parsing_stream_map) + + grpc_chttp2_stream_map_size(&t->new_stream_map); + GPR_ASSERT(new_stream_count <= UINT32_MAX); + if (new_stream_count != t->global.concurrent_stream_count) { + t->global.concurrent_stream_count = (uint32_t)new_stream_count; + maybe_start_some_streams(exec_ctx, &t->global); + } +} + +static void cancel_from_api(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, + grpc_status_code status) { + if (stream_global->id != 0) { + gpr_slice_buffer_add( + &transport_global->qbuf, + grpc_chttp2_rst_stream_create( + stream_global->id, + (uint32_t)grpc_chttp2_grpc_status_to_http2_error(status))); + } + grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status, + NULL); + grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1, + 1); +} + +void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, + grpc_status_code status, gpr_slice *slice) { + if (status != GRPC_STATUS_OK) { + stream_global->seen_error = 1; + grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); + } + /* stream_global->recv_trailing_metadata_finished gives us a + last chance replacement: we've received trailing metadata, + but something more important has become available to signal + to the upper layers - drop what we've got, and then publish + what we want - which is safe because we haven't told anyone + about the metadata yet */ + if (!stream_global->published_trailing_metadata || + stream_global->recv_trailing_metadata_finished != NULL) { + char status_string[GPR_LTOA_MIN_BUFSIZE]; + gpr_ltoa(status, status_string); + grpc_chttp2_incoming_metadata_buffer_add( + &stream_global->received_trailing_metadata, + grpc_mdelem_from_metadata_strings( + GRPC_MDSTR_GRPC_STATUS, grpc_mdstr_from_string(status_string))); + if (slice) { + grpc_chttp2_incoming_metadata_buffer_add( + &stream_global->received_trailing_metadata, + grpc_mdelem_from_metadata_strings( + GRPC_MDSTR_GRPC_MESSAGE, + grpc_mdstr_from_slice(gpr_slice_ref(*slice)))); + } + stream_global->published_trailing_metadata = 1; + grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); + } + if (slice) { + gpr_slice_unref(*slice); + } +} + +static void fail_pending_writes(grpc_exec_ctx *exec_ctx, + grpc_chttp2_stream_global *stream_global) { + grpc_chttp2_complete_closure_step( + exec_ctx, &stream_global->send_initial_metadata_finished, 0); + grpc_chttp2_complete_closure_step( + exec_ctx, &stream_global->send_trailing_metadata_finished, 0); + grpc_chttp2_complete_closure_step(exec_ctx, + &stream_global->send_message_finished, 0); +} + +void grpc_chttp2_mark_stream_closed( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, int close_reads, + int close_writes) { + if (stream_global->read_closed && stream_global->write_closed) { + /* already closed */ + return; + } + grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); + if (close_reads && !stream_global->read_closed) { + stream_global->read_closed = 1; + stream_global->published_initial_metadata = 1; + stream_global->published_trailing_metadata = 1; + } + if (close_writes && !stream_global->write_closed) { + stream_global->write_closed = 1; + if (TRANSPORT_FROM_GLOBAL(transport_global)->writing_active) { + GRPC_CHTTP2_STREAM_REF(stream_global, "finish_writes"); + grpc_chttp2_list_add_closed_waiting_for_writing(transport_global, + stream_global); + } else { + fail_pending_writes(exec_ctx, stream_global); + } + } + if (stream_global->read_closed && stream_global->write_closed) { + if (stream_global->id != 0 && + TRANSPORT_FROM_GLOBAL(transport_global)->parsing_active) { + grpc_chttp2_list_add_closed_waiting_for_parsing(transport_global, + stream_global); + } else { + if (stream_global->id != 0) { + remove_stream(exec_ctx, TRANSPORT_FROM_GLOBAL(transport_global), + stream_global->id); + } + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); + } + } +} + +static void close_from_api(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, + grpc_status_code status, + gpr_slice *optional_message) { + gpr_slice hdr; + gpr_slice status_hdr; + gpr_slice message_pfx; + uint8_t *p; + uint32_t len = 0; + + GPR_ASSERT(status >= 0 && (int)status < 100); + + GPR_ASSERT(stream_global->id != 0); + + /* Hand roll a header block. + This is unnecessarily ugly - at some point we should find a more elegant + solution. + It's complicated by the fact that our send machinery would be dead by the + time we got around to sending this, so instead we ignore HPACK compression + and just write the uncompressed bytes onto the wire. */ + status_hdr = gpr_slice_malloc(15 + (status >= 10)); + p = GPR_SLICE_START_PTR(status_hdr); + *p++ = 0x40; /* literal header */ + *p++ = 11; /* len(grpc-status) */ + *p++ = 'g'; + *p++ = 'r'; + *p++ = 'p'; + *p++ = 'c'; + *p++ = '-'; + *p++ = 's'; + *p++ = 't'; + *p++ = 'a'; + *p++ = 't'; + *p++ = 'u'; + *p++ = 's'; + if (status < 10) { + *p++ = 1; + *p++ = (uint8_t)('0' + status); + } else { + *p++ = 2; + *p++ = (uint8_t)('0' + (status / 10)); + *p++ = (uint8_t)('0' + (status % 10)); + } + GPR_ASSERT(p == GPR_SLICE_END_PTR(status_hdr)); + len += (uint32_t)GPR_SLICE_LENGTH(status_hdr); + + if (optional_message) { + GPR_ASSERT(GPR_SLICE_LENGTH(*optional_message) < 127); + message_pfx = gpr_slice_malloc(15); + p = GPR_SLICE_START_PTR(message_pfx); + *p++ = 0x40; + *p++ = 12; /* len(grpc-message) */ + *p++ = 'g'; + *p++ = 'r'; + *p++ = 'p'; + *p++ = 'c'; + *p++ = '-'; + *p++ = 'm'; + *p++ = 'e'; + *p++ = 's'; + *p++ = 's'; + *p++ = 'a'; + *p++ = 'g'; + *p++ = 'e'; + *p++ = (uint8_t)GPR_SLICE_LENGTH(*optional_message); + GPR_ASSERT(p == GPR_SLICE_END_PTR(message_pfx)); + len += (uint32_t)GPR_SLICE_LENGTH(message_pfx); + len += (uint32_t)GPR_SLICE_LENGTH(*optional_message); + } + + hdr = gpr_slice_malloc(9); + p = GPR_SLICE_START_PTR(hdr); + *p++ = (uint8_t)(len >> 16); + *p++ = (uint8_t)(len >> 8); + *p++ = (uint8_t)(len); + *p++ = GRPC_CHTTP2_FRAME_HEADER; + *p++ = GRPC_CHTTP2_DATA_FLAG_END_STREAM | GRPC_CHTTP2_DATA_FLAG_END_HEADERS; + *p++ = (uint8_t)(stream_global->id >> 24); + *p++ = (uint8_t)(stream_global->id >> 16); + *p++ = (uint8_t)(stream_global->id >> 8); + *p++ = (uint8_t)(stream_global->id); + GPR_ASSERT(p == GPR_SLICE_END_PTR(hdr)); + + gpr_slice_buffer_add(&transport_global->qbuf, hdr); + gpr_slice_buffer_add(&transport_global->qbuf, status_hdr); + if (optional_message) { + gpr_slice_buffer_add(&transport_global->qbuf, message_pfx); + gpr_slice_buffer_add(&transport_global->qbuf, + gpr_slice_ref(*optional_message)); + } + + gpr_slice_buffer_add( + &transport_global->qbuf, + grpc_chttp2_rst_stream_create(stream_global->id, GRPC_CHTTP2_NO_ERROR)); + + if (optional_message) { + gpr_slice_ref(*optional_message); + } + grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status, + optional_message); + grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1, + 1); +} + +static void cancel_stream_cb(grpc_chttp2_transport_global *transport_global, + void *user_data, + grpc_chttp2_stream_global *stream_global) { + cancel_from_api(user_data, transport_global, stream_global, + GRPC_STATUS_UNAVAILABLE); +} + +static void end_all_the_calls(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + grpc_chttp2_for_all_streams(&t->global, exec_ctx, cancel_stream_cb); +} + +static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { + close_transport_locked(exec_ctx, t); + end_all_the_calls(exec_ctx, t); +} + +/** update window from a settings change */ +static void update_global_window(void *args, uint32_t id, void *stream) { + grpc_chttp2_transport *t = args; + grpc_chttp2_stream *s = stream; + grpc_chttp2_transport_global *transport_global = &t->global; + grpc_chttp2_stream_global *stream_global = &s->global; + int was_zero; + int is_zero; + int64_t initial_window_update = t->parsing.initial_window_update; + + was_zero = stream_global->outgoing_window <= 0; + GRPC_CHTTP2_FLOW_CREDIT_STREAM("settings", transport_global, stream_global, + outgoing_window, initial_window_update); + is_zero = stream_global->outgoing_window <= 0; + + if (was_zero && !is_zero) { + grpc_chttp2_become_writable(transport_global, stream_global); + } +} + +static void read_error_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t) { + t->endpoint_reading = 0; + if (!t->writing_active && t->ep) { + destroy_endpoint(exec_ctx, t); + } +} + +/* tcp read callback */ +static void recv_data(grpc_exec_ctx *exec_ctx, void *tp, bool success) { + size_t i; + int keep_reading = 0; + grpc_chttp2_transport *t = tp; + grpc_chttp2_transport_global *transport_global = &t->global; + grpc_chttp2_transport_parsing *transport_parsing = &t->parsing; + grpc_chttp2_stream_global *stream_global; + + GPR_TIMER_BEGIN("recv_data", 0); + + lock(t); + i = 0; + GPR_ASSERT(!t->parsing_active); + if (!t->closed) { + t->parsing_active = 1; + /* merge stream lists */ + grpc_chttp2_stream_map_move_into(&t->new_stream_map, + &t->parsing_stream_map); + grpc_chttp2_prepare_to_read(transport_global, transport_parsing); + gpr_mu_unlock(&t->mu); + GPR_TIMER_BEGIN("recv_data.parse", 0); + for (; i < t->read_buffer.count && + grpc_chttp2_perform_read(exec_ctx, transport_parsing, + t->read_buffer.slices[i]); + i++) + ; + GPR_TIMER_END("recv_data.parse", 0); + gpr_mu_lock(&t->mu); + /* copy parsing qbuf to global qbuf */ + gpr_slice_buffer_move_into(&t->parsing.qbuf, &t->global.qbuf); + if (i != t->read_buffer.count) { + unlock(exec_ctx, t); + lock(t); + drop_connection(exec_ctx, t); + } + /* merge stream lists */ + grpc_chttp2_stream_map_move_into(&t->new_stream_map, + &t->parsing_stream_map); + transport_global->concurrent_stream_count = + (uint32_t)grpc_chttp2_stream_map_size(&t->parsing_stream_map); + if (transport_parsing->initial_window_update != 0) { + grpc_chttp2_stream_map_for_each(&t->parsing_stream_map, + update_global_window, t); + transport_parsing->initial_window_update = 0; + } + /* handle higher level things */ + grpc_chttp2_publish_reads(exec_ctx, transport_global, transport_parsing); + t->parsing_active = 0; + /* handle delayed transport ops (if there is one) */ + if (t->post_parsing_op) { + grpc_transport_op *op = t->post_parsing_op; + t->post_parsing_op = NULL; + perform_transport_op_locked(exec_ctx, t, op); + gpr_free(op); + } + /* if a stream is in the stream map, and gets cancelled, we need to ensure + * we are not parsing before continuing the cancellation to keep things in + * a sane state */ + while (grpc_chttp2_list_pop_closed_waiting_for_parsing(transport_global, + &stream_global)) { + GPR_ASSERT(stream_global->in_stream_map); + GPR_ASSERT(stream_global->write_closed); + GPR_ASSERT(stream_global->read_closed); + remove_stream(exec_ctx, t, stream_global->id); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); + } + } + if (!success || i != t->read_buffer.count || t->closed) { + drop_connection(exec_ctx, t); + read_error_locked(exec_ctx, t); + } else if (!t->closed) { + keep_reading = 1; + REF_TRANSPORT(t, "keep_reading"); + prevent_endpoint_shutdown(t); + } + gpr_slice_buffer_reset_and_unref(&t->read_buffer); + unlock(exec_ctx, t); + + if (keep_reading) { + grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, &t->recv_data); + allow_endpoint_shutdown_unlocked(exec_ctx, t); + UNREF_TRANSPORT(exec_ctx, t, "keep_reading"); + } else { + UNREF_TRANSPORT(exec_ctx, t, "recv_data"); + } + + GPR_TIMER_END("recv_data", 0); +} + +/******************************************************************************* + * CALLBACK LOOP + */ + +static void connectivity_state_set( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, + grpc_connectivity_state state, const char *reason) { + GRPC_CHTTP2_IF_TRACING( + gpr_log(GPR_DEBUG, "set connectivity_state=%d", state)); + grpc_connectivity_state_set( + exec_ctx, + &TRANSPORT_FROM_GLOBAL(transport_global)->channel_callback.state_tracker, + state, reason); +} + +/******************************************************************************* + * POLLSET STUFF + */ + +static void add_to_pollset_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_pollset *pollset) { + if (t->ep) { + grpc_endpoint_add_to_pollset(exec_ctx, t->ep, pollset); + } +} + +static void add_to_pollset_set_locked(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport *t, + grpc_pollset_set *pollset_set) { + if (t->ep) { + grpc_endpoint_add_to_pollset_set(exec_ctx, t->ep, pollset_set); + } +} + +static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_stream *gs, grpc_pollset *pollset) { + grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; + lock(t); + add_to_pollset_locked(exec_ctx, t, pollset); + unlock(exec_ctx, t); +} + +/******************************************************************************* + * BYTE STREAM + */ + +static void incoming_byte_stream_update_flow_control( + grpc_chttp2_transport_global *transport_global, + grpc_chttp2_stream_global *stream_global, size_t max_size_hint, + size_t have_already) { + uint32_t max_recv_bytes; + + /* clamp max recv hint to an allowable size */ + if (max_size_hint >= UINT32_MAX - transport_global->stream_lookahead) { + max_recv_bytes = UINT32_MAX - transport_global->stream_lookahead; + } else { + max_recv_bytes = (uint32_t)max_size_hint; + } + + /* account for bytes already received but unknown to higher layers */ + if (max_recv_bytes >= have_already) { + max_recv_bytes -= (uint32_t)have_already; + } else { + max_recv_bytes = 0; + } + + /* add some small lookahead to keep pipelines flowing */ + GPR_ASSERT(max_recv_bytes <= UINT32_MAX - transport_global->stream_lookahead); + max_recv_bytes += transport_global->stream_lookahead; + if (stream_global->max_recv_bytes < max_recv_bytes) { + uint32_t add_max_recv_bytes = + max_recv_bytes - stream_global->max_recv_bytes; + GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", transport_global, stream_global, + max_recv_bytes, add_max_recv_bytes); + GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", transport_global, stream_global, + unannounced_incoming_window_for_parse, + add_max_recv_bytes); + GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", transport_global, stream_global, + unannounced_incoming_window_for_writing, + add_max_recv_bytes); + grpc_chttp2_list_add_unannounced_incoming_window_available(transport_global, + stream_global); + grpc_chttp2_become_writable(transport_global, stream_global); + } +} + +static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream, + gpr_slice *slice, size_t max_size_hint, + grpc_closure *on_complete) { + grpc_chttp2_incoming_byte_stream *bs = + (grpc_chttp2_incoming_byte_stream *)byte_stream; + grpc_chttp2_transport_global *transport_global = &bs->transport->global; + grpc_chttp2_stream_global *stream_global = &bs->stream->global; + + lock(bs->transport); + if (bs->is_tail) { + incoming_byte_stream_update_flow_control(transport_global, stream_global, + max_size_hint, bs->slices.length); + } + if (bs->slices.count > 0) { + *slice = gpr_slice_buffer_take_first(&bs->slices); + unlock(exec_ctx, bs->transport); + return 1; + } else if (bs->failed) { + grpc_exec_ctx_enqueue(exec_ctx, on_complete, false, NULL); + unlock(exec_ctx, bs->transport); + return 0; + } else { + bs->on_next = on_complete; + bs->next = slice; + unlock(exec_ctx, bs->transport); + return 0; + } +} + +static void incoming_byte_stream_unref(grpc_chttp2_incoming_byte_stream *bs) { + if (gpr_unref(&bs->refs)) { + gpr_slice_buffer_destroy(&bs->slices); + gpr_free(bs); + } +} + +static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx, + grpc_byte_stream *byte_stream) { + incoming_byte_stream_unref((grpc_chttp2_incoming_byte_stream *)byte_stream); +} + +void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, + grpc_chttp2_incoming_byte_stream *bs, + gpr_slice slice) { + gpr_mu_lock(&bs->transport->mu); + if (bs->on_next != NULL) { + *bs->next = slice; + grpc_exec_ctx_enqueue(exec_ctx, bs->on_next, true, NULL); + bs->on_next = NULL; + } else { + gpr_slice_buffer_add(&bs->slices, slice); + } + gpr_mu_unlock(&bs->transport->mu); +} + +void grpc_chttp2_incoming_byte_stream_finished( + grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, int success, + int from_parsing_thread) { + if (!success) { + if (from_parsing_thread) { + gpr_mu_lock(&bs->transport->mu); + } + grpc_exec_ctx_enqueue(exec_ctx, bs->on_next, false, NULL); + bs->on_next = NULL; + bs->failed = 1; + if (from_parsing_thread) { + gpr_mu_unlock(&bs->transport->mu); + } + } else { +#ifndef NDEBUG + if (from_parsing_thread) { + gpr_mu_lock(&bs->transport->mu); + } + GPR_ASSERT(bs->on_next == NULL); + if (from_parsing_thread) { + gpr_mu_unlock(&bs->transport->mu); + } +#endif + } + incoming_byte_stream_unref(bs); +} + +grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( + grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, + grpc_chttp2_stream_parsing *stream_parsing, uint32_t frame_size, + uint32_t flags, grpc_chttp2_incoming_frame_queue *add_to_queue) { + grpc_chttp2_incoming_byte_stream *incoming_byte_stream = + gpr_malloc(sizeof(*incoming_byte_stream)); + incoming_byte_stream->base.length = frame_size; + incoming_byte_stream->base.flags = flags; + incoming_byte_stream->base.next = incoming_byte_stream_next; + incoming_byte_stream->base.destroy = incoming_byte_stream_destroy; + gpr_ref_init(&incoming_byte_stream->refs, 2); + incoming_byte_stream->next_message = NULL; + incoming_byte_stream->transport = TRANSPORT_FROM_PARSING(transport_parsing); + incoming_byte_stream->stream = STREAM_FROM_PARSING(stream_parsing); + gpr_slice_buffer_init(&incoming_byte_stream->slices); + incoming_byte_stream->on_next = NULL; + incoming_byte_stream->is_tail = 1; + incoming_byte_stream->failed = 0; + if (add_to_queue->head == NULL) { + add_to_queue->head = incoming_byte_stream; + } else { + add_to_queue->tail->is_tail = 0; + add_to_queue->tail->next_message = incoming_byte_stream; + } + add_to_queue->tail = incoming_byte_stream; + return incoming_byte_stream; +} + +/******************************************************************************* + * TRACING + */ + +static char *format_flowctl_context_var(const char *context, const char *var, + int64_t val, uint32_t id, + char **scope) { + char *underscore_pos; + char *result; + if (context == NULL) { + *scope = NULL; + gpr_asprintf(&result, "%s(%lld)", var, val); + return result; + } + underscore_pos = strchr(context, '_'); + *scope = gpr_strdup(context); + (*scope)[underscore_pos - context] = 0; + if (id != 0) { + char *tmp = *scope; + gpr_asprintf(scope, "%s[%d]", tmp, id); + gpr_free(tmp); + } + gpr_asprintf(&result, "%s.%s(%lld)", underscore_pos + 1, var, val); + return result; +} + +static int samestr(char *a, char *b) { + if (a == NULL) { + return b == NULL; + } + if (b == NULL) { + return 0; + } + return 0 == strcmp(a, b); +} + +void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase, + grpc_chttp2_flowctl_op op, const char *context1, + const char *var1, const char *context2, + const char *var2, int is_client, + uint32_t stream_id, int64_t val1, int64_t val2) { + char *scope1; + char *scope2; + char *label1 = + format_flowctl_context_var(context1, var1, val1, stream_id, &scope1); + char *label2 = + format_flowctl_context_var(context2, var2, val2, stream_id, &scope2); + char *clisvr = is_client ? "client" : "server"; + char *prefix; + + gpr_asprintf(&prefix, "FLOW % 8s: %s % 11s ", phase, clisvr, scope1); + + switch (op) { + case GRPC_CHTTP2_FLOWCTL_MOVE: + GPR_ASSERT(samestr(scope1, scope2)); + if (val2 != 0) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "%sMOVE % 40s <- % 40s giving %d", prefix, label1, label2, + val1 + val2); + } + break; + case GRPC_CHTTP2_FLOWCTL_CREDIT: + GPR_ASSERT(val2 >= 0); + if (val2 != 0) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "%sCREDIT % 40s by % 40s giving %d", prefix, label1, label2, + val1 + val2); + } + break; + case GRPC_CHTTP2_FLOWCTL_DEBIT: + GPR_ASSERT(val2 >= 0); + if (val2 != 0) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "%sDEBIT % 40s by % 40s giving %d", prefix, label1, label2, + val1 - val2); + } + break; + } + + gpr_free(scope1); + gpr_free(scope2); + gpr_free(label1); + gpr_free(label2); + gpr_free(prefix); +} + +/******************************************************************************* + * INTEGRATION GLUE + */ + +static char *chttp2_get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *t) { + return gpr_strdup(((grpc_chttp2_transport *)t)->peer_string); +} + +static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), + "chttp2", + init_stream, + set_pollset, + perform_stream_op, + perform_transport_op, + destroy_stream, + destroy_transport, + chttp2_get_peer}; + +grpc_transport *grpc_create_chttp2_transport( + grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args, + grpc_endpoint *ep, int is_client) { + grpc_chttp2_transport *t = gpr_malloc(sizeof(grpc_chttp2_transport)); + init_transport(exec_ctx, t, channel_args, ep, is_client != 0); + return &t->base; +} + +void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, + grpc_transport *transport, + gpr_slice *slices, size_t nslices) { + grpc_chttp2_transport *t = (grpc_chttp2_transport *)transport; + REF_TRANSPORT(t, "recv_data"); /* matches unref inside recv_data */ + gpr_slice_buffer_addn(&t->read_buffer, slices, nslices); + recv_data(exec_ctx, t, 1); +} diff --git a/src/core/lib/transport/chttp2_transport.h b/src/core/lib/transport/chttp2_transport.h new file mode 100644 index 0000000000..9a6cf0ed35 --- /dev/null +++ b/src/core/lib/transport/chttp2_transport.h @@ -0,0 +1,51 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CHTTP2_TRANSPORT_H +#define GRPC_CORE_TRANSPORT_CHTTP2_TRANSPORT_H + +#include "src/core/iomgr/endpoint.h" +#include "src/core/transport/transport.h" + +extern int grpc_http_trace; +extern int grpc_flowctl_trace; + +grpc_transport *grpc_create_chttp2_transport( + grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args, + grpc_endpoint *ep, int is_client); + +void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, + grpc_transport *transport, + gpr_slice *slices, size_t nslices); + +#endif /* GRPC_CORE_TRANSPORT_CHTTP2_TRANSPORT_H */ diff --git a/src/core/lib/transport/connectivity_state.c b/src/core/lib/transport/connectivity_state.c new file mode 100644 index 0000000000..87765b9799 --- /dev/null +++ b/src/core/lib/transport/connectivity_state.c @@ -0,0 +1,164 @@ +/* + * + * Copyright 2015-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/transport/connectivity_state.h" + +#include + +#include +#include +#include + +int grpc_connectivity_state_trace = 0; + +const char *grpc_connectivity_state_name(grpc_connectivity_state state) { + switch (state) { + case GRPC_CHANNEL_IDLE: + return "IDLE"; + case GRPC_CHANNEL_CONNECTING: + return "CONNECTING"; + case GRPC_CHANNEL_READY: + return "READY"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "TRANSIENT_FAILURE"; + case GRPC_CHANNEL_FATAL_FAILURE: + return "FATAL_FAILURE"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker, + grpc_connectivity_state init_state, + const char *name) { + tracker->current_state = init_state; + tracker->watchers = NULL; + tracker->name = gpr_strdup(name); +} + +void grpc_connectivity_state_destroy(grpc_exec_ctx *exec_ctx, + grpc_connectivity_state_tracker *tracker) { + int success; + grpc_connectivity_state_watcher *w; + while ((w = tracker->watchers)) { + tracker->watchers = w->next; + + if (GRPC_CHANNEL_FATAL_FAILURE != *w->current) { + *w->current = GRPC_CHANNEL_FATAL_FAILURE; + success = 1; + } else { + success = 0; + } + grpc_exec_ctx_enqueue(exec_ctx, w->notify, success, NULL); + gpr_free(w); + } + gpr_free(tracker->name); +} + +grpc_connectivity_state grpc_connectivity_state_check( + grpc_connectivity_state_tracker *tracker) { + if (grpc_connectivity_state_trace) { + gpr_log(GPR_DEBUG, "CONWATCH: %p %s: get %s", tracker, tracker->name, + grpc_connectivity_state_name(tracker->current_state)); + } + return tracker->current_state; +} + +int grpc_connectivity_state_notify_on_state_change( + grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker, + grpc_connectivity_state *current, grpc_closure *notify) { + if (grpc_connectivity_state_trace) { + if (current == NULL) { + gpr_log(GPR_DEBUG, "CONWATCH: %p %s: unsubscribe notify=%p", tracker, + tracker->name, notify); + } else { + gpr_log(GPR_DEBUG, "CONWATCH: %p %s: from %s [cur=%s] notify=%p", tracker, + tracker->name, grpc_connectivity_state_name(*current), + grpc_connectivity_state_name(tracker->current_state), notify); + } + } + if (current == NULL) { + grpc_connectivity_state_watcher *w = tracker->watchers; + if (w != NULL && w->notify == notify) { + grpc_exec_ctx_enqueue(exec_ctx, notify, false, NULL); + tracker->watchers = w->next; + gpr_free(w); + return 0; + } + while (w != NULL) { + grpc_connectivity_state_watcher *rm_candidate = w->next; + if (rm_candidate != NULL && rm_candidate->notify == notify) { + grpc_exec_ctx_enqueue(exec_ctx, notify, false, NULL); + w->next = w->next->next; + gpr_free(rm_candidate); + return 0; + } + w = w->next; + } + return 0; + } else { + if (tracker->current_state != *current) { + *current = tracker->current_state; + grpc_exec_ctx_enqueue(exec_ctx, notify, true, NULL); + } else { + grpc_connectivity_state_watcher *w = gpr_malloc(sizeof(*w)); + w->current = current; + w->notify = notify; + w->next = tracker->watchers; + tracker->watchers = w; + } + return tracker->current_state == GRPC_CHANNEL_IDLE; + } +} + +void grpc_connectivity_state_set(grpc_exec_ctx *exec_ctx, + grpc_connectivity_state_tracker *tracker, + grpc_connectivity_state state, + const char *reason) { + grpc_connectivity_state_watcher *w; + if (grpc_connectivity_state_trace) { + gpr_log(GPR_DEBUG, "SET: %p %s: %s --> %s [%s]", tracker, tracker->name, + grpc_connectivity_state_name(tracker->current_state), + grpc_connectivity_state_name(state), reason); + } + if (tracker->current_state == state) { + return; + } + GPR_ASSERT(tracker->current_state != GRPC_CHANNEL_FATAL_FAILURE); + tracker->current_state = state; + while ((w = tracker->watchers) != NULL) { + *w->current = tracker->current_state; + tracker->watchers = w->next; + grpc_exec_ctx_enqueue(exec_ctx, w->notify, true, NULL); + gpr_free(w); + } +} diff --git a/src/core/lib/transport/connectivity_state.h b/src/core/lib/transport/connectivity_state.h new file mode 100644 index 0000000000..b4a3ce924d --- /dev/null +++ b/src/core/lib/transport/connectivity_state.h @@ -0,0 +1,85 @@ +/* + * + * Copyright 2015-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_TRANSPORT_CONNECTIVITY_STATE_H +#define GRPC_CORE_TRANSPORT_CONNECTIVITY_STATE_H + +#include +#include "src/core/iomgr/exec_ctx.h" + +typedef struct grpc_connectivity_state_watcher { + /** we keep watchers in a linked list */ + struct grpc_connectivity_state_watcher *next; + /** closure to notify on change */ + grpc_closure *notify; + /** the current state as believed by the watcher */ + grpc_connectivity_state *current; +} grpc_connectivity_state_watcher; + +typedef struct { + /** current connectivity state */ + grpc_connectivity_state current_state; + /** all our watchers */ + grpc_connectivity_state_watcher *watchers; + /** a name to help debugging */ + char *name; +} grpc_connectivity_state_tracker; + +extern int grpc_connectivity_state_trace; + +const char *grpc_connectivity_state_name(grpc_connectivity_state state); + +void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker, + grpc_connectivity_state init_state, + const char *name); +void grpc_connectivity_state_destroy(grpc_exec_ctx *exec_ctx, + grpc_connectivity_state_tracker *tracker); + +/** Set connectivity state; not thread safe; access must be serialized with an + * external lock */ +void grpc_connectivity_state_set(grpc_exec_ctx *exec_ctx, + grpc_connectivity_state_tracker *tracker, + grpc_connectivity_state state, + const char *reason); + +grpc_connectivity_state grpc_connectivity_state_check( + grpc_connectivity_state_tracker *tracker); + +/** Return 1 if the channel should start connecting, 0 otherwise. + If current==NULL cancel notify if it is already queued (success==0 in that + case) */ +int grpc_connectivity_state_notify_on_state_change( + grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker, + grpc_connectivity_state *current, grpc_closure *notify); + +#endif /* GRPC_CORE_TRANSPORT_CONNECTIVITY_STATE_H */ diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c new file mode 100644 index 0000000000..7ed28feca8 --- /dev/null +++ b/src/core/lib/transport/metadata.c @@ -0,0 +1,698 @@ +/* + * + * Copyright 2015-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/transport/metadata.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/profiling/timers.h" +#include "src/core/support/murmur_hash.h" +#include "src/core/support/string.h" +#include "src/core/transport/chttp2/bin_encoder.h" +#include "src/core/transport/static_metadata.h" + +/* There are two kinds of mdelem and mdstr instances. + * Static instances are declared in static_metadata.{h,c} and + * are initialized by grpc_mdctx_global_init(). + * Dynamic instances are stored in hash tables on grpc_mdctx, and are backed + * by internal_string and internal_element structures. + * Internal helper functions here-in (is_mdstr_static, is_mdelem_static) are + * used to determine which kind of element a pointer refers to. + */ + +#define INITIAL_STRTAB_CAPACITY 4 +#define INITIAL_MDTAB_CAPACITY 4 + +#ifdef GRPC_METADATA_REFCOUNT_DEBUG +#define DEBUG_ARGS , const char *file, int line +#define FWD_DEBUG_ARGS , file, line +#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s), __FILE__, __LINE__) +#else +#define DEBUG_ARGS +#define FWD_DEBUG_ARGS +#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s)) +#endif + +#define TABLE_IDX(hash, log2_shards, capacity) \ + (((hash) >> (log2_shards)) % (capacity)) +#define SHARD_IDX(hash, log2_shards) ((hash) & ((1 << (log2_shards)) - 1)) + +typedef void (*destroy_user_data_func)(void *user_data); + +/* Shadow structure for grpc_mdstr for non-static values */ +typedef struct internal_string { + /* must be byte compatible with grpc_mdstr */ + gpr_slice slice; + uint32_t hash; + + /* private only data */ + gpr_atm refcnt; + + uint8_t has_base64_and_huffman_encoded; + gpr_slice_refcount refcount; + + gpr_slice base64_and_huffman; + + struct internal_string *bucket_next; +} internal_string; + +/* Shadow structure for grpc_mdelem for non-static elements */ +typedef struct internal_metadata { + /* must be byte compatible with grpc_mdelem */ + internal_string *key; + internal_string *value; + + /* private only data */ + gpr_atm refcnt; + + gpr_mu mu_user_data; + gpr_atm destroy_user_data; + gpr_atm user_data; + + struct internal_metadata *bucket_next; +} internal_metadata; + +typedef struct strtab_shard { + gpr_mu mu; + internal_string **strs; + size_t count; + size_t capacity; +} strtab_shard; + +typedef struct mdtab_shard { + gpr_mu mu; + internal_metadata **elems; + size_t count; + size_t capacity; + size_t free; +} mdtab_shard; + +#define LOG2_STRTAB_SHARD_COUNT 5 +#define LOG2_MDTAB_SHARD_COUNT 4 +#define STRTAB_SHARD_COUNT ((size_t)(1 << LOG2_STRTAB_SHARD_COUNT)) +#define MDTAB_SHARD_COUNT ((size_t)(1 << LOG2_MDTAB_SHARD_COUNT)) + +/* hash seed: decided at initialization time */ +static uint32_t g_hash_seed; +static int g_forced_hash_seed = 0; + +/* linearly probed hash tables for static element lookup */ +static grpc_mdstr *g_static_strtab[GRPC_STATIC_MDSTR_COUNT * 2]; +static grpc_mdelem *g_static_mdtab[GRPC_STATIC_MDELEM_COUNT * 2]; +static size_t g_static_strtab_maxprobe; +static size_t g_static_mdtab_maxprobe; + +static strtab_shard g_strtab_shard[STRTAB_SHARD_COUNT]; +static mdtab_shard g_mdtab_shard[MDTAB_SHARD_COUNT]; + +static void gc_mdtab(mdtab_shard *shard); + +void grpc_test_only_set_metadata_hash_seed(uint32_t seed) { + g_hash_seed = seed; + g_forced_hash_seed = 1; +} + +void grpc_mdctx_global_init(void) { + size_t i, j; + if (!g_forced_hash_seed) { + g_hash_seed = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec; + } + g_static_strtab_maxprobe = 0; + g_static_mdtab_maxprobe = 0; + /* build static tables */ + memset(g_static_mdtab, 0, sizeof(g_static_mdtab)); + memset(g_static_strtab, 0, sizeof(g_static_strtab)); + for (i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) { + grpc_mdstr *elem = &grpc_static_mdstr_table[i]; + const char *str = grpc_static_metadata_strings[i]; + uint32_t hash = gpr_murmur_hash3(str, strlen(str), g_hash_seed); + *(gpr_slice *)&elem->slice = gpr_slice_from_static_string(str); + *(uint32_t *)&elem->hash = hash; + for (j = 0;; j++) { + size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_strtab); + if (g_static_strtab[idx] == NULL) { + g_static_strtab[idx] = &grpc_static_mdstr_table[i]; + break; + } + } + if (j > g_static_strtab_maxprobe) { + g_static_strtab_maxprobe = j; + } + } + for (i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) { + grpc_mdelem *elem = &grpc_static_mdelem_table[i]; + grpc_mdstr *key = + &grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 0]]; + grpc_mdstr *value = + &grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 1]]; + uint32_t hash = GRPC_MDSTR_KV_HASH(key->hash, value->hash); + *(grpc_mdstr **)&elem->key = key; + *(grpc_mdstr **)&elem->value = value; + for (j = 0;; j++) { + size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_mdtab); + if (g_static_mdtab[idx] == NULL) { + g_static_mdtab[idx] = elem; + break; + } + } + if (j > g_static_mdtab_maxprobe) { + g_static_mdtab_maxprobe = j; + } + } + /* initialize shards */ + for (i = 0; i < STRTAB_SHARD_COUNT; i++) { + strtab_shard *shard = &g_strtab_shard[i]; + gpr_mu_init(&shard->mu); + shard->count = 0; + shard->capacity = INITIAL_STRTAB_CAPACITY; + shard->strs = gpr_malloc(sizeof(*shard->strs) * shard->capacity); + memset(shard->strs, 0, sizeof(*shard->strs) * shard->capacity); + } + for (i = 0; i < MDTAB_SHARD_COUNT; i++) { + mdtab_shard *shard = &g_mdtab_shard[i]; + gpr_mu_init(&shard->mu); + shard->count = 0; + shard->free = 0; + shard->capacity = INITIAL_MDTAB_CAPACITY; + shard->elems = gpr_malloc(sizeof(*shard->elems) * shard->capacity); + memset(shard->elems, 0, sizeof(*shard->elems) * shard->capacity); + } +} + +void grpc_mdctx_global_shutdown(void) { + size_t i; + for (i = 0; i < MDTAB_SHARD_COUNT; i++) { + mdtab_shard *shard = &g_mdtab_shard[i]; + gpr_mu_destroy(&shard->mu); + gc_mdtab(shard); + /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */ + if (shard->count != 0) { + gpr_log(GPR_DEBUG, "WARNING: %d metadata elements were leaked", + shard->count); + if (grpc_iomgr_abort_on_leaks()) { + abort(); + } + } + gpr_free(shard->elems); + } + for (i = 0; i < STRTAB_SHARD_COUNT; i++) { + strtab_shard *shard = &g_strtab_shard[i]; + gpr_mu_destroy(&shard->mu); + /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */ + if (shard->count != 0) { + gpr_log(GPR_DEBUG, "WARNING: %d metadata strings were leaked", + shard->count); + if (grpc_iomgr_abort_on_leaks()) { + abort(); + } + } + gpr_free(shard->strs); + } +} + +static int is_mdstr_static(grpc_mdstr *s) { + return s >= &grpc_static_mdstr_table[0] && + s < &grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; +} + +static int is_mdelem_static(grpc_mdelem *e) { + return e >= &grpc_static_mdelem_table[0] && + e < &grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; +} + +static void ref_md_locked(mdtab_shard *shard, + internal_metadata *md DEBUG_ARGS) { +#ifdef GRPC_METADATA_REFCOUNT_DEBUG + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "ELM REF:%p:%d->%d: '%s' = '%s'", md, + gpr_atm_no_barrier_load(&md->refcnt), + gpr_atm_no_barrier_load(&md->refcnt) + 1, + grpc_mdstr_as_c_string((grpc_mdstr *)md->key), + grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); +#endif + if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 2)) { + shard->free--; + } else { + GPR_ASSERT(1 != gpr_atm_no_barrier_fetch_add(&md->refcnt, -1)); + } +} + +static void grow_strtab(strtab_shard *shard) { + size_t capacity = shard->capacity * 2; + size_t i; + internal_string **strtab; + internal_string *s, *next; + + GPR_TIMER_BEGIN("grow_strtab", 0); + + strtab = gpr_malloc(sizeof(internal_string *) * capacity); + memset(strtab, 0, sizeof(internal_string *) * capacity); + + for (i = 0; i < shard->capacity; i++) { + for (s = shard->strs[i]; s; s = next) { + size_t idx = TABLE_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT, capacity); + next = s->bucket_next; + s->bucket_next = strtab[idx]; + strtab[idx] = s; + } + } + + gpr_free(shard->strs); + shard->strs = strtab; + shard->capacity = capacity; + + GPR_TIMER_END("grow_strtab", 0); +} + +static void internal_destroy_string(strtab_shard *shard, internal_string *is) { + internal_string **prev_next; + internal_string *cur; + GPR_TIMER_BEGIN("internal_destroy_string", 0); + if (is->has_base64_and_huffman_encoded) { + gpr_slice_unref(is->base64_and_huffman); + } + for (prev_next = &shard->strs[TABLE_IDX(is->hash, LOG2_STRTAB_SHARD_COUNT, + shard->capacity)], + cur = *prev_next; + cur != is; prev_next = &cur->bucket_next, cur = cur->bucket_next) + ; + *prev_next = cur->bucket_next; + shard->count--; + gpr_free(is); + GPR_TIMER_END("internal_destroy_string", 0); +} + +static void slice_ref(void *p) { + internal_string *is = + (internal_string *)((char *)p - offsetof(internal_string, refcount)); + GRPC_MDSTR_REF((grpc_mdstr *)(is)); +} + +static void slice_unref(void *p) { + internal_string *is = + (internal_string *)((char *)p - offsetof(internal_string, refcount)); + GRPC_MDSTR_UNREF((grpc_mdstr *)(is)); +} + +grpc_mdstr *grpc_mdstr_from_string(const char *str) { + return grpc_mdstr_from_buffer((const uint8_t *)str, strlen(str)); +} + +grpc_mdstr *grpc_mdstr_from_slice(gpr_slice slice) { + grpc_mdstr *result = grpc_mdstr_from_buffer(GPR_SLICE_START_PTR(slice), + GPR_SLICE_LENGTH(slice)); + gpr_slice_unref(slice); + return result; +} + +grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) { + uint32_t hash = gpr_murmur_hash3(buf, length, g_hash_seed); + internal_string *s; + strtab_shard *shard = + &g_strtab_shard[SHARD_IDX(hash, LOG2_STRTAB_SHARD_COUNT)]; + size_t i; + size_t idx; + + GPR_TIMER_BEGIN("grpc_mdstr_from_buffer", 0); + + /* search for a static string */ + for (i = 0; i <= g_static_strtab_maxprobe; i++) { + grpc_mdstr *ss; + idx = (hash + i) % GPR_ARRAY_SIZE(g_static_strtab); + ss = g_static_strtab[idx]; + if (ss == NULL) break; + if (ss->hash == hash && GPR_SLICE_LENGTH(ss->slice) == length && + 0 == memcmp(buf, GPR_SLICE_START_PTR(ss->slice), length)) { + GPR_TIMER_END("grpc_mdstr_from_buffer", 0); + return ss; + } + } + + gpr_mu_lock(&shard->mu); + + /* search for an existing string */ + idx = TABLE_IDX(hash, LOG2_STRTAB_SHARD_COUNT, shard->capacity); + for (s = shard->strs[idx]; s; s = s->bucket_next) { + if (s->hash == hash && GPR_SLICE_LENGTH(s->slice) == length && + 0 == memcmp(buf, GPR_SLICE_START_PTR(s->slice), length)) { + GRPC_MDSTR_REF((grpc_mdstr *)s); + gpr_mu_unlock(&shard->mu); + GPR_TIMER_END("grpc_mdstr_from_buffer", 0); + return (grpc_mdstr *)s; + } + } + + /* not found: create a new string */ + if (length + 1 < GPR_SLICE_INLINED_SIZE) { + /* string data goes directly into the slice */ + s = gpr_malloc(sizeof(internal_string)); + gpr_atm_rel_store(&s->refcnt, 2); + s->slice.refcount = NULL; + memcpy(s->slice.data.inlined.bytes, buf, length); + s->slice.data.inlined.bytes[length] = 0; + s->slice.data.inlined.length = (uint8_t)length; + } else { + /* string data goes after the internal_string header, and we +1 for null + terminator */ + s = gpr_malloc(sizeof(internal_string) + length + 1); + gpr_atm_rel_store(&s->refcnt, 2); + s->refcount.ref = slice_ref; + s->refcount.unref = slice_unref; + s->slice.refcount = &s->refcount; + s->slice.data.refcounted.bytes = (uint8_t *)(s + 1); + s->slice.data.refcounted.length = length; + memcpy(s->slice.data.refcounted.bytes, buf, length); + /* add a null terminator for cheap c string conversion when desired */ + s->slice.data.refcounted.bytes[length] = 0; + } + s->has_base64_and_huffman_encoded = 0; + s->hash = hash; + s->bucket_next = shard->strs[idx]; + shard->strs[idx] = s; + + shard->count++; + + if (shard->count > shard->capacity * 2) { + grow_strtab(shard); + } + + gpr_mu_unlock(&shard->mu); + GPR_TIMER_END("grpc_mdstr_from_buffer", 0); + + return (grpc_mdstr *)s; +} + +static void gc_mdtab(mdtab_shard *shard) { + size_t i; + internal_metadata **prev_next; + internal_metadata *md, *next; + + GPR_TIMER_BEGIN("gc_mdtab", 0); + for (i = 0; i < shard->capacity; i++) { + prev_next = &shard->elems[i]; + for (md = shard->elems[i]; md; md = next) { + void *user_data = (void *)gpr_atm_no_barrier_load(&md->user_data); + next = md->bucket_next; + if (gpr_atm_acq_load(&md->refcnt) == 0) { + GRPC_MDSTR_UNREF((grpc_mdstr *)md->key); + GRPC_MDSTR_UNREF((grpc_mdstr *)md->value); + if (md->user_data) { + ((destroy_user_data_func)gpr_atm_no_barrier_load( + &md->destroy_user_data))(user_data); + } + gpr_free(md); + *prev_next = next; + shard->free--; + shard->count--; + } else { + prev_next = &md->bucket_next; + } + } + } + GPR_TIMER_END("gc_mdtab", 0); +} + +static void grow_mdtab(mdtab_shard *shard) { + size_t capacity = shard->capacity * 2; + size_t i; + internal_metadata **mdtab; + internal_metadata *md, *next; + uint32_t hash; + + GPR_TIMER_BEGIN("grow_mdtab", 0); + + mdtab = gpr_malloc(sizeof(internal_metadata *) * capacity); + memset(mdtab, 0, sizeof(internal_metadata *) * capacity); + + for (i = 0; i < shard->capacity; i++) { + for (md = shard->elems[i]; md; md = next) { + size_t idx; + hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash); + next = md->bucket_next; + idx = TABLE_IDX(hash, LOG2_MDTAB_SHARD_COUNT, capacity); + md->bucket_next = mdtab[idx]; + mdtab[idx] = md; + } + } + + gpr_free(shard->elems); + shard->elems = mdtab; + shard->capacity = capacity; + + GPR_TIMER_END("grow_mdtab", 0); +} + +static void rehash_mdtab(mdtab_shard *shard) { + if (shard->free > shard->capacity / 4) { + gc_mdtab(shard); + } else { + grow_mdtab(shard); + } +} + +grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *mkey, + grpc_mdstr *mvalue) { + internal_string *key = (internal_string *)mkey; + internal_string *value = (internal_string *)mvalue; + uint32_t hash = GRPC_MDSTR_KV_HASH(mkey->hash, mvalue->hash); + internal_metadata *md; + mdtab_shard *shard = &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)]; + size_t i; + size_t idx; + + GPR_TIMER_BEGIN("grpc_mdelem_from_metadata_strings", 0); + + if (is_mdstr_static(mkey) && is_mdstr_static(mvalue)) { + for (i = 0; i <= g_static_mdtab_maxprobe; i++) { + grpc_mdelem *smd; + idx = (hash + i) % GPR_ARRAY_SIZE(g_static_mdtab); + smd = g_static_mdtab[idx]; + if (smd == NULL) break; + if (smd->key == mkey && smd->value == mvalue) { + GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0); + return smd; + } + } + } + + gpr_mu_lock(&shard->mu); + + idx = TABLE_IDX(hash, LOG2_MDTAB_SHARD_COUNT, shard->capacity); + /* search for an existing pair */ + for (md = shard->elems[idx]; md; md = md->bucket_next) { + if (md->key == key && md->value == value) { + REF_MD_LOCKED(shard, md); + GRPC_MDSTR_UNREF((grpc_mdstr *)key); + GRPC_MDSTR_UNREF((grpc_mdstr *)value); + gpr_mu_unlock(&shard->mu); + GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0); + return (grpc_mdelem *)md; + } + } + + /* not found: create a new pair */ + md = gpr_malloc(sizeof(internal_metadata)); + gpr_atm_rel_store(&md->refcnt, 2); + md->key = key; + md->value = value; + md->user_data = 0; + md->destroy_user_data = 0; + md->bucket_next = shard->elems[idx]; + shard->elems[idx] = md; + gpr_mu_init(&md->mu_user_data); +#ifdef GRPC_METADATA_REFCOUNT_DEBUG + gpr_log(GPR_DEBUG, "ELM NEW:%p:%d: '%s' = '%s'", md, + gpr_atm_no_barrier_load(&md->refcnt), + grpc_mdstr_as_c_string((grpc_mdstr *)md->key), + grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); +#endif + shard->count++; + + if (shard->count > shard->capacity * 2) { + rehash_mdtab(shard); + } + + gpr_mu_unlock(&shard->mu); + + GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0); + + return (grpc_mdelem *)md; +} + +grpc_mdelem *grpc_mdelem_from_strings(const char *key, const char *value) { + return grpc_mdelem_from_metadata_strings(grpc_mdstr_from_string(key), + grpc_mdstr_from_string(value)); +} + +grpc_mdelem *grpc_mdelem_from_slices(gpr_slice key, gpr_slice value) { + return grpc_mdelem_from_metadata_strings(grpc_mdstr_from_slice(key), + grpc_mdstr_from_slice(value)); +} + +grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key, + const uint8_t *value, + size_t value_length) { + return grpc_mdelem_from_metadata_strings( + grpc_mdstr_from_string(key), grpc_mdstr_from_buffer(value, value_length)); +} + +grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) { + internal_metadata *md = (internal_metadata *)gmd; + if (is_mdelem_static(gmd)) return gmd; +#ifdef GRPC_METADATA_REFCOUNT_DEBUG + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "ELM REF:%p:%d->%d: '%s' = '%s'", md, + gpr_atm_no_barrier_load(&md->refcnt), + gpr_atm_no_barrier_load(&md->refcnt) + 1, + grpc_mdstr_as_c_string((grpc_mdstr *)md->key), + grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); +#endif + /* we can assume the ref count is >= 1 as the application is calling + this function - meaning that no adjustment to mdtab_free is necessary, + simplifying the logic here to be just an atomic increment */ + /* use C assert to have this removed in opt builds */ + assert(gpr_atm_no_barrier_load(&md->refcnt) >= 2); + gpr_atm_no_barrier_fetch_add(&md->refcnt, 1); + return gmd; +} + +void grpc_mdelem_unref(grpc_mdelem *gmd DEBUG_ARGS) { + internal_metadata *md = (internal_metadata *)gmd; + if (!md) return; + if (is_mdelem_static(gmd)) return; +#ifdef GRPC_METADATA_REFCOUNT_DEBUG + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "ELM UNREF:%p:%d->%d: '%s' = '%s'", md, + gpr_atm_no_barrier_load(&md->refcnt), + gpr_atm_no_barrier_load(&md->refcnt) - 1, + grpc_mdstr_as_c_string((grpc_mdstr *)md->key), + grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); +#endif + if (2 == gpr_atm_full_fetch_add(&md->refcnt, -1)) { + uint32_t hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash); + mdtab_shard *shard = + &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)]; + GPR_TIMER_BEGIN("grpc_mdelem_unref.to_zero", 0); + gpr_mu_lock(&shard->mu); + if (1 == gpr_atm_no_barrier_load(&md->refcnt)) { + shard->free++; + gpr_atm_no_barrier_store(&md->refcnt, 0); + } + gpr_mu_unlock(&shard->mu); + GPR_TIMER_END("grpc_mdelem_unref.to_zero", 0); + } +} + +const char *grpc_mdstr_as_c_string(grpc_mdstr *s) { + return (const char *)GPR_SLICE_START_PTR(s->slice); +} + +grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *gs DEBUG_ARGS) { + internal_string *s = (internal_string *)gs; + if (is_mdstr_static(gs)) return gs; + GPR_ASSERT(gpr_atm_full_fetch_add(&s->refcnt, 1) != 0); + return gs; +} + +void grpc_mdstr_unref(grpc_mdstr *gs DEBUG_ARGS) { + internal_string *s = (internal_string *)gs; + if (is_mdstr_static(gs)) return; + if (2 == gpr_atm_full_fetch_add(&s->refcnt, -1)) { + strtab_shard *shard = + &g_strtab_shard[SHARD_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT)]; + gpr_mu_lock(&shard->mu); + if (1 == gpr_atm_no_barrier_load(&s->refcnt)) { + internal_destroy_string(shard, s); + } + gpr_mu_unlock(&shard->mu); + } +} + +void *grpc_mdelem_get_user_data(grpc_mdelem *md, void (*destroy_func)(void *)) { + internal_metadata *im = (internal_metadata *)md; + void *result; + if (is_mdelem_static(md)) { + return (void *)grpc_static_mdelem_user_data[md - grpc_static_mdelem_table]; + } + if (gpr_atm_acq_load(&im->destroy_user_data) == (gpr_atm)destroy_func) { + return (void *)gpr_atm_no_barrier_load(&im->user_data); + } else { + return NULL; + } + return result; +} + +void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *), + void *user_data) { + internal_metadata *im = (internal_metadata *)md; + GPR_ASSERT(!is_mdelem_static(md)); + GPR_ASSERT((user_data == NULL) == (destroy_func == NULL)); + gpr_mu_lock(&im->mu_user_data); + if (gpr_atm_no_barrier_load(&im->destroy_user_data)) { + /* user data can only be set once */ + gpr_mu_unlock(&im->mu_user_data); + if (destroy_func != NULL) { + destroy_func(user_data); + } + return; + } + gpr_atm_no_barrier_store(&im->user_data, (gpr_atm)user_data); + gpr_atm_rel_store(&im->destroy_user_data, (gpr_atm)destroy_func); + gpr_mu_unlock(&im->mu_user_data); +} + +gpr_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *gs) { + internal_string *s = (internal_string *)gs; + gpr_slice slice; + strtab_shard *shard = + &g_strtab_shard[SHARD_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT)]; + gpr_mu_lock(&shard->mu); + if (!s->has_base64_and_huffman_encoded) { + s->base64_and_huffman = + grpc_chttp2_base64_encode_and_huffman_compress(s->slice); + s->has_base64_and_huffman_encoded = 1; + } + slice = s->base64_and_huffman; + gpr_mu_unlock(&shard->mu); + return slice; +} diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h new file mode 100644 index 0000000000..5ab397848c --- /dev/null +++ b/src/core/lib/transport/metadata.h @@ -0,0 +1,156 @@ +/* + * + * Copyright 2015-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_TRANSPORT_METADATA_H +#define GRPC_CORE_TRANSPORT_METADATA_H + +#include +#include + +/* This file provides a mechanism for tracking metadata through the grpc stack. + It's not intended for consumption outside of the library. + + Metadata is tracked in the context of a grpc_mdctx. For the time being there + is one of these per-channel, avoiding cross channel interference with memory + use and lock contention. + + The context tracks unique strings (grpc_mdstr) and pairs of strings + (grpc_mdelem). Any of these objects can be checked for equality by comparing + their pointers. These objects are reference counted. + + grpc_mdelem can additionally store a (non-NULL) user data pointer. This + pointer is intended to be used to cache semantic meaning of a metadata + element. For example, an OAuth token may cache the credentials it represents + and the time at which it expires in the mdelem user data. + + Combining this metadata cache and the hpack compression table allows us to + simply lookup complete preparsed objects quickly, incurring a few atomic + ops per metadata element on the fast path. + + grpc_mdelem instances MAY live longer than their refcount implies, and are + garbage collected periodically, meaning cached data can easily outlive a + single request. + + STATIC METADATA: in static_metadata.h we declare a set of static metadata. + These mdelems and mdstrs are available via pre-declared code generated macros + and are available to code anywhere between grpc_init() and grpc_shutdown(). + They are not refcounted, but can be passed to _ref and _unref functions + declared here - in which case those functions are effectively no-ops. */ + +/* Forward declarations */ +typedef struct grpc_mdstr grpc_mdstr; +typedef struct grpc_mdelem grpc_mdelem; + +/* if changing this, make identical changes in internal_string in metadata.c */ +struct grpc_mdstr { + const gpr_slice slice; + const uint32_t hash; + /* there is a private part to this in metadata.c */ +}; + +/* if changing this, make identical changes in internal_metadata in + metadata.c */ +struct grpc_mdelem { + grpc_mdstr *const key; + grpc_mdstr *const value; + /* there is a private part to this in metadata.c */ +}; + +void grpc_test_only_set_metadata_hash_seed(uint32_t seed); + +/* Constructors for grpc_mdstr instances; take a variety of data types that + clients may have handy */ +grpc_mdstr *grpc_mdstr_from_string(const char *str); +/* Unrefs the slice. */ +grpc_mdstr *grpc_mdstr_from_slice(gpr_slice slice); +grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *str, size_t length); + +/* Returns a borrowed slice from the mdstr with its contents base64 encoded + and huffman compressed */ +gpr_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *str); + +/* Constructors for grpc_mdelem instances; take a variety of data types that + clients may have handy */ +grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *key, + grpc_mdstr *value); +grpc_mdelem *grpc_mdelem_from_strings(const char *key, const char *value); +/* Unrefs the slices. */ +grpc_mdelem *grpc_mdelem_from_slices(gpr_slice key, gpr_slice value); +grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key, + const uint8_t *value, + size_t value_length); + +/* Mutator and accessor for grpc_mdelem user data. The destructor function + is used as a type tag and is checked during user_data fetch. */ +void *grpc_mdelem_get_user_data(grpc_mdelem *md, + void (*if_destroy_func)(void *)); +void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *), + void *user_data); + +/* Reference counting */ +#ifdef GRPC_METADATA_REFCOUNT_DEBUG +#define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s), __FILE__, __LINE__) +#define GRPC_MDSTR_UNREF(s) grpc_mdstr_unref((s), __FILE__, __LINE__) +#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__) +#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__) +grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s, const char *file, int line); +void grpc_mdstr_unref(grpc_mdstr *s, const char *file, int line); +grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md, const char *file, int line); +void grpc_mdelem_unref(grpc_mdelem *md, const char *file, int line); +#else +#define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s)) +#define GRPC_MDSTR_UNREF(s) grpc_mdstr_unref((s)) +#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s)) +#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s)) +grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s); +void grpc_mdstr_unref(grpc_mdstr *s); +grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md); +void grpc_mdelem_unref(grpc_mdelem *md); +#endif + +/* Recover a char* from a grpc_mdstr. The returned string is null terminated. + Does not promise that the returned string has no embedded nulls however. */ +const char *grpc_mdstr_as_c_string(grpc_mdstr *s); + +#define GRPC_MDSTR_LENGTH(s) (GPR_SLICE_LENGTH(s->slice)) + +int grpc_mdstr_is_legal_header(grpc_mdstr *s); +int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s); +int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s); + +#define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash)) + +void grpc_mdctx_global_init(void); +void grpc_mdctx_global_shutdown(void); + +#endif /* GRPC_CORE_TRANSPORT_METADATA_H */ diff --git a/src/core/lib/transport/metadata_batch.c b/src/core/lib/transport/metadata_batch.c new file mode 100644 index 0000000000..1266862f82 --- /dev/null +++ b/src/core/lib/transport/metadata_batch.c @@ -0,0 +1,194 @@ +/* + * + * Copyright 2015, 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/transport/metadata_batch.h" + +#include + +#include +#include + +#include "src/core/profiling/timers.h" + +static void assert_valid_list(grpc_mdelem_list *list) { +#ifndef NDEBUG + grpc_linked_mdelem *l; + + GPR_ASSERT((list->head == NULL) == (list->tail == NULL)); + if (!list->head) return; + GPR_ASSERT(list->head->prev == NULL); + GPR_ASSERT(list->tail->next == NULL); + GPR_ASSERT((list->head == list->tail) == (list->head->next == NULL)); + + for (l = list->head; l; l = l->next) { + GPR_ASSERT(l->md); + GPR_ASSERT((l->prev == NULL) == (l == list->head)); + GPR_ASSERT((l->next == NULL) == (l == list->tail)); + if (l->next) GPR_ASSERT(l->next->prev == l); + if (l->prev) GPR_ASSERT(l->prev->next == l); + } +#endif /* NDEBUG */ +} + +#ifndef NDEBUG +void grpc_metadata_batch_assert_ok(grpc_metadata_batch *batch) { + assert_valid_list(&batch->list); +} +#endif /* NDEBUG */ + +void grpc_metadata_batch_init(grpc_metadata_batch *batch) { + batch->list.head = batch->list.tail = NULL; + batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME); +} + +void grpc_metadata_batch_destroy(grpc_metadata_batch *batch) { + grpc_linked_mdelem *l; + for (l = batch->list.head; l; l = l->next) { + GRPC_MDELEM_UNREF(l->md); + } +} + +void grpc_metadata_batch_add_head(grpc_metadata_batch *batch, + grpc_linked_mdelem *storage, + grpc_mdelem *elem_to_add) { + GPR_ASSERT(elem_to_add); + storage->md = elem_to_add; + grpc_metadata_batch_link_head(batch, storage); +} + +static void link_head(grpc_mdelem_list *list, grpc_linked_mdelem *storage) { + assert_valid_list(list); + GPR_ASSERT(storage->md); + storage->prev = NULL; + storage->next = list->head; + if (list->head != NULL) { + list->head->prev = storage; + } else { + list->tail = storage; + } + list->head = storage; + assert_valid_list(list); +} + +void grpc_metadata_batch_link_head(grpc_metadata_batch *batch, + grpc_linked_mdelem *storage) { + link_head(&batch->list, storage); +} + +void grpc_metadata_batch_add_tail(grpc_metadata_batch *batch, + grpc_linked_mdelem *storage, + grpc_mdelem *elem_to_add) { + GPR_ASSERT(elem_to_add); + storage->md = elem_to_add; + grpc_metadata_batch_link_tail(batch, storage); +} + +static void link_tail(grpc_mdelem_list *list, grpc_linked_mdelem *storage) { + assert_valid_list(list); + GPR_ASSERT(storage->md); + storage->prev = list->tail; + storage->next = NULL; + storage->reserved = NULL; + if (list->tail != NULL) { + list->tail->next = storage; + } else { + list->head = storage; + } + list->tail = storage; + assert_valid_list(list); +} + +void grpc_metadata_batch_link_tail(grpc_metadata_batch *batch, + grpc_linked_mdelem *storage) { + link_tail(&batch->list, storage); +} + +void grpc_metadata_batch_move(grpc_metadata_batch *dst, + grpc_metadata_batch *src) { + *dst = *src; + memset(src, 0, sizeof(grpc_metadata_batch)); +} + +void grpc_metadata_batch_filter(grpc_metadata_batch *batch, + grpc_mdelem *(*filter)(void *user_data, + grpc_mdelem *elem), + void *user_data) { + grpc_linked_mdelem *l; + grpc_linked_mdelem *next; + + GPR_TIMER_BEGIN("grpc_metadata_batch_filter", 0); + + assert_valid_list(&batch->list); + for (l = batch->list.head; l; l = next) { + grpc_mdelem *orig = l->md; + grpc_mdelem *filt = filter(user_data, orig); + next = l->next; + if (filt == NULL) { + if (l->prev) { + l->prev->next = l->next; + } + if (l->next) { + l->next->prev = l->prev; + } + if (batch->list.head == l) { + batch->list.head = l->next; + } + if (batch->list.tail == l) { + batch->list.tail = l->prev; + } + assert_valid_list(&batch->list); + GRPC_MDELEM_UNREF(l->md); + } else if (filt != orig) { + GRPC_MDELEM_UNREF(orig); + l->md = filt; + } + } + assert_valid_list(&batch->list); + + GPR_TIMER_END("grpc_metadata_batch_filter", 0); +} + +static grpc_mdelem *no_metadata_for_you(void *user_data, grpc_mdelem *elem) { + return NULL; +} + +void grpc_metadata_batch_clear(grpc_metadata_batch *batch) { + batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME); + grpc_metadata_batch_filter(batch, no_metadata_for_you, NULL); +} + +int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) { + return batch->list.head == NULL && + gpr_time_cmp(gpr_inf_future(batch->deadline.clock_type), + batch->deadline) == 0; +} diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h new file mode 100644 index 0000000000..9337b28328 --- /dev/null +++ b/src/core/lib/transport/metadata_batch.h @@ -0,0 +1,125 @@ +/* + * + * Copyright 2015-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_TRANSPORT_METADATA_BATCH_H +#define GRPC_CORE_TRANSPORT_METADATA_BATCH_H + +#include +#include +#include +#include +#include "src/core/transport/metadata.h" + +typedef struct grpc_linked_mdelem { + grpc_mdelem *md; + struct grpc_linked_mdelem *next; + struct grpc_linked_mdelem *prev; + void *reserved; +} grpc_linked_mdelem; + +typedef struct grpc_mdelem_list { + grpc_linked_mdelem *head; + grpc_linked_mdelem *tail; +} grpc_mdelem_list; + +typedef struct grpc_metadata_batch { + /** Metadata elements in this batch */ + grpc_mdelem_list list; + /** Used to calculate grpc-timeout at the point of sending, + or gpr_inf_future if this batch does not need to send a + grpc-timeout */ + gpr_timespec deadline; +} grpc_metadata_batch; + +void grpc_metadata_batch_init(grpc_metadata_batch *batch); +void grpc_metadata_batch_destroy(grpc_metadata_batch *batch); +void grpc_metadata_batch_clear(grpc_metadata_batch *batch); +int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch); + +/** Moves the metadata information from \a src to \a dst. Upon return, \a src is + * zeroed. */ +void grpc_metadata_batch_move(grpc_metadata_batch *dst, + grpc_metadata_batch *src); + +/** Add \a storage to the beginning of \a batch. storage->md is + assumed to be valid. + \a storage is owned by the caller and must survive for the + lifetime of batch. This usually means it should be around + for the lifetime of the call. */ +void grpc_metadata_batch_link_head(grpc_metadata_batch *batch, + grpc_linked_mdelem *storage); +/** Add \a storage to the end of \a batch. storage->md is + assumed to be valid. + \a storage is owned by the caller and must survive for the + lifetime of batch. This usually means it should be around + for the lifetime of the call. */ +void grpc_metadata_batch_link_tail(grpc_metadata_batch *batch, + grpc_linked_mdelem *storage); + +/** Add \a elem_to_add as the first element in \a batch, using + \a storage as backing storage for the linked list element. + \a storage is owned by the caller and must survive for the + lifetime of batch. This usually means it should be around + for the lifetime of the call. + Takes ownership of \a elem_to_add */ +void grpc_metadata_batch_add_head(grpc_metadata_batch *batch, + grpc_linked_mdelem *storage, + grpc_mdelem *elem_to_add); +/** Add \a elem_to_add as the last element in \a batch, using + \a storage as backing storage for the linked list element. + \a storage is owned by the caller and must survive for the + lifetime of batch. This usually means it should be around + for the lifetime of the call. + Takes ownership of \a elem_to_add */ +void grpc_metadata_batch_add_tail(grpc_metadata_batch *batch, + grpc_linked_mdelem *storage, + grpc_mdelem *elem_to_add); + +/** For each element in \a batch, execute \a filter. + The return value from \a filter will be substituted for the + grpc_mdelem passed to \a filter. If \a filter returns NULL, + the element will be moved to the garbage list. */ +void grpc_metadata_batch_filter(grpc_metadata_batch *batch, + grpc_mdelem *(*filter)(void *user_data, + grpc_mdelem *elem), + void *user_data); + +#ifndef NDEBUG +void grpc_metadata_batch_assert_ok(grpc_metadata_batch *comd); +#else +#define grpc_metadata_batch_assert_ok(comd) \ + do { \ + } while (0) +#endif + +#endif /* GRPC_CORE_TRANSPORT_METADATA_BATCH_H */ diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c new file mode 100644 index 0000000000..30bbb89880 --- /dev/null +++ b/src/core/lib/transport/static_metadata.c @@ -0,0 +1,160 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* + * WARNING: Auto-generated code. + * + * To make changes to this file, change + * tools/codegen/core/gen_static_metadata.py, + * and then re-run it. + * + * See metadata.h for an explanation of the interface here, and metadata.c for + * an + * explanation of what's going on. + */ + +#include "src/core/transport/static_metadata.h" + +grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; + +grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; +uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 8, 6, 2, 4, 8, 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] = + {11, 35, 10, 35, 12, 35, 12, 49, 13, 35, 14, 35, 15, 35, 16, 35, 17, 35, + 19, 35, 20, 35, 21, 35, 24, 35, 25, 35, 26, 35, 27, 35, 28, 35, 29, 35, + 30, 18, 30, 35, 31, 35, 32, 35, 36, 35, 37, 35, 38, 35, 39, 35, 42, 33, + 42, 34, 42, 48, 42, 53, 42, 54, 42, 55, 42, 56, 43, 33, 43, 48, 43, 53, + 46, 0, 46, 1, 46, 2, 50, 35, 57, 35, 58, 35, 59, 35, 60, 35, 61, 35, + 62, 35, 63, 35, 64, 35, 65, 35, 66, 40, 66, 68, 67, 78, 67, 79, 69, 35, + 70, 35, 71, 35, 72, 35, 73, 35, 74, 35, 75, 41, 75, 51, 75, 52, 76, 35, + 77, 35, 80, 3, 80, 4, 80, 5, 80, 6, 80, 7, 80, 8, 80, 9, 81, 35, + 82, 83, 84, 35, 85, 35, 86, 35, 87, 35, 88, 35}; + +const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = { + "0", + "1", + "2", + "200", + "204", + "206", + "304", + "400", + "404", + "500", + "accept", + "accept-charset", + "accept-encoding", + "accept-language", + "accept-ranges", + "access-control-allow-origin", + "age", + "allow", + "application/grpc", + ":authority", + "authorization", + "cache-control", + "census-bin", + "census-binary-bin", + "content-disposition", + "content-encoding", + "content-language", + "content-length", + "content-location", + "content-range", + "content-type", + "cookie", + "date", + "deflate", + "deflate,gzip", + "", + "etag", + "expect", + "expires", + "from", + "GET", + "grpc", + "grpc-accept-encoding", + "grpc-encoding", + "grpc-internal-encoding-request", + "grpc-message", + "grpc-status", + "grpc-timeout", + "gzip", + "gzip, deflate", + "host", + "http", + "https", + "identity", + "identity,deflate", + "identity,deflate,gzip", + "identity,gzip", + "if-match", + "if-modified-since", + "if-none-match", + "if-range", + "if-unmodified-since", + "last-modified", + "link", + "location", + "max-forwards", + ":method", + ":path", + "POST", + "proxy-authenticate", + "proxy-authorization", + "range", + "referer", + "refresh", + "retry-after", + ":scheme", + "server", + "set-cookie", + "/", + "/index.html", + ":status", + "strict-transport-security", + "te", + "trailers", + "transfer-encoding", + "user-agent", + "vary", + "via", + "www-authenticate"}; + +const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 29, 26, 30, + 28, 32, 27, 31}; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h new file mode 100644 index 0000000000..85442f8107 --- /dev/null +++ b/src/core/lib/transport/static_metadata.h @@ -0,0 +1,408 @@ +/* + * + * Copyright 2015-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. + * + */ + +/* + * WARNING: Auto-generated code. + * + * To make changes to this file, change + * tools/codegen/core/gen_static_metadata.py, + * and then re-run it. + * + * See metadata.h for an explanation of the interface here, and metadata.c for + * an + * explanation of what's going on. + */ + +#ifndef GRPC_CORE_TRANSPORT_STATIC_METADATA_H +#define GRPC_CORE_TRANSPORT_STATIC_METADATA_H + +#include "src/core/transport/metadata.h" + +#define GRPC_STATIC_MDSTR_COUNT 89 +extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; +/* "0" */ +#define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0]) +/* "1" */ +#define GRPC_MDSTR_1 (&grpc_static_mdstr_table[1]) +/* "2" */ +#define GRPC_MDSTR_2 (&grpc_static_mdstr_table[2]) +/* "200" */ +#define GRPC_MDSTR_200 (&grpc_static_mdstr_table[3]) +/* "204" */ +#define GRPC_MDSTR_204 (&grpc_static_mdstr_table[4]) +/* "206" */ +#define GRPC_MDSTR_206 (&grpc_static_mdstr_table[5]) +/* "304" */ +#define GRPC_MDSTR_304 (&grpc_static_mdstr_table[6]) +/* "400" */ +#define GRPC_MDSTR_400 (&grpc_static_mdstr_table[7]) +/* "404" */ +#define GRPC_MDSTR_404 (&grpc_static_mdstr_table[8]) +/* "500" */ +#define GRPC_MDSTR_500 (&grpc_static_mdstr_table[9]) +/* "accept" */ +#define GRPC_MDSTR_ACCEPT (&grpc_static_mdstr_table[10]) +/* "accept-charset" */ +#define GRPC_MDSTR_ACCEPT_CHARSET (&grpc_static_mdstr_table[11]) +/* "accept-encoding" */ +#define GRPC_MDSTR_ACCEPT_ENCODING (&grpc_static_mdstr_table[12]) +/* "accept-language" */ +#define GRPC_MDSTR_ACCEPT_LANGUAGE (&grpc_static_mdstr_table[13]) +/* "accept-ranges" */ +#define GRPC_MDSTR_ACCEPT_RANGES (&grpc_static_mdstr_table[14]) +/* "access-control-allow-origin" */ +#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (&grpc_static_mdstr_table[15]) +/* "age" */ +#define GRPC_MDSTR_AGE (&grpc_static_mdstr_table[16]) +/* "allow" */ +#define GRPC_MDSTR_ALLOW (&grpc_static_mdstr_table[17]) +/* "application/grpc" */ +#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (&grpc_static_mdstr_table[18]) +/* ":authority" */ +#define GRPC_MDSTR_AUTHORITY (&grpc_static_mdstr_table[19]) +/* "authorization" */ +#define GRPC_MDSTR_AUTHORIZATION (&grpc_static_mdstr_table[20]) +/* "cache-control" */ +#define GRPC_MDSTR_CACHE_CONTROL (&grpc_static_mdstr_table[21]) +/* "census-bin" */ +#define GRPC_MDSTR_CENSUS_BIN (&grpc_static_mdstr_table[22]) +/* "census-binary-bin" */ +#define GRPC_MDSTR_CENSUS_BINARY_BIN (&grpc_static_mdstr_table[23]) +/* "content-disposition" */ +#define GRPC_MDSTR_CONTENT_DISPOSITION (&grpc_static_mdstr_table[24]) +/* "content-encoding" */ +#define GRPC_MDSTR_CONTENT_ENCODING (&grpc_static_mdstr_table[25]) +/* "content-language" */ +#define GRPC_MDSTR_CONTENT_LANGUAGE (&grpc_static_mdstr_table[26]) +/* "content-length" */ +#define GRPC_MDSTR_CONTENT_LENGTH (&grpc_static_mdstr_table[27]) +/* "content-location" */ +#define GRPC_MDSTR_CONTENT_LOCATION (&grpc_static_mdstr_table[28]) +/* "content-range" */ +#define GRPC_MDSTR_CONTENT_RANGE (&grpc_static_mdstr_table[29]) +/* "content-type" */ +#define GRPC_MDSTR_CONTENT_TYPE (&grpc_static_mdstr_table[30]) +/* "cookie" */ +#define GRPC_MDSTR_COOKIE (&grpc_static_mdstr_table[31]) +/* "date" */ +#define GRPC_MDSTR_DATE (&grpc_static_mdstr_table[32]) +/* "deflate" */ +#define GRPC_MDSTR_DEFLATE (&grpc_static_mdstr_table[33]) +/* "deflate,gzip" */ +#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (&grpc_static_mdstr_table[34]) +/* "" */ +#define GRPC_MDSTR_EMPTY (&grpc_static_mdstr_table[35]) +/* "etag" */ +#define GRPC_MDSTR_ETAG (&grpc_static_mdstr_table[36]) +/* "expect" */ +#define GRPC_MDSTR_EXPECT (&grpc_static_mdstr_table[37]) +/* "expires" */ +#define GRPC_MDSTR_EXPIRES (&grpc_static_mdstr_table[38]) +/* "from" */ +#define GRPC_MDSTR_FROM (&grpc_static_mdstr_table[39]) +/* "GET" */ +#define GRPC_MDSTR_GET (&grpc_static_mdstr_table[40]) +/* "grpc" */ +#define GRPC_MDSTR_GRPC (&grpc_static_mdstr_table[41]) +/* "grpc-accept-encoding" */ +#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (&grpc_static_mdstr_table[42]) +/* "grpc-encoding" */ +#define GRPC_MDSTR_GRPC_ENCODING (&grpc_static_mdstr_table[43]) +/* "grpc-internal-encoding-request" */ +#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[44]) +/* "grpc-message" */ +#define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[45]) +/* "grpc-status" */ +#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[46]) +/* "grpc-timeout" */ +#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[47]) +/* "gzip" */ +#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[48]) +/* "gzip, deflate" */ +#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[49]) +/* "host" */ +#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[50]) +/* "http" */ +#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[51]) +/* "https" */ +#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[52]) +/* "identity" */ +#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[53]) +/* "identity,deflate" */ +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (&grpc_static_mdstr_table[54]) +/* "identity,deflate,gzip" */ +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ + (&grpc_static_mdstr_table[55]) +/* "identity,gzip" */ +#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (&grpc_static_mdstr_table[56]) +/* "if-match" */ +#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[57]) +/* "if-modified-since" */ +#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[58]) +/* "if-none-match" */ +#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[59]) +/* "if-range" */ +#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[60]) +/* "if-unmodified-since" */ +#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[61]) +/* "last-modified" */ +#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[62]) +/* "link" */ +#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[63]) +/* "location" */ +#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[64]) +/* "max-forwards" */ +#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[65]) +/* ":method" */ +#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[66]) +/* ":path" */ +#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[67]) +/* "POST" */ +#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[68]) +/* "proxy-authenticate" */ +#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[69]) +/* "proxy-authorization" */ +#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[70]) +/* "range" */ +#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[71]) +/* "referer" */ +#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[72]) +/* "refresh" */ +#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[73]) +/* "retry-after" */ +#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[74]) +/* ":scheme" */ +#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[75]) +/* "server" */ +#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[76]) +/* "set-cookie" */ +#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[77]) +/* "/" */ +#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[78]) +/* "/index.html" */ +#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[79]) +/* ":status" */ +#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[80]) +/* "strict-transport-security" */ +#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[81]) +/* "te" */ +#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[82]) +/* "trailers" */ +#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[83]) +/* "transfer-encoding" */ +#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[84]) +/* "user-agent" */ +#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[85]) +/* "vary" */ +#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[86]) +/* "via" */ +#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[87]) +/* "www-authenticate" */ +#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[88]) + +#define GRPC_STATIC_MDELEM_COUNT 78 +extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; +extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; +/* "accept-charset": "" */ +#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY (&grpc_static_mdelem_table[0]) +/* "accept": "" */ +#define GRPC_MDELEM_ACCEPT_EMPTY (&grpc_static_mdelem_table[1]) +/* "accept-encoding": "" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY (&grpc_static_mdelem_table[2]) +/* "accept-encoding": "gzip, deflate" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ + (&grpc_static_mdelem_table[3]) +/* "accept-language": "" */ +#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY (&grpc_static_mdelem_table[4]) +/* "accept-ranges": "" */ +#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY (&grpc_static_mdelem_table[5]) +/* "access-control-allow-origin": "" */ +#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ + (&grpc_static_mdelem_table[6]) +/* "age": "" */ +#define GRPC_MDELEM_AGE_EMPTY (&grpc_static_mdelem_table[7]) +/* "allow": "" */ +#define GRPC_MDELEM_ALLOW_EMPTY (&grpc_static_mdelem_table[8]) +/* ":authority": "" */ +#define GRPC_MDELEM_AUTHORITY_EMPTY (&grpc_static_mdelem_table[9]) +/* "authorization": "" */ +#define GRPC_MDELEM_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[10]) +/* "cache-control": "" */ +#define GRPC_MDELEM_CACHE_CONTROL_EMPTY (&grpc_static_mdelem_table[11]) +/* "content-disposition": "" */ +#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY (&grpc_static_mdelem_table[12]) +/* "content-encoding": "" */ +#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY (&grpc_static_mdelem_table[13]) +/* "content-language": "" */ +#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY (&grpc_static_mdelem_table[14]) +/* "content-length": "" */ +#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY (&grpc_static_mdelem_table[15]) +/* "content-location": "" */ +#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY (&grpc_static_mdelem_table[16]) +/* "content-range": "" */ +#define GRPC_MDELEM_CONTENT_RANGE_EMPTY (&grpc_static_mdelem_table[17]) +/* "content-type": "application/grpc" */ +#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ + (&grpc_static_mdelem_table[18]) +/* "content-type": "" */ +#define GRPC_MDELEM_CONTENT_TYPE_EMPTY (&grpc_static_mdelem_table[19]) +/* "cookie": "" */ +#define GRPC_MDELEM_COOKIE_EMPTY (&grpc_static_mdelem_table[20]) +/* "date": "" */ +#define GRPC_MDELEM_DATE_EMPTY (&grpc_static_mdelem_table[21]) +/* "etag": "" */ +#define GRPC_MDELEM_ETAG_EMPTY (&grpc_static_mdelem_table[22]) +/* "expect": "" */ +#define GRPC_MDELEM_EXPECT_EMPTY (&grpc_static_mdelem_table[23]) +/* "expires": "" */ +#define GRPC_MDELEM_EXPIRES_EMPTY (&grpc_static_mdelem_table[24]) +/* "from": "" */ +#define GRPC_MDELEM_FROM_EMPTY (&grpc_static_mdelem_table[25]) +/* "grpc-accept-encoding": "deflate" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE (&grpc_static_mdelem_table[26]) +/* "grpc-accept-encoding": "deflate,gzip" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \ + (&grpc_static_mdelem_table[27]) +/* "grpc-accept-encoding": "gzip" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP (&grpc_static_mdelem_table[28]) +/* "grpc-accept-encoding": "identity" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ + (&grpc_static_mdelem_table[29]) +/* "grpc-accept-encoding": "identity,deflate" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \ + (&grpc_static_mdelem_table[30]) +/* "grpc-accept-encoding": "identity,deflate,gzip" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ + (&grpc_static_mdelem_table[31]) +/* "grpc-accept-encoding": "identity,gzip" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ + (&grpc_static_mdelem_table[32]) +/* "grpc-encoding": "deflate" */ +#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE (&grpc_static_mdelem_table[33]) +/* "grpc-encoding": "gzip" */ +#define GRPC_MDELEM_GRPC_ENCODING_GZIP (&grpc_static_mdelem_table[34]) +/* "grpc-encoding": "identity" */ +#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY (&grpc_static_mdelem_table[35]) +/* "grpc-status": "0" */ +#define GRPC_MDELEM_GRPC_STATUS_0 (&grpc_static_mdelem_table[36]) +/* "grpc-status": "1" */ +#define GRPC_MDELEM_GRPC_STATUS_1 (&grpc_static_mdelem_table[37]) +/* "grpc-status": "2" */ +#define GRPC_MDELEM_GRPC_STATUS_2 (&grpc_static_mdelem_table[38]) +/* "host": "" */ +#define GRPC_MDELEM_HOST_EMPTY (&grpc_static_mdelem_table[39]) +/* "if-match": "" */ +#define GRPC_MDELEM_IF_MATCH_EMPTY (&grpc_static_mdelem_table[40]) +/* "if-modified-since": "" */ +#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[41]) +/* "if-none-match": "" */ +#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY (&grpc_static_mdelem_table[42]) +/* "if-range": "" */ +#define GRPC_MDELEM_IF_RANGE_EMPTY (&grpc_static_mdelem_table[43]) +/* "if-unmodified-since": "" */ +#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[44]) +/* "last-modified": "" */ +#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (&grpc_static_mdelem_table[45]) +/* "link": "" */ +#define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[46]) +/* "location": "" */ +#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[47]) +/* "max-forwards": "" */ +#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (&grpc_static_mdelem_table[48]) +/* ":method": "GET" */ +#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[49]) +/* ":method": "POST" */ +#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[50]) +/* ":path": "/" */ +#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[51]) +/* ":path": "/index.html" */ +#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[52]) +/* "proxy-authenticate": "" */ +#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[53]) +/* "proxy-authorization": "" */ +#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[54]) +/* "range": "" */ +#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[55]) +/* "referer": "" */ +#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[56]) +/* "refresh": "" */ +#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[57]) +/* "retry-after": "" */ +#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[58]) +/* ":scheme": "grpc" */ +#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[59]) +/* ":scheme": "http" */ +#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[60]) +/* ":scheme": "https" */ +#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[61]) +/* "server": "" */ +#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[62]) +/* "set-cookie": "" */ +#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[63]) +/* ":status": "200" */ +#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[64]) +/* ":status": "204" */ +#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[65]) +/* ":status": "206" */ +#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[66]) +/* ":status": "304" */ +#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[67]) +/* ":status": "400" */ +#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[68]) +/* ":status": "404" */ +#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[69]) +/* ":status": "500" */ +#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[70]) +/* "strict-transport-security": "" */ +#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ + (&grpc_static_mdelem_table[71]) +/* "te": "trailers" */ +#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[72]) +/* "transfer-encoding": "" */ +#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[73]) +/* "user-agent": "" */ +#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[74]) +/* "vary": "" */ +#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[75]) +/* "via": "" */ +#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[76]) +/* "www-authenticate": "" */ +#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[77]) + +extern const uint8_t + grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2]; +extern const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT]; +extern const uint8_t grpc_static_accept_encoding_metadata[8]; +#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \ + (&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]]) +#endif /* GRPC_CORE_TRANSPORT_STATIC_METADATA_H */ diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c new file mode 100644 index 0000000000..3b555fa933 --- /dev/null +++ b/src/core/lib/transport/transport.c @@ -0,0 +1,184 @@ +/* + * + * Copyright 2015-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/transport/transport.h" +#include +#include +#include +#include "src/core/transport/transport_impl.h" + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +void grpc_stream_ref(grpc_stream_refcount *refcount, const char *reason) { + gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count); + gpr_log(GPR_DEBUG, "%s %p:%p REF %d->%d %s", refcount->object_type, + refcount, refcount->destroy.cb_arg, val, val + 1, reason); +#else +void grpc_stream_ref(grpc_stream_refcount *refcount) { +#endif + gpr_ref_non_zero(&refcount->refs); +} + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount, + const char *reason) { + gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count); + gpr_log(GPR_DEBUG, "%s %p:%p UNREF %d->%d %s", refcount->object_type, + refcount, refcount->destroy.cb_arg, val, val - 1, reason); +#else +void grpc_stream_unref(grpc_exec_ctx *exec_ctx, + grpc_stream_refcount *refcount) { +#endif + if (gpr_unref(&refcount->refs)) { + grpc_exec_ctx_enqueue(exec_ctx, &refcount->destroy, true, NULL); + } +} + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, + grpc_iomgr_cb_func cb, void *cb_arg, + const char *object_type) { + refcount->object_type = object_type; +#else +void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, + grpc_iomgr_cb_func cb, void *cb_arg) { +#endif + gpr_ref_init(&refcount->refs, initial_refs); + grpc_closure_init(&refcount->destroy, cb, cb_arg); +} + +size_t grpc_transport_stream_size(grpc_transport *transport) { + return transport->vtable->sizeof_stream; +} + +void grpc_transport_destroy(grpc_exec_ctx *exec_ctx, + grpc_transport *transport) { + transport->vtable->destroy(exec_ctx, transport); +} + +int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx, + grpc_transport *transport, grpc_stream *stream, + grpc_stream_refcount *refcount, + const void *server_data) { + return transport->vtable->init_stream(exec_ctx, transport, stream, refcount, + server_data); +} + +void grpc_transport_perform_stream_op(grpc_exec_ctx *exec_ctx, + grpc_transport *transport, + grpc_stream *stream, + grpc_transport_stream_op *op) { + transport->vtable->perform_stream_op(exec_ctx, transport, stream, op); +} + +void grpc_transport_perform_op(grpc_exec_ctx *exec_ctx, + grpc_transport *transport, + grpc_transport_op *op) { + transport->vtable->perform_op(exec_ctx, transport, op); +} + +void grpc_transport_set_pollset(grpc_exec_ctx *exec_ctx, + grpc_transport *transport, grpc_stream *stream, + grpc_pollset *pollset) { + transport->vtable->set_pollset(exec_ctx, transport, stream, pollset); +} + +void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx, + grpc_transport *transport, + grpc_stream *stream) { + transport->vtable->destroy_stream(exec_ctx, transport, stream); +} + +char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx, + grpc_transport *transport) { + return transport->vtable->get_peer(exec_ctx, transport); +} + +void grpc_transport_stream_op_finish_with_failure( + grpc_exec_ctx *exec_ctx, grpc_transport_stream_op *op) { + grpc_exec_ctx_enqueue(exec_ctx, op->recv_message_ready, false, NULL); + grpc_exec_ctx_enqueue(exec_ctx, op->recv_initial_metadata_ready, false, NULL); + grpc_exec_ctx_enqueue(exec_ctx, op->on_complete, false, NULL); +} + +void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op, + grpc_status_code status) { + GPR_ASSERT(status != GRPC_STATUS_OK); + if (op->cancel_with_status == GRPC_STATUS_OK) { + op->cancel_with_status = status; + } + if (op->close_with_status != GRPC_STATUS_OK) { + op->close_with_status = GRPC_STATUS_OK; + if (op->optional_close_message != NULL) { + gpr_slice_unref(*op->optional_close_message); + op->optional_close_message = NULL; + } + } +} + +typedef struct { + gpr_slice message; + grpc_closure *then_call; + grpc_closure closure; +} close_message_data; + +static void free_message(grpc_exec_ctx *exec_ctx, void *p, bool iomgr_success) { + close_message_data *cmd = p; + gpr_slice_unref(cmd->message); + if (cmd->then_call != NULL) { + cmd->then_call->cb(exec_ctx, cmd->then_call->cb_arg, iomgr_success); + } + gpr_free(cmd); +} + +void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op, + grpc_status_code status, + gpr_slice *optional_message) { + close_message_data *cmd; + GPR_ASSERT(status != GRPC_STATUS_OK); + if (op->cancel_with_status != GRPC_STATUS_OK || + op->close_with_status != GRPC_STATUS_OK) { + if (optional_message) { + gpr_slice_unref(*optional_message); + } + return; + } + if (optional_message) { + cmd = gpr_malloc(sizeof(*cmd)); + cmd->message = *optional_message; + cmd->then_call = op->on_complete; + grpc_closure_init(&cmd->closure, free_message, cmd); + op->on_complete = &cmd->closure; + op->optional_close_message = &cmd->message; + } + op->close_with_status = status; +} diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h new file mode 100644 index 0000000000..f43e56f23c --- /dev/null +++ b/src/core/lib/transport/transport.h @@ -0,0 +1,242 @@ +/* + * + * Copyright 2015-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_TRANSPORT_TRANSPORT_H +#define GRPC_CORE_TRANSPORT_TRANSPORT_H + +#include + +#include "src/core/channel/context.h" +#include "src/core/iomgr/pollset.h" +#include "src/core/iomgr/pollset_set.h" +#include "src/core/transport/byte_stream.h" +#include "src/core/transport/metadata_batch.h" + +/* forward declarations */ +typedef struct grpc_transport grpc_transport; + +/* grpc_stream doesn't actually exist. It's used as a typesafe + opaque pointer for whatever data the transport wants to track + for a stream. */ +typedef struct grpc_stream grpc_stream; + +/*#define GRPC_STREAM_REFCOUNT_DEBUG*/ + +typedef struct grpc_stream_refcount { + gpr_refcount refs; + grpc_closure destroy; +#ifdef GRPC_STREAM_REFCOUNT_DEBUG + const char *object_type; +#endif +} grpc_stream_refcount; + +#ifdef GRPC_STREAM_REFCOUNT_DEBUG +void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, + grpc_iomgr_cb_func cb, void *cb_arg, + const char *object_type); +void grpc_stream_ref(grpc_stream_refcount *refcount, const char *reason); +void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount, + const char *reason); +#define GRPC_STREAM_REF_INIT(rc, ir, cb, cb_arg, objtype) \ + grpc_stream_ref_init(rc, ir, cb, cb_arg, objtype) +#else +void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, + grpc_iomgr_cb_func cb, void *cb_arg); +void grpc_stream_ref(grpc_stream_refcount *refcount); +void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount); +#define GRPC_STREAM_REF_INIT(rc, ir, cb, cb_arg, objtype) \ + grpc_stream_ref_init(rc, ir, cb, cb_arg) +#endif + +/* Transport stream op: a set of operations to perform on a transport + against a single stream */ +typedef struct grpc_transport_stream_op { + /** Send initial metadata to the peer, from the provided metadata batch. */ + grpc_metadata_batch *send_initial_metadata; + + /** Send trailing metadata to the peer, from the provided metadata batch. */ + grpc_metadata_batch *send_trailing_metadata; + + /** Send message data to the peer, from the provided byte stream. */ + grpc_byte_stream *send_message; + + /** Receive initial metadata from the stream, into provided metadata batch. */ + grpc_metadata_batch *recv_initial_metadata; + /** Should be enqueued when initial metadata is ready to be processed. */ + grpc_closure *recv_initial_metadata_ready; + + /** Receive message data from the stream, into provided byte stream. */ + grpc_byte_stream **recv_message; + /** Should be enqueued when one message is ready to be processed. */ + grpc_closure *recv_message_ready; + + /** Receive trailing metadata from the stream, into provided metadata batch. + */ + grpc_metadata_batch *recv_trailing_metadata; + + /** Should be enqueued when all requested operations (excluding recv_message + and recv_initial_metadata which have their own closures) in a given batch + have been completed. */ + grpc_closure *on_complete; + + /** If != GRPC_STATUS_OK, cancel this stream */ + grpc_status_code cancel_with_status; + + /** If != GRPC_STATUS_OK, send grpc-status, grpc-message, and close this + stream for both reading and writing */ + grpc_status_code close_with_status; + gpr_slice *optional_close_message; + + /* Indexes correspond to grpc_context_index enum values */ + grpc_call_context_element *context; +} grpc_transport_stream_op; + +/** Transport op: a set of operations to perform on a transport as a whole */ +typedef struct grpc_transport_op { + /** Called when processing of this op is done. */ + grpc_closure *on_consumed; + /** connectivity monitoring - set connectivity_state to NULL to unsubscribe */ + grpc_closure *on_connectivity_state_change; + grpc_connectivity_state *connectivity_state; + /** should the transport be disconnected */ + int disconnect; + /** should we send a goaway? + after a goaway is sent, once there are no more active calls on + the transport, the transport should disconnect */ + int send_goaway; + /** what should the goaway contain? */ + grpc_status_code goaway_status; + gpr_slice *goaway_message; + /** set the callback for accepting new streams; + this is a permanent callback, unlike the other one-shot closures. + If true, the callback is set to set_accept_stream_fn, with its + user_data argument set to set_accept_stream_user_data */ + bool set_accept_stream; + void (*set_accept_stream_fn)(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_transport *transport, + const void *server_data); + void *set_accept_stream_user_data; + /** add this transport to a pollset */ + grpc_pollset *bind_pollset; + /** add this transport to a pollset_set */ + grpc_pollset_set *bind_pollset_set; + /** send a ping, call this back if not NULL */ + grpc_closure *send_ping; +} grpc_transport_op; + +/* Returns the amount of memory required to store a grpc_stream for this + transport */ +size_t grpc_transport_stream_size(grpc_transport *transport); + +/* Initialize transport data for a stream. + + Returns 0 on success, any other (transport-defined) value for failure. + + Arguments: + transport - the transport on which to create this stream + stream - a pointer to uninitialized memory to initialize + server_data - either NULL for a client initiated stream, or a pointer + supplied from the accept_stream callback function */ +int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx, + grpc_transport *transport, grpc_stream *stream, + grpc_stream_refcount *refcount, + const void *server_data); + +void grpc_transport_set_pollset(grpc_exec_ctx *exec_ctx, + grpc_transport *transport, grpc_stream *stream, + grpc_pollset *pollset); + +/* Destroy transport data for a stream. + + Requires: a recv_batch with final_state == GRPC_STREAM_CLOSED has been + received by the up-layer. Must not be called in the same call stack as + recv_frame. + + Arguments: + transport - the transport on which to create this stream + stream - the grpc_stream to destroy (memory is still owned by the + caller, but any child memory must be cleaned up) */ +void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx, + grpc_transport *transport, + grpc_stream *stream); + +void grpc_transport_stream_op_finish_with_failure(grpc_exec_ctx *exec_ctx, + grpc_transport_stream_op *op); + +void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op, + grpc_status_code status); + +void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op, + grpc_status_code status, + gpr_slice *optional_message); + +char *grpc_transport_stream_op_string(grpc_transport_stream_op *op); + +/* Send a batch of operations on a transport + + Takes ownership of any objects contained in ops. + + Arguments: + transport - the transport on which to initiate the stream + stream - the stream on which to send the operations. This must be + non-NULL and previously initialized by the same transport. + op - a grpc_transport_stream_op specifying the op to perform */ +void grpc_transport_perform_stream_op(grpc_exec_ctx *exec_ctx, + grpc_transport *transport, + grpc_stream *stream, + grpc_transport_stream_op *op); + +void grpc_transport_perform_op(grpc_exec_ctx *exec_ctx, + grpc_transport *transport, + grpc_transport_op *op); + +/* Send a ping on a transport + + Calls cb with user data when a response is received. */ +void grpc_transport_ping(grpc_transport *transport, grpc_closure *cb); + +/* Advise peer of pending connection termination. */ +void grpc_transport_goaway(grpc_transport *transport, grpc_status_code status, + gpr_slice debug_data); + +/* Close a transport. Aborts all open streams. */ +void grpc_transport_close(grpc_transport *transport); + +/* Destroy the transport */ +void grpc_transport_destroy(grpc_exec_ctx *exec_ctx, grpc_transport *transport); + +/* Get the transports peer */ +char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx, + grpc_transport *transport); + +#endif /* GRPC_CORE_TRANSPORT_TRANSPORT_H */ diff --git a/src/core/lib/transport/transport_impl.h b/src/core/lib/transport/transport_impl.h new file mode 100644 index 0000000000..d9ecc4d2ba --- /dev/null +++ b/src/core/lib/transport/transport_impl.h @@ -0,0 +1,81 @@ +/* + * + * Copyright 2015-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_TRANSPORT_TRANSPORT_IMPL_H +#define GRPC_CORE_TRANSPORT_TRANSPORT_IMPL_H + +#include "src/core/transport/transport.h" + +typedef struct grpc_transport_vtable { + /* Memory required for a single stream element - this is allocated by upper + layers and initialized by the transport */ + size_t sizeof_stream; /* = sizeof(transport stream) */ + + /* name of this transport implementation */ + const char *name; + + /* implementation of grpc_transport_init_stream */ + int (*init_stream)(grpc_exec_ctx *exec_ctx, grpc_transport *self, + grpc_stream *stream, grpc_stream_refcount *refcount, + const void *server_data); + + /* implementation of grpc_transport_set_pollset */ + void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_transport *self, + grpc_stream *stream, grpc_pollset *pollset); + + /* implementation of grpc_transport_perform_stream_op */ + void (*perform_stream_op)(grpc_exec_ctx *exec_ctx, grpc_transport *self, + grpc_stream *stream, grpc_transport_stream_op *op); + + /* implementation of grpc_transport_perform_op */ + void (*perform_op)(grpc_exec_ctx *exec_ctx, grpc_transport *self, + grpc_transport_op *op); + + /* implementation of grpc_transport_destroy_stream */ + void (*destroy_stream)(grpc_exec_ctx *exec_ctx, grpc_transport *self, + grpc_stream *stream); + + /* implementation of grpc_transport_destroy */ + void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_transport *self); + + /* implementation of grpc_transport_get_peer */ + char *(*get_peer)(grpc_exec_ctx *exec_ctx, grpc_transport *self); +} grpc_transport_vtable; + +/* an instance of a grpc transport */ +struct grpc_transport { + /* pointer to a vtable defining operations on this transport */ + const grpc_transport_vtable *vtable; +}; + +#endif /* GRPC_CORE_TRANSPORT_TRANSPORT_IMPL_H */ diff --git a/src/core/lib/transport/transport_op_string.c b/src/core/lib/transport/transport_op_string.c new file mode 100644 index 0000000000..8453412480 --- /dev/null +++ b/src/core/lib/transport/transport_op_string.c @@ -0,0 +1,140 @@ +/* + * + * Copyright 2015-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/channel/channel_stack.h" + +#include +#include +#include + +#include +#include +#include +#include "src/core/support/string.h" + +/* These routines are here to facilitate debugging - they produce string + representations of various transport data structures */ + +static void put_metadata(gpr_strvec *b, grpc_mdelem *md) { + gpr_strvec_add(b, gpr_strdup("key=")); + gpr_strvec_add(b, + gpr_dump_slice(md->key->slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)); + + gpr_strvec_add(b, gpr_strdup(" value=")); + gpr_strvec_add( + b, gpr_dump_slice(md->value->slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)); +} + +static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) { + grpc_linked_mdelem *m; + for (m = md.list.head; m != NULL; m = m->next) { + if (m != md.list.head) gpr_strvec_add(b, gpr_strdup(", ")); + put_metadata(b, m->md); + } + if (gpr_time_cmp(md.deadline, gpr_inf_future(md.deadline.clock_type)) != 0) { + char *tmp; + gpr_asprintf(&tmp, " deadline=%lld.%09d", (long long)md.deadline.tv_sec, + (int)md.deadline.tv_nsec); + gpr_strvec_add(b, tmp); + } +} + +char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { + char *tmp; + char *out; + int first = 1; + + gpr_strvec b; + gpr_strvec_init(&b); + + if (op->send_initial_metadata != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + gpr_strvec_add(&b, gpr_strdup("SEND_INITIAL_METADATA{")); + put_metadata_list(&b, *op->send_initial_metadata); + gpr_strvec_add(&b, gpr_strdup("}")); + } + + if (op->send_message != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + gpr_asprintf(&tmp, "SEND_MESSAGE:flags=0x%08x:len=%d", + op->send_message->flags, op->send_message->length); + gpr_strvec_add(&b, tmp); + } + + if (op->send_trailing_metadata != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + gpr_strvec_add(&b, gpr_strdup("SEND_TRAILING_METADATA{")); + put_metadata_list(&b, *op->send_trailing_metadata); + gpr_strvec_add(&b, gpr_strdup("}")); + } + + if (op->recv_initial_metadata != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + gpr_strvec_add(&b, gpr_strdup("RECV_INITIAL_METADATA")); + } + + if (op->recv_message != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + gpr_strvec_add(&b, gpr_strdup("RECV_MESSAGE")); + } + + if (op->recv_trailing_metadata != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + gpr_strvec_add(&b, gpr_strdup("RECV_TRAILING_METADATA")); + } + + if (op->cancel_with_status != GRPC_STATUS_OK) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + gpr_asprintf(&tmp, "CANCEL:%d", op->cancel_with_status); + gpr_strvec_add(&b, tmp); + } + + out = gpr_strvec_flatten(&b, NULL); + gpr_strvec_destroy(&b); + + return out; +} + +void grpc_call_log_op(char *file, int line, gpr_log_severity severity, + grpc_call_element *elem, grpc_transport_stream_op *op) { + char *str = grpc_transport_stream_op_string(op); + gpr_log(file, line, severity, "OP[%s:%p]: %s", elem->filter->name, elem, str); + gpr_free(str); +} diff --git a/src/core/lib/tsi/fake_transport_security.c b/src/core/lib/tsi/fake_transport_security.c new file mode 100644 index 0000000000..c0106f7a33 --- /dev/null +++ b/src/core/lib/tsi/fake_transport_security.c @@ -0,0 +1,527 @@ +/* + * + * Copyright 2015-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/tsi/fake_transport_security.h" + +#include +#include + +#include +#include +#include +#include "src/core/tsi/transport_security.h" + +/* --- Constants. ---*/ +#define TSI_FAKE_FRAME_HEADER_SIZE 4 +#define TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE 64 +#define TSI_FAKE_DEFAULT_FRAME_SIZE 16384 + +/* --- Structure definitions. ---*/ + +/* a frame is encoded like this: + | size | data | + where the size field value is the size of the size field plus the size of + the data encoded in little endian on 4 bytes. */ +typedef struct { + unsigned char *data; + size_t size; + size_t allocated_size; + size_t offset; + int needs_draining; +} tsi_fake_frame; + +typedef enum { + TSI_FAKE_CLIENT_INIT = 0, + TSI_FAKE_SERVER_INIT = 1, + TSI_FAKE_CLIENT_FINISHED = 2, + TSI_FAKE_SERVER_FINISHED = 3, + TSI_FAKE_HANDSHAKE_MESSAGE_MAX = 4 +} tsi_fake_handshake_message; + +typedef struct { + tsi_handshaker base; + int is_client; + tsi_fake_handshake_message next_message_to_send; + int needs_incoming_message; + tsi_fake_frame incoming; + tsi_fake_frame outgoing; + tsi_result result; +} tsi_fake_handshaker; + +typedef struct { + tsi_frame_protector base; + tsi_fake_frame protect_frame; + tsi_fake_frame unprotect_frame; + size_t max_frame_size; +} tsi_fake_frame_protector; + +/* --- Utils. ---*/ + +static const char *tsi_fake_handshake_message_strings[] = { + "CLIENT_INIT", "SERVER_INIT", "CLIENT_FINISHED", "SERVER_FINISHED"}; + +static const char *tsi_fake_handshake_message_to_string(int msg) { + if (msg < 0 || msg >= TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { + gpr_log(GPR_ERROR, "Invalid message %d", msg); + return "UNKNOWN"; + } + return tsi_fake_handshake_message_strings[msg]; +} + +static tsi_result tsi_fake_handshake_message_from_string( + const char *msg_string, tsi_fake_handshake_message *msg) { + tsi_fake_handshake_message i; + for (i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) { + if (strncmp(msg_string, tsi_fake_handshake_message_strings[i], + strlen(tsi_fake_handshake_message_strings[i])) == 0) { + *msg = i; + return TSI_OK; + } + } + gpr_log(GPR_ERROR, "Invalid handshake message."); + return TSI_DATA_CORRUPTED; +} + +static uint32_t load32_little_endian(const unsigned char *buf) { + return ((uint32_t)(buf[0]) | (uint32_t)(buf[1] << 8) | + (uint32_t)(buf[2] << 16) | (uint32_t)(buf[3] << 24)); +} + +static void store32_little_endian(uint32_t value, unsigned char *buf) { + buf[3] = (unsigned char)((value >> 24) & 0xFF); + buf[2] = (unsigned char)((value >> 16) & 0xFF); + buf[1] = (unsigned char)((value >> 8) & 0xFF); + buf[0] = (unsigned char)((value)&0xFF); +} + +static void tsi_fake_frame_reset(tsi_fake_frame *frame, int needs_draining) { + frame->offset = 0; + frame->needs_draining = needs_draining; + if (!needs_draining) frame->size = 0; +} + +/* Returns 1 if successful, 0 otherwise. */ +static int tsi_fake_frame_ensure_size(tsi_fake_frame *frame) { + if (frame->data == NULL) { + frame->allocated_size = frame->size; + frame->data = malloc(frame->allocated_size); + if (frame->data == NULL) return 0; + } else if (frame->size > frame->allocated_size) { + unsigned char *new_data = realloc(frame->data, frame->size); + if (new_data == NULL) { + free(frame->data); + frame->data = NULL; + return 0; + } + frame->data = new_data; + frame->allocated_size = frame->size; + } + return 1; +} + +/* This method should not be called if frame->needs_framing is not 0. */ +static tsi_result fill_frame_from_bytes(const unsigned char *incoming_bytes, + size_t *incoming_bytes_size, + tsi_fake_frame *frame) { + size_t available_size = *incoming_bytes_size; + size_t to_read_size = 0; + const unsigned char *bytes_cursor = incoming_bytes; + + if (frame->needs_draining) return TSI_INTERNAL_ERROR; + if (frame->data == NULL) { + frame->allocated_size = TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE; + frame->data = malloc(frame->allocated_size); + if (frame->data == NULL) return TSI_OUT_OF_RESOURCES; + } + + if (frame->offset < TSI_FAKE_FRAME_HEADER_SIZE) { + to_read_size = TSI_FAKE_FRAME_HEADER_SIZE - frame->offset; + if (to_read_size > available_size) { + /* Just fill what we can and exit. */ + memcpy(frame->data + frame->offset, bytes_cursor, available_size); + bytes_cursor += available_size; + frame->offset += available_size; + *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes); + return TSI_INCOMPLETE_DATA; + } + memcpy(frame->data + frame->offset, bytes_cursor, to_read_size); + bytes_cursor += to_read_size; + frame->offset += to_read_size; + available_size -= to_read_size; + frame->size = load32_little_endian(frame->data); + if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES; + } + + to_read_size = frame->size - frame->offset; + if (to_read_size > available_size) { + memcpy(frame->data + frame->offset, bytes_cursor, available_size); + frame->offset += available_size; + bytes_cursor += available_size; + *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes); + return TSI_INCOMPLETE_DATA; + } + memcpy(frame->data + frame->offset, bytes_cursor, to_read_size); + bytes_cursor += to_read_size; + *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes); + tsi_fake_frame_reset(frame, 1 /* needs_draining */); + return TSI_OK; +} + +/* This method should not be called if frame->needs_framing is 0. */ +static tsi_result drain_frame_to_bytes(unsigned char *outgoing_bytes, + size_t *outgoing_bytes_size, + tsi_fake_frame *frame) { + size_t to_write_size = frame->size - frame->offset; + if (!frame->needs_draining) return TSI_INTERNAL_ERROR; + if (*outgoing_bytes_size < to_write_size) { + memcpy(outgoing_bytes, frame->data + frame->offset, *outgoing_bytes_size); + frame->offset += *outgoing_bytes_size; + return TSI_INCOMPLETE_DATA; + } + memcpy(outgoing_bytes, frame->data + frame->offset, to_write_size); + *outgoing_bytes_size = to_write_size; + tsi_fake_frame_reset(frame, 0 /* needs_draining */); + return TSI_OK; +} + +static tsi_result bytes_to_frame(unsigned char *bytes, size_t bytes_size, + tsi_fake_frame *frame) { + frame->offset = 0; + frame->size = bytes_size + TSI_FAKE_FRAME_HEADER_SIZE; + if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES; + store32_little_endian((uint32_t)frame->size, frame->data); + memcpy(frame->data + TSI_FAKE_FRAME_HEADER_SIZE, bytes, bytes_size); + tsi_fake_frame_reset(frame, 1 /* needs draining */); + return TSI_OK; +} + +static void tsi_fake_frame_destruct(tsi_fake_frame *frame) { + if (frame->data != NULL) free(frame->data); +} + +/* --- tsi_frame_protector methods implementation. ---*/ + +static tsi_result fake_protector_protect(tsi_frame_protector *self, + const unsigned char *unprotected_bytes, + size_t *unprotected_bytes_size, + unsigned char *protected_output_frames, + size_t *protected_output_frames_size) { + tsi_result result = TSI_OK; + tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; + unsigned char frame_header[TSI_FAKE_FRAME_HEADER_SIZE]; + tsi_fake_frame *frame = &impl->protect_frame; + size_t saved_output_size = *protected_output_frames_size; + size_t drained_size = 0; + size_t *num_bytes_written = protected_output_frames_size; + *num_bytes_written = 0; + + /* Try to drain first. */ + if (frame->needs_draining) { + drained_size = saved_output_size - *num_bytes_written; + result = + drain_frame_to_bytes(protected_output_frames, &drained_size, frame); + *num_bytes_written += drained_size; + protected_output_frames += drained_size; + if (result != TSI_OK) { + if (result == TSI_INCOMPLETE_DATA) { + *unprotected_bytes_size = 0; + result = TSI_OK; + } + return result; + } + } + + /* Now process the unprotected_bytes. */ + if (frame->needs_draining) return TSI_INTERNAL_ERROR; + if (frame->size == 0) { + /* New frame, create a header. */ + size_t written_in_frame_size = 0; + store32_little_endian((uint32_t)impl->max_frame_size, frame_header); + written_in_frame_size = TSI_FAKE_FRAME_HEADER_SIZE; + result = fill_frame_from_bytes(frame_header, &written_in_frame_size, frame); + if (result != TSI_INCOMPLETE_DATA) { + gpr_log(GPR_ERROR, "fill_frame_from_bytes returned %s", + tsi_result_to_string(result)); + return result; + } + } + result = + fill_frame_from_bytes(unprotected_bytes, unprotected_bytes_size, frame); + if (result != TSI_OK) { + if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; + return result; + } + + /* Try to drain again. */ + if (!frame->needs_draining) return TSI_INTERNAL_ERROR; + if (frame->offset != 0) return TSI_INTERNAL_ERROR; + drained_size = saved_output_size - *num_bytes_written; + result = drain_frame_to_bytes(protected_output_frames, &drained_size, frame); + *num_bytes_written += drained_size; + if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; + return result; +} + +static tsi_result fake_protector_protect_flush( + tsi_frame_protector *self, unsigned char *protected_output_frames, + size_t *protected_output_frames_size, size_t *still_pending_size) { + tsi_result result = TSI_OK; + tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; + tsi_fake_frame *frame = &impl->protect_frame; + if (!frame->needs_draining) { + /* Create a short frame. */ + frame->size = frame->offset; + frame->offset = 0; + frame->needs_draining = 1; + store32_little_endian((uint32_t)frame->size, + frame->data); /* Overwrite header. */ + } + result = drain_frame_to_bytes(protected_output_frames, + protected_output_frames_size, frame); + if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; + *still_pending_size = frame->size - frame->offset; + return result; +} + +static tsi_result fake_protector_unprotect( + tsi_frame_protector *self, const unsigned char *protected_frames_bytes, + size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes, + size_t *unprotected_bytes_size) { + tsi_result result = TSI_OK; + tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; + tsi_fake_frame *frame = &impl->unprotect_frame; + size_t saved_output_size = *unprotected_bytes_size; + size_t drained_size = 0; + size_t *num_bytes_written = unprotected_bytes_size; + *num_bytes_written = 0; + + /* Try to drain first. */ + if (frame->needs_draining) { + /* Go past the header if needed. */ + if (frame->offset == 0) frame->offset = TSI_FAKE_FRAME_HEADER_SIZE; + drained_size = saved_output_size - *num_bytes_written; + result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame); + unprotected_bytes += drained_size; + *num_bytes_written += drained_size; + if (result != TSI_OK) { + if (result == TSI_INCOMPLETE_DATA) { + *protected_frames_bytes_size = 0; + result = TSI_OK; + } + return result; + } + } + + /* Now process the protected_bytes. */ + if (frame->needs_draining) return TSI_INTERNAL_ERROR; + result = fill_frame_from_bytes(protected_frames_bytes, + protected_frames_bytes_size, frame); + if (result != TSI_OK) { + if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; + return result; + } + + /* Try to drain again. */ + if (!frame->needs_draining) return TSI_INTERNAL_ERROR; + if (frame->offset != 0) return TSI_INTERNAL_ERROR; + frame->offset = TSI_FAKE_FRAME_HEADER_SIZE; /* Go past the header. */ + drained_size = saved_output_size - *num_bytes_written; + result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame); + *num_bytes_written += drained_size; + if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; + return result; +} + +static void fake_protector_destroy(tsi_frame_protector *self) { + tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; + tsi_fake_frame_destruct(&impl->protect_frame); + tsi_fake_frame_destruct(&impl->unprotect_frame); + free(self); +} + +static const tsi_frame_protector_vtable frame_protector_vtable = { + fake_protector_protect, fake_protector_protect_flush, + fake_protector_unprotect, fake_protector_destroy, +}; + +/* --- tsi_handshaker methods implementation. ---*/ + +static tsi_result fake_handshaker_get_bytes_to_send_to_peer( + tsi_handshaker *self, unsigned char *bytes, size_t *bytes_size) { + tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; + tsi_result result = TSI_OK; + if (impl->needs_incoming_message || impl->result == TSI_OK) { + *bytes_size = 0; + return TSI_OK; + } + if (!impl->outgoing.needs_draining) { + tsi_fake_handshake_message next_message_to_send = + impl->next_message_to_send + 2; + const char *msg_string = + tsi_fake_handshake_message_to_string(impl->next_message_to_send); + result = bytes_to_frame((unsigned char *)msg_string, strlen(msg_string), + &impl->outgoing); + if (result != TSI_OK) return result; + if (next_message_to_send > TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { + next_message_to_send = TSI_FAKE_HANDSHAKE_MESSAGE_MAX; + } + if (tsi_tracing_enabled) { + gpr_log(GPR_INFO, "%s prepared %s.", + impl->is_client ? "Client" : "Server", + tsi_fake_handshake_message_to_string(impl->next_message_to_send)); + } + impl->next_message_to_send = next_message_to_send; + } + result = drain_frame_to_bytes(bytes, bytes_size, &impl->outgoing); + if (result != TSI_OK) return result; + if (!impl->is_client && + impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { + /* We're done. */ + if (tsi_tracing_enabled) { + gpr_log(GPR_INFO, "Server is done."); + } + impl->result = TSI_OK; + } else { + impl->needs_incoming_message = 1; + } + return TSI_OK; +} + +static tsi_result fake_handshaker_process_bytes_from_peer( + tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size) { + tsi_result result = TSI_OK; + tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; + tsi_fake_handshake_message expected_msg = impl->next_message_to_send - 1; + tsi_fake_handshake_message received_msg; + + if (!impl->needs_incoming_message || impl->result == TSI_OK) { + *bytes_size = 0; + return TSI_OK; + } + result = fill_frame_from_bytes(bytes, bytes_size, &impl->incoming); + if (result != TSI_OK) return result; + + /* We now have a complete frame. */ + result = tsi_fake_handshake_message_from_string( + (const char *)impl->incoming.data + TSI_FAKE_FRAME_HEADER_SIZE, + &received_msg); + if (result != TSI_OK) { + impl->result = result; + return result; + } + if (received_msg != expected_msg) { + gpr_log(GPR_ERROR, "Invalid received message (%s instead of %s)", + tsi_fake_handshake_message_to_string(received_msg), + tsi_fake_handshake_message_to_string(expected_msg)); + } + if (tsi_tracing_enabled) { + gpr_log(GPR_INFO, "%s received %s.", impl->is_client ? "Client" : "Server", + tsi_fake_handshake_message_to_string(received_msg)); + } + tsi_fake_frame_reset(&impl->incoming, 0 /* needs_draining */); + impl->needs_incoming_message = 0; + if (impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { + /* We're done. */ + if (tsi_tracing_enabled) { + gpr_log(GPR_INFO, "%s is done.", impl->is_client ? "Client" : "Server"); + } + impl->result = TSI_OK; + } + return TSI_OK; +} + +static tsi_result fake_handshaker_get_result(tsi_handshaker *self) { + tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; + return impl->result; +} + +static tsi_result fake_handshaker_extract_peer(tsi_handshaker *self, + tsi_peer *peer) { + tsi_result result = tsi_construct_peer(1, peer); + if (result != TSI_OK) return result; + result = tsi_construct_string_peer_property_from_cstring( + TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_FAKE_CERTIFICATE_TYPE, + &peer->properties[0]); + if (result != TSI_OK) tsi_peer_destruct(peer); + return result; +} + +static tsi_result fake_handshaker_create_frame_protector( + tsi_handshaker *self, size_t *max_protected_frame_size, + tsi_frame_protector **protector) { + *protector = tsi_create_fake_protector(max_protected_frame_size); + if (*protector == NULL) return TSI_OUT_OF_RESOURCES; + return TSI_OK; +} + +static void fake_handshaker_destroy(tsi_handshaker *self) { + tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; + tsi_fake_frame_destruct(&impl->incoming); + tsi_fake_frame_destruct(&impl->outgoing); + free(self); +} + +static const tsi_handshaker_vtable handshaker_vtable = { + fake_handshaker_get_bytes_to_send_to_peer, + fake_handshaker_process_bytes_from_peer, + fake_handshaker_get_result, + fake_handshaker_extract_peer, + fake_handshaker_create_frame_protector, + fake_handshaker_destroy, +}; + +tsi_handshaker *tsi_create_fake_handshaker(int is_client) { + tsi_fake_handshaker *impl = calloc(1, sizeof(tsi_fake_handshaker)); + impl->base.vtable = &handshaker_vtable; + impl->is_client = is_client; + impl->result = TSI_HANDSHAKE_IN_PROGRESS; + if (is_client) { + impl->needs_incoming_message = 0; + impl->next_message_to_send = TSI_FAKE_CLIENT_INIT; + } else { + impl->needs_incoming_message = 1; + impl->next_message_to_send = TSI_FAKE_SERVER_INIT; + } + return &impl->base; +} + +tsi_frame_protector *tsi_create_fake_protector( + size_t *max_protected_frame_size) { + tsi_fake_frame_protector *impl = calloc(1, sizeof(tsi_fake_frame_protector)); + if (impl == NULL) return NULL; + impl->max_frame_size = (max_protected_frame_size == NULL) + ? TSI_FAKE_DEFAULT_FRAME_SIZE + : *max_protected_frame_size; + impl->base.vtable = &frame_protector_vtable; + return &impl->base; +} diff --git a/src/core/lib/tsi/fake_transport_security.h b/src/core/lib/tsi/fake_transport_security.h new file mode 100644 index 0000000000..6b8e596290 --- /dev/null +++ b/src/core/lib/tsi/fake_transport_security.h @@ -0,0 +1,61 @@ +/* + * + * Copyright 2015-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_TSI_FAKE_TRANSPORT_SECURITY_H +#define GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H + +#include "src/core/tsi/transport_security_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for FAKE certs. */ +#define TSI_FAKE_CERTIFICATE_TYPE "FAKE" + +/* Creates a fake handshaker that will create a fake frame protector. + + No cryptography is performed in these objects. They just simulate handshake + messages going back and forth for the handshaker and do some framing on + cleartext data for the protector. */ +tsi_handshaker *tsi_create_fake_handshaker(int is_client); + +/* Creates a protector directly without going through the handshake phase. */ +tsi_frame_protector *tsi_create_fake_protector( + size_t *max_protected_frame_size); + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H */ diff --git a/src/core/lib/tsi/ssl_transport_security.c b/src/core/lib/tsi/ssl_transport_security.c new file mode 100644 index 0000000000..8df582609b --- /dev/null +++ b/src/core/lib/tsi/ssl_transport_security.c @@ -0,0 +1,1536 @@ +/* + * + * Copyright 2015-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/tsi/ssl_transport_security.h" + +#include + +#include +#include + +/* TODO(jboeuf): refactor inet_ntop into a portability header. */ +#ifdef GPR_WINSOCK_SOCKET +#include +#else +#include +#endif + +#include +#include +#include +#include + +#include +#include /* For OPENSSL_free */ +#include +#include +#include +#include + +#include "src/core/tsi/ssl_types.h" +#include "src/core/tsi/transport_security.h" + +/* --- Constants. ---*/ + +#define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND 16384 +#define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND 1024 + +/* Putting a macro like this and littering the source file with #if is really + bad practice. + TODO(jboeuf): refactor all the #if / #endif in a separate module. */ +#ifndef TSI_OPENSSL_ALPN_SUPPORT +#define TSI_OPENSSL_ALPN_SUPPORT 1 +#endif + +/* TODO(jboeuf): I have not found a way to get this number dynamically from the + SSL structure. This is what we would ultimately want though... */ +#define TSI_SSL_MAX_PROTECTION_OVERHEAD 100 + +/* --- Structure definitions. ---*/ + +struct tsi_ssl_handshaker_factory { + tsi_result (*create_handshaker)(tsi_ssl_handshaker_factory *self, + const char *server_name_indication, + tsi_handshaker **handshaker); + void (*destroy)(tsi_ssl_handshaker_factory *self); +}; + +typedef struct { + tsi_ssl_handshaker_factory base; + SSL_CTX *ssl_context; + unsigned char *alpn_protocol_list; + size_t alpn_protocol_list_length; +} tsi_ssl_client_handshaker_factory; + +typedef struct { + tsi_ssl_handshaker_factory base; + + /* Several contexts to support SNI. + The tsi_peer array contains the subject names of the server certificates + associated with the contexts at the same index. */ + SSL_CTX **ssl_contexts; + tsi_peer *ssl_context_x509_subject_names; + size_t ssl_context_count; + unsigned char *alpn_protocol_list; + size_t alpn_protocol_list_length; +} tsi_ssl_server_handshaker_factory; + +typedef struct { + tsi_handshaker base; + SSL *ssl; + BIO *into_ssl; + BIO *from_ssl; + tsi_result result; +} tsi_ssl_handshaker; + +typedef struct { + tsi_frame_protector base; + SSL *ssl; + BIO *into_ssl; + BIO *from_ssl; + unsigned char *buffer; + size_t buffer_size; + size_t buffer_offset; +} tsi_ssl_frame_protector; + +/* --- Library Initialization. ---*/ + +static gpr_once init_openssl_once = GPR_ONCE_INIT; +static gpr_mu *openssl_mutexes = NULL; + +static void openssl_locking_cb(int mode, int type, const char *file, int line) { + if (mode & CRYPTO_LOCK) { + gpr_mu_lock(&openssl_mutexes[type]); + } else { + gpr_mu_unlock(&openssl_mutexes[type]); + } +} + +static unsigned long openssl_thread_id_cb(void) { + return (unsigned long)gpr_thd_currentid(); +} + +static void init_openssl(void) { + int i; + int num_locks; + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); + num_locks = CRYPTO_num_locks(); + GPR_ASSERT(num_locks > 0); + openssl_mutexes = malloc((size_t)num_locks * sizeof(gpr_mu)); + GPR_ASSERT(openssl_mutexes != NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) { + gpr_mu_init(&openssl_mutexes[i]); + } + CRYPTO_set_locking_callback(openssl_locking_cb); + CRYPTO_set_id_callback(openssl_thread_id_cb); +} + +/* --- Ssl utils. ---*/ + +static const char *ssl_error_string(int error) { + switch (error) { + case SSL_ERROR_NONE: + return "SSL_ERROR_NONE"; + case SSL_ERROR_ZERO_RETURN: + return "SSL_ERROR_ZERO_RETURN"; + case SSL_ERROR_WANT_READ: + return "SSL_ERROR_WANT_READ"; + case SSL_ERROR_WANT_WRITE: + return "SSL_ERROR_WANT_WRITE"; + case SSL_ERROR_WANT_CONNECT: + return "SSL_ERROR_WANT_CONNECT"; + case SSL_ERROR_WANT_ACCEPT: + return "SSL_ERROR_WANT_ACCEPT"; + case SSL_ERROR_WANT_X509_LOOKUP: + return "SSL_ERROR_WANT_X509_LOOKUP"; + case SSL_ERROR_SYSCALL: + return "SSL_ERROR_SYSCALL"; + case SSL_ERROR_SSL: + return "SSL_ERROR_SSL"; + default: + return "Unknown error"; + } +} + +/* TODO(jboeuf): Remove when we are past the debugging phase with this code. */ +static void ssl_log_where_info(const SSL *ssl, int where, int flag, + const char *msg) { + if ((where & flag) && tsi_tracing_enabled) { + gpr_log(GPR_INFO, "%20.20s - %30.30s - %5.10s", msg, + SSL_state_string_long(ssl), SSL_state_string(ssl)); + } +} + +/* Used for debugging. TODO(jboeuf): Remove when code is mature enough. */ +static void ssl_info_callback(const SSL *ssl, int where, int ret) { + if (ret == 0) { + gpr_log(GPR_ERROR, "ssl_info_callback: error occured.\n"); + return; + } + + ssl_log_where_info(ssl, where, SSL_CB_LOOP, "LOOP"); + ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_START, "HANDSHAKE START"); + ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_DONE, "HANDSHAKE DONE"); +} + +/* Returns 1 if name looks like an IP address, 0 otherwise. + This is a very rough heuristic, and only handles IPv6 in hexadecimal form. */ +static int looks_like_ip_address(const char *name) { + size_t i; + size_t dot_count = 0; + size_t num_size = 0; + for (i = 0; i < strlen(name); i++) { + if (name[i] == ':') { + /* IPv6 Address in hexadecimal form, : is not allowed in DNS names. */ + return 1; + } + if (name[i] >= '0' && name[i] <= '9') { + if (num_size > 3) return 0; + num_size++; + } else if (name[i] == '.') { + if (dot_count > 3 || num_size == 0) return 0; + dot_count++; + num_size = 0; + } else { + return 0; + } + } + if (dot_count < 3 || num_size == 0) return 0; + return 1; +} + +/* Gets the subject CN from an X509 cert. */ +static tsi_result ssl_get_x509_common_name(X509 *cert, unsigned char **utf8, + size_t *utf8_size) { + int common_name_index = -1; + X509_NAME_ENTRY *common_name_entry = NULL; + ASN1_STRING *common_name_asn1 = NULL; + X509_NAME *subject_name = X509_get_subject_name(cert); + int utf8_returned_size = 0; + if (subject_name == NULL) { + gpr_log(GPR_ERROR, "Could not get subject name from certificate."); + return TSI_NOT_FOUND; + } + common_name_index = + X509_NAME_get_index_by_NID(subject_name, NID_commonName, -1); + if (common_name_index == -1) { + gpr_log(GPR_ERROR, + "Could not get common name of subject from certificate."); + return TSI_NOT_FOUND; + } + common_name_entry = X509_NAME_get_entry(subject_name, common_name_index); + if (common_name_entry == NULL) { + gpr_log(GPR_ERROR, "Could not get common name entry from certificate."); + return TSI_INTERNAL_ERROR; + } + common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry); + if (common_name_asn1 == NULL) { + gpr_log(GPR_ERROR, + "Could not get common name entry asn1 from certificate."); + return TSI_INTERNAL_ERROR; + } + utf8_returned_size = ASN1_STRING_to_UTF8(utf8, common_name_asn1); + if (utf8_returned_size < 0) { + gpr_log(GPR_ERROR, "Could not extract utf8 from asn1 string."); + return TSI_OUT_OF_RESOURCES; + } + *utf8_size = (size_t)utf8_returned_size; + return TSI_OK; +} + +/* Gets the subject CN of an X509 cert as a tsi_peer_property. */ +static tsi_result peer_property_from_x509_common_name( + X509 *cert, tsi_peer_property *property) { + unsigned char *common_name; + size_t common_name_size; + tsi_result result = + ssl_get_x509_common_name(cert, &common_name, &common_name_size); + if (result != TSI_OK) { + if (result == TSI_NOT_FOUND) { + common_name = NULL; + common_name_size = 0; + } else { + return result; + } + } + result = tsi_construct_string_peer_property( + TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, + common_name == NULL ? "" : (const char *)common_name, common_name_size, + property); + OPENSSL_free(common_name); + return result; +} + +/* Gets the X509 cert in PEM format as a tsi_peer_property. */ +static tsi_result add_pem_certificate(X509 *cert, tsi_peer_property *property) { + BIO *bio = BIO_new(BIO_s_mem()); + if (!PEM_write_bio_X509(bio, cert)) { + BIO_free(bio); + return TSI_INTERNAL_ERROR; + } + char *contents; + long len = BIO_get_mem_data(bio, &contents); + if (len <= 0) { + BIO_free(bio); + return TSI_INTERNAL_ERROR; + } + tsi_result result = tsi_construct_string_peer_property( + TSI_X509_PEM_CERT_PROPERTY, (const char *)contents, (size_t)len, + property); + BIO_free(bio); + return result; +} + +/* Gets the subject SANs from an X509 cert as a tsi_peer_property. */ +static tsi_result add_subject_alt_names_properties_to_peer( + tsi_peer *peer, GENERAL_NAMES *subject_alt_names, + size_t subject_alt_name_count) { + size_t i; + tsi_result result = TSI_OK; + + /* Reset for DNS entries filtering. */ + peer->property_count -= subject_alt_name_count; + + for (i = 0; i < subject_alt_name_count; i++) { + GENERAL_NAME *subject_alt_name = + sk_GENERAL_NAME_value(subject_alt_names, TSI_SIZE_AS_SIZE(i)); + /* Filter out the non-dns entries names. */ + if (subject_alt_name->type == GEN_DNS) { + unsigned char *name = NULL; + int name_size; + name_size = ASN1_STRING_to_UTF8(&name, subject_alt_name->d.dNSName); + if (name_size < 0) { + gpr_log(GPR_ERROR, "Could not get utf8 from asn1 string."); + result = TSI_INTERNAL_ERROR; + break; + } + result = tsi_construct_string_peer_property( + TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, (const char *)name, + (size_t)name_size, &peer->properties[peer->property_count++]); + OPENSSL_free(name); + } else if (subject_alt_name->type == GEN_IPADD) { + char ntop_buf[INET6_ADDRSTRLEN]; + int af; + + if (subject_alt_name->d.iPAddress->length == 4) { + af = AF_INET; + } else if (subject_alt_name->d.iPAddress->length == 16) { + af = AF_INET6; + } else { + gpr_log(GPR_ERROR, "SAN IP Address contained invalid IP"); + result = TSI_INTERNAL_ERROR; + break; + } + const char *name = inet_ntop(af, subject_alt_name->d.iPAddress->data, + ntop_buf, INET6_ADDRSTRLEN); + if (name == NULL) { + gpr_log(GPR_ERROR, "Could not get IP string from asn1 octet."); + result = TSI_INTERNAL_ERROR; + break; + } + + result = tsi_construct_string_peer_property_from_cstring( + TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, name, + &peer->properties[peer->property_count++]); + } + if (result != TSI_OK) break; + } + return result; +} + +/* Gets information about the peer's X509 cert as a tsi_peer object. */ +static tsi_result peer_from_x509(X509 *cert, int include_certificate_type, + tsi_peer *peer) { + /* TODO(jboeuf): Maybe add more properties. */ + GENERAL_NAMES *subject_alt_names = + X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0); + int subject_alt_name_count = (subject_alt_names != NULL) + ? (int)sk_GENERAL_NAME_num(subject_alt_names) + : 0; + size_t property_count; + tsi_result result; + GPR_ASSERT(subject_alt_name_count >= 0); + property_count = (include_certificate_type ? (size_t)1 : 0) + + 2 /* common name, certificate */ + + (size_t)subject_alt_name_count; + result = tsi_construct_peer(property_count, peer); + if (result != TSI_OK) return result; + do { + if (include_certificate_type) { + result = tsi_construct_string_peer_property_from_cstring( + TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, + &peer->properties[0]); + if (result != TSI_OK) break; + } + result = peer_property_from_x509_common_name( + cert, &peer->properties[include_certificate_type ? 1 : 0]); + if (result != TSI_OK) break; + + result = add_pem_certificate( + cert, &peer->properties[include_certificate_type ? 2 : 1]); + if (result != TSI_OK) break; + + if (subject_alt_name_count != 0) { + result = add_subject_alt_names_properties_to_peer( + peer, subject_alt_names, (size_t)subject_alt_name_count); + if (result != TSI_OK) break; + } + } while (0); + + if (subject_alt_names != NULL) { + sk_GENERAL_NAME_pop_free(subject_alt_names, GENERAL_NAME_free); + } + if (result != TSI_OK) tsi_peer_destruct(peer); + return result; +} + +/* Logs the SSL error stack. */ +static void log_ssl_error_stack(void) { + unsigned long err; + while ((err = ERR_get_error()) != 0) { + char details[256]; + ERR_error_string_n((uint32_t)err, details, sizeof(details)); + gpr_log(GPR_ERROR, "%s", details); + } +} + +/* Performs an SSL_read and handle errors. */ +static tsi_result do_ssl_read(SSL *ssl, unsigned char *unprotected_bytes, + size_t *unprotected_bytes_size) { + int read_from_ssl; + GPR_ASSERT(*unprotected_bytes_size <= INT_MAX); + read_from_ssl = + SSL_read(ssl, unprotected_bytes, (int)*unprotected_bytes_size); + if (read_from_ssl == 0) { + gpr_log(GPR_ERROR, "SSL_read returned 0 unexpectedly."); + return TSI_INTERNAL_ERROR; + } + if (read_from_ssl < 0) { + read_from_ssl = SSL_get_error(ssl, read_from_ssl); + switch (read_from_ssl) { + case SSL_ERROR_WANT_READ: + /* We need more data to finish the frame. */ + *unprotected_bytes_size = 0; + return TSI_OK; + case SSL_ERROR_WANT_WRITE: + gpr_log( + GPR_ERROR, + "Peer tried to renegotiate SSL connection. This is unsupported."); + return TSI_UNIMPLEMENTED; + case SSL_ERROR_SSL: + gpr_log(GPR_ERROR, "Corruption detected."); + log_ssl_error_stack(); + return TSI_DATA_CORRUPTED; + default: + gpr_log(GPR_ERROR, "SSL_read failed with error %s.", + ssl_error_string(read_from_ssl)); + return TSI_PROTOCOL_FAILURE; + } + } + *unprotected_bytes_size = (size_t)read_from_ssl; + return TSI_OK; +} + +/* Performs an SSL_write and handle errors. */ +static tsi_result do_ssl_write(SSL *ssl, unsigned char *unprotected_bytes, + size_t unprotected_bytes_size) { + int ssl_write_result; + GPR_ASSERT(unprotected_bytes_size <= INT_MAX); + ssl_write_result = + SSL_write(ssl, unprotected_bytes, (int)unprotected_bytes_size); + if (ssl_write_result < 0) { + ssl_write_result = SSL_get_error(ssl, ssl_write_result); + if (ssl_write_result == SSL_ERROR_WANT_READ) { + gpr_log(GPR_ERROR, + "Peer tried to renegotiate SSL connection. This is unsupported."); + return TSI_UNIMPLEMENTED; + } else { + gpr_log(GPR_ERROR, "SSL_write failed with error %s.", + ssl_error_string(ssl_write_result)); + return TSI_INTERNAL_ERROR; + } + } + return TSI_OK; +} + +/* Loads an in-memory PEM certificate chain into the SSL context. */ +static tsi_result ssl_ctx_use_certificate_chain( + SSL_CTX *context, const unsigned char *pem_cert_chain, + size_t pem_cert_chain_size) { + tsi_result result = TSI_OK; + X509 *certificate = NULL; + BIO *pem; + GPR_ASSERT(pem_cert_chain_size <= INT_MAX); + pem = BIO_new_mem_buf((void *)pem_cert_chain, (int)pem_cert_chain_size); + if (pem == NULL) return TSI_OUT_OF_RESOURCES; + + do { + certificate = PEM_read_bio_X509_AUX(pem, NULL, NULL, ""); + if (certificate == NULL) { + result = TSI_INVALID_ARGUMENT; + break; + } + if (!SSL_CTX_use_certificate(context, certificate)) { + result = TSI_INVALID_ARGUMENT; + break; + } + while (1) { + X509 *certificate_authority = PEM_read_bio_X509(pem, NULL, NULL, ""); + if (certificate_authority == NULL) { + ERR_clear_error(); + break; /* Done reading. */ + } + if (!SSL_CTX_add_extra_chain_cert(context, certificate_authority)) { + X509_free(certificate_authority); + result = TSI_INVALID_ARGUMENT; + break; + } + /* We don't need to free certificate_authority as its ownership has been + transfered to the context. That is not the case for certificate though. + */ + } + } while (0); + + if (certificate != NULL) X509_free(certificate); + BIO_free(pem); + return result; +} + +/* Loads an in-memory PEM private key into the SSL context. */ +static tsi_result ssl_ctx_use_private_key(SSL_CTX *context, + const unsigned char *pem_key, + size_t pem_key_size) { + tsi_result result = TSI_OK; + EVP_PKEY *private_key = NULL; + BIO *pem; + GPR_ASSERT(pem_key_size <= INT_MAX); + pem = BIO_new_mem_buf((void *)pem_key, (int)pem_key_size); + if (pem == NULL) return TSI_OUT_OF_RESOURCES; + do { + private_key = PEM_read_bio_PrivateKey(pem, NULL, NULL, ""); + if (private_key == NULL) { + result = TSI_INVALID_ARGUMENT; + break; + } + if (!SSL_CTX_use_PrivateKey(context, private_key)) { + result = TSI_INVALID_ARGUMENT; + break; + } + } while (0); + if (private_key != NULL) EVP_PKEY_free(private_key); + BIO_free(pem); + return result; +} + +/* Loads in-memory PEM verification certs into the SSL context and optionally + returns the verification cert names (root_names can be NULL). */ +static tsi_result ssl_ctx_load_verification_certs( + SSL_CTX *context, const unsigned char *pem_roots, size_t pem_roots_size, + STACK_OF(X509_NAME) * *root_names) { + tsi_result result = TSI_OK; + size_t num_roots = 0; + X509 *root = NULL; + X509_NAME *root_name = NULL; + BIO *pem; + X509_STORE *root_store; + GPR_ASSERT(pem_roots_size <= INT_MAX); + pem = BIO_new_mem_buf((void *)pem_roots, (int)pem_roots_size); + root_store = SSL_CTX_get_cert_store(context); + if (root_store == NULL) return TSI_INVALID_ARGUMENT; + if (pem == NULL) return TSI_OUT_OF_RESOURCES; + if (root_names != NULL) { + *root_names = sk_X509_NAME_new_null(); + if (*root_names == NULL) return TSI_OUT_OF_RESOURCES; + } + + while (1) { + root = PEM_read_bio_X509_AUX(pem, NULL, NULL, ""); + if (root == NULL) { + ERR_clear_error(); + break; /* We're at the end of stream. */ + } + if (root_names != NULL) { + root_name = X509_get_subject_name(root); + if (root_name == NULL) { + gpr_log(GPR_ERROR, "Could not get name from root certificate."); + result = TSI_INVALID_ARGUMENT; + break; + } + root_name = X509_NAME_dup(root_name); + if (root_name == NULL) { + result = TSI_OUT_OF_RESOURCES; + break; + } + sk_X509_NAME_push(*root_names, root_name); + root_name = NULL; + } + if (!X509_STORE_add_cert(root_store, root)) { + gpr_log(GPR_ERROR, "Could not add root certificate to ssl context."); + result = TSI_INTERNAL_ERROR; + break; + } + X509_free(root); + num_roots++; + } + + if (num_roots == 0) { + gpr_log(GPR_ERROR, "Could not load any root certificate."); + result = TSI_INVALID_ARGUMENT; + } + + if (result != TSI_OK) { + if (root != NULL) X509_free(root); + if (root_names != NULL) { + sk_X509_NAME_pop_free(*root_names, X509_NAME_free); + *root_names = NULL; + if (root_name != NULL) X509_NAME_free(root_name); + } + } + BIO_free(pem); + return result; +} + +/* Populates the SSL context with a private key and a cert chain, and sets the + cipher list and the ephemeral ECDH key. */ +static tsi_result populate_ssl_context( + SSL_CTX *context, const unsigned char *pem_private_key, + size_t pem_private_key_size, const unsigned char *pem_certificate_chain, + size_t pem_certificate_chain_size, const char *cipher_list) { + tsi_result result = TSI_OK; + if (pem_certificate_chain != NULL) { + result = ssl_ctx_use_certificate_chain(context, pem_certificate_chain, + pem_certificate_chain_size); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Invalid cert chain file."); + return result; + } + } + if (pem_private_key != NULL) { + result = + ssl_ctx_use_private_key(context, pem_private_key, pem_private_key_size); + if (result != TSI_OK || !SSL_CTX_check_private_key(context)) { + gpr_log(GPR_ERROR, "Invalid private key."); + return result != TSI_OK ? result : TSI_INVALID_ARGUMENT; + } + } + if ((cipher_list != NULL) && !SSL_CTX_set_cipher_list(context, cipher_list)) { + gpr_log(GPR_ERROR, "Invalid cipher list: %s.", cipher_list); + return TSI_INVALID_ARGUMENT; + } + { + EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + if (!SSL_CTX_set_tmp_ecdh(context, ecdh)) { + gpr_log(GPR_ERROR, "Could not set ephemeral ECDH key."); + EC_KEY_free(ecdh); + return TSI_INTERNAL_ERROR; + } + SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE); + EC_KEY_free(ecdh); + } + return TSI_OK; +} + +/* Extracts the CN and the SANs from an X509 cert as a peer object. */ +static tsi_result extract_x509_subject_names_from_pem_cert( + const unsigned char *pem_cert, size_t pem_cert_size, tsi_peer *peer) { + tsi_result result = TSI_OK; + X509 *cert = NULL; + BIO *pem; + GPR_ASSERT(pem_cert_size <= INT_MAX); + pem = BIO_new_mem_buf((void *)pem_cert, (int)pem_cert_size); + if (pem == NULL) return TSI_OUT_OF_RESOURCES; + + cert = PEM_read_bio_X509(pem, NULL, NULL, ""); + if (cert == NULL) { + gpr_log(GPR_ERROR, "Invalid certificate"); + result = TSI_INVALID_ARGUMENT; + } else { + result = peer_from_x509(cert, 0, peer); + } + if (cert != NULL) X509_free(cert); + BIO_free(pem); + return result; +} + +/* Builds the alpn protocol name list according to rfc 7301. */ +static tsi_result build_alpn_protocol_name_list( + const unsigned char **alpn_protocols, + const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, + unsigned char **protocol_name_list, size_t *protocol_name_list_length) { + uint16_t i; + unsigned char *current; + *protocol_name_list = NULL; + *protocol_name_list_length = 0; + if (num_alpn_protocols == 0) return TSI_INVALID_ARGUMENT; + for (i = 0; i < num_alpn_protocols; i++) { + if (alpn_protocols_lengths[i] == 0) { + gpr_log(GPR_ERROR, "Invalid 0-length protocol name."); + return TSI_INVALID_ARGUMENT; + } + *protocol_name_list_length += (size_t)alpn_protocols_lengths[i] + 1; + } + *protocol_name_list = malloc(*protocol_name_list_length); + if (*protocol_name_list == NULL) return TSI_OUT_OF_RESOURCES; + current = *protocol_name_list; + for (i = 0; i < num_alpn_protocols; i++) { + *(current++) = alpn_protocols_lengths[i]; + memcpy(current, alpn_protocols[i], alpn_protocols_lengths[i]); + current += alpn_protocols_lengths[i]; + } + /* Safety check. */ + if ((current < *protocol_name_list) || + ((uintptr_t)(current - *protocol_name_list) != + *protocol_name_list_length)) { + return TSI_INTERNAL_ERROR; + } + return TSI_OK; +} + +/* --- tsi_frame_protector methods implementation. ---*/ + +static tsi_result ssl_protector_protect(tsi_frame_protector *self, + const unsigned char *unprotected_bytes, + size_t *unprotected_bytes_size, + unsigned char *protected_output_frames, + size_t *protected_output_frames_size) { + tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; + int read_from_ssl; + size_t available; + tsi_result result = TSI_OK; + + /* First see if we have some pending data in the SSL BIO. */ + int pending_in_ssl = (int)BIO_pending(impl->from_ssl); + if (pending_in_ssl > 0) { + *unprotected_bytes_size = 0; + GPR_ASSERT(*protected_output_frames_size <= INT_MAX); + read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames, + (int)*protected_output_frames_size); + if (read_from_ssl < 0) { + gpr_log(GPR_ERROR, + "Could not read from BIO even though some data is pending"); + return TSI_INTERNAL_ERROR; + } + *protected_output_frames_size = (size_t)read_from_ssl; + return TSI_OK; + } + + /* Now see if we can send a complete frame. */ + available = impl->buffer_size - impl->buffer_offset; + if (available > *unprotected_bytes_size) { + /* If we cannot, just copy the data in our internal buffer. */ + memcpy(impl->buffer + impl->buffer_offset, unprotected_bytes, + *unprotected_bytes_size); + impl->buffer_offset += *unprotected_bytes_size; + *protected_output_frames_size = 0; + return TSI_OK; + } + + /* If we can, prepare the buffer, send it to SSL_write and read. */ + memcpy(impl->buffer + impl->buffer_offset, unprotected_bytes, available); + result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_size); + if (result != TSI_OK) return result; + + GPR_ASSERT(*protected_output_frames_size <= INT_MAX); + read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames, + (int)*protected_output_frames_size); + if (read_from_ssl < 0) { + gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write."); + return TSI_INTERNAL_ERROR; + } + *protected_output_frames_size = (size_t)read_from_ssl; + *unprotected_bytes_size = available; + impl->buffer_offset = 0; + return TSI_OK; +} + +static tsi_result ssl_protector_protect_flush( + tsi_frame_protector *self, unsigned char *protected_output_frames, + size_t *protected_output_frames_size, size_t *still_pending_size) { + tsi_result result = TSI_OK; + tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; + int read_from_ssl = 0; + int pending; + + if (impl->buffer_offset != 0) { + result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_offset); + if (result != TSI_OK) return result; + impl->buffer_offset = 0; + } + + pending = (int)BIO_pending(impl->from_ssl); + GPR_ASSERT(pending >= 0); + *still_pending_size = (size_t)pending; + if (*still_pending_size == 0) return TSI_OK; + + GPR_ASSERT(*protected_output_frames_size <= INT_MAX); + read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames, + (int)*protected_output_frames_size); + if (read_from_ssl <= 0) { + gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write."); + return TSI_INTERNAL_ERROR; + } + *protected_output_frames_size = (size_t)read_from_ssl; + pending = (int)BIO_pending(impl->from_ssl); + GPR_ASSERT(pending >= 0); + *still_pending_size = (size_t)pending; + return TSI_OK; +} + +static tsi_result ssl_protector_unprotect( + tsi_frame_protector *self, const unsigned char *protected_frames_bytes, + size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes, + size_t *unprotected_bytes_size) { + tsi_result result = TSI_OK; + int written_into_ssl = 0; + size_t output_bytes_size = *unprotected_bytes_size; + size_t output_bytes_offset = 0; + tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; + + /* First, try to read remaining data from ssl. */ + result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size); + if (result != TSI_OK) return result; + if (*unprotected_bytes_size == output_bytes_size) { + /* We have read everything we could and cannot process any more input. */ + *protected_frames_bytes_size = 0; + return TSI_OK; + } + output_bytes_offset = *unprotected_bytes_size; + unprotected_bytes += output_bytes_offset; + *unprotected_bytes_size = output_bytes_size - output_bytes_offset; + + /* Then, try to write some data to ssl. */ + GPR_ASSERT(*protected_frames_bytes_size <= INT_MAX); + written_into_ssl = BIO_write(impl->into_ssl, protected_frames_bytes, + (int)*protected_frames_bytes_size); + if (written_into_ssl < 0) { + gpr_log(GPR_ERROR, "Sending protected frame to ssl failed with %d", + written_into_ssl); + return TSI_INTERNAL_ERROR; + } + *protected_frames_bytes_size = (size_t)written_into_ssl; + + /* Now try to read some data again. */ + result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size); + if (result == TSI_OK) { + /* Don't forget to output the total number of bytes read. */ + *unprotected_bytes_size += output_bytes_offset; + } + return result; +} + +static void ssl_protector_destroy(tsi_frame_protector *self) { + tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; + if (impl->buffer != NULL) free(impl->buffer); + if (impl->ssl != NULL) SSL_free(impl->ssl); + free(self); +} + +static const tsi_frame_protector_vtable frame_protector_vtable = { + ssl_protector_protect, ssl_protector_protect_flush, ssl_protector_unprotect, + ssl_protector_destroy, +}; + +/* --- tsi_handshaker methods implementation. ---*/ + +static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, + unsigned char *bytes, + size_t *bytes_size) { + tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; + int bytes_read_from_ssl = 0; + if (bytes == NULL || bytes_size == NULL || *bytes_size == 0 || + *bytes_size > INT_MAX) { + return TSI_INVALID_ARGUMENT; + } + GPR_ASSERT(*bytes_size <= INT_MAX); + bytes_read_from_ssl = BIO_read(impl->from_ssl, bytes, (int)*bytes_size); + if (bytes_read_from_ssl < 0) { + *bytes_size = 0; + if (!BIO_should_retry(impl->from_ssl)) { + impl->result = TSI_INTERNAL_ERROR; + return impl->result; + } else { + return TSI_OK; + } + } + *bytes_size = (size_t)bytes_read_from_ssl; + return BIO_pending(impl->from_ssl) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA; +} + +static tsi_result ssl_handshaker_get_result(tsi_handshaker *self) { + tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; + if ((impl->result == TSI_HANDSHAKE_IN_PROGRESS) && + SSL_is_init_finished(impl->ssl)) { + impl->result = TSI_OK; + } + return impl->result; +} + +static tsi_result ssl_handshaker_process_bytes_from_peer( + tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size) { + tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; + int bytes_written_into_ssl_size = 0; + if (bytes == NULL || bytes_size == 0 || *bytes_size > INT_MAX) { + return TSI_INVALID_ARGUMENT; + } + GPR_ASSERT(*bytes_size <= INT_MAX); + bytes_written_into_ssl_size = + BIO_write(impl->into_ssl, bytes, (int)*bytes_size); + if (bytes_written_into_ssl_size < 0) { + gpr_log(GPR_ERROR, "Could not write to memory BIO."); + impl->result = TSI_INTERNAL_ERROR; + return impl->result; + } + *bytes_size = (size_t)bytes_written_into_ssl_size; + + if (!tsi_handshaker_is_in_progress(self)) { + impl->result = TSI_OK; + return impl->result; + } else { + /* Get ready to get some bytes from SSL. */ + int ssl_result = SSL_do_handshake(impl->ssl); + ssl_result = SSL_get_error(impl->ssl, ssl_result); + switch (ssl_result) { + case SSL_ERROR_WANT_READ: + if (BIO_pending(impl->from_ssl) == 0) { + /* We need more data. */ + return TSI_INCOMPLETE_DATA; + } else { + return TSI_OK; + } + case SSL_ERROR_NONE: + return TSI_OK; + default: { + char err_str[256]; + ERR_error_string_n(ERR_get_error(), err_str, sizeof(err_str)); + gpr_log(GPR_ERROR, "Handshake failed with fatal error %s: %s.", + ssl_error_string(ssl_result), err_str); + impl->result = TSI_PROTOCOL_FAILURE; + return impl->result; + } + } + } +} + +static tsi_result ssl_handshaker_extract_peer(tsi_handshaker *self, + tsi_peer *peer) { + tsi_result result = TSI_OK; + const unsigned char *alpn_selected = NULL; + unsigned int alpn_selected_len; + tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; + X509 *peer_cert = SSL_get_peer_certificate(impl->ssl); + if (peer_cert != NULL) { + result = peer_from_x509(peer_cert, 1, peer); + X509_free(peer_cert); + if (result != TSI_OK) return result; + } +#if TSI_OPENSSL_ALPN_SUPPORT + SSL_get0_alpn_selected(impl->ssl, &alpn_selected, &alpn_selected_len); +#endif /* TSI_OPENSSL_ALPN_SUPPORT */ + if (alpn_selected == NULL) { + /* Try npn. */ + SSL_get0_next_proto_negotiated(impl->ssl, &alpn_selected, + &alpn_selected_len); + } + if (alpn_selected != NULL) { + size_t i; + tsi_peer_property *new_properties = + calloc(1, sizeof(tsi_peer_property) * (peer->property_count + 1)); + if (new_properties == NULL) return TSI_OUT_OF_RESOURCES; + for (i = 0; i < peer->property_count; i++) { + new_properties[i] = peer->properties[i]; + } + result = tsi_construct_string_peer_property( + TSI_SSL_ALPN_SELECTED_PROTOCOL, (const char *)alpn_selected, + alpn_selected_len, &new_properties[peer->property_count]); + if (result != TSI_OK) { + free(new_properties); + return result; + } + if (peer->properties != NULL) free(peer->properties); + peer->property_count++; + peer->properties = new_properties; + } + return result; +} + +static tsi_result ssl_handshaker_create_frame_protector( + tsi_handshaker *self, size_t *max_output_protected_frame_size, + tsi_frame_protector **protector) { + size_t actual_max_output_protected_frame_size = + TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND; + tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; + tsi_ssl_frame_protector *protector_impl = + calloc(1, sizeof(tsi_ssl_frame_protector)); + if (protector_impl == NULL) { + return TSI_OUT_OF_RESOURCES; + } + + if (max_output_protected_frame_size != NULL) { + if (*max_output_protected_frame_size > + TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND) { + *max_output_protected_frame_size = + TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND; + } else if (*max_output_protected_frame_size < + TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND) { + *max_output_protected_frame_size = + TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND; + } + actual_max_output_protected_frame_size = *max_output_protected_frame_size; + } + protector_impl->buffer_size = + actual_max_output_protected_frame_size - TSI_SSL_MAX_PROTECTION_OVERHEAD; + protector_impl->buffer = malloc(protector_impl->buffer_size); + if (protector_impl->buffer == NULL) { + gpr_log(GPR_ERROR, + "Could not allocated buffer for tsi_ssl_frame_protector."); + free(protector_impl); + return TSI_INTERNAL_ERROR; + } + + /* Transfer ownership of ssl to the frame protector. It is OK as the caller + * cannot call anything else but destroy on the handshaker after this call. */ + protector_impl->ssl = impl->ssl; + impl->ssl = NULL; + protector_impl->into_ssl = impl->into_ssl; + protector_impl->from_ssl = impl->from_ssl; + + protector_impl->base.vtable = &frame_protector_vtable; + *protector = &protector_impl->base; + return TSI_OK; +} + +static void ssl_handshaker_destroy(tsi_handshaker *self) { + tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; + SSL_free(impl->ssl); /* The BIO objects are owned by ssl */ + free(impl); +} + +static const tsi_handshaker_vtable handshaker_vtable = { + ssl_handshaker_get_bytes_to_send_to_peer, + ssl_handshaker_process_bytes_from_peer, + ssl_handshaker_get_result, + ssl_handshaker_extract_peer, + ssl_handshaker_create_frame_protector, + ssl_handshaker_destroy, +}; + +/* --- tsi_ssl_handshaker_factory common methods. --- */ + +tsi_result tsi_ssl_handshaker_factory_create_handshaker( + tsi_ssl_handshaker_factory *self, const char *server_name_indication, + tsi_handshaker **handshaker) { + if (self == NULL || handshaker == NULL) return TSI_INVALID_ARGUMENT; + return self->create_handshaker(self, server_name_indication, handshaker); +} + +void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory *self) { + if (self == NULL) return; + self->destroy(self); +} + +static tsi_result create_tsi_ssl_handshaker(SSL_CTX *ctx, int is_client, + const char *server_name_indication, + tsi_handshaker **handshaker) { + SSL *ssl = SSL_new(ctx); + BIO *into_ssl = NULL; + BIO *from_ssl = NULL; + tsi_ssl_handshaker *impl = NULL; + *handshaker = NULL; + if (ctx == NULL) { + gpr_log(GPR_ERROR, "SSL Context is null. Should never happen."); + return TSI_INTERNAL_ERROR; + } + if (ssl == NULL) { + return TSI_OUT_OF_RESOURCES; + } + SSL_set_info_callback(ssl, ssl_info_callback); + + into_ssl = BIO_new(BIO_s_mem()); + from_ssl = BIO_new(BIO_s_mem()); + if (into_ssl == NULL || from_ssl == NULL) { + gpr_log(GPR_ERROR, "BIO_new failed."); + SSL_free(ssl); + if (into_ssl != NULL) BIO_free(into_ssl); + if (from_ssl != NULL) BIO_free(into_ssl); + return TSI_OUT_OF_RESOURCES; + } + SSL_set_bio(ssl, into_ssl, from_ssl); + if (is_client) { + int ssl_result; + SSL_set_connect_state(ssl); + if (server_name_indication != NULL) { + if (!SSL_set_tlsext_host_name(ssl, server_name_indication)) { + gpr_log(GPR_ERROR, "Invalid server name indication %s.", + server_name_indication); + SSL_free(ssl); + return TSI_INTERNAL_ERROR; + } + } + ssl_result = SSL_do_handshake(ssl); + ssl_result = SSL_get_error(ssl, ssl_result); + if (ssl_result != SSL_ERROR_WANT_READ) { + gpr_log(GPR_ERROR, + "Unexpected error received from first SSL_do_handshake call: %s", + ssl_error_string(ssl_result)); + SSL_free(ssl); + return TSI_INTERNAL_ERROR; + } + } else { + SSL_set_accept_state(ssl); + } + + impl = calloc(1, sizeof(tsi_ssl_handshaker)); + if (impl == NULL) { + SSL_free(ssl); + return TSI_OUT_OF_RESOURCES; + } + impl->ssl = ssl; + impl->into_ssl = into_ssl; + impl->from_ssl = from_ssl; + impl->result = TSI_HANDSHAKE_IN_PROGRESS; + impl->base.vtable = &handshaker_vtable; + *handshaker = &impl->base; + return TSI_OK; +} + +static int select_protocol_list(const unsigned char **out, + unsigned char *outlen, + const unsigned char *client_list, + size_t client_list_len, + const unsigned char *server_list, + size_t server_list_len) { + const unsigned char *client_current = client_list; + while ((unsigned int)(client_current - client_list) < client_list_len) { + unsigned char client_current_len = *(client_current++); + const unsigned char *server_current = server_list; + while ((server_current >= server_list) && + (uintptr_t)(server_current - server_list) < server_list_len) { + unsigned char server_current_len = *(server_current++); + if ((client_current_len == server_current_len) && + !memcmp(client_current, server_current, server_current_len)) { + *out = server_current; + *outlen = server_current_len; + return SSL_TLSEXT_ERR_OK; + } + server_current += server_current_len; + } + client_current += client_current_len; + } + return SSL_TLSEXT_ERR_NOACK; +} + +/* --- tsi_ssl__client_handshaker_factory methods implementation. --- */ + +static tsi_result ssl_client_handshaker_factory_create_handshaker( + tsi_ssl_handshaker_factory *self, const char *server_name_indication, + tsi_handshaker **handshaker) { + tsi_ssl_client_handshaker_factory *impl = + (tsi_ssl_client_handshaker_factory *)self; + return create_tsi_ssl_handshaker(impl->ssl_context, 1, server_name_indication, + handshaker); +} + +static void ssl_client_handshaker_factory_destroy( + tsi_ssl_handshaker_factory *self) { + tsi_ssl_client_handshaker_factory *impl = + (tsi_ssl_client_handshaker_factory *)self; + if (impl->ssl_context != NULL) SSL_CTX_free(impl->ssl_context); + if (impl->alpn_protocol_list != NULL) free(impl->alpn_protocol_list); + free(impl); +} + +static int client_handshaker_factory_npn_callback(SSL *ssl, unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg) { + tsi_ssl_client_handshaker_factory *factory = + (tsi_ssl_client_handshaker_factory *)arg; + return select_protocol_list((const unsigned char **)out, outlen, + factory->alpn_protocol_list, + factory->alpn_protocol_list_length, in, inlen); +} + +/* --- tsi_ssl_server_handshaker_factory methods implementation. --- */ + +static tsi_result ssl_server_handshaker_factory_create_handshaker( + tsi_ssl_handshaker_factory *self, const char *server_name_indication, + tsi_handshaker **handshaker) { + tsi_ssl_server_handshaker_factory *impl = + (tsi_ssl_server_handshaker_factory *)self; + if (impl->ssl_context_count == 0 || server_name_indication != NULL) { + return TSI_INVALID_ARGUMENT; + } + /* Create the handshaker with the first context. We will switch if needed + because of SNI in ssl_server_handshaker_factory_servername_callback. */ + return create_tsi_ssl_handshaker(impl->ssl_contexts[0], 0, NULL, handshaker); +} + +static void ssl_server_handshaker_factory_destroy( + tsi_ssl_handshaker_factory *self) { + tsi_ssl_server_handshaker_factory *impl = + (tsi_ssl_server_handshaker_factory *)self; + size_t i; + for (i = 0; i < impl->ssl_context_count; i++) { + if (impl->ssl_contexts[i] != NULL) { + SSL_CTX_free(impl->ssl_contexts[i]); + tsi_peer_destruct(&impl->ssl_context_x509_subject_names[i]); + } + } + if (impl->ssl_contexts != NULL) free(impl->ssl_contexts); + if (impl->ssl_context_x509_subject_names != NULL) { + free(impl->ssl_context_x509_subject_names); + } + if (impl->alpn_protocol_list != NULL) free(impl->alpn_protocol_list); + free(impl); +} + +static int does_entry_match_name(const char *entry, size_t entry_length, + const char *name) { + const char *dot; + const char *name_subdomain = NULL; + size_t name_length = strlen(name); + size_t name_subdomain_length; + if (entry_length == 0) return 0; + + /* Take care of '.' terminations. */ + if (name[name_length - 1] == '.') { + name_length--; + } + if (entry[entry_length - 1] == '.') { + entry_length--; + if (entry_length == 0) return 0; + } + + if ((name_length == entry_length) && + strncmp(name, entry, entry_length) == 0) { + return 1; /* Perfect match. */ + } + if (entry[0] != '*') return 0; + + /* Wildchar subdomain matching. */ + if (entry_length < 3 || entry[1] != '.') { /* At least *.x */ + gpr_log(GPR_ERROR, "Invalid wildchar entry."); + return 0; + } + name_subdomain = strchr(name, '.'); + if (name_subdomain == NULL) return 0; + name_subdomain_length = strlen(name_subdomain); + if (name_subdomain_length < 2) return 0; + name_subdomain++; /* Starts after the dot. */ + name_subdomain_length--; + entry += 2; /* Remove *. */ + entry_length -= 2; + dot = strchr(name_subdomain, '.'); + if ((dot == NULL) || (dot == &name_subdomain[name_subdomain_length - 1])) { + gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", name_subdomain); + return 0; + } + if (name_subdomain[name_subdomain_length - 1] == '.') { + name_subdomain_length--; + } + return ((entry_length > 0) && (name_subdomain_length == entry_length) && + strncmp(entry, name_subdomain, entry_length) == 0); +} + +static int ssl_server_handshaker_factory_servername_callback(SSL *ssl, int *ap, + void *arg) { + tsi_ssl_server_handshaker_factory *impl = + (tsi_ssl_server_handshaker_factory *)arg; + size_t i = 0; + const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); + if (servername == NULL || strlen(servername) == 0) { + return SSL_TLSEXT_ERR_NOACK; + } + + for (i = 0; i < impl->ssl_context_count; i++) { + if (tsi_ssl_peer_matches_name(&impl->ssl_context_x509_subject_names[i], + servername)) { + SSL_set_SSL_CTX(ssl, impl->ssl_contexts[i]); + return SSL_TLSEXT_ERR_OK; + } + } + gpr_log(GPR_ERROR, "No match found for server name: %s.", servername); + return SSL_TLSEXT_ERR_ALERT_WARNING; +} + +#if TSI_OPENSSL_ALPN_SUPPORT +static int server_handshaker_factory_alpn_callback( + SSL *ssl, const unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, void *arg) { + tsi_ssl_server_handshaker_factory *factory = + (tsi_ssl_server_handshaker_factory *)arg; + return select_protocol_list(out, outlen, in, inlen, + factory->alpn_protocol_list, + factory->alpn_protocol_list_length); +} +#endif /* TSI_OPENSSL_ALPN_SUPPORT */ + +static int server_handshaker_factory_npn_advertised_callback( + SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg) { + tsi_ssl_server_handshaker_factory *factory = + (tsi_ssl_server_handshaker_factory *)arg; + *out = factory->alpn_protocol_list; + GPR_ASSERT(factory->alpn_protocol_list_length <= UINT_MAX); + *outlen = (unsigned int)factory->alpn_protocol_list_length; + return SSL_TLSEXT_ERR_OK; +} + +/* --- tsi_ssl_handshaker_factory constructors. --- */ + +tsi_result tsi_create_ssl_client_handshaker_factory( + const unsigned char *pem_private_key, size_t pem_private_key_size, + const unsigned char *pem_cert_chain, size_t pem_cert_chain_size, + const unsigned char *pem_root_certs, size_t pem_root_certs_size, + const char *cipher_list, const unsigned char **alpn_protocols, + const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, + tsi_ssl_handshaker_factory **factory) { + SSL_CTX *ssl_context = NULL; + tsi_ssl_client_handshaker_factory *impl = NULL; + tsi_result result = TSI_OK; + + gpr_once_init(&init_openssl_once, init_openssl); + + if (factory == NULL) return TSI_INVALID_ARGUMENT; + *factory = NULL; + if (pem_root_certs == NULL) return TSI_INVALID_ARGUMENT; + + ssl_context = SSL_CTX_new(TLSv1_2_method()); + if (ssl_context == NULL) { + gpr_log(GPR_ERROR, "Could not create ssl context."); + return TSI_INVALID_ARGUMENT; + } + + impl = calloc(1, sizeof(tsi_ssl_client_handshaker_factory)); + if (impl == NULL) { + SSL_CTX_free(ssl_context); + return TSI_OUT_OF_RESOURCES; + } + impl->ssl_context = ssl_context; + + do { + result = + populate_ssl_context(ssl_context, pem_private_key, pem_private_key_size, + pem_cert_chain, pem_cert_chain_size, cipher_list); + if (result != TSI_OK) break; + result = ssl_ctx_load_verification_certs(ssl_context, pem_root_certs, + pem_root_certs_size, NULL); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Cannot load server root certificates."); + break; + } + + if (num_alpn_protocols != 0) { + result = build_alpn_protocol_name_list( + alpn_protocols, alpn_protocols_lengths, num_alpn_protocols, + &impl->alpn_protocol_list, &impl->alpn_protocol_list_length); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Building alpn list failed with error %s.", + tsi_result_to_string(result)); + break; + } +#if TSI_OPENSSL_ALPN_SUPPORT + GPR_ASSERT(impl->alpn_protocol_list_length < UINT_MAX); + if (SSL_CTX_set_alpn_protos( + ssl_context, impl->alpn_protocol_list, + (unsigned int)impl->alpn_protocol_list_length)) { + gpr_log(GPR_ERROR, "Could not set alpn protocol list to context."); + result = TSI_INVALID_ARGUMENT; + break; + } +#endif /* TSI_OPENSSL_ALPN_SUPPORT */ + SSL_CTX_set_next_proto_select_cb( + ssl_context, client_handshaker_factory_npn_callback, impl); + } + } while (0); + if (result != TSI_OK) { + ssl_client_handshaker_factory_destroy(&impl->base); + return result; + } + SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NULL); + /* TODO(jboeuf): Add revocation verification. */ + + impl->base.create_handshaker = + ssl_client_handshaker_factory_create_handshaker; + impl->base.destroy = ssl_client_handshaker_factory_destroy; + *factory = &impl->base; + return TSI_OK; +} + +tsi_result tsi_create_ssl_server_handshaker_factory( + const unsigned char **pem_private_keys, + const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains, + const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count, + const unsigned char *pem_client_root_certs, + size_t pem_client_root_certs_size, int force_client_auth, + const char *cipher_list, const unsigned char **alpn_protocols, + const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, + tsi_ssl_handshaker_factory **factory) { + tsi_ssl_server_handshaker_factory *impl = NULL; + tsi_result result = TSI_OK; + size_t i = 0; + + gpr_once_init(&init_openssl_once, init_openssl); + + if (factory == NULL) return TSI_INVALID_ARGUMENT; + *factory = NULL; + if (key_cert_pair_count == 0 || pem_private_keys == NULL || + pem_cert_chains == NULL) { + return TSI_INVALID_ARGUMENT; + } + + impl = calloc(1, sizeof(tsi_ssl_server_handshaker_factory)); + if (impl == NULL) return TSI_OUT_OF_RESOURCES; + impl->base.create_handshaker = + ssl_server_handshaker_factory_create_handshaker; + impl->base.destroy = ssl_server_handshaker_factory_destroy; + impl->ssl_contexts = calloc(key_cert_pair_count, sizeof(SSL_CTX *)); + impl->ssl_context_x509_subject_names = + calloc(key_cert_pair_count, sizeof(tsi_peer)); + if (impl->ssl_contexts == NULL || + impl->ssl_context_x509_subject_names == NULL) { + tsi_ssl_handshaker_factory_destroy(&impl->base); + return TSI_OUT_OF_RESOURCES; + } + impl->ssl_context_count = key_cert_pair_count; + + if (num_alpn_protocols > 0) { + result = build_alpn_protocol_name_list( + alpn_protocols, alpn_protocols_lengths, num_alpn_protocols, + &impl->alpn_protocol_list, &impl->alpn_protocol_list_length); + if (result != TSI_OK) { + tsi_ssl_handshaker_factory_destroy(&impl->base); + return result; + } + } + + for (i = 0; i < key_cert_pair_count; i++) { + do { + impl->ssl_contexts[i] = SSL_CTX_new(TLSv1_2_method()); + if (impl->ssl_contexts[i] == NULL) { + gpr_log(GPR_ERROR, "Could not create ssl context."); + result = TSI_OUT_OF_RESOURCES; + break; + } + result = populate_ssl_context( + impl->ssl_contexts[i], pem_private_keys[i], pem_private_keys_sizes[i], + pem_cert_chains[i], pem_cert_chains_sizes[i], cipher_list); + if (result != TSI_OK) break; + + if (pem_client_root_certs != NULL) { + int flags = SSL_VERIFY_PEER; + STACK_OF(X509_NAME) *root_names = NULL; + result = ssl_ctx_load_verification_certs( + impl->ssl_contexts[i], pem_client_root_certs, + pem_client_root_certs_size, &root_names); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Invalid verification certs."); + break; + } + SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names); + if (force_client_auth) flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + SSL_CTX_set_verify(impl->ssl_contexts[i], flags, NULL); + /* TODO(jboeuf): Add revocation verification. */ + } + + result = extract_x509_subject_names_from_pem_cert( + pem_cert_chains[i], pem_cert_chains_sizes[i], + &impl->ssl_context_x509_subject_names[i]); + if (result != TSI_OK) break; + + SSL_CTX_set_tlsext_servername_callback( + impl->ssl_contexts[i], + ssl_server_handshaker_factory_servername_callback); + SSL_CTX_set_tlsext_servername_arg(impl->ssl_contexts[i], impl); +#if TSI_OPENSSL_ALPN_SUPPORT + SSL_CTX_set_alpn_select_cb(impl->ssl_contexts[i], + server_handshaker_factory_alpn_callback, impl); +#endif /* TSI_OPENSSL_ALPN_SUPPORT */ + SSL_CTX_set_next_protos_advertised_cb( + impl->ssl_contexts[i], + server_handshaker_factory_npn_advertised_callback, impl); + } while (0); + + if (result != TSI_OK) { + tsi_ssl_handshaker_factory_destroy(&impl->base); + return result; + } + } + *factory = &impl->base; + return TSI_OK; +} + +/* --- tsi_ssl utils. --- */ + +int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name) { + size_t i = 0; + size_t san_count = 0; + const tsi_peer_property *cn_property = NULL; + int like_ip = looks_like_ip_address(name); + + /* Check the SAN first. */ + for (i = 0; i < peer->property_count; i++) { + const tsi_peer_property *property = &peer->properties[i]; + if (property->name == NULL) continue; + if (strcmp(property->name, + TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { + san_count++; + + if (!like_ip && does_entry_match_name(property->value.data, + property->value.length, name)) { + return 1; + } else if (like_ip && + strncmp(name, property->value.data, property->value.length) == + 0 && + strlen(name) == property->value.length) { + /* IP Addresses are exact matches only. */ + return 1; + } + } else if (strcmp(property->name, + TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) { + cn_property = property; + } + } + + /* If there's no SAN, try the CN, but only if its not like an IP Address */ + if (san_count == 0 && cn_property != NULL && !like_ip) { + if (does_entry_match_name(cn_property->value.data, + cn_property->value.length, name)) { + return 1; + } + } + + return 0; /* Not found. */ +} diff --git a/src/core/lib/tsi/ssl_transport_security.h b/src/core/lib/tsi/ssl_transport_security.h new file mode 100644 index 0000000000..612f5c64cc --- /dev/null +++ b/src/core/lib/tsi/ssl_transport_security.h @@ -0,0 +1,174 @@ +/* + * + * Copyright 2015-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_TSI_SSL_TRANSPORT_SECURITY_H +#define GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H + +#include "src/core/tsi/transport_security_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */ +#define TSI_X509_CERTIFICATE_TYPE "X509" + +/* This property is of type TSI_PEER_PROPERTY_STRING. */ +#define TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY "x509_subject_common_name" +#define TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY \ + "x509_subject_alternative_name" + +#define TSI_X509_PEM_CERT_PROPERTY "x509_pem_cert" + +#define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol" + +/* --- tsi_ssl_handshaker_factory object --- + + This object creates tsi_handshaker objects implemented in terms of the + TLS 1.2 specificiation. */ + +typedef struct tsi_ssl_handshaker_factory tsi_ssl_handshaker_factory; + +/* Creates a client handshaker factory. + - pem_private_key is the buffer containing the PEM encoding of the client's + private key. This parameter can be NULL if the client does not have a + private key. + - pem_private_key_size is the size of the associated buffer. + - pem_cert_chain is the buffer containing the PEM encoding of the client's + certificate chain. This parameter can be NULL if the client does not have + a certificate chain. + - pem_cert_chain_size is the size of the associated buffer. + - pem_roots_cert is the buffer containing the PEM encoding of the server + root certificates. This parameter cannot be NULL. + - pem_roots_cert_size is the size of the associated buffer. + - cipher_suites contains an optional list of the ciphers that the client + supports. The format of this string is described in: + https://www.openssl.org/docs/apps/ciphers.html. + This parameter can be set to NULL to use the default set of ciphers. + TODO(jboeuf): Revisit the format of this parameter. + - alpn_protocols is an array containing the protocol names that the + handshakers created with this factory support. This parameter can be NULL. + - alpn_protocols_lengths is an array containing the lengths of the alpn + protocols specified in alpn_protocols. This parameter can be NULL. + - num_alpn_protocols is the number of alpn protocols and associated lengths + specified. If this parameter is 0, the other alpn parameters must be NULL. + - factory is the address of the factory pointer to be created. + + - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case + where a parameter is invalid. */ +tsi_result tsi_create_ssl_client_handshaker_factory( + const unsigned char *pem_private_key, size_t pem_private_key_size, + const unsigned char *pem_cert_chain, size_t pem_cert_chain_size, + const unsigned char *pem_root_certs, size_t pem_root_certs_size, + const char *cipher_suites, const unsigned char **alpn_protocols, + const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, + tsi_ssl_handshaker_factory **factory); + +/* Creates a server handshaker factory. + - version indicates which version of the specification to use. + - pem_private_keys is an array containing the PEM encoding of the server's + private keys. This parameter cannot be NULL. The size of the array is + given by the key_cert_pair_count parameter. + - pem_private_keys_sizes is the array containing the sizes of the associated + buffers. + - pem_cert_chains is an array containing the PEM encoding of the server's + cert chains. This parameter cannot be NULL. The size of the array is + given by the key_cert_pair_count parameter. + - pem_cert_chains_sizes is the array containing the sizes of the associated + buffers. + - key_cert_pair_count indicates the number of items in the private_key_files + and cert_chain_files parameters. + - pem_client_roots is the buffer containing the PEM encoding of the client + root certificates. This parameter may be NULL in which case the server will + not authenticate the client. If not NULL, the force_client_auth parameter + specifies if the server will accept only authenticated clients or both + authenticated and non-authenticated clients. + - pem_client_root_certs_size is the size of the associated buffer. + - force_client_auth, if set to non-zero will force the client to authenticate + with an SSL cert. Note that this option is ignored if pem_client_root_certs + is NULL or pem_client_roots_certs_size is 0 + - cipher_suites contains an optional list of the ciphers that the server + supports. The format of this string is described in: + https://www.openssl.org/docs/apps/ciphers.html. + This parameter can be set to NULL to use the default set of ciphers. + TODO(jboeuf): Revisit the format of this parameter. + - alpn_protocols is an array containing the protocol names that the + handshakers created with this factory support. This parameter can be NULL. + - alpn_protocols_lengths is an array containing the lengths of the alpn + protocols specified in alpn_protocols. This parameter can be NULL. + - num_alpn_protocols is the number of alpn protocols and associated lengths + specified. If this parameter is 0, the other alpn parameters must be NULL. + - factory is the address of the factory pointer to be created. + + - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case + where a parameter is invalid. */ +tsi_result tsi_create_ssl_server_handshaker_factory( + const unsigned char **pem_private_keys, + const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains, + const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count, + const unsigned char *pem_client_root_certs, + size_t pem_client_root_certs_size, int force_client_auth, + const char *cipher_suites, const unsigned char **alpn_protocols, + const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, + tsi_ssl_handshaker_factory **factory); + +/* Creates a handshaker. + - self is the factory from which the handshaker will be created. + - server_name_indication indicates the name of the server the client is + trying to connect to which will be relayed to the server using the SNI + extension. + This parameter must be NULL for a server handshaker factory. + - handhshaker is the address of the handshaker pointer to be created. + + - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case + where a parameter is invalid. */ +tsi_result tsi_ssl_handshaker_factory_create_handshaker( + tsi_ssl_handshaker_factory *self, const char *server_name_indication, + tsi_handshaker **handshaker); + +/* Destroys the handshaker factory. WARNING: it is unsafe to destroy a factory + while handshakers created with this factory are still in use. */ +void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory *self); + +/* Util that checks that an ssl peer matches a specific name. + Still TODO(jboeuf): + - handle mixed case. + - handle %encoded chars. + - handle public suffix wildchar more strictly (e.g. *.co.uk) */ +int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name); + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H */ diff --git a/src/core/lib/tsi/ssl_types.h b/src/core/lib/tsi/ssl_types.h new file mode 100644 index 0000000000..6ea85fe6d4 --- /dev/null +++ b/src/core/lib/tsi/ssl_types.h @@ -0,0 +1,55 @@ +/* + * + * Copyright 2015-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_TSI_SSL_TYPES_H +#define GRPC_CORE_TSI_SSL_TYPES_H + +/* A collection of macros to cast between various integer types that are + * used differently between BoringSSL and OpenSSL: + * TSI_INT_AS_SIZE(x): convert 'int x' to a length parameter for an OpenSSL + * function + * TSI_SIZE_AS_SIZE(x): convert 'size_t x' to a length parameter for an OpenSSL + * function + */ + +#include + +#ifdef OPENSSL_IS_BORINGSSL +#define TSI_INT_AS_SIZE(x) ((size_t)(x)) +#define TSI_SIZE_AS_SIZE(x) (x) +#else +#define TSI_INT_AS_SIZE(x) (x) +#define TSI_SIZE_AS_SIZE(x) ((int)(x)) +#endif + +#endif /* GRPC_CORE_TSI_SSL_TYPES_H */ diff --git a/src/core/lib/tsi/test_creds/README b/src/core/lib/tsi/test_creds/README new file mode 100644 index 0000000000..eb8482d648 --- /dev/null +++ b/src/core/lib/tsi/test_creds/README @@ -0,0 +1,62 @@ +The test credentials (CONFIRMEDTESTKEY) have been generated with the following +commands: + +Bad credentials (badclient.* / badserver.*): +============================================ + +These are self-signed certificates: + +$ openssl req -x509 -newkey rsa:1024 -keyout badserver.key -out badserver.pem \ + -days 3650 -nodes + +When prompted for certificate information, everything is default except the +common name which is set to badserver.test.google.com. + + +Valid test credentials: +======================= + +The ca is self-signed: +---------------------- + +$ openssl req -x509 -new -newkey rsa:1024 -nodes -out ca.pem -config ca-openssl.cnf -days 3650 -extensions v3_req +When prompted for certificate information, everything is default. + +client is issued by CA: +----------------------- + +$ openssl genrsa -out client.key.rsa 1024 +$ openssl pkcs8 -topk8 -in client.key.rsa -out client.key -nocrypt +$ rm client.key.rsa +$ openssl req -new -key client.key -out client.csr + +When prompted for certificate information, everything is default except the +common name which is set to testclient. + +$ openssl ca -in client.csr -out client.pem + +server0 is issued by CA: +------------------------ + +$ openssl genrsa -out server0.key.rsa 1024 +$ openssl pkcs8 -topk8 -in server0.key.rsa -out server0.key -nocrypt +$ rm server0.key.rsa +$ openssl req -new -key server0.key -out server0.csr + +When prompted for certificate information, everything is default except the +common name which is set to *.test.google.com.au. + +$ openssl ca -in server0.csr -out server0.pem + +server1 is issued by CA with a special config for subject alternative names: +---------------------------------------------------------------------------- + +$ openssl genrsa -out server1.key.rsa 1024 +$ openssl pkcs8 -topk8 -in server1.key.rsa -out server1.key -nocrypt +$ rm server1.key.rsa +$ openssl req -new -key server1.key -out server1.csr -config server1-openssl.cnf + +When prompted for certificate information, everything is default except the +common name which is set to *.test.google.com. + +$ openssl ca -in server1.csr -out server1.pem diff --git a/src/core/lib/tsi/test_creds/badclient.key b/src/core/lib/tsi/test_creds/badclient.key new file mode 100644 index 0000000000..5832685122 --- /dev/null +++ b/src/core/lib/tsi/test_creds/badclient.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALJfYnFn4nkj52WF +E5W2qUxCfjsEFyuXYYKS/07UPWsv3gpZhtjXgdeGL+dpwEBC0IRDBfGnkMp6YY5S +O7rnEz0X3r/fvgYy+dEl2jnaA6zgc7RzMGl9U11d56gP9FiDC2190mvP/hpq2xLZ +CTbIximpmaoQyxuuH1bbYunesIG/AgMBAAECgYAdqJCEzMIyZE7oaW0tOpcB0BiP +FYoIvH4BKRH8eHvR476mt+YdDhBP1scGUmYeCT4Ej+RgHv2LPTgVYwT9eciP2+E/ +CBCNRel0Sw9JepwW0r+jWJtDY1pp6YXAgNRGX2UflvUsT+o9lZvagf9moLTMyGvU +uLFnsyfLim1B4vXvWQJBANouZllXGZoSrZLtR3VgV4tzRQvJxu84kLeIk64Ov47X +pHVBMTRBfzPEhbBodjr1m5OLaVLqkFcXftzRCrbWoKsCQQDRSoLLXOiLrtJ3DLJC +rX7Y8wrHZrqk5bMdZLGa/UX8RanhVw3+Xp+urd1711umeNJfzu/MCk4a1KkG/CU0 +rqs9AkA4cSx1DD1JSG+yxMNpsAS1xJomFIrsM9vsPt7FdndDwrF+y+CovhDkGYDk +RAHh+svGfZg/pQK2JRPimAmHhzqFAkEAu6Ya70s2FUeB3Mu9aJs2CD6hg3dQEVkB +53DI7TX48d9kGW58VX1xnqS02LyWqAPcW5qm1kLHFLdndaPNmBaj4QJBAJugl367 +9d9t/QLTSuULLaoYv2vJT3s1y9HN89EoaDDEkPVfQu6GVEXgIBtim1sI/VPSzI8H +aXvaTUwblFWSM70= +-----END PRIVATE KEY----- diff --git a/src/core/lib/tsi/test_creds/badclient.pem b/src/core/lib/tsi/test_creds/badclient.pem new file mode 100644 index 0000000000..1785970221 --- /dev/null +++ b/src/core/lib/tsi/test_creds/badclient.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICoDCCAgmgAwIBAgIJANIz2/zoRiapMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGWJhZGNsaWVudC50ZXN0Lmdvb2dsZS5j +b20wHhcNMTQwNzI4MjAwODI1WhcNMjQwNzI1MjAwODI1WjBpMQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMSIwIAYDVQQDDBliYWRjbGllbnQudGVzdC5nb29nbGUuY29tMIGf +MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyX2JxZ+J5I+dlhROVtqlMQn47BBcr +l2GCkv9O1D1rL94KWYbY14HXhi/nacBAQtCEQwXxp5DKemGOUju65xM9F96/374G +MvnRJdo52gOs4HO0czBpfVNdXeeoD/RYgwttfdJrz/4aatsS2Qk2yMYpqZmqEMsb +rh9W22Lp3rCBvwIDAQABo1AwTjAdBgNVHQ4EFgQU523AJMR8Ds9V8fhf7gu1i0MM +UqAwHwYDVR0jBBgwFoAU523AJMR8Ds9V8fhf7gu1i0MMUqAwDAYDVR0TBAUwAwEB +/zANBgkqhkiG9w0BAQUFAAOBgQCI/tvSBYH1iyfLaCTBKwpdj36+MkR9EeJJmImx +X+bjhKWXwsBX4PDMWvdusr++QGUYtyoya+hfYMXRhXua39mD54xgloQNuu9REDwX +Ffto+aOw3BcYducz6ofxicFK/Y2VeXDurSMpRv5TfGf2Qr6eOOdaRhj6ed7BibHk +X1VGZA== +-----END CERTIFICATE----- diff --git a/src/core/lib/tsi/test_creds/badserver.key b/src/core/lib/tsi/test_creds/badserver.key new file mode 100644 index 0000000000..abfbde10ff --- /dev/null +++ b/src/core/lib/tsi/test_creds/badserver.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKeZ1e1y29cmBKaW +oIUwJ5neOJUjx+eD/3nRPe+dvLXEd9+db0fG5RYRR0S3mF1Ywuj4PIxlTW2YprUS +oGSw+tcqWNIzxv94HjwYFkkvER3AblXcDBh0P2zAkzg+nf9AcAsMh0QpDTyrXtMl +gqryjq1/vkhFofKMMbY+aXJdG6OBAgMBAAECgYAAgaB51S0A22aMMkxN2rVj6530 +JWWHN4jgD1fGj41wZyWNkWYyq1Ep3ed/N6bIMWp1VbqpGe0/9YQba/D8HOTFHGRt +72YXnP1e/ds8cxU4x4j1vvqSPtXpMmkiXfXijOvCl9mrMH2xjghFAt6/1Nb9xo1m +VdcOB8OdSuOIw6CI+QJBAN5FZUbS+bRXDWII/FaAih1DBpwCxhYEN+TXPJBxSen6 +kOzGt5g+mB6YqRMZ/qshshwPq7bsgFGfJ2lIdS2t3GsCQQDBCKifV5AAkOdOUrkK +HvoX3qnVmyIA8CyvWLcIWpfZ76QAYh0q0StedKdOMXaB1jTeSJ2KU1nlss7UD1Yw +VbrDAkAwjMHpbW3jiVw//Kx5jIwehiRscWKpLnSzBJyTBFvbwsJjJai2lX2OuVO8 ++2GYKb0Iyhd81j3VFkl6grwtpRtPAkB7+n+yt555fpfRKjhGU9b09cHGu7h/OcK5 +bBVCfE0DYHLI/DsXgPiF1g6Onh4rDdUu3xyv9xDKAqnscV099hHZAkEAvcFBfXZs +tk18N+bUcvXTdZjzZbfLCHlJmwPIspZ8G/6Pn63deg4GVYoCvTwGruah+8y734Ph +7PskfPgUQlB7Ag== +-----END PRIVATE KEY----- diff --git a/src/core/lib/tsi/test_creds/badserver.pem b/src/core/lib/tsi/test_creds/badserver.pem new file mode 100644 index 0000000000..983c979f31 --- /dev/null +++ b/src/core/lib/tsi/test_creds/badserver.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICoDCCAgmgAwIBAgIJAPdqwqsKNy81MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGWJhZHNlcnZlci50ZXN0Lmdvb2dsZS5j +b20wHhcNMTQwNzI4MjAwODU0WhcNMjQwNzI1MjAwODU0WjBpMQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMSIwIAYDVQQDDBliYWRzZXJ2ZXIudGVzdC5nb29nbGUuY29tMIGf +MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnmdXtctvXJgSmlqCFMCeZ3jiVI8fn +g/950T3vnby1xHffnW9HxuUWEUdEt5hdWMLo+DyMZU1tmKa1EqBksPrXKljSM8b/ +eB48GBZJLxEdwG5V3AwYdD9swJM4Pp3/QHALDIdEKQ08q17TJYKq8o6tf75IRaHy +jDG2PmlyXRujgQIDAQABo1AwTjAdBgNVHQ4EFgQU3u/qvHr9knMBeZyAD7mAA/ec +8cUwHwYDVR0jBBgwFoAU3u/qvHr9knMBeZyAD7mAA/ec8cUwDAYDVR0TBAUwAwEB +/zANBgkqhkiG9w0BAQUFAAOBgQA/FmR1SGLguxCCfhp4CYCbrAePSyPWDi48gTwj +vVZf/OMxdVu/H8sBYFf27BjbrEugAw16DElFtgTZ83pLb2BvkUgb6vBUK5sEkgmh +z88zBsgDp8aCf4STDOLFZMBh/E9ZKkm1zogbEmlTjFp/ceSpa2gNv7OuN4WiorOh +Wvw40g== +-----END CERTIFICATE----- diff --git a/src/core/lib/tsi/test_creds/ca-openssl.cnf b/src/core/lib/tsi/test_creds/ca-openssl.cnf new file mode 100644 index 0000000000..e97b945e4b --- /dev/null +++ b/src/core/lib/tsi/test_creds/ca-openssl.cnf @@ -0,0 +1,17 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = Country Name (2 letter code) +countryName_default = AU +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = Some-State +organizationName = Organization Name (eg, company) +organizationName_default = Internet Widgits Pty Ltd +commonName = Common Name (eg, YOUR name) +commonName_default = testca + +[v3_req] +basicConstraints = CA:true +keyUsage = critical, keyCertSign diff --git a/src/core/lib/tsi/test_creds/ca.key b/src/core/lib/tsi/test_creds/ca.key new file mode 100644 index 0000000000..03c4f950e3 --- /dev/null +++ b/src/core/lib/tsi/test_creds/ca.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMBA3wVeTGHZR1Ry +e/i+J8a2cu5gXwFV6TnObzGM7bLFCO5i9v4mLo4iFzPsHmWDUxKS3Y8iXbu0eYBl +LoNY0lSvxDx33O+DuwMmVN+DzSD+Eod9zfvwOWHsazYCZT2PhNxnVWIuJXViY4JA +HUGodjx+QAi6yCAurUZGvYXGgZSBAgMBAAECgYAxRi8i9BlFlufGSBVoGmydbJOm +bwLKl9dP3o33ODSP9hok5y6A0w5plWk3AJSF1hPLleK9VcSKYGYnt0clmPVHF35g +bx2rVK8dOT0mn7rz9Zr70jcSz1ETA2QonHZ+Y+niLmcic9At6hRtWiewblUmyFQm +GwggIzi7LOyEUHrEcQJBAOXxyQvnLvtKzXiqcsW/K6rExqVJVk+KF0fzzVyMzTJx +HRBxUVgvGdEJT7j+7P2kcTyafve0BBzDSPIaDyiJ+Y0CQQDWCb7jASFSbu5M3Zcd +Gkr4ZKN1XO3VLQX10b22bQYdF45hrTN2tnzRvVUR4q86VVnXmiGiTqmLkXcA2WWf +pHfFAkAhv9olUBo6MeF0i3frBEMRfm41hk0PwZHnMqZ6pgPcGnQMnMU2rzsXzkkQ +OwJnvAIOxhJKovZTjmofdqmw5odlAkBYVUdRWjsNUTjJwj3GRf6gyq/nFMYWz3EB +RWFdM1ttkDYzu45ctO2IhfHg4sPceDMO1s6AtKQmNI9/azkUjITdAkApNa9yFRzc +TBaDNPd5KVd58LVIzoPQ6i7uMHteLXJUWqSroji6S3s4gKMFJ/dO+ZXIlgQgfJJJ +ZDL4cdrdkeoM +-----END PRIVATE KEY----- diff --git a/src/core/lib/tsi/test_creds/ca.pem b/src/core/lib/tsi/test_creds/ca.pem new file mode 100644 index 0000000000..6c8511a73c --- /dev/null +++ b/src/core/lib/tsi/test_creds/ca.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla +Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 +YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT +BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 ++L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu +g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd +Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau +sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m +oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG +Dfcog5wrJytaQ6UA0wE= +-----END CERTIFICATE----- diff --git a/src/core/lib/tsi/test_creds/client.key b/src/core/lib/tsi/test_creds/client.key new file mode 100644 index 0000000000..f48d0735d9 --- /dev/null +++ b/src/core/lib/tsi/test_creds/client.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAOxUR9uhvhbeVUIM +s5WbH0px0mehl2+6sZpNjzvE2KimZpHzMJHukVH0Ffkvhs0b8+S5Ut9VNUAqd3IM +JCCAEGtRNoQhM1t9Yr2zAckSvbRacp+FL/Cj9eDmyo00KsVGaeefA4Dh4OW+ZhkT +NKcldXqkSuj1sEf244JZYuqZp6/tAgMBAAECgYEAi2NSVqpZMafE5YYUTcMGe6QS +k2jtpsqYgggI2RnLJ/2tNZwYI5pwP8QVSbnMaiF4gokD5hGdrNDfTnb2v+yIwYEH +0w8+oG7Z81KodsiZSIDJfTGsAZhVNwOz9y0VD8BBZZ1/274Zh52AUKLjZS/ZwIbS +W2ywya855dPnH/wj+0ECQQD9X8D920kByTNHhBG18biAEZ4pxs9f0OAG8333eVcI +w2lJDLsYDZrCB2ocgA3lUdozlzPC7YDYw8reg0tkiRY5AkEA7sdNzOeQsQRn7++5 +0bP9DtT/iON1gbfxRzCfCfXdoOtfQWIzTePWtURt9X/5D9NofI0Rg5W2oGy/MLe5 +/sXHVQJBAIup5XrJDkQywNZyAUU2ecn2bCWBFjwtqd+LBmuMciI9fOKsZtEKZrz/ +U0lkeMRoSwvXE8wmGLjjrAbdfohrXFkCQQDZEx/LtIl6JINJQiswVe0tWr6k+ASP +1WXoTm+HYpoF/XUvv9LccNF1IazFj34hwRQwhx7w/V52Ieb+p0jUMYGxAkEAjDhd +9pBO1fKXWiXzi9ZKfoyTNcUq3eBSVKwPG2nItg5ycXengjT5sgcWDnciIzW7BIVI +JiqOszq9GWESErAatg== +-----END PRIVATE KEY----- diff --git a/src/core/lib/tsi/test_creds/client.pem b/src/core/lib/tsi/test_creds/client.pem new file mode 100644 index 0000000000..e332091019 --- /dev/null +++ b/src/core/lib/tsi/test_creds/client.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHzCCAYgCAQEwDQYJKoZIhvcNAQEFBQAwVjELMAkGA1UEBhMCQVUxEzARBgNV +BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTE0MDcxNzIzNTYwMloXDTI0MDcxNDIzNTYw +MlowWjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKdGVzdGNsaWVudDCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA7FRH26G+Ft5VQgyzlZsfSnHSZ6GX +b7qxmk2PO8TYqKZmkfMwke6RUfQV+S+GzRvz5LlS31U1QCp3cgwkIIAQa1E2hCEz +W31ivbMByRK9tFpyn4Uv8KP14ObKjTQqxUZp558DgOHg5b5mGRM0pyV1eqRK6PWw +R/bjglli6pmnr+0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAStSm5PM7ubROiKK6/ +T2FkKlhiTOx+Ryenm3Eio59emq+jXl+1nhPySX5G2PQzSR5vd1dIhwgZSR4Gyttk +tRZ57k/NI1brUW8joiEOMJA/Mr7H7asx7wIRYDE91Fs8GkKWd5LhoPAQj+qdG35C +OO+svdkmqH0KZo320ZUqdl2ooQ== +-----END CERTIFICATE----- diff --git a/src/core/lib/tsi/test_creds/server0.key b/src/core/lib/tsi/test_creds/server0.key new file mode 100644 index 0000000000..add153c9ae --- /dev/null +++ b/src/core/lib/tsi/test_creds/server0.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANOmffupIGC8YDau +rOF4eKnHwPszgpkkhWzKsVxhNDBxCVYx4TEjG0XWIO0iyRXupZbUC+7N/8HnEVNa +8F1jYhng14Iiq99cNQbbnuHHhIztmpocrJTxmnhGzoAnRa1Tb+GnAuRoIHRA/V2c +VUE9tbikQugFx/SPgXAw6tfWB+YvAgMBAAECgYEAoEq9qzUBgoHoVEGiSPiWWe8g +5p6yUA1qx2QTQyWTAwT4z0DjjfVKmG99bFsl8+hTnJFnoCp/gnjflEOROwkjp5kG +m0drqOPx1jeipJjpXYTBu49h+WpZ1PF+KhVtxsIm3OOCvh67iWaKyyOVb5Og8aiR +jl6dn/TdG/dlGD8AfUECQQDuNMle6p0oU8amC6O9wIMBroxx2nFstzE6O35PLEzG +/tj0kxxn9Jp2TS9mGaLCzSuXmpjlF4+NOWiBPkrLC2TfAkEA43Xg7uEUkaJAz2/W +m1lIBTLt+4rIQY/2emh33bDcA+rv8rwwrMMIv17/xPx7bs49YqGG5xufD+Rwl6TL +qFXYsQJAPrOwagax1aKvwJeBw3oAQhoTKAkLIEXcdGqipe6QSzVcIIz0xjxxyEAr +AOIwoLxnBCISqwMXq2H4K0UdZPMb2wJAdhdYLY1L6YRMk6XjzImg25oidisKZweA +FvMv8DgHMj2CUAqmVrt3SivfLH1M9C09L3zfFhOAFHcsgX58gav4MQJBANSBnrHj +tIq4l8z79CPUIuu3QyeEh+XwY8s5qE5CNTck0U59lzp9NvENHbkx3KO896TTerko ++8bXHMLkJkHPXms= +-----END PRIVATE KEY----- diff --git a/src/core/lib/tsi/test_creds/server0.pem b/src/core/lib/tsi/test_creds/server0.pem new file mode 100644 index 0000000000..ade75d8563 --- /dev/null +++ b/src/core/lib/tsi/test_creds/server0.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHDCCAYUCAQQwDQYJKoZIhvcNAQEFBQAwVjELMAkGA1UEBhMCQVUxEzARBgNV +BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTE0MDcyMjE3NTk0OVoXDTI0MDcxOTE3NTk0 +OVowVzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxFDASBgNVBAoM +C0dvb2dsZSBJbmMuMR0wGwYDVQQDDBQqLnRlc3QuZ29vZ2xlLmNvbS5hdTCBnzAN +BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA06Z9+6kgYLxgNq6s4Xh4qcfA+zOCmSSF +bMqxXGE0MHEJVjHhMSMbRdYg7SLJFe6lltQL7s3/wecRU1rwXWNiGeDXgiKr31w1 +Btue4ceEjO2amhyslPGaeEbOgCdFrVNv4acC5GggdED9XZxVQT21uKRC6AXH9I+B +cDDq19YH5i8CAwEAATANBgkqhkiG9w0BAQUFAAOBgQBtfR5qXG9TTI8YcYh7sA4V +GeNoplp0x6p7OG0NLvbJqAkUnkvjIkk1m1R2AUHhbkxzx6G75JIOoNJcWrCzywBA +BIsaTdmnNysf/s1hQJuD3IHiVb+7Ji0jhttnJlYcMid4o0tJO/a2E9YUxR+9cg0i +obb+Ql3qsvKdWBC1dDLDLw== +-----END CERTIFICATE----- diff --git a/src/core/lib/tsi/test_creds/server1-openssl.cnf b/src/core/lib/tsi/test_creds/server1-openssl.cnf new file mode 100644 index 0000000000..8a02108289 --- /dev/null +++ b/src/core/lib/tsi/test_creds/server1-openssl.cnf @@ -0,0 +1,26 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = Country Name (2 letter code) +countryName_default = US +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = Illinois +localityName = Locality Name (eg, city) +localityName_default = Chicago +organizationName = Organization Name (eg, company) +organizationName_default = Example, Co. +commonName = Common Name (eg, YOUR name) +commonName_max = 64 + +[v3_req] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = *.test.google.fr +DNS.2 = waterzooi.test.google.be +DNS.3 = *.test.youtube.com +IP.1 = "192.168.1.3" diff --git a/src/core/lib/tsi/test_creds/server1.key b/src/core/lib/tsi/test_creds/server1.key new file mode 100644 index 0000000000..143a5b8765 --- /dev/null +++ b/src/core/lib/tsi/test_creds/server1.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD +M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf +3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY +AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm +V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY +tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p +dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q +K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR +81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff +DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd +aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 +ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 +XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe +F98XJ7tIFfJq +-----END PRIVATE KEY----- diff --git a/src/core/lib/tsi/test_creds/server1.pem b/src/core/lib/tsi/test_creds/server1.pem new file mode 100644 index 0000000000..f3d43fcc5b --- /dev/null +++ b/src/core/lib/tsi/test_creds/server1.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx +MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV +BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 +ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco +LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg +zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd +9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw +CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy +em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G +CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 +hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh +y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 +-----END CERTIFICATE----- diff --git a/src/core/lib/tsi/transport_security.c b/src/core/lib/tsi/transport_security.c new file mode 100644 index 0000000000..db219a50a6 --- /dev/null +++ b/src/core/lib/tsi/transport_security.c @@ -0,0 +1,284 @@ +/* + * + * Copyright 2015, 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/tsi/transport_security.h" + +#include +#include + +/* --- Tracing. --- */ + +int tsi_tracing_enabled = 0; + +/* --- Utils. --- */ + +char *tsi_strdup(const char *src) { + char *dst; + size_t len; + if (!src) return NULL; + len = strlen(src) + 1; + dst = malloc(len); + if (!dst) return NULL; + memcpy(dst, src, len); + return dst; +} + +/* --- tsi_result common implementation. --- */ + +const char *tsi_result_to_string(tsi_result result) { + switch (result) { + case TSI_OK: + return "TSI_OK"; + case TSI_UNKNOWN_ERROR: + return "TSI_UNKNOWN_ERROR"; + case TSI_INVALID_ARGUMENT: + return "TSI_INVALID_ARGUMENT"; + case TSI_PERMISSION_DENIED: + return "TSI_PERMISSION_DENIED"; + case TSI_INCOMPLETE_DATA: + return "TSI_INCOMPLETE_DATA"; + case TSI_FAILED_PRECONDITION: + return "TSI_FAILED_PRECONDITION"; + case TSI_UNIMPLEMENTED: + return "TSI_UNIMPLEMENTED"; + case TSI_INTERNAL_ERROR: + return "TSI_INTERNAL_ERROR"; + case TSI_DATA_CORRUPTED: + return "TSI_DATA_CORRUPTED"; + case TSI_NOT_FOUND: + return "TSI_NOT_FOUND"; + case TSI_PROTOCOL_FAILURE: + return "TSI_PROTOCOL_FAILURE"; + case TSI_HANDSHAKE_IN_PROGRESS: + return "TSI_HANDSHAKE_IN_PROGRESS"; + case TSI_OUT_OF_RESOURCES: + return "TSI_OUT_OF_RESOURCES"; + default: + return "UNKNOWN"; + } +} + +/* --- tsi_frame_protector common implementation. --- + + Calls specific implementation after state/input validation. */ + +tsi_result tsi_frame_protector_protect(tsi_frame_protector *self, + const unsigned char *unprotected_bytes, + size_t *unprotected_bytes_size, + unsigned char *protected_output_frames, + size_t *protected_output_frames_size) { + if (self == NULL || unprotected_bytes == NULL || + unprotected_bytes_size == NULL || protected_output_frames == NULL || + protected_output_frames_size == NULL) { + return TSI_INVALID_ARGUMENT; + } + return self->vtable->protect(self, unprotected_bytes, unprotected_bytes_size, + protected_output_frames, + protected_output_frames_size); +} + +tsi_result tsi_frame_protector_protect_flush( + tsi_frame_protector *self, unsigned char *protected_output_frames, + size_t *protected_output_frames_size, size_t *still_pending_size) { + if (self == NULL || protected_output_frames == NULL || + protected_output_frames == NULL || still_pending_size == NULL) { + return TSI_INVALID_ARGUMENT; + } + return self->vtable->protect_flush(self, protected_output_frames, + protected_output_frames_size, + still_pending_size); +} + +tsi_result tsi_frame_protector_unprotect( + tsi_frame_protector *self, const unsigned char *protected_frames_bytes, + size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes, + size_t *unprotected_bytes_size) { + if (self == NULL || protected_frames_bytes == NULL || + protected_frames_bytes_size == NULL || unprotected_bytes == NULL || + unprotected_bytes_size == NULL) { + return TSI_INVALID_ARGUMENT; + } + return self->vtable->unprotect(self, protected_frames_bytes, + protected_frames_bytes_size, unprotected_bytes, + unprotected_bytes_size); +} + +void tsi_frame_protector_destroy(tsi_frame_protector *self) { + if (self == NULL) return; + self->vtable->destroy(self); +} + +/* --- tsi_handshaker common implementation. --- + + Calls specific implementation after state/input validation. */ + +tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, + unsigned char *bytes, + size_t *bytes_size) { + if (self == NULL || bytes == NULL || bytes_size == NULL) { + return TSI_INVALID_ARGUMENT; + } + if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; + return self->vtable->get_bytes_to_send_to_peer(self, bytes, bytes_size); +} + +tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self, + const unsigned char *bytes, + size_t *bytes_size) { + if (self == NULL || bytes == NULL || bytes_size == NULL) { + return TSI_INVALID_ARGUMENT; + } + if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; + return self->vtable->process_bytes_from_peer(self, bytes, bytes_size); +} + +tsi_result tsi_handshaker_get_result(tsi_handshaker *self) { + if (self == NULL) return TSI_INVALID_ARGUMENT; + if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; + return self->vtable->get_result(self); +} + +tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer) { + if (self == NULL || peer == NULL) return TSI_INVALID_ARGUMENT; + memset(peer, 0, sizeof(tsi_peer)); + if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; + if (tsi_handshaker_get_result(self) != TSI_OK) { + return TSI_FAILED_PRECONDITION; + } + return self->vtable->extract_peer(self, peer); +} + +tsi_result tsi_handshaker_create_frame_protector( + tsi_handshaker *self, size_t *max_protected_frame_size, + tsi_frame_protector **protector) { + tsi_result result; + if (self == NULL || protector == NULL) return TSI_INVALID_ARGUMENT; + if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; + if (tsi_handshaker_get_result(self) != TSI_OK) { + return TSI_FAILED_PRECONDITION; + } + result = self->vtable->create_frame_protector(self, max_protected_frame_size, + protector); + if (result == TSI_OK) { + self->frame_protector_created = 1; + } + return result; +} + +void tsi_handshaker_destroy(tsi_handshaker *self) { + if (self == NULL) return; + self->vtable->destroy(self); +} + +/* --- tsi_peer implementation. --- */ + +tsi_peer_property tsi_init_peer_property(void) { + tsi_peer_property property; + memset(&property, 0, sizeof(tsi_peer_property)); + return property; +} + +static void tsi_peer_destroy_list_property(tsi_peer_property *children, + size_t child_count) { + size_t i; + for (i = 0; i < child_count; i++) { + tsi_peer_property_destruct(&children[i]); + } + free(children); +} + +void tsi_peer_property_destruct(tsi_peer_property *property) { + if (property->name != NULL) { + free(property->name); + } + if (property->value.data != NULL) { + free(property->value.data); + } + *property = tsi_init_peer_property(); /* Reset everything to 0. */ +} + +void tsi_peer_destruct(tsi_peer *self) { + if (self == NULL) return; + if (self->properties != NULL) { + tsi_peer_destroy_list_property(self->properties, self->property_count); + self->properties = NULL; + } + self->property_count = 0; +} + +tsi_result tsi_construct_allocated_string_peer_property( + const char *name, size_t value_length, tsi_peer_property *property) { + *property = tsi_init_peer_property(); + if (name != NULL) { + property->name = tsi_strdup(name); + if (property->name == NULL) return TSI_OUT_OF_RESOURCES; + } + if (value_length > 0) { + property->value.data = calloc(1, value_length); + if (property->value.data == NULL) { + tsi_peer_property_destruct(property); + return TSI_OUT_OF_RESOURCES; + } + property->value.length = value_length; + } + return TSI_OK; +} + +tsi_result tsi_construct_string_peer_property_from_cstring( + const char *name, const char *value, tsi_peer_property *property) { + return tsi_construct_string_peer_property(name, value, strlen(value), + property); +} + +tsi_result tsi_construct_string_peer_property(const char *name, + const char *value, + size_t value_length, + tsi_peer_property *property) { + tsi_result result = tsi_construct_allocated_string_peer_property( + name, value_length, property); + if (result != TSI_OK) return result; + if (value_length > 0) { + memcpy(property->value.data, value, value_length); + } + return TSI_OK; +} + +tsi_result tsi_construct_peer(size_t property_count, tsi_peer *peer) { + memset(peer, 0, sizeof(tsi_peer)); + if (property_count > 0) { + peer->properties = calloc(property_count, sizeof(tsi_peer_property)); + if (peer->properties == NULL) return TSI_OUT_OF_RESOURCES; + peer->property_count = property_count; + } + return TSI_OK; +} diff --git a/src/core/lib/tsi/transport_security.h b/src/core/lib/tsi/transport_security.h new file mode 100644 index 0000000000..ecc037193b --- /dev/null +++ b/src/core/lib/tsi/transport_security.h @@ -0,0 +1,111 @@ +/* + * + * Copyright 2015-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_TSI_TRANSPORT_SECURITY_H +#define GRPC_CORE_TSI_TRANSPORT_SECURITY_H + +#include "src/core/tsi/transport_security_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern int tsi_tracing_enabled; + +/* Base for tsi_frame_protector implementations. + See transport_security_interface.h for documentation. */ +typedef struct { + tsi_result (*protect)(tsi_frame_protector *self, + const unsigned char *unprotected_bytes, + size_t *unprotected_bytes_size, + unsigned char *protected_output_frames, + size_t *protected_output_frames_size); + tsi_result (*protect_flush)(tsi_frame_protector *self, + unsigned char *protected_output_frames, + size_t *protected_output_frames_size, + size_t *still_pending_size); + tsi_result (*unprotect)(tsi_frame_protector *self, + const unsigned char *protected_frames_bytes, + size_t *protected_frames_bytes_size, + unsigned char *unprotected_bytes, + size_t *unprotected_bytes_size); + void (*destroy)(tsi_frame_protector *self); +} tsi_frame_protector_vtable; + +struct tsi_frame_protector { + const tsi_frame_protector_vtable *vtable; +}; + +/* Base for tsi_handshaker implementations. + See transport_security_interface.h for documentation. */ +typedef struct { + tsi_result (*get_bytes_to_send_to_peer)(tsi_handshaker *self, + unsigned char *bytes, + size_t *bytes_size); + tsi_result (*process_bytes_from_peer)(tsi_handshaker *self, + const unsigned char *bytes, + size_t *bytes_size); + tsi_result (*get_result)(tsi_handshaker *self); + tsi_result (*extract_peer)(tsi_handshaker *self, tsi_peer *peer); + tsi_result (*create_frame_protector)(tsi_handshaker *self, + size_t *max_protected_frame_size, + tsi_frame_protector **protector); + void (*destroy)(tsi_handshaker *self); +} tsi_handshaker_vtable; + +struct tsi_handshaker { + const tsi_handshaker_vtable *vtable; + int frame_protector_created; +}; + +/* Peer and property construction/destruction functions. */ +tsi_result tsi_construct_peer(size_t property_count, tsi_peer *peer); +tsi_peer_property tsi_init_peer_property(void); +void tsi_peer_property_destruct(tsi_peer_property *property); +tsi_result tsi_construct_string_peer_property(const char *name, + const char *value, + size_t value_length, + tsi_peer_property *property); +tsi_result tsi_construct_allocated_string_peer_property( + const char *name, size_t value_length, tsi_peer_property *property); +tsi_result tsi_construct_string_peer_property_from_cstring( + const char *name, const char *value, tsi_peer_property *property); + +/* Utils. */ +char *tsi_strdup(const char *src); /* Sadly, no strdup in C89. */ + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_H */ diff --git a/src/core/lib/tsi/transport_security_interface.h b/src/core/lib/tsi/transport_security_interface.h new file mode 100644 index 0000000000..08501802f5 --- /dev/null +++ b/src/core/lib/tsi/transport_security_interface.h @@ -0,0 +1,344 @@ +/* + * + * Copyright 2015-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_TSI_TRANSPORT_SECURITY_INTERFACE_H +#define GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* --- tsi result --- */ + +typedef enum { + TSI_OK = 0, + TSI_UNKNOWN_ERROR = 1, + TSI_INVALID_ARGUMENT = 2, + TSI_PERMISSION_DENIED = 3, + TSI_INCOMPLETE_DATA = 4, + TSI_FAILED_PRECONDITION = 5, + TSI_UNIMPLEMENTED = 6, + TSI_INTERNAL_ERROR = 7, + TSI_DATA_CORRUPTED = 8, + TSI_NOT_FOUND = 9, + TSI_PROTOCOL_FAILURE = 10, + TSI_HANDSHAKE_IN_PROGRESS = 11, + TSI_OUT_OF_RESOURCES = 12 +} tsi_result; + +const char *tsi_result_to_string(tsi_result result); + +/* --- tsi tracing --- */ + +/* Set this early to avoid races */ +extern int tsi_tracing_enabled; + +/* --- tsi_frame_protector object --- + + This object protects and unprotects buffers once the handshake is done. + Implementations of this object must be thread compatible. */ + +typedef struct tsi_frame_protector tsi_frame_protector; + +/* Outputs protected frames. + - unprotected_bytes is an input only parameter and points to the data + to be protected. + - unprotected_bytes_size is an input/output parameter used by the caller to + specify how many bytes are available in unprotected_bytes. The output + value is the number of bytes consumed during the call. + - protected_output_frames points to a buffer allocated by the caller that + will be written. + - protected_output_frames_size is an input/output parameter used by the + caller to specify how many bytes are available in protected_output_frames. + As an output, this value indicates the number of bytes written. + - This method returns TSI_OK in case of success or a specific error code in + case of failure. Note that even if all the input unprotected bytes are + consumed, they may not have been processed into the returned protected + output frames. The caller should call the protect_flush method + to make sure that there are no more protected bytes buffered in the + protector. + + A typical way to call this method would be: + + ------------------------------------------------------------------------ + unsigned char protected_buffer[4096]; + size_t protected_buffer_size = sizeof(protected_buffer); + tsi_result result = TSI_OK; + while (message_size > 0) { + size_t protected_buffer_size_to_send = protected_buffer_size; + size_t processed_message_size = message_size; + result = tsi_frame_protector_protect(protector, + message_bytes, + &processed_message_size, + protected_buffer, + &protected_buffer_size_to_send); + if (result != TSI_OK) break; + send_bytes_to_peer(protected_buffer, protected_buffer_size_to_send); + message_bytes += processed_message_size; + message_size -= processed_message_size; + + // Don't forget to flush. + if (message_size == 0) { + size_t still_pending_size; + do { + protected_buffer_size_to_send = protected_buffer_size; + result = tsi_frame_protector_protect_flush( + protector, protected_buffer, + &protected_buffer_size_to_send, &still_pending_size); + if (result != TSI_OK) break; + send_bytes_to_peer(protected_buffer, protected_buffer_size_to_send); + } while (still_pending_size > 0); + } + } + + if (result != TSI_OK) HandleError(result); + ------------------------------------------------------------------------ */ +tsi_result tsi_frame_protector_protect(tsi_frame_protector *self, + const unsigned char *unprotected_bytes, + size_t *unprotected_bytes_size, + unsigned char *protected_output_frames, + size_t *protected_output_frames_size); + +/* Indicates that we need to flush the bytes buffered in the protector and get + the resulting frame. + - protected_output_frames points to a buffer allocated by the caller that + will be written. + - protected_output_frames_size is an input/output parameter used by the + caller to specify how many bytes are available in protected_output_frames. + - still_pending_bytes is an output parameter indicating the number of bytes + that still need to be flushed from the protector.*/ +tsi_result tsi_frame_protector_protect_flush( + tsi_frame_protector *self, unsigned char *protected_output_frames, + size_t *protected_output_frames_size, size_t *still_pending_size); + +/* Outputs unprotected bytes. + - protected_frames_bytes is an input only parameter and points to the + protected frames to be unprotected. + - protected_frames_bytes_size is an input/output only parameter used by the + caller to specify how many bytes are available in protected_bytes. The + output value is the number of bytes consumed during the call. + Implementations will buffer up to a frame of protected data. + - unprotected_bytes points to a buffer allocated by the caller that will be + written. + - unprotected_bytes_size is an input/output parameter used by the caller to + specify how many bytes are available in unprotected_bytes. This + value is expected to be at most max_protected_frame_size minus overhead + which means that max_protected_frame_size is a safe bet. The output value + is the number of bytes actually written. + If *unprotected_bytes_size is unchanged, there may be more data remaining + to unprotect, and the caller should call this function again. + + - This method returns TSI_OK in case of success. Success includes cases where + there is not enough data to output a frame in which case + unprotected_bytes_size will be set to 0 and cases where the internal buffer + needs to be read before new protected data can be processed in which case + protected_frames_size will be set to 0. */ +tsi_result tsi_frame_protector_unprotect( + tsi_frame_protector *self, const unsigned char *protected_frames_bytes, + size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes, + size_t *unprotected_bytes_size); + +/* Destroys the tsi_frame_protector object. */ +void tsi_frame_protector_destroy(tsi_frame_protector *self); + +/* --- tsi_peer objects --- + + tsi_peer objects are a set of properties. The peer owns the properties. */ + +/* This property is of type TSI_PEER_PROPERTY_STRING. */ +#define TSI_CERTIFICATE_TYPE_PEER_PROPERTY "certificate_type" + +/* Property values may contain NULL characters just like C++ strings. + The length field gives the length of the string. */ +typedef struct tsi_peer_property { + char *name; + struct { + char *data; + size_t length; + } value; +} tsi_peer_property; + +typedef struct { + tsi_peer_property *properties; + size_t property_count; +} tsi_peer; + +/* Destructs the tsi_peer object. */ +void tsi_peer_destruct(tsi_peer *self); + +/* --- tsi_handshaker objects ---- + + Implementations of this object must be thread compatible. + + A typical usage of this object would be: + + ------------------------------------------------------------------------ + tsi_result result = TSI_OK; + unsigned char buf[4096]; + size_t buf_offset; + size_t buf_size; + while (1) { + // See if we need to send some bytes to the peer. + do { + size_t buf_size_to_send = sizeof(buf); + result = tsi_handshaker_get_bytes_to_send_to_peer(handshaker, buf, + &buf_size_to_send); + if (buf_size_to_send > 0) send_bytes_to_peer(buf, buf_size_to_send); + } while (result == TSI_INCOMPLETE_DATA); + if (result != TSI_OK) return result; + if (!tsi_handshaker_is_in_progress(handshaker)) break; + + do { + // Read bytes from the peer. + buf_size = sizeof(buf); + buf_offset = 0; + read_bytes_from_peer(buf, &buf_size); + if (buf_size == 0) break; + + // Process the bytes from the peer. We have to be careful as these bytes + // may contain non-handshake data (protected data). If this is the case, + // we will exit from the loop with buf_size > 0. + size_t consumed_by_handshaker = buf_size; + result = tsi_handshaker_process_bytes_from_peer( + handshaker, buf, &consumed_by_handshaker); + buf_size -= consumed_by_handshaker; + buf_offset += consumed_by_handshaker; + } while (result == TSI_INCOMPLETE_DATA); + + if (result != TSI_OK) return result; + if (!tsi_handshaker_is_in_progress(handshaker)) break; + } + + // Check the Peer. + tsi_peer peer; + do { + result = tsi_handshaker_extract_peer(handshaker, &peer); + if (result != TSI_OK) break; + result = check_peer(&peer); + } while (0); + tsi_peer_destruct(&peer); + if (result != TSI_OK) return result; + + // Create the protector. + tsi_frame_protector* protector = NULL; + result = tsi_handshaker_create_frame_protector(handshaker, NULL, + &protector); + if (result != TSI_OK) return result; + + // Do not forget to unprotect outstanding data if any. + if (buf_size > 0) { + result = tsi_frame_protector_unprotect(protector, buf + buf_offset, + buf_size, ..., ...); + .... + } + ... + ------------------------------------------------------------------------ */ +typedef struct tsi_handshaker tsi_handshaker; + +/* Gets bytes that need to be sent to the peer. + - bytes is the buffer that will be written with the data to be sent to the + peer. + - bytes_size is an input/output parameter specifying the capacity of the + bytes parameter as input and the number of bytes written as output. + Returns TSI_OK if all the data to send to the peer has been written or if + nothing has to be sent to the peer (in which base bytes_size outputs to 0), + otherwise returns TSI_INCOMPLETE_DATA which indicates that this method + needs to be called again to get all the bytes to send to the peer (there + was more data to write than the specified bytes_size). In case of a fatal + error in the handshake, another specific error code is returned. */ +tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, + unsigned char *bytes, + size_t *bytes_size); + +/* Processes bytes received from the peer. + - bytes is the buffer containing the data. + - bytes_size is an input/output parameter specifying the size of the data as + input and the number of bytes consumed as output. + Return TSI_OK if the handshake has all the data it needs to process, + otherwise return TSI_INCOMPLETE_DATA which indicates that this method + needs to be called again to complete the data needed for processing. In + case of a fatal error in the handshake, another specific error code is + returned. */ +tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self, + const unsigned char *bytes, + size_t *bytes_size); + +/* Gets the result of the handshaker. + Returns TSI_OK if the hanshake completed successfully and there has been no + errors. Returns TSI_HANDSHAKE_IN_PROGRESS if the handshaker is not done yet + but no error has been encountered so far. Otherwise the handshaker failed + with the returned error. */ +tsi_result tsi_handshaker_get_result(tsi_handshaker *self); + +/* Returns 1 if the handshake is in progress, 0 otherwise. */ +#define tsi_handshaker_is_in_progress(h) \ + (tsi_handshaker_get_result((h)) == TSI_HANDSHAKE_IN_PROGRESS) + +/* This method may return TSI_FAILED_PRECONDITION if + tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise + assuming the handshaker is not in a fatal error state. + The caller is responsible for destructing the peer. */ +tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer); + +/* This method creates a tsi_frame_protector object after the handshake phase + is done. After this method has been called successfully, the only method + that can be called on this object is Destroy. + - max_output_protected_frame_size is an input/output parameter specifying the + desired max output protected frame size as input and outputing the actual + max output frame size as the output. Passing NULL is OK and will result in + the implementation choosing the default maximum protected frame size. Note + that this size only applies to outgoing frames (generated with + tsi_frame_protector_protect) and not incoming frames (input of + tsi_frame_protector_unprotect). + - protector is an output parameter pointing to the newly created + tsi_frame_protector object. + This method may return TSI_FAILED_PRECONDITION if + tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise assuming + the handshaker is not in a fatal error state. + The caller is responsible for destroying the protector. */ +tsi_result tsi_handshaker_create_frame_protector( + tsi_handshaker *self, size_t *max_output_protected_frame_size, + tsi_frame_protector **protector); + +/* This method releases the tsi_handshaker object. After this method is called, + no other method can be called on the object. */ +void tsi_handshaker_destroy(tsi_handshaker *self); + +#ifdef __cplusplus +} +#endif + +#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H */ diff --git a/src/core/profiling/basic_timers.c b/src/core/profiling/basic_timers.c deleted file mode 100644 index 3067f52c21..0000000000 --- a/src/core/profiling/basic_timers.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GRPC_BASIC_PROFILER - -#include "src/core/profiling/timers.h" - -#include -#include -#include -#include -#include -#include - -typedef enum { BEGIN = '{', END = '}', MARK = '.' } marker_type; - -typedef struct gpr_timer_entry { - gpr_timespec tm; - const char *tagstr; - const char *file; - short line; - char type; - uint8_t important; - int thd; -} gpr_timer_entry; - -#define MAX_COUNT 1000000 - -typedef struct gpr_timer_log { - size_t num_entries; - struct gpr_timer_log *next; - struct gpr_timer_log *prev; - gpr_timer_entry log[MAX_COUNT]; -} gpr_timer_log; - -typedef struct gpr_timer_log_list { - gpr_timer_log *head; - /* valid iff head!=NULL */ - gpr_timer_log *tail; -} gpr_timer_log_list; - -static __thread gpr_timer_log *g_thread_log; -static gpr_once g_once_init = GPR_ONCE_INIT; -static FILE *output_file; -static const char *output_filename = "latency_trace.txt"; -static pthread_mutex_t g_mu; -static pthread_cond_t g_cv; -static gpr_timer_log_list g_in_progress_logs; -static gpr_timer_log_list g_done_logs; -static int g_shutdown; -static gpr_thd_id g_writing_thread; -static __thread int g_thread_id; -static int g_next_thread_id; - -static int timer_log_push_back(gpr_timer_log_list *list, gpr_timer_log *log) { - if (list->head == NULL) { - list->head = list->tail = log; - log->next = log->prev = NULL; - return 1; - } else { - log->prev = list->tail; - log->next = NULL; - list->tail->next = log; - list->tail = log; - return 0; - } -} - -static gpr_timer_log *timer_log_pop_front(gpr_timer_log_list *list) { - gpr_timer_log *out = list->head; - if (out != NULL) { - list->head = out->next; - if (list->head != NULL) { - list->head->prev = NULL; - } else { - list->tail = NULL; - } - } - return out; -} - -static void timer_log_remove(gpr_timer_log_list *list, gpr_timer_log *log) { - if (log->prev == NULL) { - list->head = log->next; - if (list->head != NULL) { - list->head->prev = NULL; - } - } else { - log->prev->next = log->next; - } - if (log->next == NULL) { - list->tail = log->prev; - if (list->tail != NULL) { - list->tail->next = NULL; - } - } else { - log->next->prev = log->prev; - } -} - -static void write_log(gpr_timer_log *log) { - size_t i; - if (output_file == NULL) { - output_file = fopen(output_filename, "w"); - } - for (i = 0; i < log->num_entries; i++) { - gpr_timer_entry *entry = &(log->log[i]); - if (gpr_time_cmp(entry->tm, gpr_time_0(entry->tm.clock_type)) < 0) { - entry->tm = gpr_time_0(entry->tm.clock_type); - } - fprintf(output_file, - "{\"t\": %lld.%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": " - "\"%s\", \"file\": \"%s\", \"line\": %d, \"imp\": %d}\n", - (long long)entry->tm.tv_sec, (int)entry->tm.tv_nsec, entry->thd, - entry->type, entry->tagstr, entry->file, entry->line, - entry->important); - } -} - -static void writing_thread(void *unused) { - gpr_timer_log *log; - pthread_mutex_lock(&g_mu); - for (;;) { - while ((log = timer_log_pop_front(&g_done_logs)) == NULL && !g_shutdown) { - pthread_cond_wait(&g_cv, &g_mu); - } - if (log != NULL) { - pthread_mutex_unlock(&g_mu); - write_log(log); - free(log); - pthread_mutex_lock(&g_mu); - } - if (g_shutdown) { - pthread_mutex_unlock(&g_mu); - return; - } - } -} - -static void flush_logs(gpr_timer_log_list *list) { - gpr_timer_log *log; - while ((log = timer_log_pop_front(list)) != NULL) { - write_log(log); - free(log); - } -} - -static void finish_writing() { - pthread_mutex_lock(&g_mu); - g_shutdown = 1; - pthread_cond_signal(&g_cv); - pthread_mutex_unlock(&g_mu); - gpr_thd_join(g_writing_thread); - - gpr_log(GPR_INFO, "flushing logs"); - - pthread_mutex_lock(&g_mu); - flush_logs(&g_done_logs); - flush_logs(&g_in_progress_logs); - pthread_mutex_unlock(&g_mu); - - if (output_file) { - fclose(output_file); - } -} - -void gpr_timers_set_log_filename(const char *filename) { - output_filename = filename; -} - -static void init_output() { - gpr_thd_options options = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&options); - gpr_thd_new(&g_writing_thread, writing_thread, NULL, &options); - atexit(finish_writing); -} - -static void rotate_log() { - gpr_timer_log *new = malloc(sizeof(*new)); - gpr_once_init(&g_once_init, init_output); - new->num_entries = 0; - pthread_mutex_lock(&g_mu); - if (g_thread_log != NULL) { - timer_log_remove(&g_in_progress_logs, g_thread_log); - if (timer_log_push_back(&g_done_logs, g_thread_log)) { - pthread_cond_signal(&g_cv); - } - } else { - g_thread_id = g_next_thread_id++; - } - timer_log_push_back(&g_in_progress_logs, new); - pthread_mutex_unlock(&g_mu); - g_thread_log = new; -} - -static void gpr_timers_log_add(const char *tagstr, marker_type type, - int important, const char *file, int line) { - gpr_timer_entry *entry; - - if (g_thread_log == NULL || g_thread_log->num_entries == MAX_COUNT) { - rotate_log(); - } - - entry = &g_thread_log->log[g_thread_log->num_entries++]; - - entry->tm = gpr_now(GPR_CLOCK_PRECISE); - entry->tagstr = tagstr; - entry->type = type; - entry->file = file; - entry->line = (short)line; - entry->important = important != 0; - entry->thd = g_thread_id; -} - -/* Latency profiler API implementation. */ -void gpr_timer_add_mark(const char *tagstr, int important, const char *file, - int line) { - gpr_timers_log_add(tagstr, MARK, important, file, line); -} - -void gpr_timer_begin(const char *tagstr, int important, const char *file, - int line) { - gpr_timers_log_add(tagstr, BEGIN, important, file, line); -} - -void gpr_timer_end(const char *tagstr, int important, const char *file, - int line) { - gpr_timers_log_add(tagstr, END, important, file, line); -} - -/* Basic profiler specific API functions. */ -void gpr_timers_global_init(void) {} - -void gpr_timers_global_destroy(void) {} - -#else /* !GRPC_BASIC_PROFILER */ -void gpr_timers_global_init(void) {} - -void gpr_timers_global_destroy(void) {} - -void gpr_timers_set_log_filename(const char *filename) {} -#endif /* GRPC_BASIC_PROFILER */ diff --git a/src/core/profiling/stap_probes.d b/src/core/profiling/stap_probes.d deleted file mode 100644 index 153de91752..0000000000 --- a/src/core/profiling/stap_probes.d +++ /dev/null @@ -1,7 +0,0 @@ -provider _stap { - probe add_mark(int tag); - probe add_important_mark(int tag); - probe timing_ns_begin(int tag); - probe timing_ns_end(int tag); -}; - diff --git a/src/core/profiling/stap_timers.c b/src/core/profiling/stap_timers.c deleted file mode 100644 index efcd1af4a1..0000000000 --- a/src/core/profiling/stap_timers.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * Copyright 2015, 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 - -#ifdef GRPC_STAP_PROFILER - -#include "src/core/profiling/timers.h" - -#include -/* Generated from src/core/profiling/stap_probes.d */ -#include "src/core/profiling/stap_probes.h" - -/* Latency profiler API implementation. */ -void gpr_timer_add_mark(int tag, const char *tagstr, void *id, const char *file, - int line) { - _STAP_ADD_MARK(tag); -} - -void gpr_timer_add_important_mark(int tag, const char *tagstr, void *id, - const char *file, int line) { - _STAP_ADD_IMPORTANT_MARK(tag); -} - -void gpr_timer_begin(int tag, const char *tagstr, void *id, const char *file, - int line) { - _STAP_TIMING_NS_BEGIN(tag); -} - -void gpr_timer_end(int tag, const char *tagstr, void *id, const char *file, - int line) { - _STAP_TIMING_NS_END(tag); -} - -#endif /* GRPC_STAP_PROFILER */ diff --git a/src/core/profiling/timers.h b/src/core/profiling/timers.h deleted file mode 100644 index 6a188dc566..0000000000 --- a/src/core/profiling/timers.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * - * Copyright 2015, 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_PROFILING_TIMERS_H -#define GRPC_CORE_PROFILING_TIMERS_H - -#ifdef __cplusplus -extern "C" { -#endif - -void gpr_timers_global_init(void); -void gpr_timers_global_destroy(void); - -void gpr_timer_add_mark(const char *tagstr, int important, const char *file, - int line); -void gpr_timer_begin(const char *tagstr, int important, const char *file, - int line); -void gpr_timer_end(const char *tagstr, int important, const char *file, - int line); - -void gpr_timers_set_log_filename(const char *filename); - -#if !(defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER)) -/* No profiling. No-op all the things. */ -#define GPR_TIMER_MARK(tag, important) \ - do { \ - } while (0) - -#define GPR_TIMER_BEGIN(tag, important) \ - do { \ - } while (0) - -#define GPR_TIMER_END(tag, important) \ - do { \ - } while (0) - -#else /* at least one profiler requested... */ -/* ... hopefully only one. */ -#if defined(GRPC_STAP_PROFILER) && defined(GRPC_BASIC_PROFILER) -#error "GRPC_STAP_PROFILER and GRPC_BASIC_PROFILER are mutually exclusive." -#endif - -/* Generic profiling interface. */ -#define GPR_TIMER_MARK(tag, important) \ - gpr_timer_add_mark(tag, important, __FILE__, __LINE__); - -#define GPR_TIMER_BEGIN(tag, important) \ - gpr_timer_begin(tag, important, __FILE__, __LINE__); - -#define GPR_TIMER_END(tag, important) \ - gpr_timer_end(tag, important, __FILE__, __LINE__); - -#ifdef GRPC_STAP_PROFILER -/* Empty placeholder for now. */ -#endif /* GRPC_STAP_PROFILER */ - -#ifdef GRPC_BASIC_PROFILER -/* Empty placeholder for now. */ -#endif /* GRPC_BASIC_PROFILER */ - -#endif /* at least one profiler requested. */ - -#ifdef __cplusplus -} - -#if (defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER)) -namespace grpc { -class ProfileScope { - public: - ProfileScope(const char *desc, bool important) : desc_(desc) { - GPR_TIMER_BEGIN(desc_, important ? 1 : 0); - } - ~ProfileScope() { GPR_TIMER_END(desc_, 0); } - - private: - const char *const desc_; -}; -} - -#define GPR_TIMER_SCOPE(tag, important) \ - ::grpc::ProfileScope _profile_scope_##__LINE__((tag), (important)) -#else -#define GPR_TIMER_SCOPE(tag, important) \ - do { \ - } while (false) -#endif -#endif - -#endif /* GRPC_CORE_PROFILING_TIMERS_H */ diff --git a/src/core/proto/grpc/lb/v0/load_balancer.pb.c b/src/core/proto/grpc/lb/v0/load_balancer.pb.c deleted file mode 100644 index 59aae30cff..0000000000 --- a/src/core/proto/grpc/lb/v0/load_balancer.pb.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * - * 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. - * - */ -/* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.3.5-dev */ - -#include "src/core/proto/grpc/lb/v0/load_balancer.pb.h" - -#if PB_PROTO_HEADER_VERSION != 30 -#error Regenerate this file with the current version of nanopb generator. -#endif - - - -const pb_field_t grpc_lb_v0_Duration_fields[3] = { - PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, grpc_lb_v0_Duration, seconds, seconds, 0), - PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, grpc_lb_v0_Duration, nanos, seconds, 0), - PB_LAST_FIELD -}; - -const pb_field_t grpc_lb_v0_LoadBalanceRequest_fields[3] = { - PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, grpc_lb_v0_LoadBalanceRequest, initial_request, initial_request, &grpc_lb_v0_InitialLoadBalanceRequest_fields), - PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v0_LoadBalanceRequest, client_stats, initial_request, &grpc_lb_v0_ClientStats_fields), - PB_LAST_FIELD -}; - -const pb_field_t grpc_lb_v0_InitialLoadBalanceRequest_fields[2] = { - PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, grpc_lb_v0_InitialLoadBalanceRequest, name, name, 0), - PB_LAST_FIELD -}; - -const pb_field_t grpc_lb_v0_ClientStats_fields[4] = { - PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, grpc_lb_v0_ClientStats, total_requests, total_requests, 0), - PB_FIELD( 2, INT64 , OPTIONAL, STATIC , OTHER, grpc_lb_v0_ClientStats, client_rpc_errors, total_requests, 0), - PB_FIELD( 3, INT64 , OPTIONAL, STATIC , OTHER, grpc_lb_v0_ClientStats, dropped_requests, client_rpc_errors, 0), - PB_LAST_FIELD -}; - -const pb_field_t grpc_lb_v0_LoadBalanceResponse_fields[3] = { - PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, grpc_lb_v0_LoadBalanceResponse, initial_response, initial_response, &grpc_lb_v0_InitialLoadBalanceResponse_fields), - PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v0_LoadBalanceResponse, server_list, initial_response, &grpc_lb_v0_ServerList_fields), - PB_LAST_FIELD -}; - -const pb_field_t grpc_lb_v0_InitialLoadBalanceResponse_fields[4] = { - PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, grpc_lb_v0_InitialLoadBalanceResponse, client_config, client_config, 0), - PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, grpc_lb_v0_InitialLoadBalanceResponse, load_balancer_delegate, client_config, 0), - PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v0_InitialLoadBalanceResponse, client_stats_report_interval, load_balancer_delegate, &grpc_lb_v0_Duration_fields), - PB_LAST_FIELD -}; - -const pb_field_t grpc_lb_v0_ServerList_fields[3] = { - PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, grpc_lb_v0_ServerList, servers, servers, &grpc_lb_v0_Server_fields), - PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v0_ServerList, expiration_interval, servers, &grpc_lb_v0_Duration_fields), - PB_LAST_FIELD -}; - -const pb_field_t grpc_lb_v0_Server_fields[5] = { - PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, grpc_lb_v0_Server, ip_address, ip_address, 0), - PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, grpc_lb_v0_Server, port, ip_address, 0), - PB_FIELD( 3, BYTES , OPTIONAL, STATIC , OTHER, grpc_lb_v0_Server, load_balance_token, port, 0), - PB_FIELD( 4, BOOL , OPTIONAL, STATIC , OTHER, grpc_lb_v0_Server, drop_request, load_balance_token, 0), - PB_LAST_FIELD -}; - - -/* Check that field information fits in pb_field_t */ -#if !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_32BIT - * compile-time option. You can do that in pb.h or on compiler command line. - * - * The reason you need to do this is that some of your messages contain tag - * numbers or field sizes that are larger than what can fit in 8 or 16 bit - * field descriptors. - */ -PB_STATIC_ASSERT((pb_membersize(grpc_lb_v0_LoadBalanceRequest, initial_request) < 65536 && pb_membersize(grpc_lb_v0_LoadBalanceRequest, client_stats) < 65536 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, initial_response) < 65536 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, server_list) < 65536 && pb_membersize(grpc_lb_v0_InitialLoadBalanceResponse, client_stats_report_interval) < 65536 && pb_membersize(grpc_lb_v0_ServerList, servers) < 65536 && pb_membersize(grpc_lb_v0_ServerList, expiration_interval) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v0_Duration_grpc_lb_v0_LoadBalanceRequest_grpc_lb_v0_InitialLoadBalanceRequest_grpc_lb_v0_ClientStats_grpc_lb_v0_LoadBalanceResponse_grpc_lb_v0_InitialLoadBalanceResponse_grpc_lb_v0_ServerList_grpc_lb_v0_Server) -#endif - -#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_16BIT - * compile-time option. You can do that in pb.h or on compiler command line. - * - * The reason you need to do this is that some of your messages contain tag - * numbers or field sizes that are larger than what can fit in the default - * 8 bit descriptors. - */ -PB_STATIC_ASSERT((pb_membersize(grpc_lb_v0_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v0_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v0_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v0_ServerList, servers) < 256 && pb_membersize(grpc_lb_v0_ServerList, expiration_interval) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v0_Duration_grpc_lb_v0_LoadBalanceRequest_grpc_lb_v0_InitialLoadBalanceRequest_grpc_lb_v0_ClientStats_grpc_lb_v0_LoadBalanceResponse_grpc_lb_v0_InitialLoadBalanceResponse_grpc_lb_v0_ServerList_grpc_lb_v0_Server) -#endif - - diff --git a/src/core/proto/grpc/lb/v0/load_balancer.pb.h b/src/core/proto/grpc/lb/v0/load_balancer.pb.h deleted file mode 100644 index 3599f881bb..0000000000 --- a/src/core/proto/grpc/lb/v0/load_balancer.pb.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * - * 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. - * - */ -/* Automatically generated nanopb header */ -/* Generated by nanopb-0.3.5-dev */ - -#ifndef PB_LOAD_BALANCER_PB_H_INCLUDED -#define PB_LOAD_BALANCER_PB_H_INCLUDED -#include "third_party/nanopb/pb.h" -#if PB_PROTO_HEADER_VERSION != 30 -#error Regenerate this file with the current version of nanopb generator. -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Struct definitions */ -typedef struct _grpc_lb_v0_ClientStats { - bool has_total_requests; - int64_t total_requests; - bool has_client_rpc_errors; - int64_t client_rpc_errors; - bool has_dropped_requests; - int64_t dropped_requests; -} grpc_lb_v0_ClientStats; - -typedef struct _grpc_lb_v0_Duration { - bool has_seconds; - int64_t seconds; - bool has_nanos; - int32_t nanos; -} grpc_lb_v0_Duration; - -typedef struct _grpc_lb_v0_InitialLoadBalanceRequest { - bool has_name; - char name[128]; -} grpc_lb_v0_InitialLoadBalanceRequest; - -typedef PB_BYTES_ARRAY_T(64) grpc_lb_v0_Server_load_balance_token_t; -typedef struct _grpc_lb_v0_Server { - bool has_ip_address; - char ip_address[46]; - bool has_port; - int32_t port; - bool has_load_balance_token; - grpc_lb_v0_Server_load_balance_token_t load_balance_token; - bool has_drop_request; - bool drop_request; -} grpc_lb_v0_Server; - -typedef struct _grpc_lb_v0_InitialLoadBalanceResponse { - bool has_client_config; - char client_config[64]; - bool has_load_balancer_delegate; - char load_balancer_delegate[64]; - bool has_client_stats_report_interval; - grpc_lb_v0_Duration client_stats_report_interval; -} grpc_lb_v0_InitialLoadBalanceResponse; - -typedef struct _grpc_lb_v0_LoadBalanceRequest { - bool has_initial_request; - grpc_lb_v0_InitialLoadBalanceRequest initial_request; - bool has_client_stats; - grpc_lb_v0_ClientStats client_stats; -} grpc_lb_v0_LoadBalanceRequest; - -typedef struct _grpc_lb_v0_ServerList { - pb_callback_t servers; - bool has_expiration_interval; - grpc_lb_v0_Duration expiration_interval; -} grpc_lb_v0_ServerList; - -typedef struct _grpc_lb_v0_LoadBalanceResponse { - bool has_initial_response; - grpc_lb_v0_InitialLoadBalanceResponse initial_response; - bool has_server_list; - grpc_lb_v0_ServerList server_list; -} grpc_lb_v0_LoadBalanceResponse; - -/* Default values for struct fields */ - -/* Initializer values for message structs */ -#define grpc_lb_v0_Duration_init_default {false, 0, false, 0} -#define grpc_lb_v0_LoadBalanceRequest_init_default {false, grpc_lb_v0_InitialLoadBalanceRequest_init_default, false, grpc_lb_v0_ClientStats_init_default} -#define grpc_lb_v0_InitialLoadBalanceRequest_init_default {false, ""} -#define grpc_lb_v0_ClientStats_init_default {false, 0, false, 0, false, 0} -#define grpc_lb_v0_LoadBalanceResponse_init_default {false, grpc_lb_v0_InitialLoadBalanceResponse_init_default, false, grpc_lb_v0_ServerList_init_default} -#define grpc_lb_v0_InitialLoadBalanceResponse_init_default {false, "", false, "", false, grpc_lb_v0_Duration_init_default} -#define grpc_lb_v0_ServerList_init_default {{{NULL}, NULL}, false, grpc_lb_v0_Duration_init_default} -#define grpc_lb_v0_Server_init_default {false, "", false, 0, false, {0, {0}}, false, 0} -#define grpc_lb_v0_Duration_init_zero {false, 0, false, 0} -#define grpc_lb_v0_LoadBalanceRequest_init_zero {false, grpc_lb_v0_InitialLoadBalanceRequest_init_zero, false, grpc_lb_v0_ClientStats_init_zero} -#define grpc_lb_v0_InitialLoadBalanceRequest_init_zero {false, ""} -#define grpc_lb_v0_ClientStats_init_zero {false, 0, false, 0, false, 0} -#define grpc_lb_v0_LoadBalanceResponse_init_zero {false, grpc_lb_v0_InitialLoadBalanceResponse_init_zero, false, grpc_lb_v0_ServerList_init_zero} -#define grpc_lb_v0_InitialLoadBalanceResponse_init_zero {false, "", false, "", false, grpc_lb_v0_Duration_init_zero} -#define grpc_lb_v0_ServerList_init_zero {{{NULL}, NULL}, false, grpc_lb_v0_Duration_init_zero} -#define grpc_lb_v0_Server_init_zero {false, "", false, 0, false, {0, {0}}, false, 0} - -/* Field tags (for use in manual encoding/decoding) */ -#define grpc_lb_v0_ClientStats_total_requests_tag 1 -#define grpc_lb_v0_ClientStats_client_rpc_errors_tag 2 -#define grpc_lb_v0_ClientStats_dropped_requests_tag 3 -#define grpc_lb_v0_Duration_seconds_tag 1 -#define grpc_lb_v0_Duration_nanos_tag 2 -#define grpc_lb_v0_InitialLoadBalanceRequest_name_tag 1 -#define grpc_lb_v0_Server_ip_address_tag 1 -#define grpc_lb_v0_Server_port_tag 2 -#define grpc_lb_v0_Server_load_balance_token_tag 3 -#define grpc_lb_v0_Server_drop_request_tag 4 -#define grpc_lb_v0_InitialLoadBalanceResponse_client_config_tag 1 -#define grpc_lb_v0_InitialLoadBalanceResponse_load_balancer_delegate_tag 2 -#define grpc_lb_v0_InitialLoadBalanceResponse_client_stats_report_interval_tag 3 -#define grpc_lb_v0_LoadBalanceRequest_initial_request_tag 1 -#define grpc_lb_v0_LoadBalanceRequest_client_stats_tag 2 -#define grpc_lb_v0_ServerList_servers_tag 1 -#define grpc_lb_v0_ServerList_expiration_interval_tag 3 -#define grpc_lb_v0_LoadBalanceResponse_initial_response_tag 1 -#define grpc_lb_v0_LoadBalanceResponse_server_list_tag 2 - -/* Struct field encoding specification for nanopb */ -extern const pb_field_t grpc_lb_v0_Duration_fields[3]; -extern const pb_field_t grpc_lb_v0_LoadBalanceRequest_fields[3]; -extern const pb_field_t grpc_lb_v0_InitialLoadBalanceRequest_fields[2]; -extern const pb_field_t grpc_lb_v0_ClientStats_fields[4]; -extern const pb_field_t grpc_lb_v0_LoadBalanceResponse_fields[3]; -extern const pb_field_t grpc_lb_v0_InitialLoadBalanceResponse_fields[4]; -extern const pb_field_t grpc_lb_v0_ServerList_fields[3]; -extern const pb_field_t grpc_lb_v0_Server_fields[5]; - -/* Maximum encoded size of messages (where known) */ -#define grpc_lb_v0_Duration_size 22 -#define grpc_lb_v0_LoadBalanceRequest_size 169 -#define grpc_lb_v0_InitialLoadBalanceRequest_size 131 -#define grpc_lb_v0_ClientStats_size 33 -#define grpc_lb_v0_LoadBalanceResponse_size (165 + grpc_lb_v0_ServerList_size) -#define grpc_lb_v0_InitialLoadBalanceResponse_size 156 -#define grpc_lb_v0_Server_size 127 - -/* Message IDs (where set with "msgid" option) */ -#ifdef PB_MSGID - -#define LOAD_BALANCER_MESSAGES \ - - -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/core/security/auth_filters.h b/src/core/security/auth_filters.h deleted file mode 100644 index 1154a1d914..0000000000 --- a/src/core/security/auth_filters.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright 2015-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_SECURITY_AUTH_FILTERS_H -#define GRPC_CORE_SECURITY_AUTH_FILTERS_H - -#include "src/core/channel/channel_stack.h" - -extern const grpc_channel_filter grpc_client_auth_filter; -extern const grpc_channel_filter grpc_server_auth_filter; - -#endif /* GRPC_CORE_SECURITY_AUTH_FILTERS_H */ diff --git a/src/core/security/b64.c b/src/core/security/b64.c deleted file mode 100644 index c40b528e2f..0000000000 --- a/src/core/security/b64.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * - * Copyright 2015-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/security/b64.h" - -#include -#include - -#include -#include -#include - -/* --- Constants. --- */ - -static const int8_t base64_bytes[] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 0x3E, -1, -1, -1, 0x3F, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, -1, -1, - -1, 0x7F, -1, -1, -1, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, -1, -1, -1, -1, -1, - -1, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, - 0x31, 0x32, 0x33, -1, -1, -1, -1, -1}; - -static const char base64_url_unsafe_chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static const char base64_url_safe_chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - -#define GRPC_BASE64_PAD_CHAR '=' -#define GRPC_BASE64_PAD_BYTE 0x7F -#define GRPC_BASE64_MULTILINE_LINE_LEN 76 -#define GRPC_BASE64_MULTILINE_NUM_BLOCKS (GRPC_BASE64_MULTILINE_LINE_LEN / 4) - -/* --- base64 functions. --- */ - -char *grpc_base64_encode(const void *vdata, size_t data_size, int url_safe, - int multiline) { - const unsigned char *data = vdata; - const char *base64_chars = - url_safe ? base64_url_safe_chars : base64_url_unsafe_chars; - size_t result_projected_size = - 4 * ((data_size + 3) / 3) + - 2 * (multiline ? (data_size / (3 * GRPC_BASE64_MULTILINE_NUM_BLOCKS)) - : 0) + - 1; - char *result = gpr_malloc(result_projected_size); - char *current = result; - size_t num_blocks = 0; - size_t i = 0; - - /* Encode each block. */ - while (data_size >= 3) { - *current++ = base64_chars[(data[i] >> 2) & 0x3F]; - *current++ = - base64_chars[((data[i] & 0x03) << 4) | ((data[i + 1] >> 4) & 0x0F)]; - *current++ = - base64_chars[((data[i + 1] & 0x0F) << 2) | ((data[i + 2] >> 6) & 0x03)]; - *current++ = base64_chars[data[i + 2] & 0x3F]; - - data_size -= 3; - i += 3; - if (multiline && (++num_blocks == GRPC_BASE64_MULTILINE_NUM_BLOCKS)) { - *current++ = '\r'; - *current++ = '\n'; - num_blocks = 0; - } - } - - /* Take care of the tail. */ - if (data_size == 2) { - *current++ = base64_chars[(data[i] >> 2) & 0x3F]; - *current++ = - base64_chars[((data[i] & 0x03) << 4) | ((data[i + 1] >> 4) & 0x0F)]; - *current++ = base64_chars[(data[i + 1] & 0x0F) << 2]; - *current++ = GRPC_BASE64_PAD_CHAR; - } else if (data_size == 1) { - *current++ = base64_chars[(data[i] >> 2) & 0x3F]; - *current++ = base64_chars[(data[i] & 0x03) << 4]; - *current++ = GRPC_BASE64_PAD_CHAR; - *current++ = GRPC_BASE64_PAD_CHAR; - } - - GPR_ASSERT(current >= result); - GPR_ASSERT((uintptr_t)(current - result) < result_projected_size); - result[current - result] = '\0'; - return result; -} - -gpr_slice grpc_base64_decode(const char *b64, int url_safe) { - return grpc_base64_decode_with_len(b64, strlen(b64), url_safe); -} - -static void decode_one_char(const unsigned char *codes, unsigned char *result, - size_t *result_offset) { - uint32_t packed = ((uint32_t)codes[0] << 2) | ((uint32_t)codes[1] >> 4); - result[(*result_offset)++] = (unsigned char)packed; -} - -static void decode_two_chars(const unsigned char *codes, unsigned char *result, - size_t *result_offset) { - uint32_t packed = ((uint32_t)codes[0] << 10) | ((uint32_t)codes[1] << 4) | - ((uint32_t)codes[2] >> 2); - result[(*result_offset)++] = (unsigned char)(packed >> 8); - result[(*result_offset)++] = (unsigned char)(packed); -} - -static int decode_group(const unsigned char *codes, size_t num_codes, - unsigned char *result, size_t *result_offset) { - GPR_ASSERT(num_codes <= 4); - - /* Short end groups that may not have padding. */ - if (num_codes == 1) { - gpr_log(GPR_ERROR, "Invalid group. Must be at least 2 bytes."); - return 0; - } - if (num_codes == 2) { - decode_one_char(codes, result, result_offset); - return 1; - } - if (num_codes == 3) { - decode_two_chars(codes, result, result_offset); - return 1; - } - - /* Regular 4 byte groups with padding or not. */ - GPR_ASSERT(num_codes == 4); - if (codes[0] == GRPC_BASE64_PAD_BYTE || codes[1] == GRPC_BASE64_PAD_BYTE) { - gpr_log(GPR_ERROR, "Invalid padding detected."); - return 0; - } - if (codes[2] == GRPC_BASE64_PAD_BYTE) { - if (codes[3] == GRPC_BASE64_PAD_BYTE) { - decode_one_char(codes, result, result_offset); - } else { - gpr_log(GPR_ERROR, "Invalid padding detected."); - return 0; - } - } else if (codes[3] == GRPC_BASE64_PAD_BYTE) { - decode_two_chars(codes, result, result_offset); - } else { - /* No padding. */ - uint32_t packed = ((uint32_t)codes[0] << 18) | ((uint32_t)codes[1] << 12) | - ((uint32_t)codes[2] << 6) | codes[3]; - result[(*result_offset)++] = (unsigned char)(packed >> 16); - result[(*result_offset)++] = (unsigned char)(packed >> 8); - result[(*result_offset)++] = (unsigned char)(packed); - } - return 1; -} - -gpr_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len, - int url_safe) { - gpr_slice result = gpr_slice_malloc(b64_len); - unsigned char *current = GPR_SLICE_START_PTR(result); - size_t result_size = 0; - unsigned char codes[4]; - size_t num_codes = 0; - - while (b64_len--) { - unsigned char c = (unsigned char)(*b64++); - signed char code; - if (c >= GPR_ARRAY_SIZE(base64_bytes)) continue; - if (url_safe) { - if (c == '+' || c == '/') { - gpr_log(GPR_ERROR, "Invalid character for url safe base64 %c", c); - goto fail; - } - if (c == '-') { - c = '+'; - } else if (c == '_') { - c = '/'; - } - } - code = base64_bytes[c]; - if (code == -1) { - if (c != '\r' && c != '\n') { - gpr_log(GPR_ERROR, "Invalid character %c", c); - goto fail; - } - } else { - codes[num_codes++] = (unsigned char)code; - if (num_codes == 4) { - if (!decode_group(codes, num_codes, current, &result_size)) goto fail; - num_codes = 0; - } - } - } - - if (num_codes != 0 && - !decode_group(codes, num_codes, current, &result_size)) { - goto fail; - } - GPR_SLICE_SET_LENGTH(result, result_size); - return result; - -fail: - gpr_slice_unref(result); - return gpr_empty_slice(); -} diff --git a/src/core/security/b64.h b/src/core/security/b64.h deleted file mode 100644 index d18f69563d..0000000000 --- a/src/core/security/b64.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright 2015-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_SECURITY_B64_H -#define GRPC_CORE_SECURITY_B64_H - -#include - -/* Encodes data using base64. It is the caller's responsability to free - the returned char * using gpr_free. Returns NULL on NULL input. */ -char *grpc_base64_encode(const void *data, size_t data_size, int url_safe, - int multiline); - -/* Decodes data according to the base64 specification. Returns an empty - slice in case of failure. */ -gpr_slice grpc_base64_decode(const char *b64, int url_safe); - -/* Same as above except that the length is provided by the caller. */ -gpr_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len, - int url_safe); - -#endif /* GRPC_CORE_SECURITY_B64_H */ diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c deleted file mode 100644 index e2c23ef98d..0000000000 --- a/src/core/security/client_auth_filter.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * - * Copyright 2015-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/security/auth_filters.h" - -#include - -#include -#include -#include - -#include "src/core/channel/channel_stack.h" -#include "src/core/security/credentials.h" -#include "src/core/security/security_connector.h" -#include "src/core/security/security_context.h" -#include "src/core/support/string.h" -#include "src/core/surface/call.h" -#include "src/core/transport/static_metadata.h" - -#define MAX_CREDENTIALS_METADATA_COUNT 4 - -/* We can have a per-call credentials. */ -typedef struct { - grpc_call_credentials *creds; - grpc_mdstr *host; - grpc_mdstr *method; - /* pollset bound to this call; if we need to make external - network requests, they should be done under this pollset - so that work can progress when this call wants work to - progress */ - grpc_pollset *pollset; - grpc_transport_stream_op op; - uint8_t security_context_set; - grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT]; - grpc_auth_metadata_context auth_md_context; -} call_data; - -/* We can have a per-channel credentials. */ -typedef struct { - grpc_channel_security_connector *security_connector; - grpc_auth_context *auth_context; -} channel_data; - -static void reset_auth_metadata_context( - grpc_auth_metadata_context *auth_md_context) { - if (auth_md_context->service_url != NULL) { - gpr_free((char *)auth_md_context->service_url); - auth_md_context->service_url = NULL; - } - if (auth_md_context->method_name != NULL) { - gpr_free((char *)auth_md_context->method_name); - auth_md_context->method_name = NULL; - } - GRPC_AUTH_CONTEXT_UNREF( - (grpc_auth_context *)auth_md_context->channel_auth_context, - "grpc_auth_metadata_context"); - auth_md_context->channel_auth_context = NULL; -} - -static void bubble_up_error(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_status_code status, const char *error_msg) { - call_data *calld = elem->call_data; - gpr_log(GPR_ERROR, "Client side authentication failure: %s", error_msg); - grpc_transport_stream_op_add_cancellation(&calld->op, status); - grpc_call_next_op(exec_ctx, elem, &calld->op); -} - -static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data, - grpc_credentials_md *md_elems, - size_t num_md, - grpc_credentials_status status) { - grpc_call_element *elem = (grpc_call_element *)user_data; - call_data *calld = elem->call_data; - grpc_transport_stream_op *op = &calld->op; - grpc_metadata_batch *mdb; - size_t i; - reset_auth_metadata_context(&calld->auth_md_context); - if (status != GRPC_CREDENTIALS_OK) { - bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED, - "Credentials failed to get metadata."); - return; - } - GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT); - GPR_ASSERT(op->send_initial_metadata != NULL); - mdb = op->send_initial_metadata; - for (i = 0; i < num_md; i++) { - grpc_metadata_batch_add_tail( - mdb, &calld->md_links[i], - grpc_mdelem_from_slices(gpr_slice_ref(md_elems[i].key), - gpr_slice_ref(md_elems[i].value))); - } - grpc_call_next_op(exec_ctx, elem, op); -} - -void build_auth_metadata_context(grpc_security_connector *sc, - grpc_auth_context *auth_context, - call_data *calld) { - char *service = gpr_strdup(grpc_mdstr_as_c_string(calld->method)); - char *last_slash = strrchr(service, '/'); - char *method_name = NULL; - char *service_url = NULL; - reset_auth_metadata_context(&calld->auth_md_context); - if (last_slash == NULL) { - gpr_log(GPR_ERROR, "No '/' found in fully qualified method name"); - service[0] = '\0'; - } else if (last_slash == service) { - /* No service part in fully qualified method name: will just be "/". */ - service[1] = '\0'; - } else { - *last_slash = '\0'; - method_name = gpr_strdup(last_slash + 1); - } - if (method_name == NULL) method_name = gpr_strdup(""); - gpr_asprintf(&service_url, "%s://%s%s", - sc->url_scheme == NULL ? "" : sc->url_scheme, - grpc_mdstr_as_c_string(calld->host), service); - calld->auth_md_context.service_url = service_url; - calld->auth_md_context.method_name = method_name; - calld->auth_md_context.channel_auth_context = - GRPC_AUTH_CONTEXT_REF(auth_context, "grpc_auth_metadata_context"); - gpr_free(service); -} - -static void send_security_metadata(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - grpc_client_security_context *ctx = - (grpc_client_security_context *)op->context[GRPC_CONTEXT_SECURITY].value; - grpc_call_credentials *channel_call_creds = - chand->security_connector->request_metadata_creds; - int call_creds_has_md = (ctx != NULL) && (ctx->creds != NULL); - - if (channel_call_creds == NULL && !call_creds_has_md) { - /* Skip sending metadata altogether. */ - grpc_call_next_op(exec_ctx, elem, op); - return; - } - - if (channel_call_creds != NULL && call_creds_has_md) { - calld->creds = grpc_composite_call_credentials_create(channel_call_creds, - ctx->creds, NULL); - if (calld->creds == NULL) { - bubble_up_error(exec_ctx, elem, GRPC_STATUS_INVALID_ARGUMENT, - "Incompatible credentials set on channel and call."); - return; - } - } else { - calld->creds = grpc_call_credentials_ref( - call_creds_has_md ? ctx->creds : channel_call_creds); - } - - build_auth_metadata_context(&chand->security_connector->base, - chand->auth_context, calld); - calld->op = *op; /* Copy op (originates from the caller's stack). */ - GPR_ASSERT(calld->pollset); - grpc_call_credentials_get_request_metadata( - exec_ctx, calld->creds, calld->pollset, calld->auth_md_context, - on_credentials_metadata, elem); -} - -static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data, - grpc_security_status status) { - grpc_call_element *elem = (grpc_call_element *)user_data; - call_data *calld = elem->call_data; - - if (status == GRPC_SECURITY_OK) { - send_security_metadata(exec_ctx, elem, &calld->op); - } else { - char *error_msg; - gpr_asprintf(&error_msg, "Invalid host %s set in :authority metadata.", - grpc_mdstr_as_c_string(calld->host)); - bubble_up_error(exec_ctx, elem, GRPC_STATUS_INVALID_ARGUMENT, error_msg); - gpr_free(error_msg); - } -} - -/* Called either: - - in response to an API call (or similar) from above, to send something - - a network event (or similar) from below, to receive something - op contains type and call direction information, in addition to the data - that is being sent or received. */ -static void auth_start_transport_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - /* grab pointers to our data from the call element */ - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - grpc_linked_mdelem *l; - grpc_client_security_context *sec_ctx = NULL; - - if (calld->security_context_set == 0 && - op->cancel_with_status == GRPC_STATUS_OK) { - calld->security_context_set = 1; - GPR_ASSERT(op->context); - if (op->context[GRPC_CONTEXT_SECURITY].value == NULL) { - op->context[GRPC_CONTEXT_SECURITY].value = - grpc_client_security_context_create(); - op->context[GRPC_CONTEXT_SECURITY].destroy = - grpc_client_security_context_destroy; - } - sec_ctx = op->context[GRPC_CONTEXT_SECURITY].value; - GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter"); - sec_ctx->auth_context = - GRPC_AUTH_CONTEXT_REF(chand->auth_context, "client_auth_filter"); - } - - if (op->send_initial_metadata != NULL) { - for (l = op->send_initial_metadata->list.head; l != NULL; l = l->next) { - grpc_mdelem *md = l->md; - /* Pointer comparison is OK for md_elems created from the same context. - */ - if (md->key == GRPC_MDSTR_AUTHORITY) { - if (calld->host != NULL) GRPC_MDSTR_UNREF(calld->host); - calld->host = GRPC_MDSTR_REF(md->value); - } else if (md->key == GRPC_MDSTR_PATH) { - if (calld->method != NULL) GRPC_MDSTR_UNREF(calld->method); - calld->method = GRPC_MDSTR_REF(md->value); - } - } - if (calld->host != NULL) { - const char *call_host = grpc_mdstr_as_c_string(calld->host); - calld->op = *op; /* Copy op (originates from the caller's stack). */ - grpc_channel_security_connector_check_call_host( - exec_ctx, chand->security_connector, call_host, chand->auth_context, - on_host_checked, elem); - return; /* early exit */ - } - } - - /* pass control down the stack */ - grpc_call_next_op(exec_ctx, elem, op); -} - -/* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { - call_data *calld = elem->call_data; - memset(calld, 0, sizeof(*calld)); -} - -static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_pollset *pollset) { - call_data *calld = elem->call_data; - calld->pollset = pollset; -} - -/* Destructor for call_data */ -static void destroy_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - call_data *calld = elem->call_data; - grpc_call_credentials_unref(calld->creds); - if (calld->host != NULL) { - GRPC_MDSTR_UNREF(calld->host); - } - if (calld->method != NULL) { - GRPC_MDSTR_UNREF(calld->method); - } - reset_auth_metadata_context(&calld->auth_md_context); -} - -/* Constructor for channel_data */ -static void init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - grpc_security_connector *sc = - grpc_find_security_connector_in_args(args->channel_args); - grpc_auth_context *auth_context = - grpc_find_auth_context_in_args(args->channel_args); - - /* grab pointers to our data from the channel element */ - channel_data *chand = elem->channel_data; - - /* The first and the last filters tend to be implemented differently to - handle the case that there's no 'next' filter to call on the up or down - path */ - GPR_ASSERT(!args->is_last); - GPR_ASSERT(sc != NULL); - GPR_ASSERT(auth_context != NULL); - - /* initialize members */ - chand->security_connector = - (grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF( - sc, "client_auth_filter"); - chand->auth_context = - GRPC_AUTH_CONTEXT_REF(auth_context, "client_auth_filter"); -} - -/* Destructor for channel data */ -static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) { - /* grab pointers to our data from the channel element */ - channel_data *chand = elem->channel_data; - grpc_channel_security_connector *sc = chand->security_connector; - if (sc != NULL) { - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "client_auth_filter"); - } - GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter"); -} - -const grpc_channel_filter grpc_client_auth_filter = { - auth_start_transport_op, grpc_channel_next_op, sizeof(call_data), - init_call_elem, set_pollset, destroy_call_elem, - sizeof(channel_data), init_channel_elem, destroy_channel_elem, - grpc_call_next_get_peer, "client-auth"}; diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c deleted file mode 100644 index c8348bc12c..0000000000 --- a/src/core/security/credentials.c +++ /dev/null @@ -1,1281 +0,0 @@ -/* - * - * Copyright 2015-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/security/credentials.h" - -#include -#include - -#include "src/core/channel/channel_args.h" -#include "src/core/channel/http_client_filter.h" -#include "src/core/http/httpcli.h" -#include "src/core/http/parser.h" -#include "src/core/iomgr/executor.h" -#include "src/core/json/json.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" - -#include -#include -#include -#include -#include - -/* -- Common. -- */ - -struct grpc_credentials_metadata_request { - grpc_call_credentials *creds; - grpc_credentials_metadata_cb cb; - void *user_data; -}; - -static grpc_credentials_metadata_request * -grpc_credentials_metadata_request_create(grpc_call_credentials *creds, - grpc_credentials_metadata_cb cb, - void *user_data) { - grpc_credentials_metadata_request *r = - gpr_malloc(sizeof(grpc_credentials_metadata_request)); - r->creds = grpc_call_credentials_ref(creds); - r->cb = cb; - r->user_data = user_data; - return r; -} - -static void grpc_credentials_metadata_request_destroy( - grpc_credentials_metadata_request *r) { - grpc_call_credentials_unref(r->creds); - gpr_free(r); -} - -grpc_channel_credentials *grpc_channel_credentials_ref( - grpc_channel_credentials *creds) { - if (creds == NULL) return NULL; - gpr_ref(&creds->refcount); - return creds; -} - -void grpc_channel_credentials_unref(grpc_channel_credentials *creds) { - if (creds == NULL) return; - if (gpr_unref(&creds->refcount)) { - if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds); - gpr_free(creds); - } -} - -void grpc_channel_credentials_release(grpc_channel_credentials *creds) { - GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds)); - grpc_channel_credentials_unref(creds); -} - -grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds) { - if (creds == NULL) return NULL; - gpr_ref(&creds->refcount); - return creds; -} - -void grpc_call_credentials_unref(grpc_call_credentials *creds) { - if (creds == NULL) return; - if (gpr_unref(&creds->refcount)) { - if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds); - gpr_free(creds); - } -} - -void grpc_call_credentials_release(grpc_call_credentials *creds) { - GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds)); - grpc_call_credentials_unref(creds); -} - -void grpc_call_credentials_get_request_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, - grpc_pollset *pollset, grpc_auth_metadata_context context, - grpc_credentials_metadata_cb cb, void *user_data) { - if (creds == NULL || creds->vtable->get_request_metadata == NULL) { - if (cb != NULL) { - cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK); - } - return; - } - creds->vtable->get_request_metadata(exec_ctx, creds, pollset, context, cb, - user_data); -} - -grpc_security_status grpc_channel_credentials_create_security_connector( - grpc_channel_credentials *channel_creds, const char *target, - const grpc_channel_args *args, grpc_channel_security_connector **sc, - grpc_channel_args **new_args) { - *new_args = NULL; - if (channel_creds == NULL) { - return GRPC_SECURITY_ERROR; - } - GPR_ASSERT(channel_creds->vtable->create_security_connector != NULL); - return channel_creds->vtable->create_security_connector( - channel_creds, NULL, target, args, sc, new_args); -} - -grpc_server_credentials *grpc_server_credentials_ref( - grpc_server_credentials *creds) { - if (creds == NULL) return NULL; - gpr_ref(&creds->refcount); - return creds; -} - -void grpc_server_credentials_unref(grpc_server_credentials *creds) { - if (creds == NULL) return; - if (gpr_unref(&creds->refcount)) { - if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds); - if (creds->processor.destroy != NULL && creds->processor.state != NULL) { - creds->processor.destroy(creds->processor.state); - } - gpr_free(creds); - } -} - -void grpc_server_credentials_release(grpc_server_credentials *creds) { - GRPC_API_TRACE("grpc_server_credentials_release(creds=%p)", 1, (creds)); - grpc_server_credentials_unref(creds); -} - -grpc_security_status grpc_server_credentials_create_security_connector( - grpc_server_credentials *creds, grpc_server_security_connector **sc) { - if (creds == NULL || creds->vtable->create_security_connector == NULL) { - gpr_log(GPR_ERROR, "Server credentials cannot create security context."); - return GRPC_SECURITY_ERROR; - } - return creds->vtable->create_security_connector(creds, sc); -} - -void grpc_server_credentials_set_auth_metadata_processor( - grpc_server_credentials *creds, grpc_auth_metadata_processor processor) { - GRPC_API_TRACE( - "grpc_server_credentials_set_auth_metadata_processor(" - "creds=%p, " - "processor=grpc_auth_metadata_processor { process: %p, state: %p })", - 3, (creds, (void *)(intptr_t)processor.process, processor.state)); - if (creds == NULL) return; - if (creds->processor.destroy != NULL && creds->processor.state != NULL) { - creds->processor.destroy(creds->processor.state); - } - creds->processor = processor; -} - -static void server_credentials_pointer_arg_destroy(void *p) { - grpc_server_credentials_unref(p); -} - -static void *server_credentials_pointer_arg_copy(void *p) { - return grpc_server_credentials_ref(p); -} - -static int server_credentials_pointer_cmp(void *a, void *b) { - return GPR_ICMP(a, b); -} - -static const grpc_arg_pointer_vtable cred_ptr_vtable = { - server_credentials_pointer_arg_copy, server_credentials_pointer_arg_destroy, - server_credentials_pointer_cmp}; - -grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *p) { - grpc_arg arg; - memset(&arg, 0, sizeof(grpc_arg)); - arg.type = GRPC_ARG_POINTER; - arg.key = GRPC_SERVER_CREDENTIALS_ARG; - arg.value.pointer.p = p; - arg.value.pointer.vtable = &cred_ptr_vtable; - return arg; -} - -grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg) { - if (strcmp(arg->key, GRPC_SERVER_CREDENTIALS_ARG) != 0) return NULL; - if (arg->type != GRPC_ARG_POINTER) { - gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, - GRPC_SERVER_CREDENTIALS_ARG); - return NULL; - } - return arg->value.pointer.p; -} - -grpc_server_credentials *grpc_find_server_credentials_in_args( - const grpc_channel_args *args) { - size_t i; - if (args == NULL) return NULL; - for (i = 0; i < args->num_args; i++) { - grpc_server_credentials *p = - grpc_server_credentials_from_arg(&args->args[i]); - if (p != NULL) return p; - } - return NULL; -} - -/* -- Ssl credentials. -- */ - -static void ssl_destruct(grpc_channel_credentials *creds) { - grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds; - if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs); - if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key); - if (c->config.pem_cert_chain != NULL) gpr_free(c->config.pem_cert_chain); -} - -static void ssl_server_destruct(grpc_server_credentials *creds) { - grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds; - size_t i; - for (i = 0; i < c->config.num_key_cert_pairs; i++) { - if (c->config.pem_private_keys[i] != NULL) { - gpr_free(c->config.pem_private_keys[i]); - } - if (c->config.pem_cert_chains[i] != NULL) { - gpr_free(c->config.pem_cert_chains[i]); - } - } - if (c->config.pem_private_keys != NULL) gpr_free(c->config.pem_private_keys); - if (c->config.pem_private_keys_sizes != NULL) { - gpr_free(c->config.pem_private_keys_sizes); - } - if (c->config.pem_cert_chains != NULL) gpr_free(c->config.pem_cert_chains); - if (c->config.pem_cert_chains_sizes != NULL) { - gpr_free(c->config.pem_cert_chains_sizes); - } - if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs); -} - -static grpc_security_status ssl_create_security_connector( - grpc_channel_credentials *creds, grpc_call_credentials *call_creds, - const char *target, const grpc_channel_args *args, - grpc_channel_security_connector **sc, grpc_channel_args **new_args) { - grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds; - grpc_security_status status = GRPC_SECURITY_OK; - size_t i = 0; - const char *overridden_target_name = NULL; - grpc_arg new_arg; - - for (i = 0; args && i < args->num_args; i++) { - grpc_arg *arg = &args->args[i]; - if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 && - arg->type == GRPC_ARG_STRING) { - overridden_target_name = arg->value.string; - break; - } - } - status = grpc_ssl_channel_security_connector_create( - call_creds, &c->config, target, overridden_target_name, sc); - if (status != GRPC_SECURITY_OK) { - return status; - } - new_arg.type = GRPC_ARG_STRING; - new_arg.key = GRPC_ARG_HTTP2_SCHEME; - new_arg.value.string = "https"; - *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1); - return status; -} - -static grpc_security_status ssl_server_create_security_connector( - grpc_server_credentials *creds, grpc_server_security_connector **sc) { - grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds; - return grpc_ssl_server_security_connector_create(&c->config, sc); -} - -static grpc_channel_credentials_vtable ssl_vtable = { - ssl_destruct, ssl_create_security_connector}; - -static grpc_server_credentials_vtable ssl_server_vtable = { - ssl_server_destruct, ssl_server_create_security_connector}; - -static void ssl_copy_key_material(const char *input, unsigned char **output, - size_t *output_size) { - *output_size = strlen(input); - *output = gpr_malloc(*output_size); - memcpy(*output, input, *output_size); -} - -static void ssl_build_config(const char *pem_root_certs, - grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, - grpc_ssl_config *config) { - if (pem_root_certs != NULL) { - ssl_copy_key_material(pem_root_certs, &config->pem_root_certs, - &config->pem_root_certs_size); - } - if (pem_key_cert_pair != NULL) { - GPR_ASSERT(pem_key_cert_pair->private_key != NULL); - GPR_ASSERT(pem_key_cert_pair->cert_chain != NULL); - ssl_copy_key_material(pem_key_cert_pair->private_key, - &config->pem_private_key, - &config->pem_private_key_size); - ssl_copy_key_material(pem_key_cert_pair->cert_chain, - &config->pem_cert_chain, - &config->pem_cert_chain_size); - } -} - -static void ssl_build_server_config( - const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, - size_t num_key_cert_pairs, int force_client_auth, - grpc_ssl_server_config *config) { - size_t i; - config->force_client_auth = force_client_auth; - if (pem_root_certs != NULL) { - ssl_copy_key_material(pem_root_certs, &config->pem_root_certs, - &config->pem_root_certs_size); - } - if (num_key_cert_pairs > 0) { - GPR_ASSERT(pem_key_cert_pairs != NULL); - config->pem_private_keys = - gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *)); - config->pem_cert_chains = - gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *)); - config->pem_private_keys_sizes = - gpr_malloc(num_key_cert_pairs * sizeof(size_t)); - config->pem_cert_chains_sizes = - gpr_malloc(num_key_cert_pairs * sizeof(size_t)); - } - config->num_key_cert_pairs = num_key_cert_pairs; - for (i = 0; i < num_key_cert_pairs; i++) { - GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL); - GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL); - ssl_copy_key_material(pem_key_cert_pairs[i].private_key, - &config->pem_private_keys[i], - &config->pem_private_keys_sizes[i]); - ssl_copy_key_material(pem_key_cert_pairs[i].cert_chain, - &config->pem_cert_chains[i], - &config->pem_cert_chains_sizes[i]); - } -} - -grpc_channel_credentials *grpc_ssl_credentials_create( - const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, - void *reserved) { - grpc_ssl_credentials *c = gpr_malloc(sizeof(grpc_ssl_credentials)); - GRPC_API_TRACE( - "grpc_ssl_credentials_create(pem_root_certs=%s, " - "pem_key_cert_pair=%p, " - "reserved=%p)", - 3, (pem_root_certs, pem_key_cert_pair, reserved)); - GPR_ASSERT(reserved == NULL); - memset(c, 0, sizeof(grpc_ssl_credentials)); - c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; - c->base.vtable = &ssl_vtable; - gpr_ref_init(&c->base.refcount, 1); - ssl_build_config(pem_root_certs, pem_key_cert_pair, &c->config); - return &c->base; -} - -grpc_server_credentials *grpc_ssl_server_credentials_create( - const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, - size_t num_key_cert_pairs, int force_client_auth, void *reserved) { - grpc_ssl_server_credentials *c = - gpr_malloc(sizeof(grpc_ssl_server_credentials)); - GRPC_API_TRACE( - "grpc_ssl_server_credentials_create(" - "pem_root_certs=%s, pem_key_cert_pairs=%p, num_key_cert_pairs=%lu, " - "force_client_auth=%d, reserved=%p)", - 5, (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs, - force_client_auth, reserved)); - GPR_ASSERT(reserved == NULL); - memset(c, 0, sizeof(grpc_ssl_server_credentials)); - c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &ssl_server_vtable; - ssl_build_server_config(pem_root_certs, pem_key_cert_pairs, - num_key_cert_pairs, force_client_auth, &c->config); - return &c->base; -} - -/* -- Jwt credentials -- */ - -static void jwt_reset_cache(grpc_service_account_jwt_access_credentials *c) { - if (c->cached.jwt_md != NULL) { - grpc_credentials_md_store_unref(c->cached.jwt_md); - c->cached.jwt_md = NULL; - } - if (c->cached.service_url != NULL) { - gpr_free(c->cached.service_url); - c->cached.service_url = NULL; - } - c->cached.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); -} - -static void jwt_destruct(grpc_call_credentials *creds) { - grpc_service_account_jwt_access_credentials *c = - (grpc_service_account_jwt_access_credentials *)creds; - grpc_auth_json_key_destruct(&c->key); - jwt_reset_cache(c); - gpr_mu_destroy(&c->cache_mu); -} - -static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx, - grpc_call_credentials *creds, - grpc_pollset *pollset, - grpc_auth_metadata_context context, - grpc_credentials_metadata_cb cb, - void *user_data) { - grpc_service_account_jwt_access_credentials *c = - (grpc_service_account_jwt_access_credentials *)creds; - gpr_timespec refresh_threshold = gpr_time_from_seconds( - GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN); - - /* See if we can return a cached jwt. */ - grpc_credentials_md_store *jwt_md = NULL; - { - gpr_mu_lock(&c->cache_mu); - if (c->cached.service_url != NULL && - strcmp(c->cached.service_url, context.service_url) == 0 && - c->cached.jwt_md != NULL && - (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, - gpr_now(GPR_CLOCK_REALTIME)), - refresh_threshold) > 0)) { - jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md); - } - gpr_mu_unlock(&c->cache_mu); - } - - if (jwt_md == NULL) { - char *jwt = NULL; - /* Generate a new jwt. */ - gpr_mu_lock(&c->cache_mu); - jwt_reset_cache(c); - jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url, - c->jwt_lifetime, NULL); - if (jwt != NULL) { - char *md_value; - gpr_asprintf(&md_value, "Bearer %s", jwt); - gpr_free(jwt); - c->cached.jwt_expiration = - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime); - c->cached.service_url = gpr_strdup(context.service_url); - c->cached.jwt_md = grpc_credentials_md_store_create(1); - grpc_credentials_md_store_add_cstrings( - c->cached.jwt_md, GRPC_AUTHORIZATION_METADATA_KEY, md_value); - gpr_free(md_value); - jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md); - } - gpr_mu_unlock(&c->cache_mu); - } - - if (jwt_md != NULL) { - cb(exec_ctx, user_data, jwt_md->entries, jwt_md->num_entries, - GRPC_CREDENTIALS_OK); - grpc_credentials_md_store_unref(jwt_md); - } else { - cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_ERROR); - } -} - -static grpc_call_credentials_vtable jwt_vtable = {jwt_destruct, - jwt_get_request_metadata}; - -grpc_call_credentials * -grpc_service_account_jwt_access_credentials_create_from_auth_json_key( - grpc_auth_json_key key, gpr_timespec token_lifetime) { - grpc_service_account_jwt_access_credentials *c; - if (!grpc_auth_json_key_is_valid(&key)) { - gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation"); - return NULL; - } - c = gpr_malloc(sizeof(grpc_service_account_jwt_access_credentials)); - memset(c, 0, sizeof(grpc_service_account_jwt_access_credentials)); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_JWT; - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &jwt_vtable; - c->key = key; - c->jwt_lifetime = token_lifetime; - gpr_mu_init(&c->cache_mu); - jwt_reset_cache(c); - return &c->base; -} - -grpc_call_credentials *grpc_service_account_jwt_access_credentials_create( - const char *json_key, gpr_timespec token_lifetime, void *reserved) { - GRPC_API_TRACE( - "grpc_service_account_jwt_access_credentials_create(" - "json_key=%s, " - "token_lifetime=" - "gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " - "reserved=%p)", - 5, - (json_key, (long long)token_lifetime.tv_sec, (int)token_lifetime.tv_nsec, - (int)token_lifetime.clock_type, reserved)); - GPR_ASSERT(reserved == NULL); - return grpc_service_account_jwt_access_credentials_create_from_auth_json_key( - grpc_auth_json_key_create_from_string(json_key), token_lifetime); -} - -/* -- Oauth2TokenFetcher credentials -- */ - -static void oauth2_token_fetcher_destruct(grpc_call_credentials *creds) { - grpc_oauth2_token_fetcher_credentials *c = - (grpc_oauth2_token_fetcher_credentials *)creds; - grpc_credentials_md_store_unref(c->access_token_md); - gpr_mu_destroy(&c->mu); - grpc_httpcli_context_destroy(&c->httpcli_context); -} - -grpc_credentials_status -grpc_oauth2_token_fetcher_credentials_parse_server_response( - const grpc_http_response *response, grpc_credentials_md_store **token_md, - gpr_timespec *token_lifetime) { - char *null_terminated_body = NULL; - char *new_access_token = NULL; - grpc_credentials_status status = GRPC_CREDENTIALS_OK; - grpc_json *json = NULL; - - if (response == NULL) { - gpr_log(GPR_ERROR, "Received NULL response."); - status = GRPC_CREDENTIALS_ERROR; - goto end; - } - - if (response->body_length > 0) { - null_terminated_body = gpr_malloc(response->body_length + 1); - null_terminated_body[response->body_length] = '\0'; - memcpy(null_terminated_body, response->body, response->body_length); - } - - if (response->status != 200) { - gpr_log(GPR_ERROR, "Call to http server ended with error %d [%s].", - response->status, - null_terminated_body != NULL ? null_terminated_body : ""); - status = GRPC_CREDENTIALS_ERROR; - goto end; - } else { - grpc_json *access_token = NULL; - grpc_json *token_type = NULL; - grpc_json *expires_in = NULL; - grpc_json *ptr; - json = grpc_json_parse_string(null_terminated_body); - if (json == NULL) { - gpr_log(GPR_ERROR, "Could not parse JSON from %s", null_terminated_body); - status = GRPC_CREDENTIALS_ERROR; - goto end; - } - if (json->type != GRPC_JSON_OBJECT) { - gpr_log(GPR_ERROR, "Response should be a JSON object"); - status = GRPC_CREDENTIALS_ERROR; - goto end; - } - for (ptr = json->child; ptr; ptr = ptr->next) { - if (strcmp(ptr->key, "access_token") == 0) { - access_token = ptr; - } else if (strcmp(ptr->key, "token_type") == 0) { - token_type = ptr; - } else if (strcmp(ptr->key, "expires_in") == 0) { - expires_in = ptr; - } - } - if (access_token == NULL || access_token->type != GRPC_JSON_STRING) { - gpr_log(GPR_ERROR, "Missing or invalid access_token in JSON."); - status = GRPC_CREDENTIALS_ERROR; - goto end; - } - if (token_type == NULL || token_type->type != GRPC_JSON_STRING) { - gpr_log(GPR_ERROR, "Missing or invalid token_type in JSON."); - status = GRPC_CREDENTIALS_ERROR; - goto end; - } - if (expires_in == NULL || expires_in->type != GRPC_JSON_NUMBER) { - gpr_log(GPR_ERROR, "Missing or invalid expires_in in JSON."); - status = GRPC_CREDENTIALS_ERROR; - goto end; - } - gpr_asprintf(&new_access_token, "%s %s", token_type->value, - access_token->value); - token_lifetime->tv_sec = strtol(expires_in->value, NULL, 10); - token_lifetime->tv_nsec = 0; - token_lifetime->clock_type = GPR_TIMESPAN; - if (*token_md != NULL) grpc_credentials_md_store_unref(*token_md); - *token_md = grpc_credentials_md_store_create(1); - grpc_credentials_md_store_add_cstrings( - *token_md, GRPC_AUTHORIZATION_METADATA_KEY, new_access_token); - status = GRPC_CREDENTIALS_OK; - } - -end: - if (status != GRPC_CREDENTIALS_OK && (*token_md != NULL)) { - grpc_credentials_md_store_unref(*token_md); - *token_md = NULL; - } - if (null_terminated_body != NULL) gpr_free(null_terminated_body); - if (new_access_token != NULL) gpr_free(new_access_token); - if (json != NULL) grpc_json_destroy(json); - return status; -} - -static void on_oauth2_token_fetcher_http_response( - grpc_exec_ctx *exec_ctx, void *user_data, - const grpc_http_response *response) { - grpc_credentials_metadata_request *r = - (grpc_credentials_metadata_request *)user_data; - grpc_oauth2_token_fetcher_credentials *c = - (grpc_oauth2_token_fetcher_credentials *)r->creds; - gpr_timespec token_lifetime; - grpc_credentials_status status; - - gpr_mu_lock(&c->mu); - status = grpc_oauth2_token_fetcher_credentials_parse_server_response( - response, &c->access_token_md, &token_lifetime); - if (status == GRPC_CREDENTIALS_OK) { - c->token_expiration = - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), token_lifetime); - r->cb(exec_ctx, r->user_data, c->access_token_md->entries, - c->access_token_md->num_entries, status); - } else { - c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); - r->cb(exec_ctx, r->user_data, NULL, 0, status); - } - gpr_mu_unlock(&c->mu); - grpc_credentials_metadata_request_destroy(r); -} - -static void oauth2_token_fetcher_get_request_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, - grpc_pollset *pollset, grpc_auth_metadata_context context, - grpc_credentials_metadata_cb cb, void *user_data) { - grpc_oauth2_token_fetcher_credentials *c = - (grpc_oauth2_token_fetcher_credentials *)creds; - gpr_timespec refresh_threshold = gpr_time_from_seconds( - GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN); - grpc_credentials_md_store *cached_access_token_md = NULL; - { - gpr_mu_lock(&c->mu); - if (c->access_token_md != NULL && - (gpr_time_cmp( - gpr_time_sub(c->token_expiration, gpr_now(GPR_CLOCK_REALTIME)), - refresh_threshold) > 0)) { - cached_access_token_md = - grpc_credentials_md_store_ref(c->access_token_md); - } - gpr_mu_unlock(&c->mu); - } - if (cached_access_token_md != NULL) { - cb(exec_ctx, user_data, cached_access_token_md->entries, - cached_access_token_md->num_entries, GRPC_CREDENTIALS_OK); - grpc_credentials_md_store_unref(cached_access_token_md); - } else { - c->fetch_func( - exec_ctx, - grpc_credentials_metadata_request_create(creds, cb, user_data), - &c->httpcli_context, pollset, on_oauth2_token_fetcher_http_response, - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), refresh_threshold)); - } -} - -static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials *c, - grpc_fetch_oauth2_func fetch_func) { - memset(c, 0, sizeof(grpc_oauth2_token_fetcher_credentials)); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; - gpr_ref_init(&c->base.refcount, 1); - gpr_mu_init(&c->mu); - c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); - c->fetch_func = fetch_func; - grpc_httpcli_context_init(&c->httpcli_context); -} - -/* -- GoogleComputeEngine credentials. -- */ - -static grpc_call_credentials_vtable compute_engine_vtable = { - oauth2_token_fetcher_destruct, oauth2_token_fetcher_get_request_metadata}; - -static void compute_engine_fetch_oauth2( - grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req, - grpc_httpcli_context *httpcli_context, grpc_pollset *pollset, - grpc_httpcli_response_cb response_cb, gpr_timespec deadline) { - grpc_http_header header = {"Metadata-Flavor", "Google"}; - grpc_httpcli_request request; - memset(&request, 0, sizeof(grpc_httpcli_request)); - request.host = GRPC_COMPUTE_ENGINE_METADATA_HOST; - request.http.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH; - request.http.hdr_count = 1; - request.http.hdrs = &header; - grpc_httpcli_get(exec_ctx, httpcli_context, pollset, &request, deadline, - response_cb, metadata_req); -} - -grpc_call_credentials *grpc_google_compute_engine_credentials_create( - void *reserved) { - grpc_oauth2_token_fetcher_credentials *c = - gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials)); - GRPC_API_TRACE("grpc_compute_engine_credentials_create(reserved=%p)", 1, - (reserved)); - GPR_ASSERT(reserved == NULL); - init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2); - c->base.vtable = &compute_engine_vtable; - return &c->base; -} - -/* -- GoogleRefreshToken credentials. -- */ - -static void refresh_token_destruct(grpc_call_credentials *creds) { - grpc_google_refresh_token_credentials *c = - (grpc_google_refresh_token_credentials *)creds; - grpc_auth_refresh_token_destruct(&c->refresh_token); - oauth2_token_fetcher_destruct(&c->base.base); -} - -static grpc_call_credentials_vtable refresh_token_vtable = { - refresh_token_destruct, oauth2_token_fetcher_get_request_metadata}; - -static void refresh_token_fetch_oauth2( - grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req, - grpc_httpcli_context *httpcli_context, grpc_pollset *pollset, - grpc_httpcli_response_cb response_cb, gpr_timespec deadline) { - grpc_google_refresh_token_credentials *c = - (grpc_google_refresh_token_credentials *)metadata_req->creds; - grpc_http_header header = {"Content-Type", - "application/x-www-form-urlencoded"}; - grpc_httpcli_request request; - char *body = NULL; - gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING, - c->refresh_token.client_id, c->refresh_token.client_secret, - c->refresh_token.refresh_token); - memset(&request, 0, sizeof(grpc_httpcli_request)); - request.host = GRPC_GOOGLE_OAUTH2_SERVICE_HOST; - request.http.path = GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH; - request.http.hdr_count = 1; - request.http.hdrs = &header; - request.handshaker = &grpc_httpcli_ssl; - grpc_httpcli_post(exec_ctx, httpcli_context, pollset, &request, body, - strlen(body), deadline, response_cb, metadata_req); - gpr_free(body); -} - -grpc_call_credentials * -grpc_refresh_token_credentials_create_from_auth_refresh_token( - grpc_auth_refresh_token refresh_token) { - grpc_google_refresh_token_credentials *c; - if (!grpc_auth_refresh_token_is_valid(&refresh_token)) { - gpr_log(GPR_ERROR, "Invalid input for refresh token credentials creation"); - return NULL; - } - c = gpr_malloc(sizeof(grpc_google_refresh_token_credentials)); - memset(c, 0, sizeof(grpc_google_refresh_token_credentials)); - init_oauth2_token_fetcher(&c->base, refresh_token_fetch_oauth2); - c->base.base.vtable = &refresh_token_vtable; - c->refresh_token = refresh_token; - return &c->base.base; -} - -grpc_call_credentials *grpc_google_refresh_token_credentials_create( - const char *json_refresh_token, void *reserved) { - GRPC_API_TRACE( - "grpc_refresh_token_credentials_create(json_refresh_token=%s, " - "reserved=%p)", - 2, (json_refresh_token, reserved)); - GPR_ASSERT(reserved == NULL); - return grpc_refresh_token_credentials_create_from_auth_refresh_token( - grpc_auth_refresh_token_create_from_string(json_refresh_token)); -} - -/* -- Metadata-only credentials. -- */ - -static void md_only_test_destruct(grpc_call_credentials *creds) { - grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds; - grpc_credentials_md_store_unref(c->md_store); -} - -static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx, - void *user_data, bool success) { - grpc_credentials_metadata_request *r = - (grpc_credentials_metadata_request *)user_data; - grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)r->creds; - r->cb(exec_ctx, r->user_data, c->md_store->entries, c->md_store->num_entries, - GRPC_CREDENTIALS_OK); - grpc_credentials_metadata_request_destroy(r); -} - -static void md_only_test_get_request_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, - grpc_pollset *pollset, grpc_auth_metadata_context context, - grpc_credentials_metadata_cb cb, void *user_data) { - grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds; - - if (c->is_async) { - grpc_credentials_metadata_request *cb_arg = - grpc_credentials_metadata_request_create(creds, cb, user_data); - grpc_executor_enqueue( - grpc_closure_create(on_simulated_token_fetch_done, cb_arg), true); - } else { - cb(exec_ctx, user_data, c->md_store->entries, 1, GRPC_CREDENTIALS_OK); - } -} - -static grpc_call_credentials_vtable md_only_test_vtable = { - md_only_test_destruct, md_only_test_get_request_metadata}; - -grpc_call_credentials *grpc_md_only_test_credentials_create( - const char *md_key, const char *md_value, int is_async) { - grpc_md_only_test_credentials *c = - gpr_malloc(sizeof(grpc_md_only_test_credentials)); - memset(c, 0, sizeof(grpc_md_only_test_credentials)); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; - c->base.vtable = &md_only_test_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->md_store = grpc_credentials_md_store_create(1); - grpc_credentials_md_store_add_cstrings(c->md_store, md_key, md_value); - c->is_async = is_async; - return &c->base; -} - -/* -- Oauth2 Access Token credentials. -- */ - -static void access_token_destruct(grpc_call_credentials *creds) { - grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds; - grpc_credentials_md_store_unref(c->access_token_md); -} - -static void access_token_get_request_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, - grpc_pollset *pollset, grpc_auth_metadata_context context, - grpc_credentials_metadata_cb cb, void *user_data) { - grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds; - cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK); -} - -static grpc_call_credentials_vtable access_token_vtable = { - access_token_destruct, access_token_get_request_metadata}; - -grpc_call_credentials *grpc_access_token_credentials_create( - const char *access_token, void *reserved) { - grpc_access_token_credentials *c = - gpr_malloc(sizeof(grpc_access_token_credentials)); - char *token_md_value; - GRPC_API_TRACE( - "grpc_access_token_credentials_create(access_token=%s, " - "reserved=%p)", - 2, (access_token, reserved)); - GPR_ASSERT(reserved == NULL); - memset(c, 0, sizeof(grpc_access_token_credentials)); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; - c->base.vtable = &access_token_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->access_token_md = grpc_credentials_md_store_create(1); - gpr_asprintf(&token_md_value, "Bearer %s", access_token); - grpc_credentials_md_store_add_cstrings( - c->access_token_md, GRPC_AUTHORIZATION_METADATA_KEY, token_md_value); - gpr_free(token_md_value); - return &c->base; -} - -/* -- Fake transport security credentials. -- */ - -static grpc_security_status fake_transport_security_create_security_connector( - grpc_channel_credentials *c, grpc_call_credentials *call_creds, - const char *target, const grpc_channel_args *args, - grpc_channel_security_connector **sc, grpc_channel_args **new_args) { - *sc = grpc_fake_channel_security_connector_create(call_creds); - return GRPC_SECURITY_OK; -} - -static grpc_security_status -fake_transport_security_server_create_security_connector( - grpc_server_credentials *c, grpc_server_security_connector **sc) { - *sc = grpc_fake_server_security_connector_create(); - return GRPC_SECURITY_OK; -} - -static grpc_channel_credentials_vtable - fake_transport_security_credentials_vtable = { - NULL, fake_transport_security_create_security_connector}; - -static grpc_server_credentials_vtable - fake_transport_security_server_credentials_vtable = { - NULL, fake_transport_security_server_create_security_connector}; - -grpc_channel_credentials *grpc_fake_transport_security_credentials_create( - void) { - grpc_channel_credentials *c = gpr_malloc(sizeof(grpc_channel_credentials)); - memset(c, 0, sizeof(grpc_channel_credentials)); - c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY; - c->vtable = &fake_transport_security_credentials_vtable; - gpr_ref_init(&c->refcount, 1); - return c; -} - -grpc_server_credentials *grpc_fake_transport_security_server_credentials_create( - void) { - grpc_server_credentials *c = gpr_malloc(sizeof(grpc_server_credentials)); - memset(c, 0, sizeof(grpc_server_credentials)); - c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY; - gpr_ref_init(&c->refcount, 1); - c->vtable = &fake_transport_security_server_credentials_vtable; - return c; -} - -/* -- Composite call credentials. -- */ - -typedef struct { - grpc_composite_call_credentials *composite_creds; - size_t creds_index; - grpc_credentials_md_store *md_elems; - grpc_auth_metadata_context auth_md_context; - void *user_data; - grpc_pollset *pollset; - grpc_credentials_metadata_cb cb; -} grpc_composite_call_credentials_metadata_context; - -static void composite_call_destruct(grpc_call_credentials *creds) { - grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds; - size_t i; - for (i = 0; i < c->inner.num_creds; i++) { - grpc_call_credentials_unref(c->inner.creds_array[i]); - } - gpr_free(c->inner.creds_array); -} - -static void composite_call_md_context_destroy( - grpc_composite_call_credentials_metadata_context *ctx) { - grpc_credentials_md_store_unref(ctx->md_elems); - gpr_free(ctx); -} - -static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data, - grpc_credentials_md *md_elems, - size_t num_md, - grpc_credentials_status status) { - grpc_composite_call_credentials_metadata_context *ctx = - (grpc_composite_call_credentials_metadata_context *)user_data; - if (status != GRPC_CREDENTIALS_OK) { - ctx->cb(exec_ctx, ctx->user_data, NULL, 0, status); - return; - } - - /* Copy the metadata in the context. */ - if (num_md > 0) { - size_t i; - for (i = 0; i < num_md; i++) { - grpc_credentials_md_store_add(ctx->md_elems, md_elems[i].key, - md_elems[i].value); - } - } - - /* See if we need to get some more metadata. */ - if (ctx->creds_index < ctx->composite_creds->inner.num_creds) { - grpc_call_credentials *inner_creds = - ctx->composite_creds->inner.creds_array[ctx->creds_index++]; - grpc_call_credentials_get_request_metadata( - exec_ctx, inner_creds, ctx->pollset, ctx->auth_md_context, - composite_call_metadata_cb, ctx); - return; - } - - /* We're done!. */ - ctx->cb(exec_ctx, ctx->user_data, ctx->md_elems->entries, - ctx->md_elems->num_entries, GRPC_CREDENTIALS_OK); - composite_call_md_context_destroy(ctx); -} - -static void composite_call_get_request_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, - grpc_pollset *pollset, grpc_auth_metadata_context auth_md_context, - grpc_credentials_metadata_cb cb, void *user_data) { - grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds; - grpc_composite_call_credentials_metadata_context *ctx; - - ctx = gpr_malloc(sizeof(grpc_composite_call_credentials_metadata_context)); - memset(ctx, 0, sizeof(grpc_composite_call_credentials_metadata_context)); - ctx->auth_md_context = auth_md_context; - ctx->user_data = user_data; - ctx->cb = cb; - ctx->composite_creds = c; - ctx->pollset = pollset; - ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds); - grpc_call_credentials_get_request_metadata( - exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset, - auth_md_context, composite_call_metadata_cb, ctx); -} - -static grpc_call_credentials_vtable composite_call_credentials_vtable = { - composite_call_destruct, composite_call_get_request_metadata}; - -static grpc_call_credentials_array get_creds_array( - grpc_call_credentials **creds_addr) { - grpc_call_credentials_array result; - grpc_call_credentials *creds = *creds_addr; - result.creds_array = creds_addr; - result.num_creds = 1; - if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) { - result = *grpc_composite_call_credentials_get_credentials(creds); - } - return result; -} - -grpc_call_credentials *grpc_composite_call_credentials_create( - grpc_call_credentials *creds1, grpc_call_credentials *creds2, - void *reserved) { - size_t i; - size_t creds_array_byte_size; - grpc_call_credentials_array creds1_array; - grpc_call_credentials_array creds2_array; - grpc_composite_call_credentials *c; - GRPC_API_TRACE( - "grpc_composite_call_credentials_create(creds1=%p, creds2=%p, " - "reserved=%p)", - 3, (creds1, creds2, reserved)); - GPR_ASSERT(reserved == NULL); - GPR_ASSERT(creds1 != NULL); - GPR_ASSERT(creds2 != NULL); - c = gpr_malloc(sizeof(grpc_composite_call_credentials)); - memset(c, 0, sizeof(grpc_composite_call_credentials)); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE; - c->base.vtable = &composite_call_credentials_vtable; - gpr_ref_init(&c->base.refcount, 1); - creds1_array = get_creds_array(&creds1); - creds2_array = get_creds_array(&creds2); - c->inner.num_creds = creds1_array.num_creds + creds2_array.num_creds; - creds_array_byte_size = c->inner.num_creds * sizeof(grpc_call_credentials *); - c->inner.creds_array = gpr_malloc(creds_array_byte_size); - memset(c->inner.creds_array, 0, creds_array_byte_size); - for (i = 0; i < creds1_array.num_creds; i++) { - grpc_call_credentials *cur_creds = creds1_array.creds_array[i]; - c->inner.creds_array[i] = grpc_call_credentials_ref(cur_creds); - } - for (i = 0; i < creds2_array.num_creds; i++) { - grpc_call_credentials *cur_creds = creds2_array.creds_array[i]; - c->inner.creds_array[i + creds1_array.num_creds] = - grpc_call_credentials_ref(cur_creds); - } - return &c->base; -} - -const grpc_call_credentials_array * -grpc_composite_call_credentials_get_credentials(grpc_call_credentials *creds) { - const grpc_composite_call_credentials *c = - (const grpc_composite_call_credentials *)creds; - GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); - return &c->inner; -} - -grpc_call_credentials *grpc_credentials_contains_type( - grpc_call_credentials *creds, const char *type, - grpc_call_credentials **composite_creds) { - size_t i; - if (strcmp(creds->type, type) == 0) { - if (composite_creds != NULL) *composite_creds = NULL; - return creds; - } else if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) { - const grpc_call_credentials_array *inner_creds_array = - grpc_composite_call_credentials_get_credentials(creds); - for (i = 0; i < inner_creds_array->num_creds; i++) { - if (strcmp(type, inner_creds_array->creds_array[i]->type) == 0) { - if (composite_creds != NULL) *composite_creds = creds; - return inner_creds_array->creds_array[i]; - } - } - } - return NULL; -} - -/* -- IAM credentials. -- */ - -static void iam_destruct(grpc_call_credentials *creds) { - grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds; - grpc_credentials_md_store_unref(c->iam_md); -} - -static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx, - grpc_call_credentials *creds, - grpc_pollset *pollset, - grpc_auth_metadata_context context, - grpc_credentials_metadata_cb cb, - void *user_data) { - grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds; - cb(exec_ctx, user_data, c->iam_md->entries, c->iam_md->num_entries, - GRPC_CREDENTIALS_OK); -} - -static grpc_call_credentials_vtable iam_vtable = {iam_destruct, - iam_get_request_metadata}; - -grpc_call_credentials *grpc_google_iam_credentials_create( - const char *token, const char *authority_selector, void *reserved) { - grpc_google_iam_credentials *c; - GRPC_API_TRACE( - "grpc_iam_credentials_create(token=%s, authority_selector=%s, " - "reserved=%p)", - 3, (token, authority_selector, reserved)); - GPR_ASSERT(reserved == NULL); - GPR_ASSERT(token != NULL); - GPR_ASSERT(authority_selector != NULL); - c = gpr_malloc(sizeof(grpc_google_iam_credentials)); - memset(c, 0, sizeof(grpc_google_iam_credentials)); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_IAM; - c->base.vtable = &iam_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->iam_md = grpc_credentials_md_store_create(2); - grpc_credentials_md_store_add_cstrings( - c->iam_md, GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, token); - grpc_credentials_md_store_add_cstrings( - c->iam_md, GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, authority_selector); - return &c->base; -} - -/* -- Plugin credentials. -- */ - -typedef struct { - void *user_data; - grpc_credentials_metadata_cb cb; -} grpc_metadata_plugin_request; - -static void plugin_destruct(grpc_call_credentials *creds) { - grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds; - if (c->plugin.state != NULL && c->plugin.destroy != NULL) { - c->plugin.destroy(c->plugin.state); - } -} - -static void plugin_md_request_metadata_ready(void *request, - const grpc_metadata *md, - size_t num_md, - grpc_status_code status, - const char *error_details) { - /* called from application code */ - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_metadata_plugin_request *r = (grpc_metadata_plugin_request *)request; - if (status != GRPC_STATUS_OK) { - if (error_details != NULL) { - gpr_log(GPR_ERROR, "Getting metadata from plugin failed with error: %s", - error_details); - } - r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR); - } else { - size_t i; - grpc_credentials_md *md_array = NULL; - if (num_md > 0) { - md_array = gpr_malloc(num_md * sizeof(grpc_credentials_md)); - for (i = 0; i < num_md; i++) { - md_array[i].key = gpr_slice_from_copied_string(md[i].key); - md_array[i].value = - gpr_slice_from_copied_buffer(md[i].value, md[i].value_length); - } - } - r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK); - if (md_array != NULL) { - for (i = 0; i < num_md; i++) { - gpr_slice_unref(md_array[i].key); - gpr_slice_unref(md_array[i].value); - } - gpr_free(md_array); - } - } - gpr_free(r); - grpc_exec_ctx_finish(&exec_ctx); -} - -static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx, - grpc_call_credentials *creds, - grpc_pollset *pollset, - grpc_auth_metadata_context context, - grpc_credentials_metadata_cb cb, - void *user_data) { - grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds; - if (c->plugin.get_metadata != NULL) { - grpc_metadata_plugin_request *request = gpr_malloc(sizeof(*request)); - memset(request, 0, sizeof(*request)); - request->user_data = user_data; - request->cb = cb; - c->plugin.get_metadata(c->plugin.state, context, - plugin_md_request_metadata_ready, request); - } else { - cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK); - } -} - -static grpc_call_credentials_vtable plugin_vtable = { - plugin_destruct, plugin_get_request_metadata}; - -grpc_call_credentials *grpc_metadata_credentials_create_from_plugin( - grpc_metadata_credentials_plugin plugin, void *reserved) { - grpc_plugin_credentials *c = gpr_malloc(sizeof(*c)); - GRPC_API_TRACE("grpc_metadata_credentials_create_from_plugin(reserved=%p)", 1, - (reserved)); - GPR_ASSERT(reserved == NULL); - memset(c, 0, sizeof(*c)); - c->base.type = plugin.type; - c->base.vtable = &plugin_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->plugin = plugin; - return &c->base; -} - -/* -- Composite channel credentials. -- */ - -static void composite_channel_destruct(grpc_channel_credentials *creds) { - grpc_composite_channel_credentials *c = - (grpc_composite_channel_credentials *)creds; - grpc_channel_credentials_unref(c->inner_creds); - grpc_call_credentials_unref(c->call_creds); -} - -static grpc_security_status composite_channel_create_security_connector( - grpc_channel_credentials *creds, grpc_call_credentials *call_creds, - const char *target, const grpc_channel_args *args, - grpc_channel_security_connector **sc, grpc_channel_args **new_args) { - grpc_composite_channel_credentials *c = - (grpc_composite_channel_credentials *)creds; - grpc_security_status status = GRPC_SECURITY_ERROR; - - GPR_ASSERT(c->inner_creds != NULL && c->call_creds != NULL && - c->inner_creds->vtable != NULL && - c->inner_creds->vtable->create_security_connector != NULL); - /* If we are passed a call_creds, create a call composite to pass it - downstream. */ - if (call_creds != NULL) { - grpc_call_credentials *composite_call_creds = - grpc_composite_call_credentials_create(c->call_creds, call_creds, NULL); - status = c->inner_creds->vtable->create_security_connector( - c->inner_creds, composite_call_creds, target, args, sc, new_args); - grpc_call_credentials_unref(composite_call_creds); - } else { - status = c->inner_creds->vtable->create_security_connector( - c->inner_creds, c->call_creds, target, args, sc, new_args); - } - return status; -} - -static grpc_channel_credentials_vtable composite_channel_credentials_vtable = { - composite_channel_destruct, composite_channel_create_security_connector}; - -grpc_channel_credentials *grpc_composite_channel_credentials_create( - grpc_channel_credentials *channel_creds, grpc_call_credentials *call_creds, - void *reserved) { - grpc_composite_channel_credentials *c = gpr_malloc(sizeof(*c)); - memset(c, 0, sizeof(*c)); - GPR_ASSERT(channel_creds != NULL && call_creds != NULL && reserved == NULL); - GRPC_API_TRACE( - "grpc_composite_channel_credentials_create(channel_creds=%p, " - "call_creds=%p, reserved=%p)", - 3, (channel_creds, call_creds, reserved)); - c->base.type = channel_creds->type; - c->base.vtable = &composite_channel_credentials_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->inner_creds = grpc_channel_credentials_ref(channel_creds); - c->call_creds = grpc_call_credentials_ref(call_creds); - return &c->base; -} diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h deleted file mode 100644 index bfa7cc71bd..0000000000 --- a/src/core/security/credentials.h +++ /dev/null @@ -1,377 +0,0 @@ -/* - * - * Copyright 2015-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_SECURITY_CREDENTIALS_H -#define GRPC_CORE_SECURITY_CREDENTIALS_H - -#include -#include -#include -#include "src/core/transport/metadata_batch.h" - -#include "src/core/http/httpcli.h" -#include "src/core/http/parser.h" -#include "src/core/security/json_token.h" -#include "src/core/security/security_connector.h" - -struct grpc_http_response; - -/* --- Constants. --- */ - -typedef enum { - GRPC_CREDENTIALS_OK = 0, - GRPC_CREDENTIALS_ERROR -} grpc_credentials_status; - -#define GRPC_FAKE_TRANSPORT_SECURITY_TYPE "fake" - -#define GRPC_CHANNEL_CREDENTIALS_TYPE_SSL "Ssl" -#define GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY \ - "FakeTransportSecurity" - -#define GRPC_CALL_CREDENTIALS_TYPE_OAUTH2 "Oauth2" -#define GRPC_CALL_CREDENTIALS_TYPE_JWT "Jwt" -#define GRPC_CALL_CREDENTIALS_TYPE_IAM "Iam" -#define GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE "Composite" - -#define GRPC_AUTHORIZATION_METADATA_KEY "authorization" -#define GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY \ - "x-goog-iam-authorization-token" -#define GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY "x-goog-iam-authority-selector" - -#define GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY "gcloud" -#define GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE \ - "application_default_credentials.json" - -#define GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS 60 - -#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata" -#define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \ - "/computeMetadata/v1/instance/service-accounts/default/token" - -#define GRPC_GOOGLE_OAUTH2_SERVICE_HOST "www.googleapis.com" -#define GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH "/oauth2/v3/token" - -#define GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX \ - "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" \ - "assertion=" - -#define GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING \ - "client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token" - -/* --- Google utils --- */ - -/* It is the caller's responsibility to gpr_free the result if not NULL. */ -char *grpc_get_well_known_google_credentials_file_path(void); - -/* Implementation function for the different platforms. */ -char *grpc_get_well_known_google_credentials_file_path_impl(void); - -/* Override for testing only. Not thread-safe */ -typedef char *(*grpc_well_known_credentials_path_getter)(void); -void grpc_override_well_known_credentials_path_getter( - grpc_well_known_credentials_path_getter getter); - -/* --- grpc_channel_credentials. --- */ - -typedef struct { - void (*destruct)(grpc_channel_credentials *c); - - grpc_security_status (*create_security_connector)( - grpc_channel_credentials *c, grpc_call_credentials *call_creds, - const char *target, const grpc_channel_args *args, - grpc_channel_security_connector **sc, grpc_channel_args **new_args); -} grpc_channel_credentials_vtable; - -struct grpc_channel_credentials { - const grpc_channel_credentials_vtable *vtable; - const char *type; - gpr_refcount refcount; -}; - -grpc_channel_credentials *grpc_channel_credentials_ref( - grpc_channel_credentials *creds); -void grpc_channel_credentials_unref(grpc_channel_credentials *creds); - -/* Creates a security connector for the channel. May also create new channel - args for the channel to be used in place of the passed in const args if - returned non NULL. In that case the caller is responsible for destroying - new_args after channel creation. */ -grpc_security_status grpc_channel_credentials_create_security_connector( - grpc_channel_credentials *creds, const char *target, - const grpc_channel_args *args, grpc_channel_security_connector **sc, - grpc_channel_args **new_args); - -/* --- grpc_credentials_md. --- */ - -typedef struct { - gpr_slice key; - gpr_slice value; -} grpc_credentials_md; - -typedef struct { - grpc_credentials_md *entries; - size_t num_entries; - size_t allocated; - gpr_refcount refcount; -} grpc_credentials_md_store; - -grpc_credentials_md_store *grpc_credentials_md_store_create( - size_t initial_capacity); - -/* Will ref key and value. */ -void grpc_credentials_md_store_add(grpc_credentials_md_store *store, - gpr_slice key, gpr_slice value); -void grpc_credentials_md_store_add_cstrings(grpc_credentials_md_store *store, - const char *key, const char *value); -grpc_credentials_md_store *grpc_credentials_md_store_ref( - grpc_credentials_md_store *store); -void grpc_credentials_md_store_unref(grpc_credentials_md_store *store); - -/* --- grpc_call_credentials. --- */ - -typedef void (*grpc_credentials_metadata_cb)(grpc_exec_ctx *exec_ctx, - void *user_data, - grpc_credentials_md *md_elems, - size_t num_md, - grpc_credentials_status status); - -typedef struct { - void (*destruct)(grpc_call_credentials *c); - void (*get_request_metadata)(grpc_exec_ctx *exec_ctx, - grpc_call_credentials *c, grpc_pollset *pollset, - grpc_auth_metadata_context context, - grpc_credentials_metadata_cb cb, - void *user_data); -} grpc_call_credentials_vtable; - -struct grpc_call_credentials { - const grpc_call_credentials_vtable *vtable; - const char *type; - gpr_refcount refcount; -}; - -grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds); -void grpc_call_credentials_unref(grpc_call_credentials *creds); -void grpc_call_credentials_get_request_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, - grpc_pollset *pollset, grpc_auth_metadata_context context, - grpc_credentials_metadata_cb cb, void *user_data); - -typedef struct { - grpc_call_credentials **creds_array; - size_t num_creds; -} grpc_call_credentials_array; - -const grpc_call_credentials_array * -grpc_composite_call_credentials_get_credentials( - grpc_call_credentials *composite_creds); - -/* Returns creds if creds is of the specified type or the inner creds of the - specified type (if found), if the creds is of type COMPOSITE. - If composite_creds is not NULL, *composite_creds will point to creds if of - type COMPOSITE in case of success. */ -grpc_call_credentials *grpc_credentials_contains_type( - grpc_call_credentials *creds, const char *type, - grpc_call_credentials **composite_creds); - -/* Exposed for testing only. */ -grpc_credentials_status -grpc_oauth2_token_fetcher_credentials_parse_server_response( - const struct grpc_http_response *response, - grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime); - -void grpc_flush_cached_google_default_credentials(void); - -/* Metadata-only credentials with the specified key and value where - asynchronicity can be simulated for testing. */ -grpc_call_credentials *grpc_md_only_test_credentials_create( - const char *md_key, const char *md_value, int is_async); - -/* Private constructor for jwt credentials from an already parsed json key. - Takes ownership of the key. */ -grpc_call_credentials * -grpc_service_account_jwt_access_credentials_create_from_auth_json_key( - grpc_auth_json_key key, gpr_timespec token_lifetime); - -/* Private constructor for refresh token credentials from an already parsed - refresh token. Takes ownership of the refresh token. */ -grpc_call_credentials * -grpc_refresh_token_credentials_create_from_auth_refresh_token( - grpc_auth_refresh_token token); - -/* --- grpc_server_credentials. --- */ - -typedef struct { - void (*destruct)(grpc_server_credentials *c); - grpc_security_status (*create_security_connector)( - grpc_server_credentials *c, grpc_server_security_connector **sc); -} grpc_server_credentials_vtable; - -struct grpc_server_credentials { - const grpc_server_credentials_vtable *vtable; - const char *type; - gpr_refcount refcount; - grpc_auth_metadata_processor processor; -}; - -grpc_security_status grpc_server_credentials_create_security_connector( - grpc_server_credentials *creds, grpc_server_security_connector **sc); - -grpc_server_credentials *grpc_server_credentials_ref( - grpc_server_credentials *creds); - -void grpc_server_credentials_unref(grpc_server_credentials *creds); - -#define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials" - -grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *c); -grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg); -grpc_server_credentials *grpc_find_server_credentials_in_args( - const grpc_channel_args *args); - -/* -- Fake transport security credentials. -- */ - -/* Creates a fake transport security credentials object for testing. */ -grpc_channel_credentials *grpc_fake_transport_security_credentials_create(void); -/* Creates a fake server transport security credentials object for testing. */ -grpc_server_credentials *grpc_fake_transport_security_server_credentials_create( - void); - -/* -- Ssl credentials. -- */ - -typedef struct { - grpc_channel_credentials base; - grpc_ssl_config config; -} grpc_ssl_credentials; - -typedef struct { - grpc_server_credentials base; - grpc_ssl_server_config config; -} grpc_ssl_server_credentials; - -/* -- Channel composite credentials. -- */ - -typedef struct { - grpc_channel_credentials base; - grpc_channel_credentials *inner_creds; - grpc_call_credentials *call_creds; -} grpc_composite_channel_credentials; - -/* -- Jwt credentials -- */ - -typedef struct { - grpc_call_credentials base; - - /* Have a simple cache for now with just 1 entry. We could have a map based on - the service_url for a more sophisticated one. */ - gpr_mu cache_mu; - struct { - grpc_credentials_md_store *jwt_md; - char *service_url; - gpr_timespec jwt_expiration; - } cached; - - grpc_auth_json_key key; - gpr_timespec jwt_lifetime; -} grpc_service_account_jwt_access_credentials; - -/* -- Oauth2TokenFetcher credentials -- - - This object is a base for credentials that need to acquire an oauth2 token - from an http service. */ - -typedef struct grpc_credentials_metadata_request - grpc_credentials_metadata_request; - -typedef void (*grpc_fetch_oauth2_func)(grpc_exec_ctx *exec_ctx, - grpc_credentials_metadata_request *req, - grpc_httpcli_context *http_context, - grpc_pollset *pollset, - grpc_httpcli_response_cb response_cb, - gpr_timespec deadline); - -typedef struct { - grpc_call_credentials base; - gpr_mu mu; - grpc_credentials_md_store *access_token_md; - gpr_timespec token_expiration; - grpc_httpcli_context httpcli_context; - grpc_fetch_oauth2_func fetch_func; -} grpc_oauth2_token_fetcher_credentials; - -/* -- GoogleRefreshToken credentials. -- */ - -typedef struct { - grpc_oauth2_token_fetcher_credentials base; - grpc_auth_refresh_token refresh_token; -} grpc_google_refresh_token_credentials; - -/* -- Oauth2 Access Token credentials. -- */ - -typedef struct { - grpc_call_credentials base; - grpc_credentials_md_store *access_token_md; -} grpc_access_token_credentials; - -/* -- Metadata-only Test credentials. -- */ - -typedef struct { - grpc_call_credentials base; - grpc_credentials_md_store *md_store; - int is_async; -} grpc_md_only_test_credentials; - -/* -- GoogleIAM credentials. -- */ - -typedef struct { - grpc_call_credentials base; - grpc_credentials_md_store *iam_md; -} grpc_google_iam_credentials; - -/* -- Composite credentials. -- */ - -typedef struct { - grpc_call_credentials base; - grpc_call_credentials_array inner; -} grpc_composite_call_credentials; - -/* -- Plugin credentials. -- */ - -typedef struct { - grpc_call_credentials base; - grpc_metadata_credentials_plugin plugin; - grpc_credentials_md_store *plugin_md; -} grpc_plugin_credentials; - -#endif /* GRPC_CORE_SECURITY_CREDENTIALS_H */ diff --git a/src/core/security/credentials_metadata.c b/src/core/security/credentials_metadata.c deleted file mode 100644 index b8a132f1ea..0000000000 --- a/src/core/security/credentials_metadata.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * Copyright 2015, 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/security/credentials.h" - -#include - -#include - -static void store_ensure_capacity(grpc_credentials_md_store *store) { - if (store->num_entries == store->allocated) { - store->allocated = (store->allocated == 0) ? 1 : store->allocated * 2; - store->entries = gpr_realloc( - store->entries, store->allocated * sizeof(grpc_credentials_md)); - } -} - -grpc_credentials_md_store *grpc_credentials_md_store_create( - size_t initial_capacity) { - grpc_credentials_md_store *store = - gpr_malloc(sizeof(grpc_credentials_md_store)); - memset(store, 0, sizeof(grpc_credentials_md_store)); - if (initial_capacity > 0) { - store->entries = gpr_malloc(initial_capacity * sizeof(grpc_credentials_md)); - store->allocated = initial_capacity; - } - gpr_ref_init(&store->refcount, 1); - return store; -} - -void grpc_credentials_md_store_add(grpc_credentials_md_store *store, - gpr_slice key, gpr_slice value) { - if (store == NULL) return; - store_ensure_capacity(store); - store->entries[store->num_entries].key = gpr_slice_ref(key); - store->entries[store->num_entries].value = gpr_slice_ref(value); - store->num_entries++; -} - -void grpc_credentials_md_store_add_cstrings(grpc_credentials_md_store *store, - const char *key, - const char *value) { - if (store == NULL) return; - store_ensure_capacity(store); - store->entries[store->num_entries].key = gpr_slice_from_copied_string(key); - store->entries[store->num_entries].value = - gpr_slice_from_copied_string(value); - store->num_entries++; -} - -grpc_credentials_md_store *grpc_credentials_md_store_ref( - grpc_credentials_md_store *store) { - if (store == NULL) return NULL; - gpr_ref(&store->refcount); - return store; -} - -void grpc_credentials_md_store_unref(grpc_credentials_md_store *store) { - if (store == NULL) return; - if (gpr_unref(&store->refcount)) { - if (store->entries != NULL) { - size_t i; - for (i = 0; i < store->num_entries; i++) { - gpr_slice_unref(store->entries[i].key); - gpr_slice_unref(store->entries[i].value); - } - gpr_free(store->entries); - } - gpr_free(store); - } -} diff --git a/src/core/security/credentials_posix.c b/src/core/security/credentials_posix.c deleted file mode 100644 index 0c92bd4a96..0000000000 --- a/src/core/security/credentials_posix.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Copyright 2015, 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 - -#ifdef GPR_POSIX_FILE - -#include "src/core/security/credentials.h" - -#include -#include -#include - -#include "src/core/support/env.h" -#include "src/core/support/string.h" - -char *grpc_get_well_known_google_credentials_file_path_impl(void) { - char *result = NULL; - char *home = gpr_getenv("HOME"); - if (home == NULL) { - gpr_log(GPR_ERROR, "Could not get HOME environment variable."); - return NULL; - } - gpr_asprintf(&result, "%s/.config/%s/%s", home, - GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY, - GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE); - gpr_free(home); - return result; -} - -#endif /* GPR_POSIX_FILE */ diff --git a/src/core/security/credentials_win32.c b/src/core/security/credentials_win32.c deleted file mode 100644 index 8ee9f706a1..0000000000 --- a/src/core/security/credentials_win32.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Copyright 2015, 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 - -#ifdef GPR_WIN32 - -#include "src/core/security/credentials.h" - -#include -#include -#include - -#include "src/core/support/env.h" -#include "src/core/support/string.h" - -char *grpc_get_well_known_google_credentials_file_path_impl(void) { - char *result = NULL; - char *appdata_path = gpr_getenv("APPDATA"); - if (appdata_path == NULL) { - gpr_log(GPR_ERROR, "Could not get APPDATA environment variable."); - return NULL; - } - gpr_asprintf(&result, "%s/%s/%s", appdata_path, - GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY, - GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE); - gpr_free(appdata_path); - return result; -} - -#endif /* GPR_WIN32 */ diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c deleted file mode 100644 index 3872e86993..0000000000 --- a/src/core/security/google_default_credentials.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * - * Copyright 2015-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/security/credentials.h" - -#include - -#include -#include -#include - -#include "src/core/http/httpcli.h" -#include "src/core/http/parser.h" -#include "src/core/support/env.h" -#include "src/core/support/load_file.h" -#include "src/core/surface/api_trace.h" - -/* -- Constants. -- */ - -#define GRPC_COMPUTE_ENGINE_DETECTION_HOST "metadata.google.internal" - -/* -- Default credentials. -- */ - -static grpc_channel_credentials *default_credentials = NULL; -static int compute_engine_detection_done = 0; -static gpr_mu g_state_mu; -static gpr_mu *g_polling_mu; -static gpr_once g_once = GPR_ONCE_INIT; - -static void init_default_credentials(void) { gpr_mu_init(&g_state_mu); } - -typedef struct { - grpc_pollset *pollset; - int is_done; - int success; -} compute_engine_detector; - -static void on_compute_engine_detection_http_response( - grpc_exec_ctx *exec_ctx, void *user_data, - const grpc_http_response *response) { - compute_engine_detector *detector = (compute_engine_detector *)user_data; - if (response != NULL && response->status == 200 && response->hdr_count > 0) { - /* Internet providers can return a generic response to all requests, so - it is necessary to check that metadata header is present also. */ - size_t i; - for (i = 0; i < response->hdr_count; i++) { - grpc_http_header *header = &response->hdrs[i]; - if (strcmp(header->key, "Metadata-Flavor") == 0 && - strcmp(header->value, "Google") == 0) { - detector->success = 1; - break; - } - } - } - gpr_mu_lock(g_polling_mu); - detector->is_done = 1; - grpc_pollset_kick(detector->pollset, NULL); - gpr_mu_unlock(g_polling_mu); -} - -static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool s) { - grpc_pollset_destroy(p); -} - -static int is_stack_running_on_compute_engine(void) { - compute_engine_detector detector; - grpc_httpcli_request request; - grpc_httpcli_context context; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_closure destroy_closure; - - /* The http call is local. If it takes more than one sec, it is for sure not - on compute engine. */ - gpr_timespec max_detection_delay = gpr_time_from_seconds(1, GPR_TIMESPAN); - - detector.pollset = gpr_malloc(grpc_pollset_size()); - grpc_pollset_init(detector.pollset, &g_polling_mu); - detector.is_done = 0; - detector.success = 0; - - memset(&request, 0, sizeof(grpc_httpcli_request)); - request.host = GRPC_COMPUTE_ENGINE_DETECTION_HOST; - request.http.path = "/"; - - grpc_httpcli_context_init(&context); - - grpc_httpcli_get( - &exec_ctx, &context, detector.pollset, &request, - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay), - on_compute_engine_detection_http_response, &detector); - - grpc_exec_ctx_finish(&exec_ctx); - - /* Block until we get the response. This is not ideal but this should only be - called once for the lifetime of the process by the default credentials. */ - gpr_mu_lock(g_polling_mu); - while (!detector.is_done) { - grpc_pollset_worker *worker = NULL; - grpc_pollset_work(&exec_ctx, detector.pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), - gpr_inf_future(GPR_CLOCK_MONOTONIC)); - } - gpr_mu_unlock(g_polling_mu); - - grpc_httpcli_context_destroy(&context); - grpc_closure_init(&destroy_closure, destroy_pollset, detector.pollset); - grpc_pollset_shutdown(&exec_ctx, detector.pollset, &destroy_closure); - grpc_exec_ctx_finish(&exec_ctx); - g_polling_mu = NULL; - - gpr_free(detector.pollset); - - return detector.success; -} - -/* Takes ownership of creds_path if not NULL. */ -static grpc_call_credentials *create_default_creds_from_path(char *creds_path) { - grpc_json *json = NULL; - grpc_auth_json_key key; - grpc_auth_refresh_token token; - grpc_call_credentials *result = NULL; - gpr_slice creds_data = gpr_empty_slice(); - int file_ok = 0; - if (creds_path == NULL) goto end; - creds_data = gpr_load_file(creds_path, 0, &file_ok); - if (!file_ok) goto end; - json = grpc_json_parse_string_with_len( - (char *)GPR_SLICE_START_PTR(creds_data), GPR_SLICE_LENGTH(creds_data)); - if (json == NULL) goto end; - - /* First, try an auth json key. */ - key = grpc_auth_json_key_create_from_json(json); - if (grpc_auth_json_key_is_valid(&key)) { - result = - grpc_service_account_jwt_access_credentials_create_from_auth_json_key( - key, grpc_max_auth_token_lifetime()); - goto end; - } - - /* Then try a refresh token if the auth json key was invalid. */ - token = grpc_auth_refresh_token_create_from_json(json); - if (grpc_auth_refresh_token_is_valid(&token)) { - result = - grpc_refresh_token_credentials_create_from_auth_refresh_token(token); - goto end; - } - -end: - if (creds_path != NULL) gpr_free(creds_path); - gpr_slice_unref(creds_data); - if (json != NULL) grpc_json_destroy(json); - return result; -} - -grpc_channel_credentials *grpc_google_default_credentials_create(void) { - grpc_channel_credentials *result = NULL; - grpc_call_credentials *call_creds = NULL; - - GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ()); - - gpr_once_init(&g_once, init_default_credentials); - - gpr_mu_lock(&g_state_mu); - - if (default_credentials != NULL) { - result = grpc_channel_credentials_ref(default_credentials); - goto end; - } - - /* First, try the environment variable. */ - call_creds = create_default_creds_from_path( - gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR)); - if (call_creds != NULL) goto end; - - /* Then the well-known file. */ - call_creds = create_default_creds_from_path( - grpc_get_well_known_google_credentials_file_path()); - if (call_creds != NULL) goto end; - - /* At last try to see if we're on compute engine (do the detection only once - since it requires a network test). */ - if (!compute_engine_detection_done) { - int need_compute_engine_creds = is_stack_running_on_compute_engine(); - compute_engine_detection_done = 1; - if (need_compute_engine_creds) { - call_creds = grpc_google_compute_engine_credentials_create(NULL); - } - } - -end: - if (result == NULL) { - if (call_creds != NULL) { - /* Blend with default ssl credentials and add a global reference so that - it - can be cached and re-served. */ - grpc_channel_credentials *ssl_creds = - grpc_ssl_credentials_create(NULL, NULL, NULL); - default_credentials = grpc_channel_credentials_ref( - grpc_composite_channel_credentials_create(ssl_creds, call_creds, - NULL)); - GPR_ASSERT(default_credentials != NULL); - grpc_channel_credentials_unref(ssl_creds); - grpc_call_credentials_unref(call_creds); - result = default_credentials; - } else { - gpr_log(GPR_ERROR, "Could not create google default credentials."); - } - } - gpr_mu_unlock(&g_state_mu); - return result; -} - -void grpc_flush_cached_google_default_credentials(void) { - gpr_once_init(&g_once, init_default_credentials); - gpr_mu_lock(&g_state_mu); - if (default_credentials != NULL) { - grpc_channel_credentials_unref(default_credentials); - default_credentials = NULL; - } - compute_engine_detection_done = 0; - gpr_mu_unlock(&g_state_mu); -} - -/* -- Well known credentials path. -- */ - -static grpc_well_known_credentials_path_getter creds_path_getter = NULL; - -char *grpc_get_well_known_google_credentials_file_path(void) { - if (creds_path_getter != NULL) return creds_path_getter(); - return grpc_get_well_known_google_credentials_file_path_impl(); -} - -void grpc_override_well_known_credentials_path_getter( - grpc_well_known_credentials_path_getter getter) { - creds_path_getter = getter; -} diff --git a/src/core/security/handshake.c b/src/core/security/handshake.c deleted file mode 100644 index 9fb10a0ecb..0000000000 --- a/src/core/security/handshake.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * - * Copyright 2015-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/security/handshake.h" - -#include -#include - -#include -#include -#include -#include "src/core/security/secure_endpoint.h" -#include "src/core/security/security_context.h" - -#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256 - -typedef struct { - grpc_security_connector *connector; - tsi_handshaker *handshaker; - bool is_client_side; - unsigned char *handshake_buffer; - size_t handshake_buffer_size; - grpc_endpoint *wrapped_endpoint; - grpc_endpoint *secure_endpoint; - gpr_slice_buffer left_overs; - gpr_slice_buffer incoming; - gpr_slice_buffer outgoing; - grpc_security_handshake_done_cb cb; - void *user_data; - grpc_closure on_handshake_data_sent_to_peer; - grpc_closure on_handshake_data_received_from_peer; - grpc_auth_context *auth_context; -} grpc_security_handshake; - -static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx, - void *setup, bool success); - -static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *setup, - bool success); - -static void security_connector_remove_handshake(grpc_security_handshake *h) { - GPR_ASSERT(!h->is_client_side); - grpc_security_connector_handshake_list *node; - grpc_security_connector_handshake_list *tmp; - grpc_server_security_connector *sc = - (grpc_server_security_connector *)h->connector; - gpr_mu_lock(&sc->mu); - node = sc->handshaking_handshakes; - if (node && node->handshake == h) { - sc->handshaking_handshakes = node->next; - gpr_free(node); - gpr_mu_unlock(&sc->mu); - return; - } - while (node) { - if (node->next->handshake == h) { - tmp = node->next; - node->next = node->next->next; - gpr_free(tmp); - gpr_mu_unlock(&sc->mu); - return; - } - node = node->next; - } - gpr_mu_unlock(&sc->mu); -} - -static void security_handshake_done(grpc_exec_ctx *exec_ctx, - grpc_security_handshake *h, - int is_success) { - if (!h->is_client_side) { - security_connector_remove_handshake(h); - } - if (is_success) { - h->cb(exec_ctx, h->user_data, GRPC_SECURITY_OK, h->secure_endpoint, - h->auth_context); - } else { - if (h->secure_endpoint != NULL) { - grpc_endpoint_shutdown(exec_ctx, h->secure_endpoint); - grpc_endpoint_destroy(exec_ctx, h->secure_endpoint); - } else { - grpc_endpoint_destroy(exec_ctx, h->wrapped_endpoint); - } - h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, NULL, NULL); - } - if (h->handshaker != NULL) tsi_handshaker_destroy(h->handshaker); - if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer); - gpr_slice_buffer_destroy(&h->left_overs); - gpr_slice_buffer_destroy(&h->outgoing); - gpr_slice_buffer_destroy(&h->incoming); - GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake"); - GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake"); - gpr_free(h); -} - -static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *user_data, - grpc_security_status status, - grpc_auth_context *auth_context) { - grpc_security_handshake *h = user_data; - tsi_frame_protector *protector; - tsi_result result; - if (status != GRPC_SECURITY_OK) { - gpr_log(GPR_ERROR, "Error checking peer."); - security_handshake_done(exec_ctx, h, 0); - return; - } - h->auth_context = GRPC_AUTH_CONTEXT_REF(auth_context, "handshake"); - result = - tsi_handshaker_create_frame_protector(h->handshaker, NULL, &protector); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Frame protector creation failed with error %s.", - tsi_result_to_string(result)); - security_handshake_done(exec_ctx, h, 0); - return; - } - h->secure_endpoint = - grpc_secure_endpoint_create(protector, h->wrapped_endpoint, - h->left_overs.slices, h->left_overs.count); - h->left_overs.count = 0; - h->left_overs.length = 0; - security_handshake_done(exec_ctx, h, 1); - return; -} - -static void check_peer(grpc_exec_ctx *exec_ctx, grpc_security_handshake *h) { - tsi_peer peer; - tsi_result result = tsi_handshaker_extract_peer(h->handshaker, &peer); - - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Peer extraction failed with error %s", - tsi_result_to_string(result)); - security_handshake_done(exec_ctx, h, 0); - return; - } - grpc_security_connector_check_peer(exec_ctx, h->connector, peer, - on_peer_checked, h); -} - -static void send_handshake_bytes_to_peer(grpc_exec_ctx *exec_ctx, - grpc_security_handshake *h) { - size_t offset = 0; - tsi_result result = TSI_OK; - gpr_slice to_send; - - do { - size_t to_send_size = h->handshake_buffer_size - offset; - result = tsi_handshaker_get_bytes_to_send_to_peer( - h->handshaker, h->handshake_buffer + offset, &to_send_size); - offset += to_send_size; - if (result == TSI_INCOMPLETE_DATA) { - h->handshake_buffer_size *= 2; - h->handshake_buffer = - gpr_realloc(h->handshake_buffer, h->handshake_buffer_size); - } - } while (result == TSI_INCOMPLETE_DATA); - - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshake failed with error %s", - tsi_result_to_string(result)); - security_handshake_done(exec_ctx, h, 0); - return; - } - - to_send = - gpr_slice_from_copied_buffer((const char *)h->handshake_buffer, offset); - gpr_slice_buffer_reset_and_unref(&h->outgoing); - gpr_slice_buffer_add(&h->outgoing, to_send); - /* TODO(klempner,jboeuf): This should probably use the client setup - deadline */ - grpc_endpoint_write(exec_ctx, h->wrapped_endpoint, &h->outgoing, - &h->on_handshake_data_sent_to_peer); -} - -static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx, - void *handshake, - bool success) { - grpc_security_handshake *h = handshake; - size_t consumed_slice_size = 0; - tsi_result result = TSI_OK; - size_t i; - size_t num_left_overs; - int has_left_overs_in_current_slice = 0; - - if (!success) { - gpr_log(GPR_ERROR, "Read failed."); - security_handshake_done(exec_ctx, h, 0); - return; - } - - for (i = 0; i < h->incoming.count; i++) { - consumed_slice_size = GPR_SLICE_LENGTH(h->incoming.slices[i]); - result = tsi_handshaker_process_bytes_from_peer( - h->handshaker, GPR_SLICE_START_PTR(h->incoming.slices[i]), - &consumed_slice_size); - if (!tsi_handshaker_is_in_progress(h->handshaker)) break; - } - - if (tsi_handshaker_is_in_progress(h->handshaker)) { - /* We may need more data. */ - if (result == TSI_INCOMPLETE_DATA) { - grpc_endpoint_read(exec_ctx, h->wrapped_endpoint, &h->incoming, - &h->on_handshake_data_received_from_peer); - return; - } else { - send_handshake_bytes_to_peer(exec_ctx, h); - return; - } - } - - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshake failed with error %s", - tsi_result_to_string(result)); - security_handshake_done(exec_ctx, h, 0); - return; - } - - /* Handshake is done and successful this point. */ - has_left_overs_in_current_slice = - (consumed_slice_size < GPR_SLICE_LENGTH(h->incoming.slices[i])); - num_left_overs = - (has_left_overs_in_current_slice ? 1 : 0) + h->incoming.count - i - 1; - if (num_left_overs == 0) { - check_peer(exec_ctx, h); - return; - } - - /* Put the leftovers in our buffer (ownership transfered). */ - if (has_left_overs_in_current_slice) { - gpr_slice_buffer_add( - &h->left_overs, - gpr_slice_split_tail(&h->incoming.slices[i], consumed_slice_size)); - gpr_slice_unref( - h->incoming.slices[i]); /* split_tail above increments refcount. */ - } - gpr_slice_buffer_addn( - &h->left_overs, &h->incoming.slices[i + 1], - num_left_overs - (size_t)has_left_overs_in_current_slice); - check_peer(exec_ctx, h); -} - -/* If handshake is NULL, the handshake is done. */ -static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, - void *handshake, bool success) { - grpc_security_handshake *h = handshake; - - /* Make sure that write is OK. */ - if (!success) { - gpr_log(GPR_ERROR, "Write failed."); - if (handshake != NULL) security_handshake_done(exec_ctx, h, 0); - return; - } - - /* We may be done. */ - if (tsi_handshaker_is_in_progress(h->handshaker)) { - /* TODO(klempner,jboeuf): This should probably use the client setup - deadline */ - grpc_endpoint_read(exec_ctx, h->wrapped_endpoint, &h->incoming, - &h->on_handshake_data_received_from_peer); - } else { - check_peer(exec_ctx, h); - } -} - -void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx, - tsi_handshaker *handshaker, - grpc_security_connector *connector, - bool is_client_side, - grpc_endpoint *nonsecure_endpoint, - grpc_security_handshake_done_cb cb, - void *user_data) { - grpc_security_connector_handshake_list *handshake_node; - grpc_security_handshake *h = gpr_malloc(sizeof(grpc_security_handshake)); - memset(h, 0, sizeof(grpc_security_handshake)); - h->handshaker = handshaker; - h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake"); - h->is_client_side = is_client_side; - h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE; - h->handshake_buffer = gpr_malloc(h->handshake_buffer_size); - h->wrapped_endpoint = nonsecure_endpoint; - h->user_data = user_data; - h->cb = cb; - grpc_closure_init(&h->on_handshake_data_sent_to_peer, - on_handshake_data_sent_to_peer, h); - grpc_closure_init(&h->on_handshake_data_received_from_peer, - on_handshake_data_received_from_peer, h); - gpr_slice_buffer_init(&h->left_overs); - gpr_slice_buffer_init(&h->outgoing); - gpr_slice_buffer_init(&h->incoming); - if (!is_client_side) { - grpc_server_security_connector *server_connector = - (grpc_server_security_connector *)connector; - handshake_node = gpr_malloc(sizeof(grpc_security_connector_handshake_list)); - handshake_node->handshake = h; - gpr_mu_lock(&server_connector->mu); - handshake_node->next = server_connector->handshaking_handshakes; - server_connector->handshaking_handshakes = handshake_node; - gpr_mu_unlock(&server_connector->mu); - } - send_handshake_bytes_to_peer(exec_ctx, h); -} - -void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, - void *handshake) { - grpc_security_handshake *h = handshake; - grpc_endpoint_shutdown(exec_ctx, h->wrapped_endpoint); -} diff --git a/src/core/security/handshake.h b/src/core/security/handshake.h deleted file mode 100644 index 4872045874..0000000000 --- a/src/core/security/handshake.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright 2015-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_SECURITY_HANDSHAKE_H -#define GRPC_CORE_SECURITY_HANDSHAKE_H - -#include "src/core/iomgr/endpoint.h" -#include "src/core/security/security_connector.h" - -/* Calls the callback upon completion. Takes owership of handshaker. */ -void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx, - tsi_handshaker *handshaker, - grpc_security_connector *connector, - bool is_client_side, - grpc_endpoint *nonsecure_endpoint, - grpc_security_handshake_done_cb cb, - void *user_data); - -void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake); - -#endif /* GRPC_CORE_SECURITY_HANDSHAKE_H */ diff --git a/src/core/security/json_token.c b/src/core/security/json_token.c deleted file mode 100644 index 372e5bfc5a..0000000000 --- a/src/core/security/json_token.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * - * Copyright 2015-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/security/json_token.h" - -#include - -#include -#include -#include - -#include "src/core/security/b64.h" -#include "src/core/support/string.h" - -#include -#include -#include - -/* --- Constants. --- */ - -/* 1 hour max. */ -gpr_timespec grpc_max_auth_token_lifetime() { - gpr_timespec out; - out.tv_sec = 3600; - out.tv_nsec = 0; - out.clock_type = GPR_TIMESPAN; - return out; -} - -#define GRPC_JWT_RSA_SHA256_ALGORITHM "RS256" -#define GRPC_JWT_TYPE "JWT" - -/* --- Override for testing. --- */ - -static grpc_jwt_encode_and_sign_override g_jwt_encode_and_sign_override = NULL; - -/* --- grpc_auth_json_key. --- */ - -static const char *json_get_string_property(const grpc_json *json, - const char *prop_name) { - grpc_json *child; - for (child = json->child; child != NULL; child = child->next) { - if (strcmp(child->key, prop_name) == 0) break; - } - if (child == NULL || child->type != GRPC_JSON_STRING) { - gpr_log(GPR_ERROR, "Invalid or missing %s property.", prop_name); - return NULL; - } - return child->value; -} - -static int set_json_key_string_property(const grpc_json *json, - const char *prop_name, - char **json_key_field) { - const char *prop_value = json_get_string_property(json, prop_name); - if (prop_value == NULL) return 0; - *json_key_field = gpr_strdup(prop_value); - return 1; -} - -int grpc_auth_json_key_is_valid(const grpc_auth_json_key *json_key) { - return (json_key != NULL) && - strcmp(json_key->type, GRPC_AUTH_JSON_TYPE_INVALID); -} - -grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json *json) { - grpc_auth_json_key result; - BIO *bio = NULL; - const char *prop_value; - int success = 0; - - memset(&result, 0, sizeof(grpc_auth_json_key)); - result.type = GRPC_AUTH_JSON_TYPE_INVALID; - if (json == NULL) { - gpr_log(GPR_ERROR, "Invalid json."); - goto end; - } - - prop_value = json_get_string_property(json, "type"); - if (prop_value == NULL || - strcmp(prop_value, GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT)) { - goto end; - } - result.type = GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT; - - if (!set_json_key_string_property(json, "private_key_id", - &result.private_key_id) || - !set_json_key_string_property(json, "client_id", &result.client_id) || - !set_json_key_string_property(json, "client_email", - &result.client_email)) { - goto end; - } - - prop_value = json_get_string_property(json, "private_key"); - if (prop_value == NULL) { - goto end; - } - bio = BIO_new(BIO_s_mem()); - success = BIO_puts(bio, prop_value); - if ((success < 0) || ((size_t)success != strlen(prop_value))) { - gpr_log(GPR_ERROR, "Could not write into openssl BIO."); - goto end; - } - result.private_key = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, ""); - if (result.private_key == NULL) { - gpr_log(GPR_ERROR, "Could not deserialize private key."); - goto end; - } - success = 1; - -end: - if (bio != NULL) BIO_free(bio); - if (!success) grpc_auth_json_key_destruct(&result); - return result; -} - -grpc_auth_json_key grpc_auth_json_key_create_from_string( - const char *json_string) { - char *scratchpad = gpr_strdup(json_string); - grpc_json *json = grpc_json_parse_string(scratchpad); - grpc_auth_json_key result = grpc_auth_json_key_create_from_json(json); - if (json != NULL) grpc_json_destroy(json); - gpr_free(scratchpad); - return result; -} - -void grpc_auth_json_key_destruct(grpc_auth_json_key *json_key) { - if (json_key == NULL) return; - json_key->type = GRPC_AUTH_JSON_TYPE_INVALID; - if (json_key->client_id != NULL) { - gpr_free(json_key->client_id); - json_key->client_id = NULL; - } - if (json_key->private_key_id != NULL) { - gpr_free(json_key->private_key_id); - json_key->private_key_id = NULL; - } - if (json_key->client_email != NULL) { - gpr_free(json_key->client_email); - json_key->client_email = NULL; - } - if (json_key->private_key != NULL) { - RSA_free(json_key->private_key); - json_key->private_key = NULL; - } -} - -/* --- jwt encoding and signature. --- */ - -static grpc_json *create_child(grpc_json *brother, grpc_json *parent, - const char *key, const char *value, - grpc_json_type type) { - grpc_json *child = grpc_json_create(type); - if (brother) brother->next = child; - if (!parent->child) parent->child = child; - child->parent = parent; - child->value = value; - child->key = key; - return child; -} - -static char *encoded_jwt_header(const char *key_id, const char *algorithm) { - grpc_json *json = grpc_json_create(GRPC_JSON_OBJECT); - grpc_json *child = NULL; - char *json_str = NULL; - char *result = NULL; - - child = create_child(NULL, json, "alg", algorithm, GRPC_JSON_STRING); - child = create_child(child, json, "typ", GRPC_JWT_TYPE, GRPC_JSON_STRING); - create_child(child, json, "kid", key_id, GRPC_JSON_STRING); - - json_str = grpc_json_dump_to_string(json, 0); - result = grpc_base64_encode(json_str, strlen(json_str), 1, 0); - gpr_free(json_str); - grpc_json_destroy(json); - return result; -} - -static char *encoded_jwt_claim(const grpc_auth_json_key *json_key, - const char *audience, - gpr_timespec token_lifetime, const char *scope) { - grpc_json *json = grpc_json_create(GRPC_JSON_OBJECT); - grpc_json *child = NULL; - char *json_str = NULL; - char *result = NULL; - gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); - gpr_timespec expiration = gpr_time_add(now, token_lifetime); - char now_str[GPR_LTOA_MIN_BUFSIZE]; - char expiration_str[GPR_LTOA_MIN_BUFSIZE]; - if (gpr_time_cmp(token_lifetime, grpc_max_auth_token_lifetime()) > 0) { - gpr_log(GPR_INFO, "Cropping token lifetime to maximum allowed value."); - expiration = gpr_time_add(now, grpc_max_auth_token_lifetime()); - } - int64_ttoa(now.tv_sec, now_str); - int64_ttoa(expiration.tv_sec, expiration_str); - - child = - create_child(NULL, json, "iss", json_key->client_email, GRPC_JSON_STRING); - if (scope != NULL) { - child = create_child(child, json, "scope", scope, GRPC_JSON_STRING); - } else { - /* Unscoped JWTs need a sub field. */ - child = create_child(child, json, "sub", json_key->client_email, - GRPC_JSON_STRING); - } - - child = create_child(child, json, "aud", audience, GRPC_JSON_STRING); - child = create_child(child, json, "iat", now_str, GRPC_JSON_NUMBER); - create_child(child, json, "exp", expiration_str, GRPC_JSON_NUMBER); - - json_str = grpc_json_dump_to_string(json, 0); - result = grpc_base64_encode(json_str, strlen(json_str), 1, 0); - gpr_free(json_str); - grpc_json_destroy(json); - return result; -} - -static char *dot_concat_and_free_strings(char *str1, char *str2) { - size_t str1_len = strlen(str1); - size_t str2_len = strlen(str2); - size_t result_len = str1_len + 1 /* dot */ + str2_len; - char *result = gpr_malloc(result_len + 1 /* NULL terminated */); - char *current = result; - memcpy(current, str1, str1_len); - current += str1_len; - *(current++) = '.'; - memcpy(current, str2, str2_len); - current += str2_len; - GPR_ASSERT(current >= result); - GPR_ASSERT((uintptr_t)(current - result) == result_len); - *current = '\0'; - gpr_free(str1); - gpr_free(str2); - return result; -} - -const EVP_MD *openssl_digest_from_algorithm(const char *algorithm) { - if (strcmp(algorithm, GRPC_JWT_RSA_SHA256_ALGORITHM) == 0) { - return EVP_sha256(); - } else { - gpr_log(GPR_ERROR, "Unknown algorithm %s.", algorithm); - return NULL; - } -} - -char *compute_and_encode_signature(const grpc_auth_json_key *json_key, - const char *signature_algorithm, - const char *to_sign) { - const EVP_MD *md = openssl_digest_from_algorithm(signature_algorithm); - EVP_MD_CTX *md_ctx = NULL; - EVP_PKEY *key = EVP_PKEY_new(); - size_t sig_len = 0; - unsigned char *sig = NULL; - char *result = NULL; - if (md == NULL) return NULL; - md_ctx = EVP_MD_CTX_create(); - if (md_ctx == NULL) { - gpr_log(GPR_ERROR, "Could not create MD_CTX"); - goto end; - } - EVP_PKEY_set1_RSA(key, json_key->private_key); - if (EVP_DigestSignInit(md_ctx, NULL, md, NULL, key) != 1) { - gpr_log(GPR_ERROR, "DigestInit failed."); - goto end; - } - if (EVP_DigestSignUpdate(md_ctx, to_sign, strlen(to_sign)) != 1) { - gpr_log(GPR_ERROR, "DigestUpdate failed."); - goto end; - } - if (EVP_DigestSignFinal(md_ctx, NULL, &sig_len) != 1) { - gpr_log(GPR_ERROR, "DigestFinal (get signature length) failed."); - goto end; - } - sig = gpr_malloc(sig_len); - if (EVP_DigestSignFinal(md_ctx, sig, &sig_len) != 1) { - gpr_log(GPR_ERROR, "DigestFinal (signature compute) failed."); - goto end; - } - result = grpc_base64_encode(sig, sig_len, 1, 0); - -end: - if (key != NULL) EVP_PKEY_free(key); - if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx); - if (sig != NULL) gpr_free(sig); - return result; -} - -char *grpc_jwt_encode_and_sign(const grpc_auth_json_key *json_key, - const char *audience, - gpr_timespec token_lifetime, const char *scope) { - if (g_jwt_encode_and_sign_override != NULL) { - return g_jwt_encode_and_sign_override(json_key, audience, token_lifetime, - scope); - } else { - const char *sig_algo = GRPC_JWT_RSA_SHA256_ALGORITHM; - char *to_sign = dot_concat_and_free_strings( - encoded_jwt_header(json_key->private_key_id, sig_algo), - encoded_jwt_claim(json_key, audience, token_lifetime, scope)); - char *sig = compute_and_encode_signature(json_key, sig_algo, to_sign); - if (sig == NULL) { - gpr_free(to_sign); - return NULL; - } - return dot_concat_and_free_strings(to_sign, sig); - } -} - -void grpc_jwt_encode_and_sign_set_override( - grpc_jwt_encode_and_sign_override func) { - g_jwt_encode_and_sign_override = func; -} - -/* --- grpc_auth_refresh_token --- */ - -int grpc_auth_refresh_token_is_valid( - const grpc_auth_refresh_token *refresh_token) { - return (refresh_token != NULL) && - strcmp(refresh_token->type, GRPC_AUTH_JSON_TYPE_INVALID); -} - -grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json( - const grpc_json *json) { - grpc_auth_refresh_token result; - const char *prop_value; - int success = 0; - - memset(&result, 0, sizeof(grpc_auth_refresh_token)); - result.type = GRPC_AUTH_JSON_TYPE_INVALID; - if (json == NULL) { - gpr_log(GPR_ERROR, "Invalid json."); - goto end; - } - - prop_value = json_get_string_property(json, "type"); - if (prop_value == NULL || - strcmp(prop_value, GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER)) { - goto end; - } - result.type = GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER; - - if (!set_json_key_string_property(json, "client_secret", - &result.client_secret) || - !set_json_key_string_property(json, "client_id", &result.client_id) || - !set_json_key_string_property(json, "refresh_token", - &result.refresh_token)) { - goto end; - } - success = 1; - -end: - if (!success) grpc_auth_refresh_token_destruct(&result); - return result; -} - -grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string( - const char *json_string) { - char *scratchpad = gpr_strdup(json_string); - grpc_json *json = grpc_json_parse_string(scratchpad); - grpc_auth_refresh_token result = - grpc_auth_refresh_token_create_from_json(json); - if (json != NULL) grpc_json_destroy(json); - gpr_free(scratchpad); - return result; -} - -void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token) { - if (refresh_token == NULL) return; - refresh_token->type = GRPC_AUTH_JSON_TYPE_INVALID; - if (refresh_token->client_id != NULL) { - gpr_free(refresh_token->client_id); - refresh_token->client_id = NULL; - } - if (refresh_token->client_secret != NULL) { - gpr_free(refresh_token->client_secret); - refresh_token->client_secret = NULL; - } - if (refresh_token->refresh_token != NULL) { - gpr_free(refresh_token->refresh_token); - refresh_token->refresh_token = NULL; - } -} diff --git a/src/core/security/json_token.h b/src/core/security/json_token.h deleted file mode 100644 index d183f9b3a3..0000000000 --- a/src/core/security/json_token.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * - * Copyright 2015-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_SECURITY_JSON_TOKEN_H -#define GRPC_CORE_SECURITY_JSON_TOKEN_H - -#include -#include - -#include "src/core/json/json.h" - -/* --- Constants. --- */ - -#define GRPC_JWT_OAUTH2_AUDIENCE "https://www.googleapis.com/oauth2/v3/token" - -#define GRPC_AUTH_JSON_TYPE_INVALID "invalid" -#define GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT "service_account" -#define GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER "authorized_user" - -/* --- auth_json_key parsing. --- */ - -typedef struct { - const char *type; - char *private_key_id; - char *client_id; - char *client_email; - RSA *private_key; -} grpc_auth_json_key; - -/* Returns 1 if the object is valid, 0 otherwise. */ -int grpc_auth_json_key_is_valid(const grpc_auth_json_key *json_key); - -/* Creates a json_key object from string. Returns an invalid object if a parsing - error has been encountered. */ -grpc_auth_json_key grpc_auth_json_key_create_from_string( - const char *json_string); - -/* Creates a json_key object from parsed json. Returns an invalid object if a - parsing error has been encountered. */ -grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json *json); - -/* Destructs the object. */ -void grpc_auth_json_key_destruct(grpc_auth_json_key *json_key); - -/* --- json token encoding and signing. --- */ - -/* Caller is responsible for calling gpr_free on the returned value. May return - NULL on invalid input. The scope parameter may be NULL. */ -char *grpc_jwt_encode_and_sign(const grpc_auth_json_key *json_key, - const char *audience, - gpr_timespec token_lifetime, const char *scope); - -/* Override encode_and_sign function for testing. */ -typedef char *(*grpc_jwt_encode_and_sign_override)( - const grpc_auth_json_key *json_key, const char *audience, - gpr_timespec token_lifetime, const char *scope); - -/* Set a custom encode_and_sign override for testing. */ -void grpc_jwt_encode_and_sign_set_override( - grpc_jwt_encode_and_sign_override func); - -/* --- auth_refresh_token parsing. --- */ - -typedef struct { - const char *type; - char *client_id; - char *client_secret; - char *refresh_token; -} grpc_auth_refresh_token; - -/* Returns 1 if the object is valid, 0 otherwise. */ -int grpc_auth_refresh_token_is_valid( - const grpc_auth_refresh_token *refresh_token); - -/* Creates a refresh token object from string. Returns an invalid object if a - parsing error has been encountered. */ -grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string( - const char *json_string); - -/* Creates a refresh token object from parsed json. Returns an invalid object if - a parsing error has been encountered. */ -grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json( - const grpc_json *json); - -/* Destructs the object. */ -void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token); - -#endif /* GRPC_CORE_SECURITY_JSON_TOKEN_H */ diff --git a/src/core/security/jwt_verifier.c b/src/core/security/jwt_verifier.c deleted file mode 100644 index 0bb8e05306..0000000000 --- a/src/core/security/jwt_verifier.c +++ /dev/null @@ -1,843 +0,0 @@ -/* - * - * Copyright 2015-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/security/jwt_verifier.h" - -#include -#include - -#include "src/core/http/httpcli.h" -#include "src/core/security/b64.h" -#include "src/core/tsi/ssl_types.h" - -#include -#include -#include -#include -#include - -/* --- Utils. --- */ - -const char *grpc_jwt_verifier_status_to_string( - grpc_jwt_verifier_status status) { - switch (status) { - case GRPC_JWT_VERIFIER_OK: - return "OK"; - case GRPC_JWT_VERIFIER_BAD_SIGNATURE: - return "BAD_SIGNATURE"; - case GRPC_JWT_VERIFIER_BAD_FORMAT: - return "BAD_FORMAT"; - case GRPC_JWT_VERIFIER_BAD_AUDIENCE: - return "BAD_AUDIENCE"; - case GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR: - return "KEY_RETRIEVAL_ERROR"; - case GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE: - return "TIME_CONSTRAINT_FAILURE"; - case GRPC_JWT_VERIFIER_GENERIC_ERROR: - return "GENERIC_ERROR"; - default: - return "UNKNOWN"; - } -} - -static const EVP_MD *evp_md_from_alg(const char *alg) { - if (strcmp(alg, "RS256") == 0) { - return EVP_sha256(); - } else if (strcmp(alg, "RS384") == 0) { - return EVP_sha384(); - } else if (strcmp(alg, "RS512") == 0) { - return EVP_sha512(); - } else { - return NULL; - } -} - -static grpc_json *parse_json_part_from_jwt(const char *str, size_t len, - gpr_slice *buffer) { - grpc_json *json; - - *buffer = grpc_base64_decode_with_len(str, len, 1); - if (GPR_SLICE_IS_EMPTY(*buffer)) { - gpr_log(GPR_ERROR, "Invalid base64."); - return NULL; - } - json = grpc_json_parse_string_with_len((char *)GPR_SLICE_START_PTR(*buffer), - GPR_SLICE_LENGTH(*buffer)); - if (json == NULL) { - gpr_slice_unref(*buffer); - gpr_log(GPR_ERROR, "JSON parsing error."); - } - return json; -} - -static const char *validate_string_field(const grpc_json *json, - const char *key) { - if (json->type != GRPC_JSON_STRING) { - gpr_log(GPR_ERROR, "Invalid %s field [%s]", key, json->value); - return NULL; - } - return json->value; -} - -static gpr_timespec validate_time_field(const grpc_json *json, - const char *key) { - gpr_timespec result = gpr_time_0(GPR_CLOCK_REALTIME); - if (json->type != GRPC_JSON_NUMBER) { - gpr_log(GPR_ERROR, "Invalid %s field [%s]", key, json->value); - return result; - } - result.tv_sec = strtol(json->value, NULL, 10); - return result; -} - -/* --- JOSE header. see http://tools.ietf.org/html/rfc7515#section-4 --- */ - -typedef struct { - const char *alg; - const char *kid; - const char *typ; - /* TODO(jboeuf): Add others as needed (jku, jwk, x5u, x5c and so on...). */ - gpr_slice buffer; -} jose_header; - -static void jose_header_destroy(jose_header *h) { - gpr_slice_unref(h->buffer); - gpr_free(h); -} - -/* Takes ownership of json and buffer. */ -static jose_header *jose_header_from_json(grpc_json *json, gpr_slice buffer) { - grpc_json *cur; - jose_header *h = gpr_malloc(sizeof(jose_header)); - memset(h, 0, sizeof(jose_header)); - h->buffer = buffer; - for (cur = json->child; cur != NULL; cur = cur->next) { - if (strcmp(cur->key, "alg") == 0) { - /* We only support RSA-1.5 signatures for now. - Beware of this if we add HMAC support: - https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/ - */ - if (cur->type != GRPC_JSON_STRING || strncmp(cur->value, "RS", 2) || - evp_md_from_alg(cur->value) == NULL) { - gpr_log(GPR_ERROR, "Invalid alg field [%s]", cur->value); - goto error; - } - h->alg = cur->value; - } else if (strcmp(cur->key, "typ") == 0) { - h->typ = validate_string_field(cur, "typ"); - if (h->typ == NULL) goto error; - } else if (strcmp(cur->key, "kid") == 0) { - h->kid = validate_string_field(cur, "kid"); - if (h->kid == NULL) goto error; - } - } - if (h->alg == NULL) { - gpr_log(GPR_ERROR, "Missing alg field."); - goto error; - } - grpc_json_destroy(json); - h->buffer = buffer; - return h; - -error: - grpc_json_destroy(json); - jose_header_destroy(h); - return NULL; -} - -/* --- JWT claims. see http://tools.ietf.org/html/rfc7519#section-4.1 */ - -struct grpc_jwt_claims { - /* Well known properties already parsed. */ - const char *sub; - const char *iss; - const char *aud; - const char *jti; - gpr_timespec iat; - gpr_timespec exp; - gpr_timespec nbf; - - grpc_json *json; - gpr_slice buffer; -}; - -void grpc_jwt_claims_destroy(grpc_jwt_claims *claims) { - grpc_json_destroy(claims->json); - gpr_slice_unref(claims->buffer); - gpr_free(claims); -} - -const grpc_json *grpc_jwt_claims_json(const grpc_jwt_claims *claims) { - if (claims == NULL) return NULL; - return claims->json; -} - -const char *grpc_jwt_claims_subject(const grpc_jwt_claims *claims) { - if (claims == NULL) return NULL; - return claims->sub; -} - -const char *grpc_jwt_claims_issuer(const grpc_jwt_claims *claims) { - if (claims == NULL) return NULL; - return claims->iss; -} - -const char *grpc_jwt_claims_id(const grpc_jwt_claims *claims) { - if (claims == NULL) return NULL; - return claims->jti; -} - -const char *grpc_jwt_claims_audience(const grpc_jwt_claims *claims) { - if (claims == NULL) return NULL; - return claims->aud; -} - -gpr_timespec grpc_jwt_claims_issued_at(const grpc_jwt_claims *claims) { - if (claims == NULL) return gpr_inf_past(GPR_CLOCK_REALTIME); - return claims->iat; -} - -gpr_timespec grpc_jwt_claims_expires_at(const grpc_jwt_claims *claims) { - if (claims == NULL) return gpr_inf_future(GPR_CLOCK_REALTIME); - return claims->exp; -} - -gpr_timespec grpc_jwt_claims_not_before(const grpc_jwt_claims *claims) { - if (claims == NULL) return gpr_inf_past(GPR_CLOCK_REALTIME); - return claims->nbf; -} - -/* Takes ownership of json and buffer even in case of failure. */ -grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, gpr_slice buffer) { - grpc_json *cur; - grpc_jwt_claims *claims = gpr_malloc(sizeof(grpc_jwt_claims)); - memset(claims, 0, sizeof(grpc_jwt_claims)); - claims->json = json; - claims->buffer = buffer; - claims->iat = gpr_inf_past(GPR_CLOCK_REALTIME); - claims->nbf = gpr_inf_past(GPR_CLOCK_REALTIME); - claims->exp = gpr_inf_future(GPR_CLOCK_REALTIME); - - /* Per the spec, all fields are optional. */ - for (cur = json->child; cur != NULL; cur = cur->next) { - if (strcmp(cur->key, "sub") == 0) { - claims->sub = validate_string_field(cur, "sub"); - if (claims->sub == NULL) goto error; - } else if (strcmp(cur->key, "iss") == 0) { - claims->iss = validate_string_field(cur, "iss"); - if (claims->iss == NULL) goto error; - } else if (strcmp(cur->key, "aud") == 0) { - claims->aud = validate_string_field(cur, "aud"); - if (claims->aud == NULL) goto error; - } else if (strcmp(cur->key, "jti") == 0) { - claims->jti = validate_string_field(cur, "jti"); - if (claims->jti == NULL) goto error; - } else if (strcmp(cur->key, "iat") == 0) { - claims->iat = validate_time_field(cur, "iat"); - if (gpr_time_cmp(claims->iat, gpr_time_0(GPR_CLOCK_REALTIME)) == 0) - goto error; - } else if (strcmp(cur->key, "exp") == 0) { - claims->exp = validate_time_field(cur, "exp"); - if (gpr_time_cmp(claims->exp, gpr_time_0(GPR_CLOCK_REALTIME)) == 0) - goto error; - } else if (strcmp(cur->key, "nbf") == 0) { - claims->nbf = validate_time_field(cur, "nbf"); - if (gpr_time_cmp(claims->nbf, gpr_time_0(GPR_CLOCK_REALTIME)) == 0) - goto error; - } - } - return claims; - -error: - grpc_jwt_claims_destroy(claims); - return NULL; -} - -grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims, - const char *audience) { - gpr_timespec skewed_now; - int audience_ok; - - GPR_ASSERT(claims != NULL); - - skewed_now = - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_clock_skew); - if (gpr_time_cmp(skewed_now, claims->nbf) < 0) { - gpr_log(GPR_ERROR, "JWT is not valid yet."); - return GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE; - } - skewed_now = - gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_clock_skew); - if (gpr_time_cmp(skewed_now, claims->exp) > 0) { - gpr_log(GPR_ERROR, "JWT is expired."); - return GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE; - } - - if (audience == NULL) { - audience_ok = claims->aud == NULL; - } else { - audience_ok = claims->aud != NULL && strcmp(audience, claims->aud) == 0; - } - if (!audience_ok) { - gpr_log(GPR_ERROR, "Audience mismatch: expected %s and found %s.", - audience == NULL ? "NULL" : audience, - claims->aud == NULL ? "NULL" : claims->aud); - return GRPC_JWT_VERIFIER_BAD_AUDIENCE; - } - return GRPC_JWT_VERIFIER_OK; -} - -/* --- verifier_cb_ctx object. --- */ - -typedef struct { - grpc_jwt_verifier *verifier; - grpc_pollset *pollset; - jose_header *header; - grpc_jwt_claims *claims; - char *audience; - gpr_slice signature; - gpr_slice signed_data; - void *user_data; - grpc_jwt_verification_done_cb user_cb; -} verifier_cb_ctx; - -/* Takes ownership of the header, claims and signature. */ -static verifier_cb_ctx *verifier_cb_ctx_create( - grpc_jwt_verifier *verifier, grpc_pollset *pollset, jose_header *header, - grpc_jwt_claims *claims, const char *audience, gpr_slice signature, - const char *signed_jwt, size_t signed_jwt_len, void *user_data, - grpc_jwt_verification_done_cb cb) { - verifier_cb_ctx *ctx = gpr_malloc(sizeof(verifier_cb_ctx)); - memset(ctx, 0, sizeof(verifier_cb_ctx)); - ctx->verifier = verifier; - ctx->pollset = pollset; - ctx->header = header; - ctx->audience = gpr_strdup(audience); - ctx->claims = claims; - ctx->signature = signature; - ctx->signed_data = gpr_slice_from_copied_buffer(signed_jwt, signed_jwt_len); - ctx->user_data = user_data; - ctx->user_cb = cb; - return ctx; -} - -void verifier_cb_ctx_destroy(verifier_cb_ctx *ctx) { - if (ctx->audience != NULL) gpr_free(ctx->audience); - if (ctx->claims != NULL) grpc_jwt_claims_destroy(ctx->claims); - gpr_slice_unref(ctx->signature); - gpr_slice_unref(ctx->signed_data); - jose_header_destroy(ctx->header); - /* TODO: see what to do with claims... */ - gpr_free(ctx); -} - -/* --- grpc_jwt_verifier object. --- */ - -/* Clock skew defaults to one minute. */ -gpr_timespec grpc_jwt_verifier_clock_skew = {60, 0, GPR_TIMESPAN}; - -/* Max delay defaults to one minute. */ -gpr_timespec grpc_jwt_verifier_max_delay = {60, 0, GPR_TIMESPAN}; - -typedef struct { - char *email_domain; - char *key_url_prefix; -} email_key_mapping; - -struct grpc_jwt_verifier { - email_key_mapping *mappings; - size_t num_mappings; /* Should be very few, linear search ok. */ - size_t allocated_mappings; - grpc_httpcli_context http_ctx; -}; - -static grpc_json *json_from_http(const grpc_httpcli_response *response) { - grpc_json *json = NULL; - - if (response == NULL) { - gpr_log(GPR_ERROR, "HTTP response is NULL."); - return NULL; - } - if (response->status != 200) { - gpr_log(GPR_ERROR, "Call to http server failed with error %d.", - response->status); - return NULL; - } - - json = grpc_json_parse_string_with_len(response->body, response->body_length); - if (json == NULL) { - gpr_log(GPR_ERROR, "Invalid JSON found in response."); - } - return json; -} - -static const grpc_json *find_property_by_name(const grpc_json *json, - const char *name) { - const grpc_json *cur; - for (cur = json->child; cur != NULL; cur = cur->next) { - if (strcmp(cur->key, name) == 0) return cur; - } - return NULL; -} - -static EVP_PKEY *extract_pkey_from_x509(const char *x509_str) { - X509 *x509 = NULL; - EVP_PKEY *result = NULL; - BIO *bio = BIO_new(BIO_s_mem()); - size_t len = strlen(x509_str); - GPR_ASSERT(len < INT_MAX); - BIO_write(bio, x509_str, (int)len); - x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); - if (x509 == NULL) { - gpr_log(GPR_ERROR, "Unable to parse x509 cert."); - goto end; - } - result = X509_get_pubkey(x509); - if (result == NULL) { - gpr_log(GPR_ERROR, "Cannot find public key in X509 cert."); - } - -end: - BIO_free(bio); - if (x509 != NULL) X509_free(x509); - return result; -} - -static BIGNUM *bignum_from_base64(const char *b64) { - BIGNUM *result = NULL; - gpr_slice bin; - - if (b64 == NULL) return NULL; - bin = grpc_base64_decode(b64, 1); - if (GPR_SLICE_IS_EMPTY(bin)) { - gpr_log(GPR_ERROR, "Invalid base64 for big num."); - return NULL; - } - result = BN_bin2bn(GPR_SLICE_START_PTR(bin), - TSI_SIZE_AS_SIZE(GPR_SLICE_LENGTH(bin)), NULL); - gpr_slice_unref(bin); - return result; -} - -static EVP_PKEY *pkey_from_jwk(const grpc_json *json, const char *kty) { - const grpc_json *key_prop; - RSA *rsa = NULL; - EVP_PKEY *result = NULL; - - GPR_ASSERT(kty != NULL && json != NULL); - if (strcmp(kty, "RSA") != 0) { - gpr_log(GPR_ERROR, "Unsupported key type %s.", kty); - goto end; - } - rsa = RSA_new(); - if (rsa == NULL) { - gpr_log(GPR_ERROR, "Could not create rsa key."); - goto end; - } - for (key_prop = json->child; key_prop != NULL; key_prop = key_prop->next) { - if (strcmp(key_prop->key, "n") == 0) { - rsa->n = bignum_from_base64(validate_string_field(key_prop, "n")); - if (rsa->n == NULL) goto end; - } else if (strcmp(key_prop->key, "e") == 0) { - rsa->e = bignum_from_base64(validate_string_field(key_prop, "e")); - if (rsa->e == NULL) goto end; - } - } - if (rsa->e == NULL || rsa->n == NULL) { - gpr_log(GPR_ERROR, "Missing RSA public key field."); - goto end; - } - result = EVP_PKEY_new(); - EVP_PKEY_set1_RSA(result, rsa); /* uprefs rsa. */ - -end: - if (rsa != NULL) RSA_free(rsa); - return result; -} - -static EVP_PKEY *find_verification_key(const grpc_json *json, - const char *header_alg, - const char *header_kid) { - const grpc_json *jkey; - const grpc_json *jwk_keys; - /* Try to parse the json as a JWK set: - https://tools.ietf.org/html/rfc7517#section-5. */ - jwk_keys = find_property_by_name(json, "keys"); - if (jwk_keys == NULL) { - /* Use the google proprietary format which is: - { : , : , ... } */ - const grpc_json *cur = find_property_by_name(json, header_kid); - if (cur == NULL) return NULL; - return extract_pkey_from_x509(cur->value); - } - - if (jwk_keys->type != GRPC_JSON_ARRAY) { - gpr_log(GPR_ERROR, - "Unexpected value type of keys property in jwks key set."); - return NULL; - } - /* Key format is specified in: - https://tools.ietf.org/html/rfc7518#section-6. */ - for (jkey = jwk_keys->child; jkey != NULL; jkey = jkey->next) { - grpc_json *key_prop; - const char *alg = NULL; - const char *kid = NULL; - const char *kty = NULL; - - if (jkey->type != GRPC_JSON_OBJECT) continue; - for (key_prop = jkey->child; key_prop != NULL; key_prop = key_prop->next) { - if (strcmp(key_prop->key, "alg") == 0 && - key_prop->type == GRPC_JSON_STRING) { - alg = key_prop->value; - } else if (strcmp(key_prop->key, "kid") == 0 && - key_prop->type == GRPC_JSON_STRING) { - kid = key_prop->value; - } else if (strcmp(key_prop->key, "kty") == 0 && - key_prop->type == GRPC_JSON_STRING) { - kty = key_prop->value; - } - } - if (alg != NULL && kid != NULL && kty != NULL && - strcmp(kid, header_kid) == 0 && strcmp(alg, header_alg) == 0) { - return pkey_from_jwk(jkey, kty); - } - } - gpr_log(GPR_ERROR, - "Could not find matching key in key set for kid=%s and alg=%s", - header_kid, header_alg); - return NULL; -} - -static int verify_jwt_signature(EVP_PKEY *key, const char *alg, - gpr_slice signature, gpr_slice signed_data) { - EVP_MD_CTX *md_ctx = EVP_MD_CTX_create(); - const EVP_MD *md = evp_md_from_alg(alg); - int result = 0; - - GPR_ASSERT(md != NULL); /* Checked before. */ - if (md_ctx == NULL) { - gpr_log(GPR_ERROR, "Could not create EVP_MD_CTX."); - goto end; - } - if (EVP_DigestVerifyInit(md_ctx, NULL, md, NULL, key) != 1) { - gpr_log(GPR_ERROR, "EVP_DigestVerifyInit failed."); - goto end; - } - if (EVP_DigestVerifyUpdate(md_ctx, GPR_SLICE_START_PTR(signed_data), - GPR_SLICE_LENGTH(signed_data)) != 1) { - gpr_log(GPR_ERROR, "EVP_DigestVerifyUpdate failed."); - goto end; - } - if (EVP_DigestVerifyFinal(md_ctx, GPR_SLICE_START_PTR(signature), - GPR_SLICE_LENGTH(signature)) != 1) { - gpr_log(GPR_ERROR, "JWT signature verification failed."); - goto end; - } - result = 1; - -end: - if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx); - return result; -} - -static void on_keys_retrieved(grpc_exec_ctx *exec_ctx, void *user_data, - const grpc_httpcli_response *response) { - grpc_json *json = json_from_http(response); - verifier_cb_ctx *ctx = (verifier_cb_ctx *)user_data; - EVP_PKEY *verification_key = NULL; - grpc_jwt_verifier_status status = GRPC_JWT_VERIFIER_GENERIC_ERROR; - grpc_jwt_claims *claims = NULL; - - if (json == NULL) { - status = GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR; - goto end; - } - verification_key = - find_verification_key(json, ctx->header->alg, ctx->header->kid); - if (verification_key == NULL) { - gpr_log(GPR_ERROR, "Could not find verification key with kid %s.", - ctx->header->kid); - status = GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR; - goto end; - } - - if (!verify_jwt_signature(verification_key, ctx->header->alg, ctx->signature, - ctx->signed_data)) { - status = GRPC_JWT_VERIFIER_BAD_SIGNATURE; - goto end; - } - - status = grpc_jwt_claims_check(ctx->claims, ctx->audience); - if (status == GRPC_JWT_VERIFIER_OK) { - /* Pass ownership. */ - claims = ctx->claims; - ctx->claims = NULL; - } - -end: - if (json != NULL) grpc_json_destroy(json); - if (verification_key != NULL) EVP_PKEY_free(verification_key); - ctx->user_cb(ctx->user_data, status, claims); - verifier_cb_ctx_destroy(ctx); -} - -static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data, - const grpc_httpcli_response *response) { - const grpc_json *cur; - grpc_json *json = json_from_http(response); - verifier_cb_ctx *ctx = (verifier_cb_ctx *)user_data; - grpc_httpcli_request req; - const char *jwks_uri; - - /* TODO(jboeuf): Cache the jwks_uri in order to avoid this hop next time. */ - if (json == NULL) goto error; - cur = find_property_by_name(json, "jwks_uri"); - if (cur == NULL) { - gpr_log(GPR_ERROR, "Could not find jwks_uri in openid config."); - goto error; - } - jwks_uri = validate_string_field(cur, "jwks_uri"); - if (jwks_uri == NULL) goto error; - if (strstr(jwks_uri, "https://") != jwks_uri) { - gpr_log(GPR_ERROR, "Invalid non https jwks_uri: %s.", jwks_uri); - goto error; - } - jwks_uri += 8; - req.handshaker = &grpc_httpcli_ssl; - req.host = gpr_strdup(jwks_uri); - req.http.path = strchr(jwks_uri, '/'); - if (req.http.path == NULL) { - req.http.path = ""; - } else { - *(req.host + (req.http.path - jwks_uri)) = '\0'; - } - grpc_httpcli_get( - exec_ctx, &ctx->verifier->http_ctx, ctx->pollset, &req, - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay), - on_keys_retrieved, ctx); - grpc_json_destroy(json); - gpr_free(req.host); - return; - -error: - if (json != NULL) grpc_json_destroy(json); - ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL); - verifier_cb_ctx_destroy(ctx); -} - -static email_key_mapping *verifier_get_mapping(grpc_jwt_verifier *v, - const char *email_domain) { - size_t i; - if (v->mappings == NULL) return NULL; - for (i = 0; i < v->num_mappings; i++) { - if (strcmp(email_domain, v->mappings[i].email_domain) == 0) { - return &v->mappings[i]; - } - } - return NULL; -} - -static void verifier_put_mapping(grpc_jwt_verifier *v, const char *email_domain, - const char *key_url_prefix) { - email_key_mapping *mapping = verifier_get_mapping(v, email_domain); - GPR_ASSERT(v->num_mappings < v->allocated_mappings); - if (mapping != NULL) { - gpr_free(mapping->key_url_prefix); - mapping->key_url_prefix = gpr_strdup(key_url_prefix); - return; - } - v->mappings[v->num_mappings].email_domain = gpr_strdup(email_domain); - v->mappings[v->num_mappings].key_url_prefix = gpr_strdup(key_url_prefix); - v->num_mappings++; - GPR_ASSERT(v->num_mappings <= v->allocated_mappings); -} - -/* Takes ownership of ctx. */ -static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx, - verifier_cb_ctx *ctx) { - const char *at_sign; - grpc_httpcli_response_cb http_cb; - char *path_prefix = NULL; - const char *iss; - grpc_httpcli_request req; - memset(&req, 0, sizeof(grpc_httpcli_request)); - req.handshaker = &grpc_httpcli_ssl; - - GPR_ASSERT(ctx != NULL && ctx->header != NULL && ctx->claims != NULL); - iss = ctx->claims->iss; - if (ctx->header->kid == NULL) { - gpr_log(GPR_ERROR, "Missing kid in jose header."); - goto error; - } - if (iss == NULL) { - gpr_log(GPR_ERROR, "Missing iss in claims."); - goto error; - } - - /* This code relies on: - https://openid.net/specs/openid-connect-discovery-1_0.html - Nobody seems to implement the account/email/webfinger part 2. of the spec - so we will rely instead on email/url mappings if we detect such an issuer. - Part 4, on the other hand is implemented by both google and salesforce. */ - - /* Very non-sophisticated way to detect an email address. Should be good - enough for now... */ - at_sign = strchr(iss, '@'); - if (at_sign != NULL) { - email_key_mapping *mapping; - const char *email_domain = at_sign + 1; - GPR_ASSERT(ctx->verifier != NULL); - mapping = verifier_get_mapping(ctx->verifier, email_domain); - if (mapping == NULL) { - gpr_log(GPR_ERROR, "Missing mapping for issuer email."); - goto error; - } - req.host = gpr_strdup(mapping->key_url_prefix); - path_prefix = strchr(req.host, '/'); - if (path_prefix == NULL) { - gpr_asprintf(&req.http.path, "/%s", iss); - } else { - *(path_prefix++) = '\0'; - gpr_asprintf(&req.http.path, "/%s/%s", path_prefix, iss); - } - http_cb = on_keys_retrieved; - } else { - req.host = gpr_strdup(strstr(iss, "https://") == iss ? iss + 8 : iss); - path_prefix = strchr(req.host, '/'); - if (path_prefix == NULL) { - req.http.path = gpr_strdup(GRPC_OPENID_CONFIG_URL_SUFFIX); - } else { - *(path_prefix++) = 0; - gpr_asprintf(&req.http.path, "/%s%s", path_prefix, - GRPC_OPENID_CONFIG_URL_SUFFIX); - } - http_cb = on_openid_config_retrieved; - } - - grpc_httpcli_get( - exec_ctx, &ctx->verifier->http_ctx, ctx->pollset, &req, - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay), - http_cb, ctx); - gpr_free(req.host); - gpr_free(req.http.path); - return; - -error: - ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL); - verifier_cb_ctx_destroy(ctx); -} - -void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx, - grpc_jwt_verifier *verifier, - grpc_pollset *pollset, const char *jwt, - const char *audience, - grpc_jwt_verification_done_cb cb, - void *user_data) { - const char *dot = NULL; - grpc_json *json; - jose_header *header = NULL; - grpc_jwt_claims *claims = NULL; - gpr_slice header_buffer; - gpr_slice claims_buffer; - gpr_slice signature; - size_t signed_jwt_len; - const char *cur = jwt; - - GPR_ASSERT(verifier != NULL && jwt != NULL && audience != NULL && cb != NULL); - dot = strchr(cur, '.'); - if (dot == NULL) goto error; - json = parse_json_part_from_jwt(cur, (size_t)(dot - cur), &header_buffer); - if (json == NULL) goto error; - header = jose_header_from_json(json, header_buffer); - if (header == NULL) goto error; - - cur = dot + 1; - dot = strchr(cur, '.'); - if (dot == NULL) goto error; - json = parse_json_part_from_jwt(cur, (size_t)(dot - cur), &claims_buffer); - if (json == NULL) goto error; - claims = grpc_jwt_claims_from_json(json, claims_buffer); - if (claims == NULL) goto error; - - signed_jwt_len = (size_t)(dot - jwt); - cur = dot + 1; - signature = grpc_base64_decode(cur, 1); - if (GPR_SLICE_IS_EMPTY(signature)) goto error; - retrieve_key_and_verify( - exec_ctx, - verifier_cb_ctx_create(verifier, pollset, header, claims, audience, - signature, jwt, signed_jwt_len, user_data, cb)); - return; - -error: - if (header != NULL) jose_header_destroy(header); - if (claims != NULL) grpc_jwt_claims_destroy(claims); - cb(user_data, GRPC_JWT_VERIFIER_BAD_FORMAT, NULL); -} - -grpc_jwt_verifier *grpc_jwt_verifier_create( - const grpc_jwt_verifier_email_domain_key_url_mapping *mappings, - size_t num_mappings) { - grpc_jwt_verifier *v = gpr_malloc(sizeof(grpc_jwt_verifier)); - memset(v, 0, sizeof(grpc_jwt_verifier)); - grpc_httpcli_context_init(&v->http_ctx); - - /* We know at least of one mapping. */ - v->allocated_mappings = 1 + num_mappings; - v->mappings = gpr_malloc(v->allocated_mappings * sizeof(email_key_mapping)); - verifier_put_mapping(v, GRPC_GOOGLE_SERVICE_ACCOUNTS_EMAIL_DOMAIN, - GRPC_GOOGLE_SERVICE_ACCOUNTS_KEY_URL_PREFIX); - /* User-Provided mappings. */ - if (mappings != NULL) { - size_t i; - for (i = 0; i < num_mappings; i++) { - verifier_put_mapping(v, mappings[i].email_domain, - mappings[i].key_url_prefix); - } - } - return v; -} - -void grpc_jwt_verifier_destroy(grpc_jwt_verifier *v) { - size_t i; - if (v == NULL) return; - grpc_httpcli_context_destroy(&v->http_ctx); - if (v->mappings != NULL) { - for (i = 0; i < v->num_mappings; i++) { - gpr_free(v->mappings[i].email_domain); - gpr_free(v->mappings[i].key_url_prefix); - } - gpr_free(v->mappings); - } - gpr_free(v); -} diff --git a/src/core/security/jwt_verifier.h b/src/core/security/jwt_verifier.h deleted file mode 100644 index d898d2193f..0000000000 --- a/src/core/security/jwt_verifier.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * - * Copyright 2015-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_SECURITY_JWT_VERIFIER_H -#define GRPC_CORE_SECURITY_JWT_VERIFIER_H - -#include "src/core/iomgr/pollset.h" -#include "src/core/json/json.h" - -#include -#include - -/* --- Constants. --- */ - -#define GRPC_OPENID_CONFIG_URL_SUFFIX "/.well-known/openid-configuration" -#define GRPC_GOOGLE_SERVICE_ACCOUNTS_EMAIL_DOMAIN \ - "developer.gserviceaccount.com" -#define GRPC_GOOGLE_SERVICE_ACCOUNTS_KEY_URL_PREFIX \ - "www.googleapis.com/robot/v1/metadata/x509" - -/* --- grpc_jwt_verifier_status. --- */ - -typedef enum { - GRPC_JWT_VERIFIER_OK = 0, - GRPC_JWT_VERIFIER_BAD_SIGNATURE, - GRPC_JWT_VERIFIER_BAD_FORMAT, - GRPC_JWT_VERIFIER_BAD_AUDIENCE, - GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, - GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE, - GRPC_JWT_VERIFIER_GENERIC_ERROR -} grpc_jwt_verifier_status; - -const char *grpc_jwt_verifier_status_to_string(grpc_jwt_verifier_status status); - -/* --- grpc_jwt_claims. --- */ - -typedef struct grpc_jwt_claims grpc_jwt_claims; - -void grpc_jwt_claims_destroy(grpc_jwt_claims *claims); - -/* Returns the whole JSON tree of the claims. */ -const grpc_json *grpc_jwt_claims_json(const grpc_jwt_claims *claims); - -/* Access to registered claims in https://tools.ietf.org/html/rfc7519#page-9 */ -const char *grpc_jwt_claims_subject(const grpc_jwt_claims *claims); -const char *grpc_jwt_claims_issuer(const grpc_jwt_claims *claims); -const char *grpc_jwt_claims_id(const grpc_jwt_claims *claims); -const char *grpc_jwt_claims_audience(const grpc_jwt_claims *claims); -gpr_timespec grpc_jwt_claims_issued_at(const grpc_jwt_claims *claims); -gpr_timespec grpc_jwt_claims_expires_at(const grpc_jwt_claims *claims); -gpr_timespec grpc_jwt_claims_not_before(const grpc_jwt_claims *claims); - -/* --- grpc_jwt_verifier. --- */ - -typedef struct grpc_jwt_verifier grpc_jwt_verifier; - -typedef struct { - /* The email domain is the part after the @ sign. */ - const char *email_domain; - - /* The key url prefix will be used to get the public key from the issuer: - https:/// - Therefore the key_url_prefix must NOT contain https://. */ - const char *key_url_prefix; -} grpc_jwt_verifier_email_domain_key_url_mapping; - -/* Globals to control the verifier. Not thread-safe. */ -extern gpr_timespec grpc_jwt_verifier_clock_skew; -extern gpr_timespec grpc_jwt_verifier_max_delay; - -/* The verifier can be created with some custom mappings to help with key - discovery in the case where the issuer is an email address. - mappings can be NULL in which case num_mappings MUST be 0. - A verifier object has one built-in mapping (unless overridden): - GRPC_GOOGLE_SERVICE_ACCOUNTS_EMAIL_DOMAIN -> - GRPC_GOOGLE_SERVICE_ACCOUNTS_KEY_URL_PREFIX.*/ -grpc_jwt_verifier *grpc_jwt_verifier_create( - const grpc_jwt_verifier_email_domain_key_url_mapping *mappings, - size_t num_mappings); - -/*The verifier must not be destroyed if there are still outstanding callbacks.*/ -void grpc_jwt_verifier_destroy(grpc_jwt_verifier *verifier); - -/* User provided callback that will be called when the verification of the JWT - is done (maybe in another thread). - It is the responsibility of the callee to call grpc_jwt_claims_destroy on - the claims. */ -typedef void (*grpc_jwt_verification_done_cb)(void *user_data, - grpc_jwt_verifier_status status, - grpc_jwt_claims *claims); - -/* Verifies for the JWT for the given expected audience. */ -void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx, - grpc_jwt_verifier *verifier, - grpc_pollset *pollset, const char *jwt, - const char *audience, - grpc_jwt_verification_done_cb cb, - void *user_data); - -/* --- TESTING ONLY exposed functions. --- */ - -grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, gpr_slice buffer); -grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims, - const char *audience); - -#endif /* GRPC_CORE_SECURITY_JWT_VERIFIER_H */ diff --git a/src/core/security/secure_endpoint.c b/src/core/security/secure_endpoint.c deleted file mode 100644 index 58b081dc4a..0000000000 --- a/src/core/security/secure_endpoint.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * - * Copyright 2015-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/security/secure_endpoint.h" -#include -#include -#include -#include -#include -#include "src/core/debug/trace.h" -#include "src/core/support/string.h" -#include "src/core/tsi/transport_security_interface.h" - -#define STAGING_BUFFER_SIZE 8192 - -typedef struct { - grpc_endpoint base; - grpc_endpoint *wrapped_ep; - struct tsi_frame_protector *protector; - gpr_mu protector_mu; - /* saved upper level callbacks and user_data. */ - grpc_closure *read_cb; - grpc_closure *write_cb; - grpc_closure on_read; - gpr_slice_buffer *read_buffer; - gpr_slice_buffer source_buffer; - /* saved handshaker leftover data to unprotect. */ - gpr_slice_buffer leftover_bytes; - /* buffers for read and write */ - gpr_slice read_staging_buffer; - - gpr_slice write_staging_buffer; - gpr_slice_buffer output_buffer; - - gpr_refcount ref; -} secure_endpoint; - -int grpc_trace_secure_endpoint = 0; - -static void destroy(grpc_exec_ctx *exec_ctx, secure_endpoint *secure_ep) { - secure_endpoint *ep = secure_ep; - grpc_endpoint_destroy(exec_ctx, ep->wrapped_ep); - tsi_frame_protector_destroy(ep->protector); - gpr_slice_buffer_destroy(&ep->leftover_bytes); - gpr_slice_unref(ep->read_staging_buffer); - gpr_slice_unref(ep->write_staging_buffer); - gpr_slice_buffer_destroy(&ep->output_buffer); - gpr_slice_buffer_destroy(&ep->source_buffer); - gpr_mu_destroy(&ep->protector_mu); - gpr_free(ep); -} - -/*#define GRPC_SECURE_ENDPOINT_REFCOUNT_DEBUG*/ -#ifdef GRPC_SECURE_ENDPOINT_REFCOUNT_DEBUG -#define SECURE_ENDPOINT_UNREF(exec_ctx, ep, reason) \ - secure_endpoint_unref((exec_ctx), (ep), (reason), __FILE__, __LINE__) -#define SECURE_ENDPOINT_REF(ep, reason) \ - secure_endpoint_ref((ep), (reason), __FILE__, __LINE__) -static void secure_endpoint_unref(secure_endpoint *ep, - grpc_closure_list *closure_list, - const char *reason, const char *file, - int line) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SECENDP unref %p : %s %d -> %d", - ep, reason, ep->ref.count, ep->ref.count - 1); - if (gpr_unref(&ep->ref)) { - destroy(exec_ctx, ep); - } -} - -static void secure_endpoint_ref(secure_endpoint *ep, const char *reason, - const char *file, int line) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SECENDP ref %p : %s %d -> %d", - ep, reason, ep->ref.count, ep->ref.count + 1); - gpr_ref(&ep->ref); -} -#else -#define SECURE_ENDPOINT_UNREF(exec_ctx, ep, reason) \ - secure_endpoint_unref((exec_ctx), (ep)) -#define SECURE_ENDPOINT_REF(ep, reason) secure_endpoint_ref((ep)) -static void secure_endpoint_unref(grpc_exec_ctx *exec_ctx, - secure_endpoint *ep) { - if (gpr_unref(&ep->ref)) { - destroy(exec_ctx, ep); - } -} - -static void secure_endpoint_ref(secure_endpoint *ep) { gpr_ref(&ep->ref); } -#endif - -static void flush_read_staging_buffer(secure_endpoint *ep, uint8_t **cur, - uint8_t **end) { - gpr_slice_buffer_add(ep->read_buffer, ep->read_staging_buffer); - ep->read_staging_buffer = gpr_slice_malloc(STAGING_BUFFER_SIZE); - *cur = GPR_SLICE_START_PTR(ep->read_staging_buffer); - *end = GPR_SLICE_END_PTR(ep->read_staging_buffer); -} - -static void call_read_cb(grpc_exec_ctx *exec_ctx, secure_endpoint *ep, - bool success) { - if (grpc_trace_secure_endpoint) { - size_t i; - for (i = 0; i < ep->read_buffer->count; i++) { - char *data = gpr_dump_slice(ep->read_buffer->slices[i], - GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_DEBUG, "READ %p: %s", ep, data); - gpr_free(data); - } - } - ep->read_buffer = NULL; - grpc_exec_ctx_enqueue(exec_ctx, ep->read_cb, success, NULL); - SECURE_ENDPOINT_UNREF(exec_ctx, ep, "read"); -} - -static void on_read(grpc_exec_ctx *exec_ctx, void *user_data, bool success) { - unsigned i; - uint8_t keep_looping = 0; - tsi_result result = TSI_OK; - secure_endpoint *ep = (secure_endpoint *)user_data; - uint8_t *cur = GPR_SLICE_START_PTR(ep->read_staging_buffer); - uint8_t *end = GPR_SLICE_END_PTR(ep->read_staging_buffer); - - if (!success) { - gpr_slice_buffer_reset_and_unref(ep->read_buffer); - call_read_cb(exec_ctx, ep, 0); - return; - } - - /* TODO(yangg) check error, maybe bail out early */ - for (i = 0; i < ep->source_buffer.count; i++) { - gpr_slice encrypted = ep->source_buffer.slices[i]; - uint8_t *message_bytes = GPR_SLICE_START_PTR(encrypted); - size_t message_size = GPR_SLICE_LENGTH(encrypted); - - while (message_size > 0 || keep_looping) { - size_t unprotected_buffer_size_written = (size_t)(end - cur); - size_t processed_message_size = message_size; - gpr_mu_lock(&ep->protector_mu); - result = tsi_frame_protector_unprotect(ep->protector, message_bytes, - &processed_message_size, cur, - &unprotected_buffer_size_written); - gpr_mu_unlock(&ep->protector_mu); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Decryption error: %s", - tsi_result_to_string(result)); - break; - } - message_bytes += processed_message_size; - message_size -= processed_message_size; - cur += unprotected_buffer_size_written; - - if (cur == end) { - flush_read_staging_buffer(ep, &cur, &end); - /* Force to enter the loop again to extract buffered bytes in protector. - The bytes could be buffered because of running out of staging_buffer. - If this happens at the end of all slices, doing another unprotect - avoids leaving data in the protector. */ - keep_looping = 1; - } else if (unprotected_buffer_size_written > 0) { - keep_looping = 1; - } else { - keep_looping = 0; - } - } - if (result != TSI_OK) break; - } - - if (cur != GPR_SLICE_START_PTR(ep->read_staging_buffer)) { - gpr_slice_buffer_add( - ep->read_buffer, - gpr_slice_split_head( - &ep->read_staging_buffer, - (size_t)(cur - GPR_SLICE_START_PTR(ep->read_staging_buffer)))); - } - - /* TODO(yangg) experiment with moving this block after read_cb to see if it - helps latency */ - gpr_slice_buffer_reset_and_unref(&ep->source_buffer); - - if (result != TSI_OK) { - gpr_slice_buffer_reset_and_unref(ep->read_buffer); - call_read_cb(exec_ctx, ep, 0); - return; - } - - call_read_cb(exec_ctx, ep, 1); -} - -static void endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep, - gpr_slice_buffer *slices, grpc_closure *cb) { - secure_endpoint *ep = (secure_endpoint *)secure_ep; - ep->read_cb = cb; - ep->read_buffer = slices; - gpr_slice_buffer_reset_and_unref(ep->read_buffer); - - SECURE_ENDPOINT_REF(ep, "read"); - if (ep->leftover_bytes.count) { - gpr_slice_buffer_swap(&ep->leftover_bytes, &ep->source_buffer); - GPR_ASSERT(ep->leftover_bytes.count == 0); - on_read(exec_ctx, ep, 1); - return; - } - - grpc_endpoint_read(exec_ctx, ep->wrapped_ep, &ep->source_buffer, - &ep->on_read); -} - -static void flush_write_staging_buffer(secure_endpoint *ep, uint8_t **cur, - uint8_t **end) { - gpr_slice_buffer_add(&ep->output_buffer, ep->write_staging_buffer); - ep->write_staging_buffer = gpr_slice_malloc(STAGING_BUFFER_SIZE); - *cur = GPR_SLICE_START_PTR(ep->write_staging_buffer); - *end = GPR_SLICE_END_PTR(ep->write_staging_buffer); -} - -static void endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep, - gpr_slice_buffer *slices, grpc_closure *cb) { - unsigned i; - tsi_result result = TSI_OK; - secure_endpoint *ep = (secure_endpoint *)secure_ep; - uint8_t *cur = GPR_SLICE_START_PTR(ep->write_staging_buffer); - uint8_t *end = GPR_SLICE_END_PTR(ep->write_staging_buffer); - - gpr_slice_buffer_reset_and_unref(&ep->output_buffer); - - if (grpc_trace_secure_endpoint) { - for (i = 0; i < slices->count; i++) { - char *data = - gpr_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_DEBUG, "WRITE %p: %s", ep, data); - gpr_free(data); - } - } - - for (i = 0; i < slices->count; i++) { - gpr_slice plain = slices->slices[i]; - uint8_t *message_bytes = GPR_SLICE_START_PTR(plain); - size_t message_size = GPR_SLICE_LENGTH(plain); - while (message_size > 0) { - size_t protected_buffer_size_to_send = (size_t)(end - cur); - size_t processed_message_size = message_size; - gpr_mu_lock(&ep->protector_mu); - result = tsi_frame_protector_protect(ep->protector, message_bytes, - &processed_message_size, cur, - &protected_buffer_size_to_send); - gpr_mu_unlock(&ep->protector_mu); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Encryption error: %s", - tsi_result_to_string(result)); - break; - } - message_bytes += processed_message_size; - message_size -= processed_message_size; - cur += protected_buffer_size_to_send; - - if (cur == end) { - flush_write_staging_buffer(ep, &cur, &end); - } - } - if (result != TSI_OK) break; - } - if (result == TSI_OK) { - size_t still_pending_size; - do { - size_t protected_buffer_size_to_send = (size_t)(end - cur); - gpr_mu_lock(&ep->protector_mu); - result = tsi_frame_protector_protect_flush(ep->protector, cur, - &protected_buffer_size_to_send, - &still_pending_size); - gpr_mu_unlock(&ep->protector_mu); - if (result != TSI_OK) break; - cur += protected_buffer_size_to_send; - if (cur == end) { - flush_write_staging_buffer(ep, &cur, &end); - } - } while (still_pending_size > 0); - if (cur != GPR_SLICE_START_PTR(ep->write_staging_buffer)) { - gpr_slice_buffer_add( - &ep->output_buffer, - gpr_slice_split_head( - &ep->write_staging_buffer, - (size_t)(cur - GPR_SLICE_START_PTR(ep->write_staging_buffer)))); - } - } - - if (result != TSI_OK) { - /* TODO(yangg) do different things according to the error type? */ - gpr_slice_buffer_reset_and_unref(&ep->output_buffer); - grpc_exec_ctx_enqueue(exec_ctx, cb, false, NULL); - return; - } - - grpc_endpoint_write(exec_ctx, ep->wrapped_ep, &ep->output_buffer, cb); -} - -static void endpoint_shutdown(grpc_exec_ctx *exec_ctx, - grpc_endpoint *secure_ep) { - secure_endpoint *ep = (secure_endpoint *)secure_ep; - grpc_endpoint_shutdown(exec_ctx, ep->wrapped_ep); -} - -static void endpoint_destroy(grpc_exec_ctx *exec_ctx, - grpc_endpoint *secure_ep) { - secure_endpoint *ep = (secure_endpoint *)secure_ep; - SECURE_ENDPOINT_UNREF(exec_ctx, ep, "destroy"); -} - -static void endpoint_add_to_pollset(grpc_exec_ctx *exec_ctx, - grpc_endpoint *secure_ep, - grpc_pollset *pollset) { - secure_endpoint *ep = (secure_endpoint *)secure_ep; - grpc_endpoint_add_to_pollset(exec_ctx, ep->wrapped_ep, pollset); -} - -static void endpoint_add_to_pollset_set(grpc_exec_ctx *exec_ctx, - grpc_endpoint *secure_ep, - grpc_pollset_set *pollset_set) { - secure_endpoint *ep = (secure_endpoint *)secure_ep; - grpc_endpoint_add_to_pollset_set(exec_ctx, ep->wrapped_ep, pollset_set); -} - -static char *endpoint_get_peer(grpc_endpoint *secure_ep) { - secure_endpoint *ep = (secure_endpoint *)secure_ep; - return grpc_endpoint_get_peer(ep->wrapped_ep); -} - -static const grpc_endpoint_vtable vtable = { - endpoint_read, endpoint_write, - endpoint_add_to_pollset, endpoint_add_to_pollset_set, - endpoint_shutdown, endpoint_destroy, - endpoint_get_peer}; - -grpc_endpoint *grpc_secure_endpoint_create( - struct tsi_frame_protector *protector, grpc_endpoint *transport, - gpr_slice *leftover_slices, size_t leftover_nslices) { - size_t i; - secure_endpoint *ep = (secure_endpoint *)gpr_malloc(sizeof(secure_endpoint)); - ep->base.vtable = &vtable; - ep->wrapped_ep = transport; - ep->protector = protector; - gpr_slice_buffer_init(&ep->leftover_bytes); - for (i = 0; i < leftover_nslices; i++) { - gpr_slice_buffer_add(&ep->leftover_bytes, - gpr_slice_ref(leftover_slices[i])); - } - ep->write_staging_buffer = gpr_slice_malloc(STAGING_BUFFER_SIZE); - ep->read_staging_buffer = gpr_slice_malloc(STAGING_BUFFER_SIZE); - gpr_slice_buffer_init(&ep->output_buffer); - gpr_slice_buffer_init(&ep->source_buffer); - ep->read_buffer = NULL; - grpc_closure_init(&ep->on_read, on_read, ep); - gpr_mu_init(&ep->protector_mu); - gpr_ref_init(&ep->ref, 1); - return &ep->base; -} diff --git a/src/core/security/secure_endpoint.h b/src/core/security/secure_endpoint.h deleted file mode 100644 index 7368f8424b..0000000000 --- a/src/core/security/secure_endpoint.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright 2015-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_SECURITY_SECURE_ENDPOINT_H -#define GRPC_CORE_SECURITY_SECURE_ENDPOINT_H - -#include -#include "src/core/iomgr/endpoint.h" - -struct tsi_frame_protector; - -extern int grpc_trace_secure_endpoint; - -/* Takes ownership of protector and to_wrap, and refs leftover_slices. */ -grpc_endpoint *grpc_secure_endpoint_create( - struct tsi_frame_protector *protector, grpc_endpoint *to_wrap, - gpr_slice *leftover_slices, size_t leftover_nslices); - -#endif /* GRPC_CORE_SECURITY_SECURE_ENDPOINT_H */ diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c deleted file mode 100644 index fbec263eed..0000000000 --- a/src/core/security/security_connector.c +++ /dev/null @@ -1,812 +0,0 @@ -/* - * - * Copyright 2015-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/security/security_connector.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include "src/core/security/credentials.h" -#include "src/core/security/handshake.h" -#include "src/core/security/secure_endpoint.h" -#include "src/core/security/security_context.h" -#include "src/core/support/env.h" -#include "src/core/support/load_file.h" -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/alpn.h" -#include "src/core/tsi/fake_transport_security.h" -#include "src/core/tsi/ssl_transport_security.h" - -/* -- Constants. -- */ - -#ifndef INSTALL_PREFIX -static const char *installed_roots_path = "/usr/share/grpc/roots.pem"; -#else -static const char *installed_roots_path = - INSTALL_PREFIX "/share/grpc/roots.pem"; -#endif - -/* -- Overridden default roots. -- */ - -static grpc_ssl_roots_override_callback ssl_roots_override_cb = NULL; - -void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) { - ssl_roots_override_cb = cb; -} - -/* -- Cipher suites. -- */ - -/* Defines the cipher suites that we accept by default. All these cipher suites - are compliant with HTTP2. */ -#define GRPC_SSL_CIPHER_SUITES \ - "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-" \ - "SHA384:ECDHE-RSA-AES256-GCM-SHA384" - -static gpr_once cipher_suites_once = GPR_ONCE_INIT; -static const char *cipher_suites = NULL; - -static void init_cipher_suites(void) { - char *overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES"); - cipher_suites = overridden != NULL ? overridden : GRPC_SSL_CIPHER_SUITES; -} - -static const char *ssl_cipher_suites(void) { - gpr_once_init(&cipher_suites_once, init_cipher_suites); - return cipher_suites; -} - -/* -- Common methods. -- */ - -/* Returns the first property with that name. */ -const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer, - const char *name) { - size_t i; - if (peer == NULL) return NULL; - for (i = 0; i < peer->property_count; i++) { - const tsi_peer_property *property = &peer->properties[i]; - if (name == NULL && property->name == NULL) { - return property; - } - if (name != NULL && property->name != NULL && - strcmp(property->name, name) == 0) { - return property; - } - } - return NULL; -} - -void grpc_server_security_connector_shutdown( - grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector) { - grpc_security_connector_handshake_list *tmp; - gpr_mu_lock(&connector->mu); - while (connector->handshaking_handshakes) { - tmp = connector->handshaking_handshakes; - grpc_security_handshake_shutdown( - exec_ctx, connector->handshaking_handshakes->handshake); - connector->handshaking_handshakes = tmp->next; - gpr_free(tmp); - } - gpr_mu_unlock(&connector->mu); -} - -void grpc_channel_security_connector_do_handshake( - grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, - grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb, - void *user_data) { - if (sc == NULL || nonsecure_endpoint == NULL) { - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); - } else { - sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, cb, user_data); - } -} - -void grpc_server_security_connector_do_handshake( - grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, - grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, - grpc_security_handshake_done_cb cb, void *user_data) { - if (sc == NULL || nonsecure_endpoint == NULL) { - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); - } else { - sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, cb, user_data); - } -} - -void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx, - grpc_security_connector *sc, - tsi_peer peer, - grpc_security_peer_check_cb cb, - void *user_data) { - if (sc == NULL) { - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL); - tsi_peer_destruct(&peer); - } else { - sc->vtable->check_peer(exec_ctx, sc, peer, cb, user_data); - } -} - -void grpc_channel_security_connector_check_call_host( - grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, - const char *host, grpc_auth_context *auth_context, - grpc_security_call_host_check_cb cb, void *user_data) { - if (sc == NULL || sc->check_call_host == NULL) { - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR); - } else { - sc->check_call_host(exec_ctx, sc, host, auth_context, cb, user_data); - } -} - -#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG -grpc_security_connector *grpc_security_connector_ref( - grpc_security_connector *sc, const char *file, int line, - const char *reason) { - if (sc == NULL) return NULL; - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SECURITY_CONNECTOR:%p ref %d -> %d %s", sc, - (int)sc->refcount.count, (int)sc->refcount.count + 1, reason); -#else -grpc_security_connector *grpc_security_connector_ref( - grpc_security_connector *sc) { - if (sc == NULL) return NULL; -#endif - gpr_ref(&sc->refcount); - return sc; -} - -#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG -void grpc_security_connector_unref(grpc_security_connector *sc, - const char *file, int line, - const char *reason) { - if (sc == NULL) return; - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SECURITY_CONNECTOR:%p unref %d -> %d %s", sc, - (int)sc->refcount.count, (int)sc->refcount.count - 1, reason); -#else -void grpc_security_connector_unref(grpc_security_connector *sc) { - if (sc == NULL) return; -#endif - if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc); -} - -static void connector_pointer_arg_destroy(void *p) { - GRPC_SECURITY_CONNECTOR_UNREF(p, "connector_pointer_arg"); -} - -static void *connector_pointer_arg_copy(void *p) { - return GRPC_SECURITY_CONNECTOR_REF(p, "connector_pointer_arg"); -} - -static int connector_pointer_cmp(void *a, void *b) { return GPR_ICMP(a, b); } - -static const grpc_arg_pointer_vtable connector_pointer_vtable = { - connector_pointer_arg_copy, connector_pointer_arg_destroy, - connector_pointer_cmp}; - -grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc) { - grpc_arg result; - result.type = GRPC_ARG_POINTER; - result.key = GRPC_SECURITY_CONNECTOR_ARG; - result.value.pointer.vtable = &connector_pointer_vtable; - result.value.pointer.p = sc; - return result; -} - -grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg) { - if (strcmp(arg->key, GRPC_SECURITY_CONNECTOR_ARG)) return NULL; - if (arg->type != GRPC_ARG_POINTER) { - gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, - GRPC_SECURITY_CONNECTOR_ARG); - return NULL; - } - return arg->value.pointer.p; -} - -grpc_security_connector *grpc_find_security_connector_in_args( - const grpc_channel_args *args) { - size_t i; - if (args == NULL) return NULL; - for (i = 0; i < args->num_args; i++) { - grpc_security_connector *sc = - grpc_security_connector_from_arg(&args->args[i]); - if (sc != NULL) return sc; - } - return NULL; -} - -/* -- Fake implementation. -- */ - -static void fake_channel_destroy(grpc_security_connector *sc) { - grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc; - grpc_call_credentials_unref(c->request_metadata_creds); - gpr_free(sc); -} - -static void fake_server_destroy(grpc_security_connector *sc) { - grpc_server_security_connector *c = (grpc_server_security_connector *)sc; - gpr_mu_destroy(&c->mu); - gpr_free(sc); -} - -static void fake_check_peer(grpc_exec_ctx *exec_ctx, - grpc_security_connector *sc, tsi_peer peer, - grpc_security_peer_check_cb cb, void *user_data) { - const char *prop_name; - grpc_security_status status = GRPC_SECURITY_OK; - grpc_auth_context *auth_context = NULL; - if (peer.property_count != 1) { - gpr_log(GPR_ERROR, "Fake peers should only have 1 property."); - status = GRPC_SECURITY_ERROR; - goto end; - } - prop_name = peer.properties[0].name; - if (prop_name == NULL || - strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) { - gpr_log(GPR_ERROR, "Unexpected property in fake peer: %s.", - prop_name == NULL ? "" : prop_name); - status = GRPC_SECURITY_ERROR; - goto end; - } - if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE, - peer.properties[0].value.length)) { - gpr_log(GPR_ERROR, "Invalid value for cert type property."); - status = GRPC_SECURITY_ERROR; - goto end; - } - auth_context = grpc_auth_context_create(NULL); - grpc_auth_context_add_cstring_property( - auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, - GRPC_FAKE_TRANSPORT_SECURITY_TYPE); - -end: - cb(exec_ctx, user_data, status, auth_context); - grpc_auth_context_unref(auth_context); - tsi_peer_destruct(&peer); -} - -static void fake_channel_check_call_host(grpc_exec_ctx *exec_ctx, - grpc_channel_security_connector *sc, - const char *host, - grpc_auth_context *auth_context, - grpc_security_call_host_check_cb cb, - void *user_data) { - cb(exec_ctx, user_data, GRPC_SECURITY_OK); -} - -static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx, - grpc_channel_security_connector *sc, - grpc_endpoint *nonsecure_endpoint, - grpc_security_handshake_done_cb cb, - void *user_data) { - grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), &sc->base, - true, nonsecure_endpoint, cb, user_data); -} - -static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx, - grpc_server_security_connector *sc, - grpc_tcp_server_acceptor *acceptor, - grpc_endpoint *nonsecure_endpoint, - grpc_security_handshake_done_cb cb, - void *user_data) { - grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), &sc->base, - false, nonsecure_endpoint, cb, user_data); -} - -static grpc_security_connector_vtable fake_channel_vtable = { - fake_channel_destroy, fake_check_peer}; - -static grpc_security_connector_vtable fake_server_vtable = {fake_server_destroy, - fake_check_peer}; - -grpc_channel_security_connector *grpc_fake_channel_security_connector_create( - grpc_call_credentials *request_metadata_creds) { - grpc_channel_security_connector *c = gpr_malloc(sizeof(*c)); - memset(c, 0, sizeof(*c)); - gpr_ref_init(&c->base.refcount, 1); - c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; - c->base.vtable = &fake_channel_vtable; - c->request_metadata_creds = grpc_call_credentials_ref(request_metadata_creds); - c->check_call_host = fake_channel_check_call_host; - c->do_handshake = fake_channel_do_handshake; - return c; -} - -grpc_server_security_connector *grpc_fake_server_security_connector_create( - void) { - grpc_server_security_connector *c = - gpr_malloc(sizeof(grpc_server_security_connector)); - memset(c, 0, sizeof(*c)); - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &fake_server_vtable; - c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; - c->do_handshake = fake_server_do_handshake; - gpr_mu_init(&c->mu); - return c; -} - -/* --- Ssl implementation. --- */ - -typedef struct { - grpc_channel_security_connector base; - tsi_ssl_handshaker_factory *handshaker_factory; - char *target_name; - char *overridden_target_name; -} grpc_ssl_channel_security_connector; - -typedef struct { - grpc_server_security_connector base; - tsi_ssl_handshaker_factory *handshaker_factory; -} grpc_ssl_server_security_connector; - -static void ssl_channel_destroy(grpc_security_connector *sc) { - grpc_ssl_channel_security_connector *c = - (grpc_ssl_channel_security_connector *)sc; - grpc_call_credentials_unref(c->base.request_metadata_creds); - if (c->handshaker_factory != NULL) { - tsi_ssl_handshaker_factory_destroy(c->handshaker_factory); - } - if (c->target_name != NULL) gpr_free(c->target_name); - if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name); - gpr_free(sc); -} - -static void ssl_server_destroy(grpc_security_connector *sc) { - grpc_ssl_server_security_connector *c = - (grpc_ssl_server_security_connector *)sc; - - if (c->handshaker_factory != NULL) { - tsi_ssl_handshaker_factory_destroy(c->handshaker_factory); - } - gpr_mu_destroy(&c->base.mu); - gpr_free(sc); -} - -static grpc_security_status ssl_create_handshaker( - tsi_ssl_handshaker_factory *handshaker_factory, bool is_client, - const char *peer_name, tsi_handshaker **handshaker) { - tsi_result result = TSI_OK; - if (handshaker_factory == NULL) return GRPC_SECURITY_ERROR; - result = tsi_ssl_handshaker_factory_create_handshaker( - handshaker_factory, is_client ? peer_name : NULL, handshaker); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); - return GRPC_SECURITY_ERROR; - } - return GRPC_SECURITY_OK; -} - -static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx, - grpc_channel_security_connector *sc, - grpc_endpoint *nonsecure_endpoint, - grpc_security_handshake_done_cb cb, - void *user_data) { - grpc_ssl_channel_security_connector *c = - (grpc_ssl_channel_security_connector *)sc; - tsi_handshaker *handshaker; - grpc_security_status status = ssl_create_handshaker( - c->handshaker_factory, true, - c->overridden_target_name != NULL ? c->overridden_target_name - : c->target_name, - &handshaker); - if (status != GRPC_SECURITY_OK) { - cb(exec_ctx, user_data, status, NULL, NULL); - } else { - grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true, - nonsecure_endpoint, cb, user_data); - } -} - -static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx, - grpc_server_security_connector *sc, - grpc_tcp_server_acceptor *acceptor, - grpc_endpoint *nonsecure_endpoint, - grpc_security_handshake_done_cb cb, - void *user_data) { - grpc_ssl_server_security_connector *c = - (grpc_ssl_server_security_connector *)sc; - tsi_handshaker *handshaker; - grpc_security_status status = - ssl_create_handshaker(c->handshaker_factory, false, NULL, &handshaker); - if (status != GRPC_SECURITY_OK) { - cb(exec_ctx, user_data, status, NULL, NULL); - } else { - grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, false, - nonsecure_endpoint, cb, user_data); - } -} - -static int ssl_host_matches_name(const tsi_peer *peer, const char *peer_name) { - char *allocated_name = NULL; - int r; - - if (strchr(peer_name, ':') != NULL) { - char *ignored_port; - gpr_split_host_port(peer_name, &allocated_name, &ignored_port); - gpr_free(ignored_port); - peer_name = allocated_name; - if (!peer_name) return 0; - } - r = tsi_ssl_peer_matches_name(peer, peer_name); - gpr_free(allocated_name); - return r; -} - -grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer) { - size_t i; - grpc_auth_context *ctx = NULL; - const char *peer_identity_property_name = NULL; - - /* The caller has checked the certificate type property. */ - GPR_ASSERT(peer->property_count >= 1); - ctx = grpc_auth_context_create(NULL); - grpc_auth_context_add_cstring_property( - ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, - GRPC_SSL_TRANSPORT_SECURITY_TYPE); - for (i = 0; i < peer->property_count; i++) { - const tsi_peer_property *prop = &peer->properties[i]; - if (prop->name == NULL) continue; - if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) { - /* If there is no subject alt name, have the CN as the identity. */ - if (peer_identity_property_name == NULL) { - peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME; - } - grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME, - prop->value.data, prop->value.length); - } else if (strcmp(prop->name, - TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { - peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME; - grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME, - prop->value.data, prop->value.length); - } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) { - grpc_auth_context_add_property(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME, - prop->value.data, prop->value.length); - } - } - if (peer_identity_property_name != NULL) { - GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( - ctx, peer_identity_property_name) == 1); - } - return ctx; -} - -static grpc_security_status ssl_check_peer(grpc_security_connector *sc, - const char *peer_name, - const tsi_peer *peer, - grpc_auth_context **auth_context) { - /* Check the ALPN. */ - const tsi_peer_property *p = - tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); - if (p == NULL) { - gpr_log(GPR_ERROR, "Missing selected ALPN property."); - return GRPC_SECURITY_ERROR; - } - if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) { - gpr_log(GPR_ERROR, "Invalid ALPN value."); - return GRPC_SECURITY_ERROR; - } - - /* Check the peer name if specified. */ - if (peer_name != NULL && !ssl_host_matches_name(peer, peer_name)) { - gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name); - return GRPC_SECURITY_ERROR; - } - *auth_context = tsi_ssl_peer_to_auth_context(peer); - return GRPC_SECURITY_OK; -} - -static void ssl_channel_check_peer(grpc_exec_ctx *exec_ctx, - grpc_security_connector *sc, tsi_peer peer, - grpc_security_peer_check_cb cb, - void *user_data) { - grpc_ssl_channel_security_connector *c = - (grpc_ssl_channel_security_connector *)sc; - grpc_security_status status; - grpc_auth_context *auth_context = NULL; - status = ssl_check_peer(sc, c->overridden_target_name != NULL - ? c->overridden_target_name - : c->target_name, - &peer, &auth_context); - cb(exec_ctx, user_data, status, auth_context); - grpc_auth_context_unref(auth_context); - tsi_peer_destruct(&peer); -} - -static void ssl_server_check_peer(grpc_exec_ctx *exec_ctx, - grpc_security_connector *sc, tsi_peer peer, - grpc_security_peer_check_cb cb, - void *user_data) { - grpc_auth_context *auth_context = NULL; - grpc_security_status status = ssl_check_peer(sc, NULL, &peer, &auth_context); - tsi_peer_destruct(&peer); - cb(exec_ctx, user_data, status, auth_context); - grpc_auth_context_unref(auth_context); -} - -static void add_shallow_auth_property_to_peer(tsi_peer *peer, - const grpc_auth_property *prop, - const char *tsi_prop_name) { - tsi_peer_property *tsi_prop = &peer->properties[peer->property_count++]; - tsi_prop->name = (char *)tsi_prop_name; - tsi_prop->value.data = prop->value; - tsi_prop->value.length = prop->value_length; -} - -tsi_peer tsi_shallow_peer_from_ssl_auth_context( - const grpc_auth_context *auth_context) { - size_t max_num_props = 0; - grpc_auth_property_iterator it; - const grpc_auth_property *prop; - tsi_peer peer; - memset(&peer, 0, sizeof(peer)); - - it = grpc_auth_context_property_iterator(auth_context); - while (grpc_auth_property_iterator_next(&it) != NULL) max_num_props++; - - if (max_num_props > 0) { - peer.properties = gpr_malloc(max_num_props * sizeof(tsi_peer_property)); - it = grpc_auth_context_property_iterator(auth_context); - while ((prop = grpc_auth_property_iterator_next(&it)) != NULL) { - if (strcmp(prop->name, GRPC_X509_SAN_PROPERTY_NAME) == 0) { - add_shallow_auth_property_to_peer( - &peer, prop, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY); - } else if (strcmp(prop->name, GRPC_X509_CN_PROPERTY_NAME) == 0) { - add_shallow_auth_property_to_peer( - &peer, prop, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); - } else if (strcmp(prop->name, GRPC_X509_PEM_CERT_PROPERTY_NAME) == 0) { - add_shallow_auth_property_to_peer(&peer, prop, - TSI_X509_PEM_CERT_PROPERTY); - } - } - } - return peer; -} - -void tsi_shallow_peer_destruct(tsi_peer *peer) { - if (peer->properties != NULL) gpr_free(peer->properties); -} - -static void ssl_channel_check_call_host(grpc_exec_ctx *exec_ctx, - grpc_channel_security_connector *sc, - const char *host, - grpc_auth_context *auth_context, - grpc_security_call_host_check_cb cb, - void *user_data) { - grpc_ssl_channel_security_connector *c = - (grpc_ssl_channel_security_connector *)sc; - grpc_security_status status = GRPC_SECURITY_ERROR; - tsi_peer peer = tsi_shallow_peer_from_ssl_auth_context(auth_context); - if (ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; - - /* If the target name was overridden, then the original target_name was - 'checked' transitively during the previous peer check at the end of the - handshake. */ - if (c->overridden_target_name != NULL && strcmp(host, c->target_name) == 0) { - status = GRPC_SECURITY_OK; - } - cb(exec_ctx, user_data, status); - tsi_shallow_peer_destruct(&peer); -} - -static grpc_security_connector_vtable ssl_channel_vtable = { - ssl_channel_destroy, ssl_channel_check_peer}; - -static grpc_security_connector_vtable ssl_server_vtable = { - ssl_server_destroy, ssl_server_check_peer}; - -static gpr_slice compute_default_pem_root_certs_once(void) { - gpr_slice result = gpr_empty_slice(); - - /* First try to load the roots from the environment. */ - char *default_root_certs_path = - gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); - if (default_root_certs_path != NULL) { - result = gpr_load_file(default_root_certs_path, 0, NULL); - gpr_free(default_root_certs_path); - } - - /* Try overridden roots if needed. */ - grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL; - if (GPR_SLICE_IS_EMPTY(result) && ssl_roots_override_cb != NULL) { - char *pem_root_certs = NULL; - ovrd_res = ssl_roots_override_cb(&pem_root_certs); - if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) { - GPR_ASSERT(pem_root_certs != NULL); - result = gpr_slice_new(pem_root_certs, strlen(pem_root_certs), gpr_free); - } - } - - /* Fall back to installed certs if needed. */ - if (GPR_SLICE_IS_EMPTY(result) && - ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) { - result = gpr_load_file(installed_roots_path, 0, NULL); - } - return result; -} - -static gpr_slice default_pem_root_certs; - -static void init_default_pem_root_certs(void) { - default_pem_root_certs = compute_default_pem_root_certs_once(); -} - -gpr_slice grpc_get_default_ssl_roots_for_testing(void) { - return compute_default_pem_root_certs_once(); -} - -size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs) { - /* TODO(jboeuf@google.com): Maybe revisit the approach which consists in - loading all the roots once for the lifetime of the process. */ - static gpr_once once = GPR_ONCE_INIT; - gpr_once_init(&once, init_default_pem_root_certs); - *pem_root_certs = GPR_SLICE_START_PTR(default_pem_root_certs); - return GPR_SLICE_LENGTH(default_pem_root_certs); -} - -grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_call_credentials *request_metadata_creds, - const grpc_ssl_config *config, const char *target_name, - const char *overridden_target_name, grpc_channel_security_connector **sc) { - size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions(); - const unsigned char **alpn_protocol_strings = - gpr_malloc(sizeof(const char *) * num_alpn_protocols); - unsigned char *alpn_protocol_string_lengths = - gpr_malloc(sizeof(unsigned char) * num_alpn_protocols); - tsi_result result = TSI_OK; - grpc_ssl_channel_security_connector *c; - size_t i; - const unsigned char *pem_root_certs; - size_t pem_root_certs_size; - char *port; - - for (i = 0; i < num_alpn_protocols; i++) { - alpn_protocol_strings[i] = - (const unsigned char *)grpc_chttp2_get_alpn_version_index(i); - alpn_protocol_string_lengths[i] = - (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i)); - } - - if (config == NULL || target_name == NULL) { - gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); - goto error; - } - if (config->pem_root_certs == NULL) { - pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs); - if (pem_root_certs == NULL || pem_root_certs_size == 0) { - gpr_log(GPR_ERROR, "Could not get default pem root certs."); - goto error; - } - } else { - pem_root_certs = config->pem_root_certs; - pem_root_certs_size = config->pem_root_certs_size; - } - - c = gpr_malloc(sizeof(grpc_ssl_channel_security_connector)); - memset(c, 0, sizeof(grpc_ssl_channel_security_connector)); - - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &ssl_channel_vtable; - c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = ssl_channel_check_call_host; - c->base.do_handshake = ssl_channel_do_handshake; - gpr_split_host_port(target_name, &c->target_name, &port); - gpr_free(port); - if (overridden_target_name != NULL) { - c->overridden_target_name = gpr_strdup(overridden_target_name); - } - result = tsi_create_ssl_client_handshaker_factory( - config->pem_private_key, config->pem_private_key_size, - config->pem_cert_chain, config->pem_cert_chain_size, pem_root_certs, - pem_root_certs_size, ssl_cipher_suites(), alpn_protocol_strings, - alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols, - &c->handshaker_factory); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - ssl_channel_destroy(&c->base.base); - *sc = NULL; - goto error; - } - *sc = &c->base; - gpr_free((void *)alpn_protocol_strings); - gpr_free(alpn_protocol_string_lengths); - return GRPC_SECURITY_OK; - -error: - gpr_free((void *)alpn_protocol_strings); - gpr_free(alpn_protocol_string_lengths); - return GRPC_SECURITY_ERROR; -} - -grpc_security_status grpc_ssl_server_security_connector_create( - const grpc_ssl_server_config *config, grpc_server_security_connector **sc) { - size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions(); - const unsigned char **alpn_protocol_strings = - gpr_malloc(sizeof(const char *) * num_alpn_protocols); - unsigned char *alpn_protocol_string_lengths = - gpr_malloc(sizeof(unsigned char) * num_alpn_protocols); - tsi_result result = TSI_OK; - grpc_ssl_server_security_connector *c; - size_t i; - - for (i = 0; i < num_alpn_protocols; i++) { - alpn_protocol_strings[i] = - (const unsigned char *)grpc_chttp2_get_alpn_version_index(i); - alpn_protocol_string_lengths[i] = - (unsigned char)strlen(grpc_chttp2_get_alpn_version_index(i)); - } - - if (config == NULL || config->num_key_cert_pairs == 0) { - gpr_log(GPR_ERROR, "An SSL server needs a key and a cert."); - goto error; - } - c = gpr_malloc(sizeof(grpc_ssl_server_security_connector)); - memset(c, 0, sizeof(grpc_ssl_server_security_connector)); - - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; - c->base.base.vtable = &ssl_server_vtable; - result = tsi_create_ssl_server_handshaker_factory( - (const unsigned char **)config->pem_private_keys, - config->pem_private_keys_sizes, - (const unsigned char **)config->pem_cert_chains, - config->pem_cert_chains_sizes, config->num_key_cert_pairs, - config->pem_root_certs, config->pem_root_certs_size, - config->force_client_auth, ssl_cipher_suites(), alpn_protocol_strings, - alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols, - &c->handshaker_factory); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - ssl_server_destroy(&c->base.base); - *sc = NULL; - goto error; - } - gpr_mu_init(&c->base.mu); - c->base.do_handshake = ssl_server_do_handshake; - *sc = &c->base; - gpr_free((void *)alpn_protocol_strings); - gpr_free(alpn_protocol_string_lengths); - return GRPC_SECURITY_OK; - -error: - gpr_free((void *)alpn_protocol_strings); - gpr_free(alpn_protocol_string_lengths); - return GRPC_SECURITY_ERROR; -} diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h deleted file mode 100644 index 6f915ebb9d..0000000000 --- a/src/core/security/security_connector.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * - * Copyright 2015-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_SECURITY_SECURITY_CONNECTOR_H -#define GRPC_CORE_SECURITY_SECURITY_CONNECTOR_H - -#include -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/tcp_server.h" -#include "src/core/tsi/transport_security_interface.h" - -/* --- status enum. --- */ - -typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status; - -/* --- URL schemes. --- */ - -#define GRPC_SSL_URL_SCHEME "https" -#define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security" - -/* --- security_connector object. --- - - A security connector object represents away to configure the underlying - transport security mechanism and check the resulting trusted peer. */ - -typedef struct grpc_security_connector grpc_security_connector; - -#define GRPC_SECURITY_CONNECTOR_ARG "grpc.security_connector" - -typedef void (*grpc_security_peer_check_cb)(grpc_exec_ctx *exec_ctx, - void *user_data, - grpc_security_status status, - grpc_auth_context *auth_context); - -/* Ownership of the secure_endpoint is transfered. */ -typedef void (*grpc_security_handshake_done_cb)( - grpc_exec_ctx *exec_ctx, void *user_data, grpc_security_status status, - grpc_endpoint *secure_endpoint, grpc_auth_context *auth_context); - -typedef struct { - void (*destroy)(grpc_security_connector *sc); - void (*check_peer)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc, - tsi_peer peer, grpc_security_peer_check_cb cb, - void *user_data); -} grpc_security_connector_vtable; - -typedef struct grpc_security_connector_handshake_list { - void *handshake; - struct grpc_security_connector_handshake_list *next; -} grpc_security_connector_handshake_list; - -struct grpc_security_connector { - const grpc_security_connector_vtable *vtable; - gpr_refcount refcount; - const char *url_scheme; -}; - -/* Refcounting. */ -#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG -#define GRPC_SECURITY_CONNECTOR_REF(p, r) \ - grpc_security_connector_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \ - grpc_security_connector_unref((p), __FILE__, __LINE__, (r)) -grpc_security_connector *grpc_security_connector_ref( - grpc_security_connector *policy, const char *file, int line, - const char *reason); -void grpc_security_connector_unref(grpc_security_connector *policy, - const char *file, int line, - const char *reason); -#else -#define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p)) -#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p)) -grpc_security_connector *grpc_security_connector_ref( - grpc_security_connector *policy); -void grpc_security_connector_unref(grpc_security_connector *policy); -#endif - -/* Check the peer. Callee takes ownership of the peer object. - The callback will include the resulting auth_context. */ -void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx, - grpc_security_connector *sc, - tsi_peer peer, - grpc_security_peer_check_cb cb, - void *user_data); - -/* Util to encapsulate the connector in a channel arg. */ -grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc); - -/* Util to get the connector from a channel arg. */ -grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg); - -/* Util to find the connector from channel args. */ -grpc_security_connector *grpc_find_security_connector_in_args( - const grpc_channel_args *args); - -/* --- channel_security_connector object. --- - - A channel security connector object represents away to configure the - underlying transport security mechanism on the client side. */ - -typedef struct grpc_channel_security_connector grpc_channel_security_connector; - -typedef void (*grpc_security_call_host_check_cb)(grpc_exec_ctx *exec_ctx, - void *user_data, - grpc_security_status status); - -struct grpc_channel_security_connector { - grpc_security_connector base; - grpc_call_credentials *request_metadata_creds; - void (*check_call_host)(grpc_exec_ctx *exec_ctx, - grpc_channel_security_connector *sc, const char *host, - grpc_auth_context *auth_context, - grpc_security_call_host_check_cb cb, void *user_data); - void (*do_handshake)(grpc_exec_ctx *exec_ctx, - grpc_channel_security_connector *sc, - grpc_endpoint *nonsecure_endpoint, - grpc_security_handshake_done_cb cb, void *user_data); -}; - -/* Checks that the host that will be set for a call is acceptable. */ -void grpc_channel_security_connector_check_call_host( - grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, - const char *host, grpc_auth_context *auth_context, - grpc_security_call_host_check_cb cb, void *user_data); - -/* Handshake. */ -void grpc_channel_security_connector_do_handshake( - grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector, - grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb, - void *user_data); - -/* --- server_security_connector object. --- - - A server security connector object represents away to configure the - underlying transport security mechanism on the server side. */ - -typedef struct grpc_server_security_connector grpc_server_security_connector; - -struct grpc_server_security_connector { - grpc_security_connector base; - gpr_mu mu; - grpc_security_connector_handshake_list *handshaking_handshakes; - const grpc_channel_args *channel_args; - void (*do_handshake)(grpc_exec_ctx *exec_ctx, - grpc_server_security_connector *sc, - grpc_tcp_server_acceptor *acceptor, - grpc_endpoint *nonsecure_endpoint, - grpc_security_handshake_done_cb cb, void *user_data); -}; - -void grpc_server_security_connector_do_handshake( - grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, - grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, - grpc_security_handshake_done_cb cb, void *user_data); - -void grpc_server_security_connector_shutdown( - grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector); - -/* --- Creation security connectors. --- */ - -/* For TESTING ONLY! - Creates a fake connector that emulates real channel security. */ -grpc_channel_security_connector *grpc_fake_channel_security_connector_create( - grpc_call_credentials *request_metadata_creds); - -/* For TESTING ONLY! - Creates a fake connector that emulates real server security. */ -grpc_server_security_connector *grpc_fake_server_security_connector_create( - void); - -/* Config for ssl clients. */ -typedef struct { - unsigned char *pem_private_key; - size_t pem_private_key_size; - unsigned char *pem_cert_chain; - size_t pem_cert_chain_size; - unsigned char *pem_root_certs; - size_t pem_root_certs_size; -} grpc_ssl_config; - -/* Creates an SSL channel_security_connector. - - request_metadata_creds is the credentials object which metadata - will be sent with each request. This parameter can be NULL. - - config is the SSL config to be used for the SSL channel establishment. - - is_client should be 0 for a server or a non-0 value for a client. - - secure_peer_name is the secure peer name that should be checked in - grpc_channel_security_connector_check_peer. This parameter may be NULL in - which case the peer name will not be checked. Note that if this parameter - is not NULL, then, pem_root_certs should not be NULL either. - - sc is a pointer on the connector to be created. - This function returns GRPC_SECURITY_OK in case of success or a - specific error code otherwise. -*/ -grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_call_credentials *request_metadata_creds, - const grpc_ssl_config *config, const char *target_name, - const char *overridden_target_name, grpc_channel_security_connector **sc); - -/* Gets the default ssl roots. */ -size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs); - -/* Exposed for TESTING ONLY!. */ -gpr_slice grpc_get_default_ssl_roots_for_testing(void); - -/* Config for ssl servers. */ -typedef struct { - unsigned char **pem_private_keys; - size_t *pem_private_keys_sizes; - unsigned char **pem_cert_chains; - size_t *pem_cert_chains_sizes; - size_t num_key_cert_pairs; - unsigned char *pem_root_certs; - size_t pem_root_certs_size; - int force_client_auth; -} grpc_ssl_server_config; - -/* Creates an SSL server_security_connector. - - config is the SSL config to be used for the SSL channel establishment. - - sc is a pointer on the connector to be created. - This function returns GRPC_SECURITY_OK in case of success or a - specific error code otherwise. -*/ -grpc_security_status grpc_ssl_server_security_connector_create( - const grpc_ssl_server_config *config, grpc_server_security_connector **sc); - -/* Util. */ -const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer, - const char *name); - -/* Exposed for testing only. */ -grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer); -tsi_peer tsi_shallow_peer_from_ssl_auth_context( - const grpc_auth_context *auth_context); -void tsi_shallow_peer_destruct(tsi_peer *peer); - -#endif /* GRPC_CORE_SECURITY_SECURITY_CONNECTOR_H */ diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c deleted file mode 100644 index f6afc0f633..0000000000 --- a/src/core/security/security_context.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include "src/core/security/security_context.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" - -#include -#include -#include -#include - -/* --- grpc_call --- */ - -grpc_call_error grpc_call_set_credentials(grpc_call *call, - grpc_call_credentials *creds) { - grpc_client_security_context *ctx = NULL; - GRPC_API_TRACE("grpc_call_set_credentials(call=%p, creds=%p)", 2, - (call, creds)); - if (!grpc_call_is_client(call)) { - gpr_log(GPR_ERROR, "Method is client-side only."); - return GRPC_CALL_ERROR_NOT_ON_SERVER; - } - ctx = (grpc_client_security_context *)grpc_call_context_get( - call, GRPC_CONTEXT_SECURITY); - if (ctx == NULL) { - ctx = grpc_client_security_context_create(); - ctx->creds = grpc_call_credentials_ref(creds); - grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx, - grpc_client_security_context_destroy); - } else { - grpc_call_credentials_unref(ctx->creds); - ctx->creds = grpc_call_credentials_ref(creds); - } - return GRPC_CALL_OK; -} - -grpc_auth_context *grpc_call_auth_context(grpc_call *call) { - void *sec_ctx = grpc_call_context_get(call, GRPC_CONTEXT_SECURITY); - GRPC_API_TRACE("grpc_call_auth_context(call=%p)", 1, (call)); - if (sec_ctx == NULL) return NULL; - return grpc_call_is_client(call) - ? GRPC_AUTH_CONTEXT_REF( - ((grpc_client_security_context *)sec_ctx)->auth_context, - "grpc_call_auth_context client") - : GRPC_AUTH_CONTEXT_REF( - ((grpc_server_security_context *)sec_ctx)->auth_context, - "grpc_call_auth_context server"); -} - -void grpc_auth_context_release(grpc_auth_context *context) { - GRPC_API_TRACE("grpc_auth_context_release(context=%p)", 1, (context)); - GRPC_AUTH_CONTEXT_UNREF(context, "grpc_auth_context_unref"); -} - -/* --- grpc_client_security_context --- */ - -grpc_client_security_context *grpc_client_security_context_create(void) { - grpc_client_security_context *ctx = - gpr_malloc(sizeof(grpc_client_security_context)); - memset(ctx, 0, sizeof(grpc_client_security_context)); - return ctx; -} - -void grpc_client_security_context_destroy(void *ctx) { - grpc_client_security_context *c = (grpc_client_security_context *)ctx; - grpc_call_credentials_unref(c->creds); - GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context"); - gpr_free(ctx); -} - -/* --- grpc_server_security_context --- */ - -grpc_server_security_context *grpc_server_security_context_create(void) { - grpc_server_security_context *ctx = - gpr_malloc(sizeof(grpc_server_security_context)); - memset(ctx, 0, sizeof(grpc_server_security_context)); - return ctx; -} - -void grpc_server_security_context_destroy(void *ctx) { - grpc_server_security_context *c = (grpc_server_security_context *)ctx; - GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "server_security_context"); - gpr_free(ctx); -} - -/* --- grpc_auth_context --- */ - -static grpc_auth_property_iterator empty_iterator = {NULL, 0, NULL}; - -grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained) { - grpc_auth_context *ctx = gpr_malloc(sizeof(grpc_auth_context)); - memset(ctx, 0, sizeof(grpc_auth_context)); - gpr_ref_init(&ctx->refcount, 1); - if (chained != NULL) { - ctx->chained = GRPC_AUTH_CONTEXT_REF(chained, "chained"); - ctx->peer_identity_property_name = - ctx->chained->peer_identity_property_name; - } - return ctx; -} - -#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG -grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *ctx, - const char *file, int line, - const char *reason) { - if (ctx == NULL) return NULL; - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "AUTH_CONTEXT:%p ref %d -> %d %s", ctx, (int)ctx->refcount.count, - (int)ctx->refcount.count + 1, reason); -#else -grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *ctx) { - if (ctx == NULL) return NULL; -#endif - gpr_ref(&ctx->refcount); - return ctx; -} - -#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG -void grpc_auth_context_unref(grpc_auth_context *ctx, const char *file, int line, - const char *reason) { - if (ctx == NULL) return; - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "AUTH_CONTEXT:%p unref %d -> %d %s", ctx, (int)ctx->refcount.count, - (int)ctx->refcount.count - 1, reason); -#else -void grpc_auth_context_unref(grpc_auth_context *ctx) { - if (ctx == NULL) return; -#endif - if (gpr_unref(&ctx->refcount)) { - size_t i; - GRPC_AUTH_CONTEXT_UNREF(ctx->chained, "chained"); - if (ctx->properties.array != NULL) { - for (i = 0; i < ctx->properties.count; i++) { - grpc_auth_property_reset(&ctx->properties.array[i]); - } - gpr_free(ctx->properties.array); - } - gpr_free(ctx); - } -} - -const char *grpc_auth_context_peer_identity_property_name( - const grpc_auth_context *ctx) { - GRPC_API_TRACE("grpc_auth_context_peer_identity_property_name(ctx=%p)", 1, - (ctx)); - return ctx->peer_identity_property_name; -} - -int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context *ctx, - const char *name) { - grpc_auth_property_iterator it = - grpc_auth_context_find_properties_by_name(ctx, name); - const grpc_auth_property *prop = grpc_auth_property_iterator_next(&it); - GRPC_API_TRACE( - "grpc_auth_context_set_peer_identity_property_name(ctx=%p, name=%s)", 2, - (ctx, name)); - if (prop == NULL) { - gpr_log(GPR_ERROR, "Property name %s not found in auth context.", - name != NULL ? name : "NULL"); - return 0; - } - ctx->peer_identity_property_name = prop->name; - return 1; -} - -int grpc_auth_context_peer_is_authenticated(const grpc_auth_context *ctx) { - GRPC_API_TRACE("grpc_auth_context_peer_is_authenticated(ctx=%p)", 1, (ctx)); - return ctx->peer_identity_property_name == NULL ? 0 : 1; -} - -grpc_auth_property_iterator grpc_auth_context_property_iterator( - const grpc_auth_context *ctx) { - grpc_auth_property_iterator it = empty_iterator; - GRPC_API_TRACE("grpc_auth_context_property_iterator(ctx=%p)", 1, (ctx)); - if (ctx == NULL) return it; - it.ctx = ctx; - return it; -} - -const grpc_auth_property *grpc_auth_property_iterator_next( - grpc_auth_property_iterator *it) { - GRPC_API_TRACE("grpc_auth_property_iterator_next(it=%p)", 1, (it)); - if (it == NULL || it->ctx == NULL) return NULL; - while (it->index == it->ctx->properties.count) { - if (it->ctx->chained == NULL) return NULL; - it->ctx = it->ctx->chained; - it->index = 0; - } - if (it->name == NULL) { - return &it->ctx->properties.array[it->index++]; - } else { - while (it->index < it->ctx->properties.count) { - const grpc_auth_property *prop = &it->ctx->properties.array[it->index++]; - GPR_ASSERT(prop->name != NULL); - if (strcmp(it->name, prop->name) == 0) { - return prop; - } - } - /* We could not find the name, try another round. */ - return grpc_auth_property_iterator_next(it); - } -} - -grpc_auth_property_iterator grpc_auth_context_find_properties_by_name( - const grpc_auth_context *ctx, const char *name) { - grpc_auth_property_iterator it = empty_iterator; - GRPC_API_TRACE("grpc_auth_context_find_properties_by_name(ctx=%p, name=%s)", - 2, (ctx, name)); - if (ctx == NULL || name == NULL) return empty_iterator; - it.ctx = ctx; - it.name = name; - return it; -} - -grpc_auth_property_iterator grpc_auth_context_peer_identity( - const grpc_auth_context *ctx) { - GRPC_API_TRACE("grpc_auth_context_peer_identity(ctx=%p)", 1, (ctx)); - if (ctx == NULL) return empty_iterator; - return grpc_auth_context_find_properties_by_name( - ctx, ctx->peer_identity_property_name); -} - -static void ensure_auth_context_capacity(grpc_auth_context *ctx) { - if (ctx->properties.count == ctx->properties.capacity) { - ctx->properties.capacity = - GPR_MAX(ctx->properties.capacity + 8, ctx->properties.capacity * 2); - ctx->properties.array = - gpr_realloc(ctx->properties.array, - ctx->properties.capacity * sizeof(grpc_auth_property)); - } -} - -void grpc_auth_context_add_property(grpc_auth_context *ctx, const char *name, - const char *value, size_t value_length) { - grpc_auth_property *prop; - GRPC_API_TRACE( - "grpc_auth_context_add_property(ctx=%p, name=%s, value=%*.*s, " - "value_length=%lu)", - 6, (ctx, name, (int)value_length, (int)value_length, value, - (unsigned long)value_length)); - ensure_auth_context_capacity(ctx); - prop = &ctx->properties.array[ctx->properties.count++]; - prop->name = gpr_strdup(name); - prop->value = gpr_malloc(value_length + 1); - memcpy(prop->value, value, value_length); - prop->value[value_length] = '\0'; - prop->value_length = value_length; -} - -void grpc_auth_context_add_cstring_property(grpc_auth_context *ctx, - const char *name, - const char *value) { - grpc_auth_property *prop; - GRPC_API_TRACE( - "grpc_auth_context_add_cstring_property(ctx=%p, name=%s, value=%s)", 3, - (ctx, name, value)); - ensure_auth_context_capacity(ctx); - prop = &ctx->properties.array[ctx->properties.count++]; - prop->name = gpr_strdup(name); - prop->value = gpr_strdup(value); - prop->value_length = strlen(value); -} - -void grpc_auth_property_reset(grpc_auth_property *property) { - gpr_free(property->name); - gpr_free(property->value); - memset(property, 0, sizeof(grpc_auth_property)); -} - -static void auth_context_pointer_arg_destroy(void *p) { - GRPC_AUTH_CONTEXT_UNREF(p, "auth_context_pointer_arg"); -} - -static void *auth_context_pointer_arg_copy(void *p) { - return GRPC_AUTH_CONTEXT_REF(p, "auth_context_pointer_arg"); -} - -static int auth_context_pointer_cmp(void *a, void *b) { return GPR_ICMP(a, b); } - -static const grpc_arg_pointer_vtable auth_context_pointer_vtable = { - auth_context_pointer_arg_copy, auth_context_pointer_arg_destroy, - auth_context_pointer_cmp}; - -grpc_arg grpc_auth_context_to_arg(grpc_auth_context *p) { - grpc_arg arg; - memset(&arg, 0, sizeof(grpc_arg)); - arg.type = GRPC_ARG_POINTER; - arg.key = GRPC_AUTH_CONTEXT_ARG; - arg.value.pointer.p = p; - arg.value.pointer.vtable = &auth_context_pointer_vtable; - return arg; -} - -grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg) { - if (strcmp(arg->key, GRPC_AUTH_CONTEXT_ARG) != 0) return NULL; - if (arg->type != GRPC_ARG_POINTER) { - gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, - GRPC_AUTH_CONTEXT_ARG); - return NULL; - } - return arg->value.pointer.p; -} - -grpc_auth_context *grpc_find_auth_context_in_args( - const grpc_channel_args *args) { - size_t i; - if (args == NULL) return NULL; - for (i = 0; i < args->num_args; i++) { - grpc_auth_context *p = grpc_auth_context_from_arg(&args->args[i]); - if (p != NULL) return p; - } - return NULL; -} diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h deleted file mode 100644 index 61601f538b..0000000000 --- a/src/core/security/security_context.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * - * Copyright 2015-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_SECURITY_SECURITY_CONTEXT_H -#define GRPC_CORE_SECURITY_SECURITY_CONTEXT_H - -#include "src/core/iomgr/pollset.h" -#include "src/core/security/credentials.h" - -/* --- grpc_auth_context --- - - High level authentication context object. Can optionally be chained. */ - -/* Property names are always NULL terminated. */ - -typedef struct { - grpc_auth_property *array; - size_t count; - size_t capacity; -} grpc_auth_property_array; - -struct grpc_auth_context { - struct grpc_auth_context *chained; - grpc_auth_property_array properties; - gpr_refcount refcount; - const char *peer_identity_property_name; - grpc_pollset *pollset; -}; - -/* Creation. */ -grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained); - -/* Refcounting. */ -#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG -#define GRPC_AUTH_CONTEXT_REF(p, r) \ - grpc_auth_context_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_AUTH_CONTEXT_UNREF(p, r) \ - grpc_auth_context_unref((p), __FILE__, __LINE__, (r)) -grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *policy, - const char *file, int line, - const char *reason); -void grpc_auth_context_unref(grpc_auth_context *policy, const char *file, - int line, const char *reason); -#else -#define GRPC_AUTH_CONTEXT_REF(p, r) grpc_auth_context_ref((p)) -#define GRPC_AUTH_CONTEXT_UNREF(p, r) grpc_auth_context_unref((p)) -grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *policy); -void grpc_auth_context_unref(grpc_auth_context *policy); -#endif - -void grpc_auth_property_reset(grpc_auth_property *property); - -/* --- grpc_client_security_context --- - - Internal client-side security context. */ - -typedef struct { - grpc_call_credentials *creds; - grpc_auth_context *auth_context; -} grpc_client_security_context; - -grpc_client_security_context *grpc_client_security_context_create(void); -void grpc_client_security_context_destroy(void *ctx); - -/* --- grpc_server_security_context --- - - Internal server-side security context. */ - -typedef struct { - grpc_auth_context *auth_context; -} grpc_server_security_context; - -grpc_server_security_context *grpc_server_security_context_create(void); -void grpc_server_security_context_destroy(void *ctx); - -/* --- Channel args for auth context --- */ -#define GRPC_AUTH_CONTEXT_ARG "grpc.auth_context" - -grpc_arg grpc_auth_context_to_arg(grpc_auth_context *c); -grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg); -grpc_auth_context *grpc_find_auth_context_in_args( - const grpc_channel_args *args); - -#endif /* GRPC_CORE_SECURITY_SECURITY_CONTEXT_H */ diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c deleted file mode 100644 index f3c411d6d4..0000000000 --- a/src/core/security/server_auth_filter.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include "src/core/security/auth_filters.h" -#include "src/core/security/credentials.h" -#include "src/core/security/security_context.h" - -#include -#include - -typedef struct call_data { - grpc_metadata_batch *recv_initial_metadata; - /* Closure to call when finished with the auth_on_recv hook. */ - grpc_closure *on_done_recv; - /* Receive closures are chained: we inject this closure as the on_done_recv - up-call on transport_op, and remember to call our on_done_recv member after - handling it. */ - grpc_closure auth_on_recv; - grpc_transport_stream_op transport_op; - grpc_metadata_array md; - const grpc_metadata *consumed_md; - size_t num_consumed_md; - grpc_auth_context *auth_context; -} call_data; - -typedef struct channel_data { - grpc_auth_context *auth_context; - grpc_server_credentials *creds; -} channel_data; - -static grpc_metadata_array metadata_batch_to_md_array( - const grpc_metadata_batch *batch) { - grpc_linked_mdelem *l; - grpc_metadata_array result; - grpc_metadata_array_init(&result); - for (l = batch->list.head; l != NULL; l = l->next) { - grpc_metadata *usr_md = NULL; - grpc_mdelem *md = l->md; - grpc_mdstr *key = md->key; - grpc_mdstr *value = md->value; - if (result.count == result.capacity) { - result.capacity = GPR_MAX(result.capacity + 8, result.capacity * 2); - result.metadata = - gpr_realloc(result.metadata, result.capacity * sizeof(grpc_metadata)); - } - usr_md = &result.metadata[result.count++]; - usr_md->key = grpc_mdstr_as_c_string(key); - usr_md->value = grpc_mdstr_as_c_string(value); - usr_md->value_length = GPR_SLICE_LENGTH(value->slice); - } - return result; -} - -static grpc_mdelem *remove_consumed_md(void *user_data, grpc_mdelem *md) { - grpc_call_element *elem = user_data; - call_data *calld = elem->call_data; - size_t i; - for (i = 0; i < calld->num_consumed_md; i++) { - const grpc_metadata *consumed_md = &calld->consumed_md[i]; - /* Maybe we could do a pointer comparison but we do not have any guarantee - that the metadata processor used the same pointers for consumed_md in the - callback. */ - if (GPR_SLICE_LENGTH(md->key->slice) != strlen(consumed_md->key) || - GPR_SLICE_LENGTH(md->value->slice) != consumed_md->value_length) { - continue; - } - if (memcmp(GPR_SLICE_START_PTR(md->key->slice), consumed_md->key, - GPR_SLICE_LENGTH(md->key->slice)) == 0 && - memcmp(GPR_SLICE_START_PTR(md->value->slice), consumed_md->value, - GPR_SLICE_LENGTH(md->value->slice)) == 0) { - return NULL; /* Delete. */ - } - } - return md; -} - -/* called from application code */ -static void on_md_processing_done( - void *user_data, const grpc_metadata *consumed_md, size_t num_consumed_md, - const grpc_metadata *response_md, size_t num_response_md, - grpc_status_code status, const char *error_details) { - grpc_call_element *elem = user_data; - call_data *calld = elem->call_data; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - /* TODO(jboeuf): Implement support for response_md. */ - if (response_md != NULL && num_response_md > 0) { - gpr_log(GPR_INFO, - "response_md in auth metadata processing not supported for now. " - "Ignoring..."); - } - - if (status == GRPC_STATUS_OK) { - calld->consumed_md = consumed_md; - calld->num_consumed_md = num_consumed_md; - grpc_metadata_batch_filter(calld->recv_initial_metadata, remove_consumed_md, - elem); - grpc_metadata_array_destroy(&calld->md); - calld->on_done_recv->cb(&exec_ctx, calld->on_done_recv->cb_arg, 1); - } else { - gpr_slice message; - grpc_transport_stream_op close_op; - memset(&close_op, 0, sizeof(close_op)); - grpc_metadata_array_destroy(&calld->md); - error_details = error_details != NULL - ? error_details - : "Authentication metadata processing failed."; - message = gpr_slice_from_copied_string(error_details); - calld->transport_op.send_initial_metadata = NULL; - if (calld->transport_op.send_message != NULL) { - grpc_byte_stream_destroy(&exec_ctx, calld->transport_op.send_message); - calld->transport_op.send_message = NULL; - } - calld->transport_op.send_trailing_metadata = NULL; - grpc_transport_stream_op_add_close(&close_op, status, &message); - grpc_call_next_op(&exec_ctx, elem, &close_op); - calld->on_done_recv->cb(&exec_ctx, calld->on_done_recv->cb_arg, 0); - } - - grpc_exec_ctx_finish(&exec_ctx); -} - -static void auth_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, - bool success) { - grpc_call_element *elem = user_data; - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - if (success) { - if (chand->creds->processor.process != NULL) { - calld->md = metadata_batch_to_md_array(calld->recv_initial_metadata); - chand->creds->processor.process( - chand->creds->processor.state, calld->auth_context, - calld->md.metadata, calld->md.count, on_md_processing_done, elem); - return; - } - } - calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, success); -} - -static void set_recv_ops_md_callbacks(grpc_call_element *elem, - grpc_transport_stream_op *op) { - call_data *calld = elem->call_data; - - if (op->recv_initial_metadata != NULL) { - /* substitute our callback for the higher callback */ - calld->recv_initial_metadata = op->recv_initial_metadata; - calld->on_done_recv = op->recv_initial_metadata_ready; - op->recv_initial_metadata_ready = &calld->auth_on_recv; - calld->transport_op = *op; - } -} - -/* Called either: - - in response to an API call (or similar) from above, to send something - - a network event (or similar) from below, to receive something - op contains type and call direction information, in addition to the data - that is being sent or received. */ -static void auth_start_transport_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - set_recv_ops_md_callbacks(elem, op); - grpc_call_next_op(exec_ctx, elem, op); -} - -/* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { - /* grab pointers to our data from the call element */ - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - grpc_server_security_context *server_ctx = NULL; - - /* initialize members */ - memset(calld, 0, sizeof(*calld)); - grpc_closure_init(&calld->auth_on_recv, auth_on_recv, elem); - - if (args->context[GRPC_CONTEXT_SECURITY].value != NULL) { - args->context[GRPC_CONTEXT_SECURITY].destroy( - args->context[GRPC_CONTEXT_SECURITY].value); - } - - server_ctx = grpc_server_security_context_create(); - server_ctx->auth_context = grpc_auth_context_create(chand->auth_context); - calld->auth_context = server_ctx->auth_context; - - args->context[GRPC_CONTEXT_SECURITY].value = server_ctx; - args->context[GRPC_CONTEXT_SECURITY].destroy = - grpc_server_security_context_destroy; -} - -static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_pollset *pollset) {} - -/* Destructor for call_data */ -static void destroy_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) {} - -/* Constructor for channel_data */ -static void init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - grpc_auth_context *auth_context = - grpc_find_auth_context_in_args(args->channel_args); - grpc_server_credentials *creds = - grpc_find_server_credentials_in_args(args->channel_args); - /* grab pointers to our data from the channel element */ - channel_data *chand = elem->channel_data; - - GPR_ASSERT(!args->is_last); - GPR_ASSERT(auth_context != NULL); - GPR_ASSERT(creds != NULL); - - /* initialize members */ - chand->auth_context = - GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter"); - chand->creds = grpc_server_credentials_ref(creds); -} - -/* Destructor for channel data */ -static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) { - /* grab pointers to our data from the channel element */ - channel_data *chand = elem->channel_data; - GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter"); - grpc_server_credentials_unref(chand->creds); -} - -const grpc_channel_filter grpc_server_auth_filter = { - auth_start_transport_op, grpc_channel_next_op, sizeof(call_data), - init_call_elem, set_pollset, destroy_call_elem, - sizeof(channel_data), init_channel_elem, destroy_channel_elem, - grpc_call_next_get_peer, "server-auth"}; diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c deleted file mode 100644 index da29ca934b..0000000000 --- a/src/core/security/server_secure_chttp2.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include - -#include -#include -#include -#include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/tcp_server.h" -#include "src/core/security/auth_filters.h" -#include "src/core/security/credentials.h" -#include "src/core/security/security_connector.h" -#include "src/core/security/security_context.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" - -typedef struct grpc_server_secure_state { - grpc_server *server; - grpc_tcp_server *tcp; - grpc_server_security_connector *sc; - grpc_server_credentials *creds; - int is_shutdown; - gpr_mu mu; - gpr_refcount refcount; - grpc_closure destroy_closure; - grpc_closure *destroy_callback; -} grpc_server_secure_state; - -static void state_ref(grpc_server_secure_state *state) { - gpr_ref(&state->refcount); -} - -static void state_unref(grpc_server_secure_state *state) { - if (gpr_unref(&state->refcount)) { - /* ensure all threads have unlocked */ - gpr_mu_lock(&state->mu); - gpr_mu_unlock(&state->mu); - /* clean up */ - GRPC_SECURITY_CONNECTOR_UNREF(&state->sc->base, "server"); - grpc_server_credentials_unref(state->creds); - gpr_free(state); - } -} - -static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep, - grpc_transport *transport, - grpc_auth_context *auth_context) { - grpc_server_secure_state *state = statep; - grpc_channel_args *args_copy; - grpc_arg args_to_add[2]; - args_to_add[0] = grpc_server_credentials_to_arg(state->creds); - args_to_add[1] = grpc_auth_context_to_arg(auth_context); - args_copy = grpc_channel_args_copy_and_add( - grpc_server_get_channel_args(state->server), args_to_add, - GPR_ARRAY_SIZE(args_to_add)); - grpc_server_setup_transport(exec_ctx, state->server, transport, args_copy); - grpc_channel_args_destroy(args_copy); -} - -static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, - grpc_security_status status, - grpc_endpoint *secure_endpoint, - grpc_auth_context *auth_context) { - grpc_server_secure_state *state = statep; - grpc_transport *transport; - if (status == GRPC_SECURITY_OK) { - if (secure_endpoint) { - gpr_mu_lock(&state->mu); - if (!state->is_shutdown) { - transport = grpc_create_chttp2_transport( - exec_ctx, grpc_server_get_channel_args(state->server), - secure_endpoint, 0); - setup_transport(exec_ctx, state, transport, auth_context); - grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); - } else { - /* We need to consume this here, because the server may already have - * gone away. */ - grpc_endpoint_destroy(exec_ctx, secure_endpoint); - } - gpr_mu_unlock(&state->mu); - } - } else { - gpr_log(GPR_ERROR, "Secure transport failed with error %d", status); - } - state_unref(state); -} - -static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, - grpc_tcp_server_acceptor *acceptor) { - grpc_server_secure_state *state = statep; - state_ref(state); - grpc_server_security_connector_do_handshake( - exec_ctx, state->sc, acceptor, tcp, on_secure_handshake_done, state); -} - -/* Server callback: start listening on our ports */ -static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep, - grpc_pollset **pollsets, size_t pollset_count) { - grpc_server_secure_state *state = statep; - grpc_tcp_server_start(exec_ctx, state->tcp, pollsets, pollset_count, - on_accept, state); -} - -static void destroy_done(grpc_exec_ctx *exec_ctx, void *statep, bool success) { - grpc_server_secure_state *state = statep; - if (state->destroy_callback != NULL) { - state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg, - success); - } - grpc_server_security_connector_shutdown(exec_ctx, state->sc); - state_unref(state); -} - -/* Server callback: destroy the tcp listener (so we don't generate further - callbacks) */ -static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep, - grpc_closure *callback) { - grpc_server_secure_state *state = statep; - grpc_tcp_server *tcp; - gpr_mu_lock(&state->mu); - state->is_shutdown = 1; - state->destroy_callback = callback; - tcp = state->tcp; - gpr_mu_unlock(&state->mu); - grpc_tcp_server_unref(exec_ctx, tcp); -} - -int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, - grpc_server_credentials *creds) { - grpc_resolved_addresses *resolved = NULL; - grpc_tcp_server *tcp = NULL; - grpc_server_secure_state *state = NULL; - size_t i; - unsigned count = 0; - int port_num = -1; - int port_temp; - grpc_security_status status = GRPC_SECURITY_ERROR; - grpc_server_security_connector *sc = NULL; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - GRPC_API_TRACE( - "grpc_server_add_secure_http2_port(" - "server=%p, addr=%s, creds=%p)", - 3, (server, addr, creds)); - - /* create security context */ - if (creds == NULL) goto error; - status = grpc_server_credentials_create_security_connector(creds, &sc); - if (status != GRPC_SECURITY_OK) { - gpr_log(GPR_ERROR, - "Unable to create secure server with credentials of type %s.", - creds->type); - goto error; - } - sc->channel_args = grpc_server_get_channel_args(server); - - /* resolve address */ - resolved = grpc_blocking_resolve_address(addr, "https"); - if (!resolved) { - goto error; - } - state = gpr_malloc(sizeof(*state)); - memset(state, 0, sizeof(*state)); - grpc_closure_init(&state->destroy_closure, destroy_done, state); - tcp = grpc_tcp_server_create(&state->destroy_closure); - if (!tcp) { - goto error; - } - - state->server = server; - state->tcp = tcp; - state->sc = sc; - state->creds = grpc_server_credentials_ref(creds); - state->is_shutdown = 0; - gpr_mu_init(&state->mu); - gpr_ref_init(&state->refcount, 1); - - for (i = 0; i < resolved->naddrs; i++) { - port_temp = grpc_tcp_server_add_port( - tcp, (struct sockaddr *)&resolved->addrs[i].addr, - resolved->addrs[i].len); - if (port_temp > 0) { - if (port_num == -1) { - port_num = port_temp; - } else { - GPR_ASSERT(port_num == port_temp); - } - count++; - } - } - if (count == 0) { - gpr_log(GPR_ERROR, "No address added out of total %d resolved", - resolved->naddrs); - goto error; - } - if (count != resolved->naddrs) { - gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved", - count, resolved->naddrs); - /* if it's an error, don't we want to goto error; here ? */ - } - grpc_resolved_addresses_destroy(resolved); - - /* Register with the server only upon success */ - grpc_server_add_listener(&exec_ctx, server, state, start, destroy); - - grpc_exec_ctx_finish(&exec_ctx); - return port_num; - -/* Error path: cleanup and return */ -error: - if (resolved) { - grpc_resolved_addresses_destroy(resolved); - } - if (tcp) { - grpc_tcp_server_unref(&exec_ctx, tcp); - } else { - if (sc) { - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server"); - } - if (state) { - gpr_free(state); - } - } - grpc_exec_ctx_finish(&exec_ctx); - return 0; -} diff --git a/src/core/statistics/census_init.c b/src/core/statistics/census_init.c deleted file mode 100644 index b6a962f228..0000000000 --- a/src/core/statistics/census_init.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright 2015-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/statistics/census_interface.h" - -#include -#include "src/core/statistics/census_rpc_stats.h" -#include "src/core/statistics/census_tracing.h" - -void census_init(void) { - census_tracing_init(); - census_stats_store_init(); -} - -void census_shutdown(void) { - census_stats_store_shutdown(); - census_tracing_shutdown(); -} diff --git a/src/core/statistics/census_interface.h b/src/core/statistics/census_interface.h deleted file mode 100644 index ce8ff92cd4..0000000000 --- a/src/core/statistics/census_interface.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * - * Copyright 2015-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_STATISTICS_CENSUS_INTERFACE_H -#define GRPC_CORE_STATISTICS_CENSUS_INTERFACE_H - -#include - -/* Maximum length of an individual census trace annotation. */ -#define CENSUS_MAX_ANNOTATION_LENGTH 200 - -/* Structure of a census op id. Define as structure because 64bit integer is not - available on every platform for C89. */ -typedef struct census_op_id { - uint32_t upper; - uint32_t lower; -} census_op_id; - -typedef struct census_rpc_stats census_rpc_stats; - -/* Initializes Census library. No-op if Census is already initialized. */ -void census_init(void); - -/* Shutdown Census Library. */ -void census_shutdown(void); - -/* Annotates grpc method name on a census_op_id. The method name has the format - of /. Returns 0 iff - op_id and method_name are all valid. op_id is valid after its creation and - before calling census_tracing_end_op(). - - TODO(hongyu): Figure out valid characters set for service name and command - name and document requirements here.*/ -int census_add_method_tag(census_op_id op_id, const char *method_name); - -/* Annotates tracing information to a specific op_id. - Up to CENSUS_MAX_ANNOTATION_LENGTH bytes are recorded. */ -void census_tracing_print(census_op_id op_id, const char *annotation); - -/* Starts tracing for an RPC. Returns a locally unique census_op_id */ -census_op_id census_tracing_start_op(void); - -/* Ends tracing. Calling this function will invalidate the input op_id. */ -void census_tracing_end_op(census_op_id op_id); - -#endif /* GRPC_CORE_STATISTICS_CENSUS_INTERFACE_H */ diff --git a/src/core/statistics/census_log.c b/src/core/statistics/census_log.c deleted file mode 100644 index 3802d1cc7a..0000000000 --- a/src/core/statistics/census_log.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* Available log space is divided up in blocks of - CENSUS_LOG_2_MAX_RECORD_SIZE bytes. A block can be in one of the - following three data structures: - - Free blocks (free_block_list) - - Blocks with unread data (dirty_block_list) - - Blocks currently attached to cores (core_local_blocks[]) - - census_log_start_write() moves a block from core_local_blocks[] to the - end of dirty_block_list when block: - - is out-of-space OR - - has an incomplete record (an incomplete record occurs when a thread calls - census_log_start_write() and is context-switched before calling - census_log_end_write() - So, blocks in dirty_block_list are ordered, from oldest to newest, by time - when block is detached from the core. - - census_log_read_next() first iterates over dirty_block_list and then - core_local_blocks[]. It moves completely read blocks from dirty_block_list - to free_block_list. Blocks in core_local_blocks[] are not freed, even when - completely read. - - If log is configured to discard old records and free_block_list is empty, - census_log_start_write() iterates over dirty_block_list to allocate a - new block. It moves the oldest available block (no pending read/write) to - core_local_blocks[]. - - core_local_block_struct is used to implement a map from core id to the block - associated with that core. This mapping is advisory. It is possible that the - block returned by this mapping is no longer associated with that core. This - mapping is updated, lazily, by census_log_start_write(). - - Locking in block struct: - - Exclusive g_log.lock must be held before calling any functions operatong on - block structs except census_log_start_write() and - census_log_end_write(). - - Writes to a block are serialized via writer_lock. - census_log_start_write() acquires this lock and - census_log_end_write() releases it. On failure to acquire the lock, - writer allocates a new block for the current core and updates - core_local_block accordingly. - - Simultaneous read and write access is allowed. Reader can safely read up to - committed bytes (bytes_committed). - - reader_lock protects the block, currently being read, from getting recycled. - start_read() acquires reader_lock and end_read() releases the lock. - - Read/write access to a block is disabled via try_disable_access(). It returns - with both writer_lock and reader_lock held. These locks are subsequently - released by enable_access() to enable access to the block. - - A note on naming: Most function/struct names are prepended by cl_ - (shorthand for census_log). Further, functions that manipulate structures - include the name of the structure, which will be passed as the first - argument. E.g. cl_block_initialize() will initialize a cl_block. -*/ -#include "src/core/statistics/census_log.h" -#include -#include -#include -#include -#include -#include -#include -#include - -/* End of platform specific code */ - -typedef struct census_log_block_list_struct { - struct census_log_block_list_struct *next; - struct census_log_block_list_struct *prev; - struct census_log_block *block; -} cl_block_list_struct; - -typedef struct census_log_block { - /* Pointer to underlying buffer */ - char *buffer; - gpr_atm writer_lock; - gpr_atm reader_lock; - /* Keeps completely written bytes. Declared atomic because accessed - simultaneously by reader and writer. */ - gpr_atm bytes_committed; - /* Bytes already read */ - int32_t bytes_read; - /* Links for list */ - cl_block_list_struct link; -/* We want this structure to be cacheline aligned. We assume the following - sizes for the various parts on 32/64bit systems: - type 32b size 64b size - char* 4 8 - 3x gpr_atm 12 24 - int32_t 4 8 (assumes padding) - cl_block_list_struct 12 24 - TOTAL 32 64 - - Depending on the size of our cacheline and the architecture, we - selectively add char buffering to this structure. The size is checked - via assert in census_log_initialize(). */ -#if defined(GPR_ARCH_64) -#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 64) -#else -#if defined(GPR_ARCH_32) -#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 32) -#else -#error "Unknown architecture" -#endif -#endif -#if CL_BLOCK_PAD_SIZE > 0 - char padding[CL_BLOCK_PAD_SIZE]; -#endif -} cl_block; - -/* A list of cl_blocks, doubly-linked through cl_block::link. */ -typedef struct census_log_block_list { - int32_t count; /* Number of items in list. */ - cl_block_list_struct ht; /* head/tail of linked list. */ -} cl_block_list; - -/* Cacheline aligned block pointers to avoid false sharing. Block pointer must - be initialized via set_block(), before calling other functions */ -typedef struct census_log_core_local_block { - gpr_atm block; -/* Ensure cachline alignment: we assume sizeof(gpr_atm) == 4 or 8 */ -#if defined(GPR_ARCH_64) -#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 8) -#else -#if defined(GPR_ARCH_32) -#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 4) -#else -#error "Unknown architecture" -#endif -#endif -#if CL_CORE_LOCAL_BLOCK_PAD_SIZE > 0 - char padding[CL_CORE_LOCAL_BLOCK_PAD_SIZE]; -#endif -} cl_core_local_block; - -struct census_log { - int discard_old_records; - /* Number of cores (aka hardware-contexts) */ - unsigned num_cores; - /* number of CENSUS_LOG_2_MAX_RECORD_SIZE blocks in log */ - int32_t num_blocks; - cl_block *blocks; /* Block metadata. */ - cl_core_local_block *core_local_blocks; /* Keeps core to block mappings. */ - gpr_mu lock; - int initialized; /* has log been initialized? */ - /* Keeps the state of the reader iterator. A value of 0 indicates that - iterator has reached the end. census_log_init_reader() resets the - value to num_core to restart iteration. */ - uint32_t read_iterator_state; - /* Points to the block being read. If non-NULL, the block is locked for - reading (block_being_read_->reader_lock is held). */ - cl_block *block_being_read; - /* A non-zero value indicates that log is full. */ - gpr_atm is_full; - char *buffer; - cl_block_list free_block_list; - cl_block_list dirty_block_list; - gpr_atm out_of_space_count; -}; - -/* Single internal log */ -static struct census_log g_log; - -/* Functions that operate on an atomic memory location used as a lock */ - -/* Returns non-zero if lock is acquired */ -static int cl_try_lock(gpr_atm *lock) { return gpr_atm_acq_cas(lock, 0, 1); } - -static void cl_unlock(gpr_atm *lock) { gpr_atm_rel_store(lock, 0); } - -/* Functions that operate on cl_core_local_block's */ - -static void cl_core_local_block_set_block(cl_core_local_block *clb, - cl_block *block) { - gpr_atm_rel_store(&clb->block, (gpr_atm)block); -} - -static cl_block *cl_core_local_block_get_block(cl_core_local_block *clb) { - return (cl_block *)gpr_atm_acq_load(&clb->block); -} - -/* Functions that operate on cl_block_list_struct's */ - -static void cl_block_list_struct_initialize(cl_block_list_struct *bls, - cl_block *block) { - bls->next = bls->prev = bls; - bls->block = block; -} - -/* Functions that operate on cl_block_list's */ - -static void cl_block_list_initialize(cl_block_list *list) { - list->count = 0; - cl_block_list_struct_initialize(&list->ht, NULL); -} - -/* Returns head of *this, or NULL if empty. */ -static cl_block *cl_block_list_head(cl_block_list *list) { - return list->ht.next->block; -} - -/* Insert element *e after *pos. */ -static void cl_block_list_insert(cl_block_list *list, cl_block_list_struct *pos, - cl_block_list_struct *e) { - list->count++; - e->next = pos->next; - e->prev = pos; - e->next->prev = e; - e->prev->next = e; -} - -/* Insert block at the head of the list */ -static void cl_block_list_insert_at_head(cl_block_list *list, cl_block *block) { - cl_block_list_insert(list, &list->ht, &block->link); -} - -/* Insert block at the tail of the list */ -static void cl_block_list_insert_at_tail(cl_block_list *list, cl_block *block) { - cl_block_list_insert(list, list->ht.prev, &block->link); -} - -/* Removes block *b. Requires *b be in the list. */ -static void cl_block_list_remove(cl_block_list *list, cl_block *b) { - list->count--; - b->link.next->prev = b->link.prev; - b->link.prev->next = b->link.next; -} - -/* Functions that operate on cl_block's */ - -static void cl_block_initialize(cl_block *block, char *buffer) { - block->buffer = buffer; - gpr_atm_rel_store(&block->writer_lock, 0); - gpr_atm_rel_store(&block->reader_lock, 0); - gpr_atm_rel_store(&block->bytes_committed, 0); - block->bytes_read = 0; - cl_block_list_struct_initialize(&block->link, block); -} - -/* Guards against exposing partially written buffer to the reader. */ -static void cl_block_set_bytes_committed(cl_block *block, - int32_t bytes_committed) { - gpr_atm_rel_store(&block->bytes_committed, bytes_committed); -} - -static int32_t cl_block_get_bytes_committed(cl_block *block) { - return gpr_atm_acq_load(&block->bytes_committed); -} - -/* Tries to disable future read/write access to this block. Succeeds if: - - no in-progress write AND - - no in-progress read AND - - 'discard_data' set to true OR no unread data - On success, clears the block state and returns with writer_lock_ and - reader_lock_ held. These locks are released by a subsequent - cl_block_access_enable() call. */ -static int cl_block_try_disable_access(cl_block *block, int discard_data) { - if (!cl_try_lock(&block->writer_lock)) { - return 0; - } - if (!cl_try_lock(&block->reader_lock)) { - cl_unlock(&block->writer_lock); - return 0; - } - if (!discard_data && - (block->bytes_read != cl_block_get_bytes_committed(block))) { - cl_unlock(&block->reader_lock); - cl_unlock(&block->writer_lock); - return 0; - } - cl_block_set_bytes_committed(block, 0); - block->bytes_read = 0; - return 1; -} - -static void cl_block_enable_access(cl_block *block) { - cl_unlock(&block->reader_lock); - cl_unlock(&block->writer_lock); -} - -/* Returns with writer_lock held. */ -static void *cl_block_start_write(cl_block *block, size_t size) { - int32_t bytes_committed; - if (!cl_try_lock(&block->writer_lock)) { - return NULL; - } - bytes_committed = cl_block_get_bytes_committed(block); - if (bytes_committed + size > CENSUS_LOG_MAX_RECORD_SIZE) { - cl_unlock(&block->writer_lock); - return NULL; - } - return block->buffer + bytes_committed; -} - -/* Releases writer_lock and increments committed bytes by 'bytes_written'. - 'bytes_written' must be <= 'size' specified in the corresponding - StartWrite() call. This function is thread-safe. */ -static void cl_block_end_write(cl_block *block, size_t bytes_written) { - cl_block_set_bytes_committed( - block, cl_block_get_bytes_committed(block) + bytes_written); - cl_unlock(&block->writer_lock); -} - -/* Returns a pointer to the first unread byte in buffer. The number of bytes - available are returned in 'bytes_available'. Acquires reader lock that is - released by a subsequent cl_block_end_read() call. Returns NULL if: - - read in progress - - no data available */ -static void *cl_block_start_read(cl_block *block, size_t *bytes_available) { - void *record; - if (!cl_try_lock(&block->reader_lock)) { - return NULL; - } - /* bytes_committed may change from under us. Use bytes_available to update - bytes_read below. */ - *bytes_available = cl_block_get_bytes_committed(block) - block->bytes_read; - if (*bytes_available == 0) { - cl_unlock(&block->reader_lock); - return NULL; - } - record = block->buffer + block->bytes_read; - block->bytes_read += *bytes_available; - return record; -} - -static void cl_block_end_read(cl_block *block) { - cl_unlock(&block->reader_lock); -} - -/* Internal functions operating on g_log */ - -/* Allocates a new free block (or recycles an available dirty block if log is - configured to discard old records). Returns NULL if out-of-space. */ -static cl_block *cl_allocate_block(void) { - cl_block *block = cl_block_list_head(&g_log.free_block_list); - if (block != NULL) { - cl_block_list_remove(&g_log.free_block_list, block); - return block; - } - if (!g_log.discard_old_records) { - /* No free block and log is configured to keep old records. */ - return NULL; - } - /* Recycle dirty block. Start from the oldest. */ - for (block = cl_block_list_head(&g_log.dirty_block_list); block != NULL; - block = block->link.next->block) { - if (cl_block_try_disable_access(block, 1 /* discard data */)) { - cl_block_list_remove(&g_log.dirty_block_list, block); - return block; - } - } - return NULL; -} - -/* Allocates a new block and updates core id => block mapping. 'old_block' - points to the block that the caller thinks is attached to - 'core_id'. 'old_block' may be NULL. Returns non-zero if: - - allocated a new block OR - - 'core_id' => 'old_block' mapping changed (another thread allocated a - block before lock was acquired). */ -static int cl_allocate_core_local_block(int32_t core_id, cl_block *old_block) { - /* Now that we have the lock, check if core-local mapping has changed. */ - cl_core_local_block *core_local_block = &g_log.core_local_blocks[core_id]; - cl_block *block = cl_core_local_block_get_block(core_local_block); - if ((block != NULL) && (block != old_block)) { - return 1; - } - if (block != NULL) { - cl_core_local_block_set_block(core_local_block, NULL); - cl_block_list_insert_at_tail(&g_log.dirty_block_list, block); - } - block = cl_allocate_block(); - if (block == NULL) { - gpr_atm_rel_store(&g_log.is_full, 1); - return 0; - } - cl_core_local_block_set_block(core_local_block, block); - cl_block_enable_access(block); - return 1; -} - -static cl_block *cl_get_block(void *record) { - uintptr_t p = (uintptr_t)((char *)record - g_log.buffer); - uintptr_t index = p >> CENSUS_LOG_2_MAX_RECORD_SIZE; - return &g_log.blocks[index]; -} - -/* Gets the next block to read and tries to free 'prev' block (if not NULL). - Returns NULL if reached the end. */ -static cl_block *cl_next_block_to_read(cl_block *prev) { - cl_block *block = NULL; - if (g_log.read_iterator_state == g_log.num_cores) { - /* We are traversing dirty list; find the next dirty block. */ - if (prev != NULL) { - /* Try to free the previous block if there is no unread data. This block - may have unread data if previously incomplete record completed between - read_next() calls. */ - block = prev->link.next->block; - if (cl_block_try_disable_access(prev, 0 /* do not discard data */)) { - cl_block_list_remove(&g_log.dirty_block_list, prev); - cl_block_list_insert_at_head(&g_log.free_block_list, prev); - gpr_atm_rel_store(&g_log.is_full, 0); - } - } else { - block = cl_block_list_head(&g_log.dirty_block_list); - } - if (block != NULL) { - return block; - } - /* We are done with the dirty list; moving on to core-local blocks. */ - } - while (g_log.read_iterator_state > 0) { - g_log.read_iterator_state--; - block = cl_core_local_block_get_block( - &g_log.core_local_blocks[g_log.read_iterator_state]); - if (block != NULL) { - return block; - } - } - return NULL; -} - -/* External functions: primary stats_log interface */ -void census_log_initialize(size_t size_in_mb, int discard_old_records) { - int32_t ix; - /* Check cacheline alignment. */ - GPR_ASSERT(sizeof(cl_block) % GPR_CACHELINE_SIZE == 0); - GPR_ASSERT(sizeof(cl_core_local_block) % GPR_CACHELINE_SIZE == 0); - GPR_ASSERT(!g_log.initialized); - g_log.discard_old_records = discard_old_records; - g_log.num_cores = gpr_cpu_num_cores(); - /* Ensure at least as many blocks as there are cores. */ - g_log.num_blocks = GPR_MAX( - g_log.num_cores, (size_in_mb << 20) >> CENSUS_LOG_2_MAX_RECORD_SIZE); - gpr_mu_init(&g_log.lock); - g_log.read_iterator_state = 0; - g_log.block_being_read = NULL; - gpr_atm_rel_store(&g_log.is_full, 0); - g_log.core_local_blocks = (cl_core_local_block *)gpr_malloc_aligned( - g_log.num_cores * sizeof(cl_core_local_block), GPR_CACHELINE_SIZE_LOG); - memset(g_log.core_local_blocks, 0, - g_log.num_cores * sizeof(cl_core_local_block)); - g_log.blocks = (cl_block *)gpr_malloc_aligned( - g_log.num_blocks * sizeof(cl_block), GPR_CACHELINE_SIZE_LOG); - memset(g_log.blocks, 0, g_log.num_blocks * sizeof(cl_block)); - g_log.buffer = gpr_malloc(g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE); - memset(g_log.buffer, 0, g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE); - cl_block_list_initialize(&g_log.free_block_list); - cl_block_list_initialize(&g_log.dirty_block_list); - for (ix = 0; ix < g_log.num_blocks; ++ix) { - cl_block *block = g_log.blocks + ix; - cl_block_initialize(block, - g_log.buffer + (CENSUS_LOG_MAX_RECORD_SIZE * ix)); - cl_block_try_disable_access(block, 1 /* discard data */); - cl_block_list_insert_at_tail(&g_log.free_block_list, block); - } - gpr_atm_rel_store(&g_log.out_of_space_count, 0); - g_log.initialized = 1; -} - -void census_log_shutdown(void) { - GPR_ASSERT(g_log.initialized); - gpr_mu_destroy(&g_log.lock); - gpr_free_aligned(g_log.core_local_blocks); - g_log.core_local_blocks = NULL; - gpr_free_aligned(g_log.blocks); - g_log.blocks = NULL; - gpr_free(g_log.buffer); - g_log.buffer = NULL; - g_log.initialized = 0; -} - -void *census_log_start_write(size_t size) { - /* Used to bound number of times block allocation is attempted. */ - int32_t attempts_remaining = g_log.num_blocks; - /* TODO(aveitch): move this inside the do loop when current_cpu is fixed */ - int32_t core_id = gpr_cpu_current_cpu(); - GPR_ASSERT(g_log.initialized); - if (size > CENSUS_LOG_MAX_RECORD_SIZE) { - return NULL; - } - do { - int allocated; - void *record = NULL; - cl_block *block = - cl_core_local_block_get_block(&g_log.core_local_blocks[core_id]); - if (block && (record = cl_block_start_write(block, size))) { - return record; - } - /* Need to allocate a new block. We are here if: - - No block associated with the core OR - - Write in-progress on the block OR - - block is out of space */ - if (gpr_atm_acq_load(&g_log.is_full)) { - gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1); - return NULL; - } - gpr_mu_lock(&g_log.lock); - allocated = cl_allocate_core_local_block(core_id, block); - gpr_mu_unlock(&g_log.lock); - if (!allocated) { - gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1); - return NULL; - } - } while (attempts_remaining--); - /* Give up. */ - gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1); - return NULL; -} - -void census_log_end_write(void *record, size_t bytes_written) { - GPR_ASSERT(g_log.initialized); - cl_block_end_write(cl_get_block(record), bytes_written); -} - -void census_log_init_reader(void) { - GPR_ASSERT(g_log.initialized); - gpr_mu_lock(&g_log.lock); - /* If a block is locked for reading unlock it. */ - if (g_log.block_being_read != NULL) { - cl_block_end_read(g_log.block_being_read); - g_log.block_being_read = NULL; - } - g_log.read_iterator_state = g_log.num_cores; - gpr_mu_unlock(&g_log.lock); -} - -const void *census_log_read_next(size_t *bytes_available) { - GPR_ASSERT(g_log.initialized); - gpr_mu_lock(&g_log.lock); - if (g_log.block_being_read != NULL) { - cl_block_end_read(g_log.block_being_read); - } - do { - g_log.block_being_read = cl_next_block_to_read(g_log.block_being_read); - if (g_log.block_being_read != NULL) { - void *record = - cl_block_start_read(g_log.block_being_read, bytes_available); - if (record != NULL) { - gpr_mu_unlock(&g_log.lock); - return record; - } - } - } while (g_log.block_being_read != NULL); - gpr_mu_unlock(&g_log.lock); - return NULL; -} - -size_t census_log_remaining_space(void) { - size_t space; - GPR_ASSERT(g_log.initialized); - gpr_mu_lock(&g_log.lock); - if (g_log.discard_old_records) { - /* Remaining space is not meaningful; just return the entire log space. */ - space = g_log.num_blocks << CENSUS_LOG_2_MAX_RECORD_SIZE; - } else { - space = g_log.free_block_list.count * CENSUS_LOG_MAX_RECORD_SIZE; - } - gpr_mu_unlock(&g_log.lock); - return space; -} - -int census_log_out_of_space_count(void) { - GPR_ASSERT(g_log.initialized); - return gpr_atm_acq_load(&g_log.out_of_space_count); -} diff --git a/src/core/statistics/census_log.h b/src/core/statistics/census_log.h deleted file mode 100644 index e7ce0d4433..0000000000 --- a/src/core/statistics/census_log.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * Copyright 2015-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_STATISTICS_CENSUS_LOG_H -#define GRPC_CORE_STATISTICS_CENSUS_LOG_H - -#include - -/* Maximum record size, in bytes. */ -#define CENSUS_LOG_2_MAX_RECORD_SIZE 14 /* 2^14 = 16KB */ -#define CENSUS_LOG_MAX_RECORD_SIZE (1 << CENSUS_LOG_2_MAX_RECORD_SIZE) - -/* Initialize the statistics logging subsystem with the given log size. A log - size of 0 will result in the smallest possible log for the platform - (approximately CENSUS_LOG_MAX_RECORD_SIZE * gpr_cpu_num_cores()). If - discard_old_records is non-zero, then new records will displace older ones - when the log is full. This function must be called before any other - census_log functions. -*/ -void census_log_initialize(size_t size_in_mb, int discard_old_records); - -/* Shutdown the logging subsystem. Caller must ensure that: - - no in progress or future call to any census_log functions - - no incomplete records -*/ -void census_log_shutdown(void); - -/* Allocates and returns a 'size' bytes record and marks it in use. A - subsequent census_log_end_write() marks the record complete. The - 'bytes_written' census_log_end_write() argument must be <= - 'size'. Returns NULL if out-of-space AND: - - log is configured to keep old records OR - - all blocks are pinned by incomplete records. -*/ -void *census_log_start_write(size_t size); - -void census_log_end_write(void *record, size_t bytes_written); - -/* census_log_read_next() iterates over blocks with data and for each block - returns a pointer to the first unread byte. The number of bytes that can be - read are returned in 'bytes_available'. Reader is expected to read all - available data. Reading the data consumes it i.e. it cannot be read again. - census_log_read_next() returns NULL if the end is reached i.e last block - is read. census_log_init_reader() starts the iteration or aborts the - current iteration. -*/ -void census_log_init_reader(void); -const void *census_log_read_next(size_t *bytes_available); - -/* Returns estimated remaining space across all blocks, in bytes. If log is - configured to discard old records, returns total log space. Otherwise, - returns space available in empty blocks (partially filled blocks are - treated as full). -*/ -size_t census_log_remaining_space(void); - -/* Returns the number of times gprc_stats_log_start_write() failed due to - out-of-space. */ -int census_log_out_of_space_count(void); - -#endif /* GRPC_CORE_STATISTICS_CENSUS_LOG_H */ diff --git a/src/core/statistics/census_rpc_stats.c b/src/core/statistics/census_rpc_stats.c deleted file mode 100644 index c78d6fd612..0000000000 --- a/src/core/statistics/census_rpc_stats.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include -#include -#include -#include "src/core/statistics/census_interface.h" -#include "src/core/statistics/census_rpc_stats.h" -#include "src/core/statistics/census_tracing.h" -#include "src/core/statistics/hash_table.h" -#include "src/core/statistics/window_stats.h" -#include "src/core/support/murmur_hash.h" -#include "src/core/support/string.h" - -#define NUM_INTERVALS 3 -#define MINUTE_INTERVAL 0 -#define HOUR_INTERVAL 1 -#define TOTAL_INTERVAL 2 - -/* for easier typing */ -typedef census_per_method_rpc_stats per_method_stats; - -/* Ensure mu is only initialized once. */ -static gpr_once g_stats_store_mu_init = GPR_ONCE_INIT; -/* Guards two stats stores. */ -static gpr_mu g_mu; -static census_ht *g_client_stats_store = NULL; -static census_ht *g_server_stats_store = NULL; - -static void init_mutex(void) { gpr_mu_init(&g_mu); } - -static void init_mutex_once(void) { - gpr_once_init(&g_stats_store_mu_init, init_mutex); -} - -static int cmp_str_keys(const void *k1, const void *k2) { - return strcmp((const char *)k1, (const char *)k2); -} - -/* TODO(hongyu): replace it with cityhash64 */ -static uint64_t simple_hash(const void *k) { - size_t len = strlen(k); - uint64_t higher = gpr_murmur_hash3((const char *)k, len / 2, 0); - return higher << 32 | - gpr_murmur_hash3((const char *)k + len / 2, len - len / 2, 0); -} - -static void delete_stats(void *stats) { - census_window_stats_destroy((struct census_window_stats *)stats); -} - -static void delete_key(void *key) { gpr_free(key); } - -static const census_ht_option ht_opt = { - CENSUS_HT_POINTER /* key type */, 1999 /* n_of_buckets */, - simple_hash /* hash function */, cmp_str_keys /* key comparator */, - delete_stats /* data deleter */, delete_key /* key deleter */ -}; - -static void init_rpc_stats(void *stats) { - memset(stats, 0, sizeof(census_rpc_stats)); -} - -static void stat_add_proportion(double p, void *base, const void *addme) { - census_rpc_stats *b = (census_rpc_stats *)base; - census_rpc_stats *a = (census_rpc_stats *)addme; - b->cnt += p * a->cnt; - b->rpc_error_cnt += p * a->rpc_error_cnt; - b->app_error_cnt += p * a->app_error_cnt; - b->elapsed_time_ms += p * a->elapsed_time_ms; - b->api_request_bytes += p * a->api_request_bytes; - b->wire_request_bytes += p * a->wire_request_bytes; - b->api_response_bytes += p * a->api_response_bytes; - b->wire_response_bytes += p * a->wire_response_bytes; -} - -static void stat_add(void *base, const void *addme) { - stat_add_proportion(1.0, base, addme); -} - -static gpr_timespec min_hour_total_intervals[3] = { - {60, 0}, {3600, 0}, {36000000, 0}}; - -static const census_window_stats_stat_info window_stats_settings = { - sizeof(census_rpc_stats), init_rpc_stats, stat_add, stat_add_proportion}; - -census_rpc_stats *census_rpc_stats_create_empty(void) { - census_rpc_stats *ret = - (census_rpc_stats *)gpr_malloc(sizeof(census_rpc_stats)); - memset(ret, 0, sizeof(census_rpc_stats)); - return ret; -} - -void census_aggregated_rpc_stats_set_empty(census_aggregated_rpc_stats *data) { - int i = 0; - for (i = 0; i < data->num_entries; i++) { - if (data->stats[i].method != NULL) { - gpr_free((void *)data->stats[i].method); - } - } - if (data->stats != NULL) { - gpr_free(data->stats); - } - data->num_entries = 0; - data->stats = NULL; -} - -static void record_stats(census_ht *store, census_op_id op_id, - const census_rpc_stats *stats) { - gpr_mu_lock(&g_mu); - if (store != NULL) { - census_trace_obj *trace = NULL; - census_internal_lock_trace_store(); - trace = census_get_trace_obj_locked(op_id); - if (trace != NULL) { - const char *method_name = census_get_trace_method_name(trace); - struct census_window_stats *window_stats = NULL; - census_ht_key key; - key.ptr = (void *)method_name; - window_stats = census_ht_find(store, key); - census_internal_unlock_trace_store(); - if (window_stats == NULL) { - window_stats = census_window_stats_create(3, min_hour_total_intervals, - 30, &window_stats_settings); - key.ptr = gpr_strdup(key.ptr); - census_ht_insert(store, key, (void *)window_stats); - } - census_window_stats_add(window_stats, gpr_now(GPR_CLOCK_REALTIME), stats); - } else { - census_internal_unlock_trace_store(); - } - } - gpr_mu_unlock(&g_mu); -} - -void census_record_rpc_client_stats(census_op_id op_id, - const census_rpc_stats *stats) { - record_stats(g_client_stats_store, op_id, stats); -} - -void census_record_rpc_server_stats(census_op_id op_id, - const census_rpc_stats *stats) { - record_stats(g_server_stats_store, op_id, stats); -} - -/* Get stats from input stats store */ -static void get_stats(census_ht *store, census_aggregated_rpc_stats *data) { - GPR_ASSERT(data != NULL); - if (data->num_entries != 0) { - census_aggregated_rpc_stats_set_empty(data); - } - gpr_mu_lock(&g_mu); - if (store != NULL) { - size_t n; - unsigned i, j; - gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); - census_ht_kv *kv = census_ht_get_all_elements(store, &n); - if (kv != NULL) { - data->num_entries = n; - data->stats = - (per_method_stats *)gpr_malloc(sizeof(per_method_stats) * n); - for (i = 0; i < n; i++) { - census_window_stats_sums sums[NUM_INTERVALS]; - for (j = 0; j < NUM_INTERVALS; j++) { - sums[j].statistic = (void *)census_rpc_stats_create_empty(); - } - data->stats[i].method = gpr_strdup(kv[i].k.ptr); - census_window_stats_get_sums(kv[i].v, now, sums); - data->stats[i].minute_stats = - *(census_rpc_stats *)sums[MINUTE_INTERVAL].statistic; - data->stats[i].hour_stats = - *(census_rpc_stats *)sums[HOUR_INTERVAL].statistic; - data->stats[i].total_stats = - *(census_rpc_stats *)sums[TOTAL_INTERVAL].statistic; - for (j = 0; j < NUM_INTERVALS; j++) { - gpr_free(sums[j].statistic); - } - } - gpr_free(kv); - } - } - gpr_mu_unlock(&g_mu); -} - -void census_get_client_stats(census_aggregated_rpc_stats *data) { - get_stats(g_client_stats_store, data); -} - -void census_get_server_stats(census_aggregated_rpc_stats *data) { - get_stats(g_server_stats_store, data); -} - -void census_stats_store_init(void) { - init_mutex_once(); - gpr_mu_lock(&g_mu); - if (g_client_stats_store == NULL && g_server_stats_store == NULL) { - g_client_stats_store = census_ht_create(&ht_opt); - g_server_stats_store = census_ht_create(&ht_opt); - } else { - gpr_log(GPR_ERROR, "Census stats store already initialized."); - } - gpr_mu_unlock(&g_mu); -} - -void census_stats_store_shutdown(void) { - init_mutex_once(); - gpr_mu_lock(&g_mu); - if (g_client_stats_store != NULL) { - census_ht_destroy(g_client_stats_store); - g_client_stats_store = NULL; - } else { - gpr_log(GPR_ERROR, "Census server stats store not initialized."); - } - if (g_server_stats_store != NULL) { - census_ht_destroy(g_server_stats_store); - g_server_stats_store = NULL; - } else { - gpr_log(GPR_ERROR, "Census client stats store not initialized."); - } - gpr_mu_unlock(&g_mu); -} diff --git a/src/core/statistics/census_rpc_stats.h b/src/core/statistics/census_rpc_stats.h deleted file mode 100644 index f7f220e45f..0000000000 --- a/src/core/statistics/census_rpc_stats.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * Copyright 2015-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_STATISTICS_CENSUS_RPC_STATS_H -#define GRPC_CORE_STATISTICS_CENSUS_RPC_STATS_H - -#include -#include "src/core/statistics/census_interface.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct census_rpc_stats { - uint64_t cnt; - uint64_t rpc_error_cnt; - uint64_t app_error_cnt; - double elapsed_time_ms; - double api_request_bytes; - double wire_request_bytes; - double api_response_bytes; - double wire_response_bytes; -}; - -/* Creates an empty rpc stats object on heap. */ -census_rpc_stats *census_rpc_stats_create_empty(void); - -typedef struct census_per_method_rpc_stats { - const char *method; - census_rpc_stats minute_stats; /* cumulative stats in the past minute */ - census_rpc_stats hour_stats; /* cumulative stats in the past hour */ - census_rpc_stats total_stats; /* cumulative stats from last gc */ -} census_per_method_rpc_stats; - -typedef struct census_aggregated_rpc_stats { - int num_entries; - census_per_method_rpc_stats *stats; -} census_aggregated_rpc_stats; - -/* Initializes an aggregated rpc stats object to an empty state. */ -void census_aggregated_rpc_stats_set_empty(census_aggregated_rpc_stats *data); - -/* Records client side stats of a rpc. */ -void census_record_rpc_client_stats(census_op_id op_id, - const census_rpc_stats *stats); - -/* Records server side stats of a rpc. */ -void census_record_rpc_server_stats(census_op_id op_id, - const census_rpc_stats *stats); - -/* The following two functions are intended for inprocess query of - per-service per-method stats from grpc implementations. */ - -/* Populates *data_map with server side aggregated per-service per-method - stats. - DO NOT CALL from outside of grpc code. */ -void census_get_server_stats(census_aggregated_rpc_stats *data_map); - -/* Populates *data_map with client side aggregated per-service per-method - stats. - DO NOT CALL from outside of grpc code. */ -void census_get_client_stats(census_aggregated_rpc_stats *data_map); - -void census_stats_store_init(void); -void census_stats_store_shutdown(void); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_STATISTICS_CENSUS_RPC_STATS_H */ diff --git a/src/core/statistics/census_tracing.c b/src/core/statistics/census_tracing.c deleted file mode 100644 index ad82498eba..0000000000 --- a/src/core/statistics/census_tracing.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * - * Copyright 2015-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/statistics/census_tracing.h" -#include "src/core/statistics/census_interface.h" - -#include -#include - -#include -#include -#include -#include -#include "src/core/statistics/hash_table.h" -#include "src/core/support/string.h" - -void census_trace_obj_destroy(census_trace_obj *obj) { - census_trace_annotation *p = obj->annotations; - while (p != NULL) { - census_trace_annotation *next = p->next; - gpr_free(p); - p = next; - } - gpr_free(obj->method); - gpr_free(obj); -} - -static void delete_trace_obj(void *obj) { - census_trace_obj_destroy((census_trace_obj *)obj); -} - -static const census_ht_option ht_opt = { - CENSUS_HT_UINT64 /* key type */, - 571 /* n_of_buckets */, - NULL /* hash */, - NULL /* compare_keys */, - delete_trace_obj /* delete data */, - NULL /* delete key */ -}; - -static gpr_once g_init_mutex_once = GPR_ONCE_INIT; -static gpr_mu g_mu; /* Guards following two static variables. */ -static census_ht *g_trace_store = NULL; -static uint64_t g_id = 0; - -static census_ht_key op_id_as_key(census_op_id *id) { - return *(census_ht_key *)id; -} - -static uint64_t op_id_2_uint64(census_op_id *id) { - uint64_t ret; - memcpy(&ret, id, sizeof(census_op_id)); - return ret; -} - -static void init_mutex(void) { gpr_mu_init(&g_mu); } - -static void init_mutex_once(void) { - gpr_once_init(&g_init_mutex_once, init_mutex); -} - -census_op_id census_tracing_start_op(void) { - gpr_mu_lock(&g_mu); - { - census_trace_obj *ret = gpr_malloc(sizeof(census_trace_obj)); - memset(ret, 0, sizeof(census_trace_obj)); - g_id++; - memcpy(&ret->id, &g_id, sizeof(census_op_id)); - ret->rpc_stats.cnt = 1; - ret->ts = gpr_now(GPR_CLOCK_REALTIME); - census_ht_insert(g_trace_store, op_id_as_key(&ret->id), (void *)ret); - gpr_log(GPR_DEBUG, "Start tracing for id %lu", g_id); - gpr_mu_unlock(&g_mu); - return ret->id; - } -} - -int census_add_method_tag(census_op_id op_id, const char *method) { - int ret = 0; - census_trace_obj *trace = NULL; - gpr_mu_lock(&g_mu); - trace = census_ht_find(g_trace_store, op_id_as_key(&op_id)); - if (trace == NULL) { - ret = 1; - } else { - trace->method = gpr_strdup(method); - } - gpr_mu_unlock(&g_mu); - return ret; -} - -void census_tracing_print(census_op_id op_id, const char *anno_txt) { - census_trace_obj *trace = NULL; - gpr_mu_lock(&g_mu); - trace = census_ht_find(g_trace_store, op_id_as_key(&op_id)); - if (trace != NULL) { - census_trace_annotation *anno = gpr_malloc(sizeof(census_trace_annotation)); - anno->ts = gpr_now(GPR_CLOCK_REALTIME); - { - char *d = anno->txt; - const char *s = anno_txt; - int n = 0; - for (; n < CENSUS_MAX_ANNOTATION_LENGTH && *s != '\0'; ++n) { - *d++ = *s++; - } - *d = '\0'; - } - anno->next = trace->annotations; - trace->annotations = anno; - } - gpr_mu_unlock(&g_mu); -} - -void census_tracing_end_op(census_op_id op_id) { - census_trace_obj *trace = NULL; - gpr_mu_lock(&g_mu); - trace = census_ht_find(g_trace_store, op_id_as_key(&op_id)); - if (trace != NULL) { - trace->rpc_stats.elapsed_time_ms = gpr_timespec_to_micros( - gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), trace->ts)); - gpr_log(GPR_DEBUG, "End tracing for id %lu, method %s, latency %f us", - op_id_2_uint64(&op_id), trace->method, - trace->rpc_stats.elapsed_time_ms); - census_ht_erase(g_trace_store, op_id_as_key(&op_id)); - } - gpr_mu_unlock(&g_mu); -} - -void census_tracing_init(void) { - init_mutex_once(); - gpr_mu_lock(&g_mu); - if (g_trace_store == NULL) { - g_id = 1; - g_trace_store = census_ht_create(&ht_opt); - } else { - gpr_log(GPR_ERROR, "Census trace store already initialized."); - } - gpr_mu_unlock(&g_mu); -} - -void census_tracing_shutdown(void) { - gpr_mu_lock(&g_mu); - if (g_trace_store != NULL) { - census_ht_destroy(g_trace_store); - g_trace_store = NULL; - } else { - gpr_log(GPR_ERROR, "Census trace store is not initialized."); - } - gpr_mu_unlock(&g_mu); -} - -void census_internal_lock_trace_store(void) { gpr_mu_lock(&g_mu); } - -void census_internal_unlock_trace_store(void) { gpr_mu_unlock(&g_mu); } - -census_trace_obj *census_get_trace_obj_locked(census_op_id op_id) { - if (g_trace_store == NULL) { - gpr_log(GPR_ERROR, "Census trace store is not initialized."); - return NULL; - } - return (census_trace_obj *)census_ht_find(g_trace_store, - op_id_as_key(&op_id)); -} - -const char *census_get_trace_method_name(const census_trace_obj *trace) { - return trace->method; -} - -static census_trace_annotation *dup_annotation_chain( - census_trace_annotation *from) { - census_trace_annotation *ret = NULL; - census_trace_annotation **to = &ret; - for (; from != NULL; from = from->next) { - *to = gpr_malloc(sizeof(census_trace_annotation)); - memcpy(*to, from, sizeof(census_trace_annotation)); - to = &(*to)->next; - } - return ret; -} - -static census_trace_obj *trace_obj_dup(census_trace_obj *from) { - census_trace_obj *to = NULL; - GPR_ASSERT(from != NULL); - to = gpr_malloc(sizeof(census_trace_obj)); - to->id = from->id; - to->ts = from->ts; - to->rpc_stats = from->rpc_stats; - to->method = gpr_strdup(from->method); - to->annotations = dup_annotation_chain(from->annotations); - return to; -} - -census_trace_obj **census_get_active_ops(int *num_active_ops) { - census_trace_obj **ret = NULL; - gpr_mu_lock(&g_mu); - if (g_trace_store != NULL) { - size_t n = 0; - census_ht_kv *all_kvs = census_ht_get_all_elements(g_trace_store, &n); - *num_active_ops = (int)n; - if (n != 0) { - size_t i = 0; - ret = gpr_malloc(sizeof(census_trace_obj *) * n); - for (i = 0; i < n; i++) { - ret[i] = trace_obj_dup((census_trace_obj *)all_kvs[i].v); - } - } - gpr_free(all_kvs); - } - gpr_mu_unlock(&g_mu); - return ret; -} diff --git a/src/core/statistics/census_tracing.h b/src/core/statistics/census_tracing.h deleted file mode 100644 index b611e95bf4..0000000000 --- a/src/core/statistics/census_tracing.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * - * Copyright 2015-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_STATISTICS_CENSUS_TRACING_H -#define GRPC_CORE_STATISTICS_CENSUS_TRACING_H - -#include -#include "src/core/statistics/census_rpc_stats.h" - -/* WARNING: The data structures and APIs provided by this file are for GRPC - library's internal use ONLY. They might be changed in backward-incompatible - ways and are not subject to any deprecation policy. - They are not recommended for external use. - */ -#ifdef __cplusplus -extern "C" { -#endif - -/* Struct for a trace annotation. */ -typedef struct census_trace_annotation { - gpr_timespec ts; /* timestamp of the annotation */ - char txt[CENSUS_MAX_ANNOTATION_LENGTH + 1]; /* actual txt annotation */ - struct census_trace_annotation *next; -} census_trace_annotation; - -typedef struct census_trace_obj { - census_op_id id; - gpr_timespec ts; - census_rpc_stats rpc_stats; - char *method; - census_trace_annotation *annotations; -} census_trace_obj; - -/* Deletes trace object. */ -void census_trace_obj_destroy(census_trace_obj *obj); - -/* Initializes trace store. This function is thread safe. */ -void census_tracing_init(void); - -/* Shutsdown trace store. This function is thread safe. */ -void census_tracing_shutdown(void); - -/* Gets trace obj corresponding to the input op_id. Returns NULL if trace store - is not initialized or trace obj is not found. Requires trace store being - locked before calling this function. */ -census_trace_obj *census_get_trace_obj_locked(census_op_id op_id); - -/* The following two functions acquire and release the trace store global lock. - They are for census internal use only. */ -void census_internal_lock_trace_store(void); -void census_internal_unlock_trace_store(void); - -/* Gets method name associated with the input trace object. */ -const char *census_get_trace_method_name(const census_trace_obj *trace); - -/* Returns an array of pointers to trace objects of currently active operations - and fills in number of active operations. Returns NULL if there are no active - operations. - Caller owns the returned objects. */ -census_trace_obj **census_get_active_ops(int *num_active_ops); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_STATISTICS_CENSUS_TRACING_H */ diff --git a/src/core/statistics/hash_table.c b/src/core/statistics/hash_table.c deleted file mode 100644 index 3ef79c0d7d..0000000000 --- a/src/core/statistics/hash_table.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * - * Copyright 2015-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/statistics/hash_table.h" - -#include -#include - -#include -#include -#include - -#define CENSUS_HT_NUM_BUCKETS 1999 - -/* A single hash table data entry */ -typedef struct ht_entry { - census_ht_key key; - void *data; - struct ht_entry *next; -} ht_entry; - -/* hash table bucket */ -typedef struct bucket { - /* NULL if bucket is empty */ - ht_entry *next; - /* -1 if all buckets are empty. */ - int32_t prev_non_empty_bucket; - /* -1 if all buckets are empty. */ - int32_t next_non_empty_bucket; -} bucket; - -struct unresizable_hash_table { - /* Number of entries in the table */ - size_t size; - /* Number of buckets */ - uint32_t num_buckets; - /* Array of buckets initialized at creation time. Memory consumption is - 16 bytes per bucket on a 64-bit platform. */ - bucket *buckets; - /* Index of the first non-empty bucket. -1 iff size == 0. */ - int32_t first_non_empty_bucket; - /* Index of the last non_empty bucket. -1 iff size == 0. */ - int32_t last_non_empty_bucket; - /* Immutable options of this hash table, initialized at creation time. */ - census_ht_option options; -}; - -typedef struct entry_locator { - int32_t bucket_idx; - int is_first_in_chain; - int found; - ht_entry *prev_entry; -} entry_locator; - -/* Asserts if option is not valid. */ -void check_options(const census_ht_option *option) { - GPR_ASSERT(option != NULL); - GPR_ASSERT(option->num_buckets > 0); - GPR_ASSERT(option->key_type == CENSUS_HT_UINT64 || - option->key_type == CENSUS_HT_POINTER); - if (option->key_type == CENSUS_HT_UINT64) { - GPR_ASSERT(option->hash == NULL); - } else if (option->key_type == CENSUS_HT_POINTER) { - GPR_ASSERT(option->hash != NULL); - GPR_ASSERT(option->compare_keys != NULL); - } -} - -#define REMOVE_NEXT(options, ptr) \ - do { \ - ht_entry *tmp = (ptr)->next; \ - (ptr)->next = tmp->next; \ - delete_entry(options, tmp); \ - } while (0) - -static void delete_entry(const census_ht_option *opt, ht_entry *p) { - if (opt->delete_data != NULL) { - opt->delete_data(p->data); - } - if (opt->delete_key != NULL) { - opt->delete_key(p->key.ptr); - } - gpr_free(p); -} - -static uint64_t hash(const census_ht_option *opt, census_ht_key key) { - return opt->key_type == CENSUS_HT_UINT64 ? key.val : opt->hash(key.ptr); -} - -census_ht *census_ht_create(const census_ht_option *option) { - int i; - census_ht *ret = NULL; - check_options(option); - ret = (census_ht *)gpr_malloc(sizeof(census_ht)); - ret->size = 0; - ret->num_buckets = option->num_buckets; - ret->buckets = (bucket *)gpr_malloc(sizeof(bucket) * ret->num_buckets); - ret->options = *option; - /* initialize each bucket */ - for (i = 0; i < ret->options.num_buckets; i++) { - ret->buckets[i].prev_non_empty_bucket = -1; - ret->buckets[i].next_non_empty_bucket = -1; - ret->buckets[i].next = NULL; - } - return ret; -} - -static int32_t find_bucket_idx(const census_ht *ht, census_ht_key key) { - return hash(&ht->options, key) % ht->num_buckets; -} - -static int keys_match(const census_ht_option *opt, const ht_entry *p, - const census_ht_key key) { - GPR_ASSERT(opt->key_type == CENSUS_HT_UINT64 || - opt->key_type == CENSUS_HT_POINTER); - if (opt->key_type == CENSUS_HT_UINT64) return p->key.val == key.val; - return !opt->compare_keys((p->key).ptr, key.ptr); -} - -static entry_locator ht_find(const census_ht *ht, census_ht_key key) { - entry_locator loc = {0, 0, 0, NULL}; - int32_t idx = 0; - ht_entry *ptr = NULL; - GPR_ASSERT(ht != NULL); - idx = find_bucket_idx(ht, key); - ptr = ht->buckets[idx].next; - if (ptr == NULL) { - /* bucket is empty */ - return loc; - } - if (keys_match(&ht->options, ptr, key)) { - loc.bucket_idx = idx; - loc.is_first_in_chain = 1; - loc.found = 1; - return loc; - } else { - for (; ptr->next != NULL; ptr = ptr->next) { - if (keys_match(&ht->options, ptr->next, key)) { - loc.bucket_idx = idx; - loc.is_first_in_chain = 0; - loc.found = 1; - loc.prev_entry = ptr; - return loc; - } - } - } - /* Could not find the key */ - return loc; -} - -void *census_ht_find(const census_ht *ht, census_ht_key key) { - entry_locator loc = ht_find(ht, key); - if (loc.found == 0) { - return NULL; - } - return loc.is_first_in_chain ? ht->buckets[loc.bucket_idx].next->data - : loc.prev_entry->next->data; -} - -void census_ht_insert(census_ht *ht, census_ht_key key, void *data) { - int32_t idx = find_bucket_idx(ht, key); - ht_entry *ptr = NULL; - entry_locator loc = ht_find(ht, key); - if (loc.found) { - /* Replace old value with new value. */ - ptr = loc.is_first_in_chain ? ht->buckets[loc.bucket_idx].next - : loc.prev_entry->next; - if (ht->options.delete_data != NULL) { - ht->options.delete_data(ptr->data); - } - ptr->data = data; - return; - } - - /* first entry in the table. */ - if (ht->size == 0) { - ht->buckets[idx].next_non_empty_bucket = -1; - ht->buckets[idx].prev_non_empty_bucket = -1; - ht->first_non_empty_bucket = idx; - ht->last_non_empty_bucket = idx; - } else if (ht->buckets[idx].next == NULL) { - /* first entry in the bucket. */ - ht->buckets[ht->last_non_empty_bucket].next_non_empty_bucket = idx; - ht->buckets[idx].prev_non_empty_bucket = ht->last_non_empty_bucket; - ht->buckets[idx].next_non_empty_bucket = -1; - ht->last_non_empty_bucket = idx; - } - ptr = (ht_entry *)gpr_malloc(sizeof(ht_entry)); - ptr->key = key; - ptr->data = data; - ptr->next = ht->buckets[idx].next; - ht->buckets[idx].next = ptr; - ht->size++; -} - -void census_ht_erase(census_ht *ht, census_ht_key key) { - entry_locator loc = ht_find(ht, key); - if (loc.found == 0) { - /* noop if not found */ - return; - } - ht->size--; - if (loc.is_first_in_chain) { - bucket *b = &ht->buckets[loc.bucket_idx]; - GPR_ASSERT(b->next != NULL); - /* The only entry in the bucket */ - if (b->next->next == NULL) { - int prev = b->prev_non_empty_bucket; - int next = b->next_non_empty_bucket; - if (prev != -1) { - ht->buckets[prev].next_non_empty_bucket = next; - } else { - ht->first_non_empty_bucket = next; - } - if (next != -1) { - ht->buckets[next].prev_non_empty_bucket = prev; - } else { - ht->last_non_empty_bucket = prev; - } - } - REMOVE_NEXT(&ht->options, b); - } else { - GPR_ASSERT(loc.prev_entry->next != NULL); - REMOVE_NEXT(&ht->options, loc.prev_entry); - } -} - -/* Returns NULL if input table is empty. */ -census_ht_kv *census_ht_get_all_elements(const census_ht *ht, size_t *num) { - census_ht_kv *ret = NULL; - int i = 0; - int32_t idx = -1; - GPR_ASSERT(ht != NULL && num != NULL); - *num = ht->size; - if (*num == 0) { - return NULL; - } - - ret = (census_ht_kv *)gpr_malloc(sizeof(census_ht_kv) * ht->size); - idx = ht->first_non_empty_bucket; - while (idx >= 0) { - ht_entry *ptr = ht->buckets[idx].next; - for (; ptr != NULL; ptr = ptr->next) { - ret[i].k = ptr->key; - ret[i].v = ptr->data; - i++; - } - idx = ht->buckets[idx].next_non_empty_bucket; - } - return ret; -} - -static void ht_delete_entry_chain(const census_ht_option *options, - ht_entry *first) { - if (first == NULL) { - return; - } - if (first->next != NULL) { - ht_delete_entry_chain(options, first->next); - } - delete_entry(options, first); -} - -void census_ht_destroy(census_ht *ht) { - unsigned i; - for (i = 0; i < ht->num_buckets; ++i) { - ht_delete_entry_chain(&ht->options, ht->buckets[i].next); - } - gpr_free(ht->buckets); - gpr_free(ht); -} - -size_t census_ht_get_size(const census_ht *ht) { return ht->size; } diff --git a/src/core/statistics/hash_table.h b/src/core/statistics/hash_table.h deleted file mode 100644 index f4bf2ba49a..0000000000 --- a/src/core/statistics/hash_table.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * - * Copyright 2015-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_STATISTICS_HASH_TABLE_H -#define GRPC_CORE_STATISTICS_HASH_TABLE_H - -#include - -#include - -/* A chain based hash table with fixed number of buckets. - Your probably shouldn't use this code directly. It is implemented for the - use case in census trace store and stats store, where number of entries in - the table is in the scale of upto several thousands, entries are added and - removed from the table very frequently (~100k/s), the frequency of find() - operations is roughly several times of the frequency of insert() and erase() - Comparing to find(), the insert(), erase() and get_all_entries() operations - are much less freqent (<1/s). - - Per bucket memory overhead is about (8 + sizeof(intptr_t) bytes. - Per entry memory overhead is about (8 + 2 * sizeof(intptr_t) bytes. - - All functions are not thread-safe. Synchronization will be provided in the - upper layer (in trace store and stats store). -*/ - -/* Opaque hash table struct */ -typedef struct unresizable_hash_table census_ht; - -/* Currently, the hash_table can take two types of keys. (uint64 for trace - store and const char* for stats store). */ -typedef union { - uint64_t val; - void *ptr; -} census_ht_key; - -typedef enum census_ht_key_type { - CENSUS_HT_UINT64 = 0, - CENSUS_HT_POINTER = 1 -} census_ht_key_type; - -typedef struct census_ht_option { - /* Type of hash key */ - census_ht_key_type key_type; - /* Desired number of buckets, preferably a prime number */ - int32_t num_buckets; - /* Fucntion to calculate uint64 hash value of the key. Only takes effect if - key_type is POINTER. */ - uint64_t (*hash)(const void *); - /* Function to compare two keys, returns 0 iff equal. Only takes effect if - key_type is POINTER */ - int (*compare_keys)(const void *k1, const void *k2); - /* Value deleter. NULL if no specialized delete function is needed. */ - void (*delete_data)(void *); - /* Key deleter. NULL if table does not own the key. (e.g. key is part of the - value or key is not owned by the table.) */ - void (*delete_key)(void *); -} census_ht_option; - -/* Creates a hashtable with fixed number of buckets according to the settings - specified in 'options' arg. Function pointers "hash" and "compare_keys" must - be provided if key_type is POINTER. Asserts if fail to create. */ -census_ht *census_ht_create(const census_ht_option *options); - -/* Deletes hash table instance. Frees all dynamic memory owned by ht.*/ -void census_ht_destroy(census_ht *ht); - -/* Inserts the input key-val pair into hash_table. If an entry with the same key - exists in the table, the corresponding value will be overwritten by the input - val. */ -void census_ht_insert(census_ht *ht, census_ht_key key, void *val); - -/* Returns pointer to data, returns NULL if not found. */ -void *census_ht_find(const census_ht *ht, census_ht_key key); - -/* Erase hash table entry with input key. Noop if key is not found. */ -void census_ht_erase(census_ht *ht, census_ht_key key); - -typedef struct census_ht_kv { - census_ht_key k; - void *v; -} census_ht_kv; - -/* Returns an array of pointers to all values in the hash table. Order of the - elements can be arbitrary. Sets 'num' to the size of returned array. Caller - owns returned array. */ -census_ht_kv *census_ht_get_all_elements(const census_ht *ht, size_t *num); - -/* Returns number of elements kept. */ -size_t census_ht_get_size(const census_ht *ht); - -/* Functor applied on each key-value pair while iterating through entries in the - table. The functor should not mutate data. */ -typedef void (*census_ht_itr_cb)(census_ht_key key, const void *val_ptr, - void *state); - -/* Iterates through all key-value pairs in the hash_table. The callback function - should not invalidate data entries. */ -uint64_t census_ht_for_all(const census_ht *ht, census_ht_itr_cb); - -#endif /* GRPC_CORE_STATISTICS_HASH_TABLE_H */ diff --git a/src/core/statistics/window_stats.c b/src/core/statistics/window_stats.c deleted file mode 100644 index eb296865a0..0000000000 --- a/src/core/statistics/window_stats.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * - * Copyright 2015-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/statistics/window_stats.h" -#include -#include -#include -#include -#include -#include -#include - -/* typedefs make typing long names easier. Use cws (for census_window_stats) */ -typedef census_window_stats_stat_info cws_stat_info; -typedef struct census_window_stats_sum cws_sum; - -/* Each interval is composed of a number of buckets, which hold a count of - entries and a single statistic */ -typedef struct census_window_stats_bucket { - int64_t count; - void *statistic; -} cws_bucket; - -/* Each interval has a set of buckets, and the variables needed to keep - track of their current state */ -typedef struct census_window_stats_interval_stats { - /* The buckets. There will be 'granularity' + 1 of these. */ - cws_bucket *buckets; - /* Index of the bucket containing the smallest time interval. */ - int bottom_bucket; - /* The smallest time storable in the current window. */ - int64_t bottom; - /* The largest time storable in the current window + 1ns */ - int64_t top; - /* The width of each bucket in ns. */ - int64_t width; -} cws_interval_stats; - -typedef struct census_window_stats { - /* Number of intervals. */ - int nintervals; - /* Number of buckets in each interval. 'granularity' + 1. */ - int nbuckets; - /* Record of stat_info. */ - cws_stat_info stat_info; - /* Stats for each interval. */ - cws_interval_stats *interval_stats; - /* The time the newset stat was recorded. */ - int64_t newest_time; -} window_stats; - -/* Calculate an actual bucket index from a logical index 'IDX'. Other - parameters supply information on the interval struct and overall stats. */ -#define BUCKET_IDX(IS, IDX, WSTATS) \ - ((IS->bottom_bucket + (IDX)) % WSTATS->nbuckets) - -/* The maximum seconds value we can have in a valid timespec. More than this - will result in overflow in timespec_to_ns(). This works out to ~292 years. - TODO: consider using doubles instead of int64. */ -static int64_t max_seconds = (GPR_INT64_MAX - GPR_NS_PER_SEC) / GPR_NS_PER_SEC; - -static int64_t timespec_to_ns(const gpr_timespec ts) { - if (ts.tv_sec > max_seconds) { - return GPR_INT64_MAX - 1; - } - return ts.tv_sec * GPR_NS_PER_SEC + ts.tv_nsec; -} - -static void cws_initialize_statistic(void *statistic, - const cws_stat_info *stat_info) { - if (stat_info->stat_initialize == NULL) { - memset(statistic, 0, stat_info->stat_size); - } else { - stat_info->stat_initialize(statistic); - } -} - -/* Create and initialize a statistic */ -static void *cws_create_statistic(const cws_stat_info *stat_info) { - void *stat = gpr_malloc(stat_info->stat_size); - cws_initialize_statistic(stat, stat_info); - return stat; -} - -window_stats *census_window_stats_create(int nintervals, - const gpr_timespec intervals[], - int granularity, - const cws_stat_info *stat_info) { - window_stats *ret; - int i; - /* validate inputs */ - GPR_ASSERT(nintervals > 0 && granularity > 2 && intervals != NULL && - stat_info != NULL); - for (i = 0; i < nintervals; i++) { - int64_t ns = timespec_to_ns(intervals[i]); - GPR_ASSERT(intervals[i].tv_sec >= 0 && intervals[i].tv_nsec >= 0 && - intervals[i].tv_nsec < GPR_NS_PER_SEC && ns >= 100 && - granularity * 10 <= ns); - } - /* Allocate and initialize relevant data structures */ - ret = (window_stats *)gpr_malloc(sizeof(window_stats)); - ret->nintervals = nintervals; - ret->nbuckets = granularity + 1; - ret->stat_info = *stat_info; - ret->interval_stats = - (cws_interval_stats *)gpr_malloc(nintervals * sizeof(cws_interval_stats)); - for (i = 0; i < nintervals; i++) { - int64_t size_ns = timespec_to_ns(intervals[i]); - cws_interval_stats *is = ret->interval_stats + i; - cws_bucket *buckets = is->buckets = - (cws_bucket *)gpr_malloc(ret->nbuckets * sizeof(cws_bucket)); - int b; - for (b = 0; b < ret->nbuckets; b++) { - buckets[b].statistic = cws_create_statistic(stat_info); - buckets[b].count = 0; - } - is->bottom_bucket = 0; - is->bottom = 0; - is->width = size_ns / granularity; - /* Check for possible overflow issues, and maximize interval size if the - user requested something large enough. */ - if ((GPR_INT64_MAX - is->width) > size_ns) { - is->top = size_ns + is->width; - } else { - is->top = GPR_INT64_MAX; - is->width = GPR_INT64_MAX / (granularity + 1); - } - /* If size doesn't divide evenly, we can have a width slightly too small; - better to have it slightly large. */ - if ((size_ns - (granularity + 1) * is->width) > 0) { - is->width += 1; - } - } - ret->newest_time = 0; - return ret; -} - -/* When we try adding a measurement above the current interval range, we - need to "shift" the buckets sufficiently to cover the new range. */ -static void cws_shift_buckets(const window_stats *wstats, - cws_interval_stats *is, int64_t when_ns) { - int i; - /* number of bucket time widths to "shift" */ - int shift; - /* number of buckets to clear */ - int nclear; - GPR_ASSERT(when_ns >= is->top); - /* number of bucket time widths to "shift" */ - shift = ((when_ns - is->top) / is->width) + 1; - /* number of buckets to clear - limited by actual number of buckets */ - nclear = GPR_MIN(shift, wstats->nbuckets); - for (i = 0; i < nclear; i++) { - int b = BUCKET_IDX(is, i, wstats); - is->buckets[b].count = 0; - cws_initialize_statistic(is->buckets[b].statistic, &wstats->stat_info); - } - /* adjust top/bottom times and current bottom bucket */ - is->bottom_bucket = BUCKET_IDX(is, shift, wstats); - is->top += shift * is->width; - is->bottom += shift * is->width; -} - -void census_window_stats_add(window_stats *wstats, const gpr_timespec when, - const void *stat_value) { - int i; - int64_t when_ns = timespec_to_ns(when); - GPR_ASSERT(wstats->interval_stats != NULL); - for (i = 0; i < wstats->nintervals; i++) { - cws_interval_stats *is = wstats->interval_stats + i; - cws_bucket *bucket; - if (when_ns < is->bottom) { /* Below smallest time in interval: drop */ - continue; - } - if (when_ns >= is->top) { /* above limit: shift buckets */ - cws_shift_buckets(wstats, is, when_ns); - } - /* Add the stat. */ - GPR_ASSERT(is->bottom <= when_ns && when_ns < is->top); - bucket = is->buckets + - BUCKET_IDX(is, (when_ns - is->bottom) / is->width, wstats); - bucket->count++; - wstats->stat_info.stat_add(bucket->statistic, stat_value); - } - if (when_ns > wstats->newest_time) { - wstats->newest_time = when_ns; - } -} - -/* Add a specific bucket contents to an accumulating total. */ -static void cws_add_bucket_to_sum(cws_sum *sum, const cws_bucket *bucket, - const cws_stat_info *stat_info) { - sum->count += bucket->count; - stat_info->stat_add(sum->statistic, bucket->statistic); -} - -/* Add a proportion to an accumulating sum. */ -static void cws_add_proportion_to_sum(double p, cws_sum *sum, - const cws_bucket *bucket, - const cws_stat_info *stat_info) { - sum->count += p * bucket->count; - stat_info->stat_add_proportion(p, sum->statistic, bucket->statistic); -} - -void census_window_stats_get_sums(const window_stats *wstats, - const gpr_timespec when, cws_sum sums[]) { - int i; - int64_t when_ns = timespec_to_ns(when); - GPR_ASSERT(wstats->interval_stats != NULL); - for (i = 0; i < wstats->nintervals; i++) { - int when_bucket; - int new_bucket; - double last_proportion = 1.0; - double bottom_proportion; - cws_interval_stats *is = wstats->interval_stats + i; - cws_sum *sum = sums + i; - sum->count = 0; - cws_initialize_statistic(sum->statistic, &wstats->stat_info); - if (when_ns < is->bottom) { - continue; - } - if (when_ns >= is->top) { - cws_shift_buckets(wstats, is, when_ns); - } - /* Calculating the appropriate amount of which buckets to use can get - complicated. Essentially there are two cases: - 1) if the "top" bucket (new_bucket, where the newest additions to the - stats recorded are entered) corresponds to 'when', then we need - to take a proportion of it - (if when < newest_time) or the full - thing. We also (possibly) need to take a corresponding - proportion of the bottom bucket. - 2) Other cases, we just take a straight proportion. - */ - when_bucket = (when_ns - is->bottom) / is->width; - new_bucket = (wstats->newest_time - is->bottom) / is->width; - if (new_bucket == when_bucket) { - int64_t bottom_bucket_time = is->bottom + when_bucket * is->width; - if (when_ns < wstats->newest_time) { - last_proportion = (double)(when_ns - bottom_bucket_time) / - (double)(wstats->newest_time - bottom_bucket_time); - bottom_proportion = - (double)(is->width - (when_ns - bottom_bucket_time)) / is->width; - } else { - bottom_proportion = - (double)(is->width - (wstats->newest_time - bottom_bucket_time)) / - is->width; - } - } else { - last_proportion = - (double)(when_ns + 1 - is->bottom - when_bucket * is->width) / - is->width; - bottom_proportion = 1.0 - last_proportion; - } - cws_add_proportion_to_sum(last_proportion, sum, - is->buckets + BUCKET_IDX(is, when_bucket, wstats), - &wstats->stat_info); - if (when_bucket != 0) { /* last bucket isn't also bottom bucket */ - int b; - /* Add all of "bottom" bucket if we are looking at a subset of the - full interval, or a proportion if we are adding full interval. */ - cws_add_proportion_to_sum( - (when_bucket == wstats->nbuckets - 1 ? bottom_proportion : 1.0), sum, - is->buckets + is->bottom_bucket, &wstats->stat_info); - /* Add all the remaining buckets (everything but top and bottom). */ - for (b = 1; b < when_bucket; b++) { - cws_add_bucket_to_sum(sum, is->buckets + BUCKET_IDX(is, b, wstats), - &wstats->stat_info); - } - } - } -} - -void census_window_stats_destroy(window_stats *wstats) { - int i; - GPR_ASSERT(wstats->interval_stats != NULL); - for (i = 0; i < wstats->nintervals; i++) { - int b; - for (b = 0; b < wstats->nbuckets; b++) { - gpr_free(wstats->interval_stats[i].buckets[b].statistic); - } - gpr_free(wstats->interval_stats[i].buckets); - } - gpr_free(wstats->interval_stats); - /* Ensure any use-after free triggers assert. */ - wstats->interval_stats = NULL; - gpr_free(wstats); -} diff --git a/src/core/statistics/window_stats.h b/src/core/statistics/window_stats.h deleted file mode 100644 index 774277180f..0000000000 --- a/src/core/statistics/window_stats.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * - * Copyright 2015-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_STATISTICS_WINDOW_STATS_H -#define GRPC_CORE_STATISTICS_WINDOW_STATS_H - -#include - -/* Keep rolling sums of a user-defined statistic (containing a number of - measurements) over a a number of time intervals ("windows"). For example, - you can use a window_stats object to answer questions such as - "Approximately how many RPCs/s did I receive over the past minute, and - approximately how many bytes did I send out over that period?". - - The type of data to record, and the time intervals to keep are specified - when creating the object via a call to census_window_stats_create(). - - A window's interval is divided into one or more "buckets"; the interval - must be divisible by the number of buckets. Internally, these buckets - control the granularity of window_stats' measurements. Increasing the - number of buckets lets the object respond more quickly to changes in the - overall rate of data added into the object, at the cost of additional - memory usage. - - Here's some code which keeps one minute/hour measurements for two values - (latency in seconds and bytes transferred), with each interval divided into - 4 buckets. - - typedef struct my_stat { - double latency; - int bytes; - } my_stat; - - void add_my_stat(void* base, const void* addme) { - my_stat* b = (my_stat*)base; - const my_stat* a = (const my_stat*)addme; - b->latency += a->latency; - b->bytes += a->bytes; - } - - void add_proportion_my_stat(double p, void* base, const void* addme) { - (my_stat*)result->latency += p * (const my_stat*)base->latency; - (my_stat*)result->bytes += p * (const my_stat*)base->bytes; - } - - #define kNumIntervals 2 - #define kMinInterval 0 - #define kHourInterval 1 - #define kNumBuckets 4 - - const struct census_window_stats_stat_info kMyStatInfo - = { sizeof(my_stat), NULL, add_my_stat, add_proportion_my_stat }; - gpr_timespec intervals[kNumIntervals] = {{60, 0}, {3600, 0}}; - my_stat stat; - my_stat sums[kNumIntervals]; - census_window_stats_sums result[kNumIntervals]; - struct census_window_stats* stats - = census_window_stats_create(kNumIntervals, intervals, kNumBuckets, - &kMyStatInfo); - // Record a new event, taking 15.3ms, transferring 1784 bytes. - stat.latency = 0.153; - stat.bytes = 1784; - census_window_stats_add(stats, gpr_now(GPR_CLOCK_REALTIME), &stat); - // Get sums and print them out - result[kMinInterval].statistic = &sums[kMinInterval]; - result[kHourInterval].statistic = &sums[kHourInterval]; - census_window_stats_get_sums(stats, gpr_now(GPR_CLOCK_REALTIME), result); - printf("%d events/min, average time %gs, average bytes %g\n", - result[kMinInterval].count, - (my_stat*)result[kMinInterval].statistic->latency / - result[kMinInterval].count, - (my_stat*)result[kMinInterval].statistic->bytes / - result[kMinInterval].count - ); - printf("%d events/hr, average time %gs, average bytes %g\n", - result[kHourInterval].count, - (my_stat*)result[kHourInterval].statistic->latency / - result[kHourInterval].count, - (my_stat*)result[kHourInterval].statistic->bytes / - result[kHourInterval].count - ); -*/ - -/* Opaque structure for representing window_stats object */ -struct census_window_stats; - -/* Information provided by API user on the information they want to record */ -typedef struct census_window_stats_stat_info { - /* Number of bytes in user-defined object. */ - size_t stat_size; - /* Function to initialize a user-defined statistics object. If this is set - * to NULL, then the object will be zero-initialized. */ - void (*stat_initialize)(void *stat); - /* Function to add one user-defined statistics object ('addme') to 'base' */ - void (*stat_add)(void *base, const void *addme); - /* As for previous function, but only add a proportion 'p'. This API will - currently only use 'p' values in the range [0,1], but other values are - possible in the future, and should be supported. */ - void (*stat_add_proportion)(double p, void *base, const void *addme); -} census_window_stats_stat_info; - -/* Create a new window_stats object. 'nintervals' is the number of - 'intervals', and must be >=1. 'granularity' is the number of buckets, with - a larger number using more memory, but providing greater accuracy of - results. 'granularity should be > 2. We also require that each interval be - at least 10 * 'granularity' nanoseconds in size. 'stat_info' contains - information about the statistic to be gathered. Intervals greater than ~192 - years will be treated as essentially infinite in size. This function will - GPR_ASSERT() if the object cannot be created or any of the parameters have - invalid values. This function is thread-safe. */ -struct census_window_stats *census_window_stats_create( - int nintervals, const gpr_timespec intervals[], int granularity, - const census_window_stats_stat_info *stat_info); - -/* Add a new measurement (in 'stat_value'), as of a given time ('when'). - This function is thread-compatible. */ -void census_window_stats_add(struct census_window_stats *wstats, - const gpr_timespec when, const void *stat_value); - -/* Structure used to record a single intervals sum for a given statistic */ -typedef struct census_window_stats_sum { - /* Total count of samples. Note that because some internal interpolation - is performed, the count of samples returned for each interval may not be an - integral value. */ - double count; - /* Sum for statistic */ - void *statistic; -} census_window_stats_sums; - -/* Retrieve a set of all values stored in a window_stats object 'wstats'. The - number of 'sums' MUST be the same as the number 'nintervals' used in - census_window_stats_create(). This function is thread-compatible. */ -void census_window_stats_get_sums(const struct census_window_stats *wstats, - const gpr_timespec when, - struct census_window_stats_sum sums[]); - -/* Destroy a window_stats object. Once this function has been called, the - object will no longer be usable from any of the above functions (and - calling them will most likely result in a NULL-pointer dereference or - assertion failure). This function is thread-compatible. */ -void census_window_stats_destroy(struct census_window_stats *wstats); - -#endif /* GRPC_CORE_STATISTICS_WINDOW_STATS_H */ diff --git a/src/core/support/alloc.c b/src/core/support/alloc.c deleted file mode 100644 index fd9fb8f5e7..0000000000 --- a/src/core/support/alloc.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include -#include -#include -#include "src/core/profiling/timers.h" - -static gpr_allocation_functions g_alloc_functions = {malloc, realloc, free}; - -gpr_allocation_functions gpr_get_allocation_functions() { - return g_alloc_functions; -} - -void gpr_set_allocation_functions(gpr_allocation_functions functions) { - GPR_ASSERT(functions.malloc_fn != NULL); - GPR_ASSERT(functions.realloc_fn != NULL); - GPR_ASSERT(functions.free_fn != NULL); - g_alloc_functions = functions; -} - -void *gpr_malloc(size_t size) { - void *p; - GPR_TIMER_BEGIN("gpr_malloc", 0); - p = g_alloc_functions.malloc_fn(size); - if (!p) { - abort(); - } - GPR_TIMER_END("gpr_malloc", 0); - return p; -} - -void gpr_free(void *p) { - GPR_TIMER_BEGIN("gpr_free", 0); - g_alloc_functions.free_fn(p); - GPR_TIMER_END("gpr_free", 0); -} - -void *gpr_realloc(void *p, size_t size) { - GPR_TIMER_BEGIN("gpr_realloc", 0); - p = g_alloc_functions.realloc_fn(p, size); - if (!p) { - abort(); - } - GPR_TIMER_END("gpr_realloc", 0); - return p; -} - -void *gpr_malloc_aligned(size_t size, size_t alignment_log) { - size_t alignment = ((size_t)1) << alignment_log; - size_t extra = alignment - 1 + sizeof(void *); - void *p = gpr_malloc(size + extra); - void **ret = (void **)(((uintptr_t)p + extra) & ~(alignment - 1)); - ret[-1] = p; - return (void *)ret; -} - -void gpr_free_aligned(void *ptr) { gpr_free(((void **)ptr)[-1]); } diff --git a/src/core/support/avl.c b/src/core/support/avl.c deleted file mode 100644 index f378b3ee17..0000000000 --- a/src/core/support/avl.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include -#include - -#include -#include -#include - -gpr_avl gpr_avl_create(const gpr_avl_vtable *vtable) { - gpr_avl out; - out.vtable = vtable; - out.root = NULL; - return out; -} - -static gpr_avl_node *ref_node(gpr_avl_node *node) { - if (node) { - gpr_ref(&node->refs); - } - return node; -} - -static void unref_node(const gpr_avl_vtable *vtable, gpr_avl_node *node) { - if (node == NULL) { - return; - } - if (gpr_unref(&node->refs)) { - vtable->destroy_key(node->key); - vtable->destroy_value(node->value); - unref_node(vtable, node->left); - unref_node(vtable, node->right); - gpr_free(node); - } -} - -static long node_height(gpr_avl_node *node) { - return node == NULL ? 0 : node->height; -} - -#ifndef NDEBUG -static long calculate_height(gpr_avl_node *node) { - return node == NULL ? 0 : 1 + GPR_MAX(calculate_height(node->left), - calculate_height(node->right)); -} - -static gpr_avl_node *assert_invariants(gpr_avl_node *n) { - if (n == NULL) return NULL; - assert_invariants(n->left); - assert_invariants(n->right); - assert(calculate_height(n) == n->height); - assert(labs(node_height(n->left) - node_height(n->right)) <= 1); - return n; -} -#else -static gpr_avl_node *assert_invariants(gpr_avl_node *n) { return n; } -#endif - -gpr_avl_node *new_node(void *key, void *value, gpr_avl_node *left, - gpr_avl_node *right) { - gpr_avl_node *node = gpr_malloc(sizeof(*node)); - gpr_ref_init(&node->refs, 1); - node->key = key; - node->value = value; - node->left = assert_invariants(left); - node->right = assert_invariants(right); - node->height = 1 + GPR_MAX(node_height(left), node_height(right)); - return node; -} - -static gpr_avl_node *get(const gpr_avl_vtable *vtable, gpr_avl_node *node, - void *key) { - long cmp; - - if (node == NULL) { - return NULL; - } - - cmp = vtable->compare_keys(node->key, key); - if (cmp == 0) { - return node; - } else if (cmp > 0) { - return get(vtable, node->left, key); - } else { - return get(vtable, node->right, key); - } -} - -void *gpr_avl_get(gpr_avl avl, void *key) { - gpr_avl_node *node = get(avl.vtable, avl.root, key); - return node ? node->value : NULL; -} - -static gpr_avl_node *rotate_left(const gpr_avl_vtable *vtable, void *key, - void *value, gpr_avl_node *left, - gpr_avl_node *right) { - gpr_avl_node *n = - new_node(vtable->copy_key(right->key), vtable->copy_value(right->value), - new_node(key, value, left, ref_node(right->left)), - ref_node(right->right)); - unref_node(vtable, right); - return n; -} - -static gpr_avl_node *rotate_right(const gpr_avl_vtable *vtable, void *key, - void *value, gpr_avl_node *left, - gpr_avl_node *right) { - gpr_avl_node *n = new_node( - vtable->copy_key(left->key), vtable->copy_value(left->value), - ref_node(left->left), new_node(key, value, ref_node(left->right), right)); - unref_node(vtable, left); - return n; -} - -static gpr_avl_node *rotate_left_right(const gpr_avl_vtable *vtable, void *key, - void *value, gpr_avl_node *left, - gpr_avl_node *right) { - /* rotate_right(..., rotate_left(left), right) */ - gpr_avl_node *n = new_node( - vtable->copy_key(left->right->key), - vtable->copy_value(left->right->value), - new_node(vtable->copy_key(left->key), vtable->copy_value(left->value), - ref_node(left->left), ref_node(left->right->left)), - new_node(key, value, ref_node(left->right->right), right)); - unref_node(vtable, left); - return n; -} - -static gpr_avl_node *rotate_right_left(const gpr_avl_vtable *vtable, void *key, - void *value, gpr_avl_node *left, - gpr_avl_node *right) { - /* rotate_left(..., left, rotate_right(right)) */ - gpr_avl_node *n = new_node( - vtable->copy_key(right->left->key), - vtable->copy_value(right->left->value), - new_node(key, value, left, ref_node(right->left->left)), - new_node(vtable->copy_key(right->key), vtable->copy_value(right->value), - ref_node(right->left->right), ref_node(right->right))); - unref_node(vtable, right); - return n; -} - -static gpr_avl_node *rebalance(const gpr_avl_vtable *vtable, void *key, - void *value, gpr_avl_node *left, - gpr_avl_node *right) { - switch (node_height(left) - node_height(right)) { - case 2: - if (node_height(left->left) - node_height(left->right) == -1) { - return assert_invariants( - rotate_left_right(vtable, key, value, left, right)); - } else { - return assert_invariants(rotate_right(vtable, key, value, left, right)); - } - case -2: - if (node_height(right->left) - node_height(right->right) == 1) { - return assert_invariants( - rotate_right_left(vtable, key, value, left, right)); - } else { - return assert_invariants(rotate_left(vtable, key, value, left, right)); - } - default: - return assert_invariants(new_node(key, value, left, right)); - } -} - -static gpr_avl_node *add(const gpr_avl_vtable *vtable, gpr_avl_node *node, - void *key, void *value) { - long cmp; - if (node == NULL) { - return new_node(key, value, NULL, NULL); - } - cmp = vtable->compare_keys(node->key, key); - if (cmp == 0) { - return new_node(key, value, ref_node(node->left), ref_node(node->right)); - } else if (cmp > 0) { - return rebalance( - vtable, vtable->copy_key(node->key), vtable->copy_value(node->value), - add(vtable, node->left, key, value), ref_node(node->right)); - } else { - return rebalance(vtable, vtable->copy_key(node->key), - vtable->copy_value(node->value), ref_node(node->left), - add(vtable, node->right, key, value)); - } -} - -gpr_avl gpr_avl_add(gpr_avl avl, void *key, void *value) { - gpr_avl_node *old_root = avl.root; - avl.root = add(avl.vtable, avl.root, key, value); - assert_invariants(avl.root); - unref_node(avl.vtable, old_root); - return avl; -} - -static gpr_avl_node *in_order_head(gpr_avl_node *node) { - while (node->left != NULL) { - node = node->left; - } - return node; -} - -static gpr_avl_node *in_order_tail(gpr_avl_node *node) { - while (node->right != NULL) { - node = node->right; - } - return node; -} - -static gpr_avl_node *remove(const gpr_avl_vtable *vtable, gpr_avl_node *node, - void *key) { - long cmp; - if (node == NULL) { - return NULL; - } - cmp = vtable->compare_keys(node->key, key); - if (cmp == 0) { - if (node->left == NULL) { - return ref_node(node->right); - } else if (node->right == NULL) { - return ref_node(node->left); - } else if (node->left->height < node->right->height) { - gpr_avl_node *h = in_order_head(node->right); - return rebalance(vtable, vtable->copy_key(h->key), - vtable->copy_value(h->value), ref_node(node->left), - remove(vtable, node->right, h->key)); - } else { - gpr_avl_node *h = in_order_tail(node->left); - return rebalance( - vtable, vtable->copy_key(h->key), vtable->copy_value(h->value), - remove(vtable, node->left, h->key), ref_node(node->right)); - } - } else if (cmp > 0) { - return rebalance(vtable, vtable->copy_key(node->key), - vtable->copy_value(node->value), - remove(vtable, node->left, key), ref_node(node->right)); - } else { - return rebalance(vtable, vtable->copy_key(node->key), - vtable->copy_value(node->value), ref_node(node->left), - remove(vtable, node->right, key)); - } -} - -gpr_avl gpr_avl_remove(gpr_avl avl, void *key) { - gpr_avl_node *old_root = avl.root; - avl.root = remove(avl.vtable, avl.root, key); - assert_invariants(avl.root); - unref_node(avl.vtable, old_root); - return avl; -} - -gpr_avl gpr_avl_ref(gpr_avl avl) { - ref_node(avl.root); - return avl; -} - -void gpr_avl_unref(gpr_avl avl) { unref_node(avl.vtable, avl.root); } diff --git a/src/core/support/backoff.c b/src/core/support/backoff.c deleted file mode 100644 index 4ccfb774ed..0000000000 --- a/src/core/support/backoff.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * - * 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/support/backoff.h" - -#include - -void gpr_backoff_init(gpr_backoff *backoff, double multiplier, double jitter, - int64_t min_timeout_millis, int64_t max_timeout_millis) { - backoff->multiplier = multiplier; - backoff->jitter = jitter; - backoff->min_timeout_millis = min_timeout_millis; - backoff->max_timeout_millis = max_timeout_millis; - backoff->rng_state = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec; -} - -gpr_timespec gpr_backoff_begin(gpr_backoff *backoff, gpr_timespec now) { - backoff->current_timeout_millis = backoff->min_timeout_millis; - return gpr_time_add( - now, gpr_time_from_millis(backoff->current_timeout_millis, GPR_TIMESPAN)); -} - -/* Generate a random number between 0 and 1. */ -static double generate_uniform_random_number(uint32_t *rng_state) { - *rng_state = (1103515245 * *rng_state + 12345) % ((uint32_t)1 << 31); - return *rng_state / (double)((uint32_t)1 << 31); -} - -gpr_timespec gpr_backoff_step(gpr_backoff *backoff, gpr_timespec now) { - double new_timeout_millis = - backoff->multiplier * (double)backoff->current_timeout_millis; - double jitter_range = backoff->jitter * new_timeout_millis; - double jitter = - (2 * generate_uniform_random_number(&backoff->rng_state) - 1) * - jitter_range; - backoff->current_timeout_millis = - GPR_CLAMP((int64_t)(new_timeout_millis + jitter), - backoff->min_timeout_millis, backoff->max_timeout_millis); - return gpr_time_add( - now, gpr_time_from_millis(backoff->current_timeout_millis, GPR_TIMESPAN)); -} - -void gpr_backoff_reset(gpr_backoff *backoff) { - // forces step() to return a timeout of min_timeout_millis - backoff->current_timeout_millis = 0; -} diff --git a/src/core/support/backoff.h b/src/core/support/backoff.h deleted file mode 100644 index 0f933c3149..0000000000 --- a/src/core/support/backoff.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * 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_SUPPORT_BACKOFF_H -#define GRPC_CORE_SUPPORT_BACKOFF_H - -#include - -typedef struct { - /// const: multiplier between retry attempts - double multiplier; - /// const: amount to randomize backoffs - double jitter; - /// const: minimum time between retries in milliseconds - int64_t min_timeout_millis; - /// const: maximum time between retries in milliseconds - int64_t max_timeout_millis; - - /// random number generator - uint32_t rng_state; - - /// current retry timeout in milliseconds - int64_t current_timeout_millis; -} gpr_backoff; - -/// Initialize backoff machinery - does not need to be destroyed -void gpr_backoff_init(gpr_backoff *backoff, double multiplier, double jitter, - int64_t min_timeout_millis, int64_t max_timeout_millis); - -/// Begin retry loop: returns a timespec for the NEXT retry -gpr_timespec gpr_backoff_begin(gpr_backoff *backoff, gpr_timespec now); -/// Step a retry loop: returns a timespec for the NEXT retry -gpr_timespec gpr_backoff_step(gpr_backoff *backoff, gpr_timespec now); -/// Reset the backoff, so the next gpr_backoff_step will be a gpr_backoff_begin -/// instead -void gpr_backoff_reset(gpr_backoff *backoff); - -#endif /* GRPC_CORE_SUPPORT_BACKOFF_H */ diff --git a/src/core/support/block_annotate.h b/src/core/support/block_annotate.h deleted file mode 100644 index 79a18039f4..0000000000 --- a/src/core/support/block_annotate.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright 2015-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_SUPPORT_BLOCK_ANNOTATE_H -#define GRPC_CORE_SUPPORT_BLOCK_ANNOTATE_H - -/* These annotations identify the beginning and end of regions where - the code may block for reasons other than synchronization functions. - These include poll, epoll, and getaddrinfo. */ - -#define GRPC_SCHEDULING_START_BLOCKING_REGION \ - do { \ - } while (0) -#define GRPC_SCHEDULING_END_BLOCKING_REGION \ - do { \ - } while (0) - -#endif /* GRPC_CORE_SUPPORT_BLOCK_ANNOTATE_H */ diff --git a/src/core/support/cmdline.c b/src/core/support/cmdline.c deleted file mode 100644 index eff46a1655..0000000000 --- a/src/core/support/cmdline.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include -#include -#include - -#include -#include -#include -#include "src/core/support/string.h" - -typedef enum { ARGTYPE_INT, ARGTYPE_BOOL, ARGTYPE_STRING } argtype; - -typedef struct arg { - const char *name; - const char *help; - argtype type; - void *value; - struct arg *next; -} arg; - -struct gpr_cmdline { - const char *description; - arg *args; - const char *argv0; - - const char *extra_arg_name; - const char *extra_arg_help; - void (*extra_arg)(void *user_data, const char *arg); - void *extra_arg_user_data; - - int (*state)(gpr_cmdline *cl, char *arg); - arg *cur_arg; - - int survive_failure; -}; - -static int normal_state(gpr_cmdline *cl, char *arg); - -gpr_cmdline *gpr_cmdline_create(const char *description) { - gpr_cmdline *cl = gpr_malloc(sizeof(gpr_cmdline)); - memset(cl, 0, sizeof(gpr_cmdline)); - - cl->description = description; - cl->state = normal_state; - - return cl; -} - -void gpr_cmdline_set_survive_failure(gpr_cmdline *cl) { - cl->survive_failure = 1; -} - -void gpr_cmdline_destroy(gpr_cmdline *cl) { - while (cl->args) { - arg *a = cl->args; - cl->args = a->next; - gpr_free(a); - } - gpr_free(cl); -} - -static void add_arg(gpr_cmdline *cl, const char *name, const char *help, - argtype type, void *value) { - arg *a; - - for (a = cl->args; a; a = a->next) { - GPR_ASSERT(0 != strcmp(a->name, name)); - } - - a = gpr_malloc(sizeof(arg)); - memset(a, 0, sizeof(arg)); - a->name = name; - a->help = help; - a->type = type; - a->value = value; - a->next = cl->args; - cl->args = a; -} - -void gpr_cmdline_add_int(gpr_cmdline *cl, const char *name, const char *help, - int *value) { - add_arg(cl, name, help, ARGTYPE_INT, value); -} - -void gpr_cmdline_add_flag(gpr_cmdline *cl, const char *name, const char *help, - int *value) { - add_arg(cl, name, help, ARGTYPE_BOOL, value); -} - -void gpr_cmdline_add_string(gpr_cmdline *cl, const char *name, const char *help, - char **value) { - add_arg(cl, name, help, ARGTYPE_STRING, value); -} - -void gpr_cmdline_on_extra_arg( - gpr_cmdline *cl, const char *name, const char *help, - void (*on_extra_arg)(void *user_data, const char *arg), void *user_data) { - GPR_ASSERT(!cl->extra_arg); - GPR_ASSERT(on_extra_arg); - - cl->extra_arg = on_extra_arg; - cl->extra_arg_user_data = user_data; - cl->extra_arg_name = name; - cl->extra_arg_help = help; -} - -/* recursively descend argument list, adding the last element - to s first - so that arguments are added in the order they were - added to the list by api calls */ -static void add_args_to_usage(gpr_strvec *s, arg *a) { - char *tmp; - - if (!a) return; - add_args_to_usage(s, a->next); - - switch (a->type) { - case ARGTYPE_BOOL: - gpr_asprintf(&tmp, " [--%s|--no-%s]", a->name, a->name); - gpr_strvec_add(s, tmp); - break; - case ARGTYPE_STRING: - gpr_asprintf(&tmp, " [--%s=string]", a->name); - gpr_strvec_add(s, tmp); - break; - case ARGTYPE_INT: - gpr_asprintf(&tmp, " [--%s=int]", a->name); - gpr_strvec_add(s, tmp); - break; - } -} - -char *gpr_cmdline_usage_string(gpr_cmdline *cl, const char *argv0) { - /* TODO(ctiller): make this prettier */ - gpr_strvec s; - char *tmp; - const char *name = strrchr(argv0, '/'); - - if (name) { - name++; - } else { - name = argv0; - } - - gpr_strvec_init(&s); - - gpr_asprintf(&tmp, "Usage: %s", name); - gpr_strvec_add(&s, tmp); - add_args_to_usage(&s, cl->args); - if (cl->extra_arg) { - gpr_asprintf(&tmp, " [%s...]", cl->extra_arg_name); - gpr_strvec_add(&s, tmp); - } - gpr_strvec_add(&s, gpr_strdup("\n")); - - tmp = gpr_strvec_flatten(&s, NULL); - gpr_strvec_destroy(&s); - return tmp; -} - -static int print_usage_and_die(gpr_cmdline *cl) { - char *usage = gpr_cmdline_usage_string(cl, cl->argv0); - fprintf(stderr, "%s", usage); - gpr_free(usage); - if (!cl->survive_failure) { - exit(1); - } - return 0; -} - -static int extra_state(gpr_cmdline *cl, char *str) { - if (!cl->extra_arg) { - return print_usage_and_die(cl); - } - cl->extra_arg(cl->extra_arg_user_data, str); - return 1; -} - -static arg *find_arg(gpr_cmdline *cl, char *name) { - arg *a; - - for (a = cl->args; a; a = a->next) { - if (0 == strcmp(a->name, name)) { - break; - } - } - - if (!a) { - fprintf(stderr, "Unknown argument: %s\n", name); - return NULL; - } - - return a; -} - -static int value_state(gpr_cmdline *cl, char *str) { - long intval; - char *end; - - GPR_ASSERT(cl->cur_arg); - - switch (cl->cur_arg->type) { - case ARGTYPE_INT: - intval = strtol(str, &end, 0); - if (*end || intval < INT_MIN || intval > INT_MAX) { - fprintf(stderr, "expected integer, got '%s' for %s\n", str, - cl->cur_arg->name); - return print_usage_and_die(cl); - } - *(int *)cl->cur_arg->value = (int)intval; - break; - case ARGTYPE_BOOL: - if (0 == strcmp(str, "1") || 0 == strcmp(str, "true")) { - *(int *)cl->cur_arg->value = 1; - } else if (0 == strcmp(str, "0") || 0 == strcmp(str, "false")) { - *(int *)cl->cur_arg->value = 0; - } else { - fprintf(stderr, "expected boolean, got '%s' for %s\n", str, - cl->cur_arg->name); - return print_usage_and_die(cl); - } - break; - case ARGTYPE_STRING: - *(char **)cl->cur_arg->value = str; - break; - } - - cl->state = normal_state; - return 1; -} - -static int normal_state(gpr_cmdline *cl, char *str) { - char *eq = NULL; - char *tmp = NULL; - char *arg_name = NULL; - int r = 1; - - if (0 == strcmp(str, "-help") || 0 == strcmp(str, "--help") || - 0 == strcmp(str, "-h")) { - return print_usage_and_die(cl); - } - - cl->cur_arg = NULL; - - if (str[0] == '-') { - if (str[1] == '-') { - if (str[2] == 0) { - /* handle '--' to move to just extra args */ - cl->state = extra_state; - return 1; - } - str += 2; - } else { - str += 1; - } - /* first byte of str is now past the leading '-' or '--' */ - if (str[0] == 'n' && str[1] == 'o' && str[2] == '-') { - /* str is of the form '--no-foo' - it's a flag disable */ - str += 3; - cl->cur_arg = find_arg(cl, str); - if (cl->cur_arg == NULL) { - return print_usage_and_die(cl); - } - if (cl->cur_arg->type != ARGTYPE_BOOL) { - fprintf(stderr, "%s is not a flag argument\n", str); - return print_usage_and_die(cl); - } - *(int *)cl->cur_arg->value = 0; - return 1; /* early out */ - } - eq = strchr(str, '='); - if (eq != NULL) { - /* copy the string into a temp buffer and extract the name */ - tmp = arg_name = gpr_malloc((size_t)(eq - str + 1)); - memcpy(arg_name, str, (size_t)(eq - str)); - arg_name[eq - str] = 0; - } else { - arg_name = str; - } - cl->cur_arg = find_arg(cl, arg_name); - if (cl->cur_arg == NULL) { - return print_usage_and_die(cl); - } - if (eq != NULL) { - /* str was of the type --foo=value, parse the value */ - r = value_state(cl, eq + 1); - } else if (cl->cur_arg->type != ARGTYPE_BOOL) { - /* flag types don't have a '--foo value' variant, other types do */ - cl->state = value_state; - } else { - /* flag parameter: just set the value */ - *(int *)cl->cur_arg->value = 1; - } - } else { - r = extra_state(cl, str); - } - - gpr_free(tmp); - return r; -} - -int gpr_cmdline_parse(gpr_cmdline *cl, int argc, char **argv) { - int i; - - GPR_ASSERT(argc >= 1); - cl->argv0 = argv[0]; - - for (i = 1; i < argc; i++) { - if (!cl->state(cl, argv[i])) { - return 0; - } - } - return 1; -} diff --git a/src/core/support/cpu_iphone.c b/src/core/support/cpu_iphone.c deleted file mode 100644 index 82b49b47bc..0000000000 --- a/src/core/support/cpu_iphone.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright 2015, 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 - -#ifdef GPR_CPU_IPHONE - -/* Probably 2 instead of 1, but see comment on gpr_cpu_current_cpu. */ -unsigned gpr_cpu_num_cores(void) { return 1; } - -/* Most code that's using this is using it to shard across work queues. So - unless profiling shows it's a problem or there appears a way to detect the - currently running CPU core, let's have it shard the default way. - Note that the interface in cpu.h lets gpr_cpu_num_cores return 0, but doing - it makes it impossible for gpr_cpu_current_cpu to satisfy its stated range, - and some code might be relying on it. */ -unsigned gpr_cpu_current_cpu(void) { return 0; } - -#endif /* GPR_CPU_IPHONE */ diff --git a/src/core/support/cpu_linux.c b/src/core/support/cpu_linux.c deleted file mode 100644 index 5597df2d03..0000000000 --- a/src/core/support/cpu_linux.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * - * Copyright 2015-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 _GNU_SOURCE -#define _GNU_SOURCE -#endif /* _GNU_SOURCE */ - -#include - -#ifdef GPR_CPU_LINUX - -#include -#include -#include -#include - -#include -#include -#include - -static int ncpus = 0; - -static void init_num_cpus() { - /* This must be signed. sysconf returns -1 when the number cannot be - determined */ - ncpus = (int)sysconf(_SC_NPROCESSORS_ONLN); - if (ncpus < 1) { - gpr_log(GPR_ERROR, "Cannot determine number of CPUs: assuming 1"); - ncpus = 1; - } -} - -unsigned gpr_cpu_num_cores(void) { - static gpr_once once = GPR_ONCE_INIT; - gpr_once_init(&once, init_num_cpus); - return (unsigned)ncpus; -} - -unsigned gpr_cpu_current_cpu(void) { - int cpu = sched_getcpu(); - if (cpu < 0) { - gpr_log(GPR_ERROR, "Error determining current CPU: %s\n", strerror(errno)); - return 0; - } - return (unsigned)cpu; -} - -#endif /* GPR_CPU_LINUX */ diff --git a/src/core/support/cpu_posix.c b/src/core/support/cpu_posix.c deleted file mode 100644 index e508ddd8ca..0000000000 --- a/src/core/support/cpu_posix.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_CPU_POSIX - -#include -#include -#include - -#include -#include - -static __thread char magic_thread_local; - -static long ncpus = 0; - -static void init_ncpus() { - ncpus = sysconf(_SC_NPROCESSORS_ONLN); - if (ncpus < 1 || ncpus > INT32_MAX) { - gpr_log(GPR_ERROR, "Cannot determine number of CPUs: assuming 1"); - ncpus = 1; - } -} - -unsigned gpr_cpu_num_cores(void) { - static gpr_once once = GPR_ONCE_INIT; - gpr_once_init(&once, init_ncpus); - return (unsigned)ncpus; -} - -/* This is a cheap, but good enough, pointer hash for sharding things: */ -static size_t shard_ptr(const void *info) { - size_t x = (size_t)info; - return ((x >> 4) ^ (x >> 9) ^ (x >> 14)) % gpr_cpu_num_cores(); -} - -unsigned gpr_cpu_current_cpu(void) { - /* NOTE: there's no way I know to return the actual cpu index portably... - most code that's using this is using it to shard across work queues though, - so here we use thread identity instead to achieve a similar though not - identical effect */ - return (unsigned)shard_ptr(&magic_thread_local); -} - -#endif /* GPR_CPU_POSIX */ diff --git a/src/core/support/cpu_windows.c b/src/core/support/cpu_windows.c deleted file mode 100644 index ce32eb0a9d..0000000000 --- a/src/core/support/cpu_windows.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright 2015, 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 - -#ifdef GPR_WIN32 -#include - -unsigned gpr_cpu_num_cores(void) { - SYSTEM_INFO si; - GetSystemInfo(&si); - return si.dwNumberOfProcessors; -} - -unsigned gpr_cpu_current_cpu(void) { return GetCurrentProcessorNumber(); } - -#endif /* GPR_WIN32 */ diff --git a/src/core/support/env.h b/src/core/support/env.h deleted file mode 100644 index 2902456947..0000000000 --- a/src/core/support/env.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Copyright 2015-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_SUPPORT_ENV_H -#define GRPC_CORE_SUPPORT_ENV_H - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Env utility functions */ - -/* Gets the environment variable value with the specified name. - Returns a newly allocated string. It is the responsability of the caller to - gpr_free the return value if not NULL (which means that the environment - variable exists). */ -char *gpr_getenv(const char *name); - -/* Sets the the environment with the specified name to the specified value. */ -void gpr_setenv(const char *name, const char *value); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_SUPPORT_ENV_H */ diff --git a/src/core/support/env_linux.c b/src/core/support/env_linux.c deleted file mode 100644 index fe51f846b7..0000000000 --- a/src/core/support/env_linux.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* for secure_getenv. */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include - -#ifdef GPR_LINUX_ENV - -#include "src/core/support/env.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include "src/core/support/string.h" - -char *gpr_getenv(const char *name) { -#if defined(GPR_BACKWARDS_COMPATIBILITY_MODE) - typedef char *(*getenv_type)(const char *); - static getenv_type getenv_func = NULL; - /* Check to see which getenv variant is supported (go from most - * to least secure) */ - const char *names[] = {"secure_getenv", "__secure_getenv", "getenv"}; - for (size_t i = 0; getenv_func == NULL && i < GPR_ARRAY_SIZE(names); i++) { - getenv_func = (getenv_type)dlsym(RTLD_DEFAULT, names[i]); - if (getenv_func != NULL && strstr(names[i], "secure") == NULL) { - gpr_log(GPR_DEBUG, - "Warning: insecure environment read function '%s' used", - names[i]); - } - } - char *result = getenv_func(name); - return result == NULL ? result : gpr_strdup(result); -#elif __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17) - char *result = secure_getenv(name); - return result == NULL ? result : gpr_strdup(result); -#else - gpr_log(GPR_DEBUG, "Warning: insecure environment read function '%s' used", - "getenv"); - char *result = getenv(name); - return result == NULL ? result : gpr_strdup(result); -#endif -} - -void gpr_setenv(const char *name, const char *value) { - int res = setenv(name, value, 1); - GPR_ASSERT(res == 0); -} - -#endif /* GPR_LINUX_ENV */ diff --git a/src/core/support/env_posix.c b/src/core/support/env_posix.c deleted file mode 100644 index 256212be76..0000000000 --- a/src/core/support/env_posix.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_ENV - -#include "src/core/support/env.h" - -#include - -#include - -#include -#include "src/core/support/string.h" - -char *gpr_getenv(const char *name) { - char *result = getenv(name); - return result == NULL ? result : gpr_strdup(result); -} - -void gpr_setenv(const char *name, const char *value) { - int res = setenv(name, value, 1); - GPR_ASSERT(res == 0); -} - -#endif /* GPR_POSIX_ENV */ diff --git a/src/core/support/env_win32.c b/src/core/support/env_win32.c deleted file mode 100644 index 10258283ba..0000000000 --- a/src/core/support/env_win32.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_WIN32 - -#include "src/core/support/env.h" -#include "src/core/support/string.h" - -#ifdef __MINGW32__ -errno_t getenv_s(size_t *size_needed, char *buffer, size_t size, - const char *varname); -#else -#include -#endif - -#include -#include -#include - -char *gpr_getenv(const char *name) { - size_t size; - char *result = NULL; - errno_t err; - - err = getenv_s(&size, NULL, 0, name); - if (err || (size == 0)) return NULL; - result = gpr_malloc(size); - err = getenv_s(&size, result, size, name); - if (err) { - gpr_free(result); - return NULL; - } - return result; -} - -void gpr_setenv(const char *name, const char *value) { - errno_t res = _putenv_s(name, value); - GPR_ASSERT(res == 0); -} - -#endif /* GPR_WIN32 */ diff --git a/src/core/support/histogram.c b/src/core/support/histogram.c deleted file mode 100644 index 62227be1a6..0000000000 --- a/src/core/support/histogram.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include -#include -#include - -#include -#include -#include -#include - -/* Histograms are stored with exponentially increasing bucket sizes. - The first bucket is [0, m) where m = 1 + resolution - Bucket n (n>=1) contains [m**n, m**(n+1)) - There are sufficient buckets to reach max_bucket_start */ - -struct gpr_histogram { - /* Sum of all values seen so far */ - double sum; - /* Sum of squares of all values seen so far */ - double sum_of_squares; - /* number of values seen so far */ - double count; - /* m in the description */ - double multiplier; - double one_on_log_multiplier; - /* minimum value seen */ - double min_seen; - /* maximum value seen */ - double max_seen; - /* maximum representable value */ - double max_possible; - /* number of buckets */ - size_t num_buckets; - /* the buckets themselves */ - uint32_t *buckets; -}; - -/* determine a bucket index given a value - does no bounds checking */ -static size_t bucket_for_unchecked(gpr_histogram *h, double x) { - return (size_t)(log(x) * h->one_on_log_multiplier); -} - -/* bounds checked version of the above */ -static size_t bucket_for(gpr_histogram *h, double x) { - size_t bucket = bucket_for_unchecked(h, GPR_CLAMP(x, 1.0, h->max_possible)); - GPR_ASSERT(bucket < h->num_buckets); - return bucket; -} - -/* at what value does a bucket start? */ -static double bucket_start(gpr_histogram *h, double x) { - return pow(h->multiplier, x); -} - -gpr_histogram *gpr_histogram_create(double resolution, - double max_bucket_start) { - gpr_histogram *h = gpr_malloc(sizeof(gpr_histogram)); - GPR_ASSERT(resolution > 0.0); - GPR_ASSERT(max_bucket_start > resolution); - h->sum = 0.0; - h->sum_of_squares = 0.0; - h->multiplier = 1.0 + resolution; - h->one_on_log_multiplier = 1.0 / log(1.0 + resolution); - h->max_possible = max_bucket_start; - h->count = 0.0; - h->min_seen = max_bucket_start; - h->max_seen = 0.0; - h->num_buckets = bucket_for_unchecked(h, max_bucket_start) + 1; - GPR_ASSERT(h->num_buckets > 1); - GPR_ASSERT(h->num_buckets < 100000000); - h->buckets = gpr_malloc(sizeof(uint32_t) * h->num_buckets); - memset(h->buckets, 0, sizeof(uint32_t) * h->num_buckets); - return h; -} - -void gpr_histogram_destroy(gpr_histogram *h) { - gpr_free(h->buckets); - gpr_free(h); -} - -void gpr_histogram_add(gpr_histogram *h, double x) { - h->sum += x; - h->sum_of_squares += x * x; - h->count++; - if (x < h->min_seen) { - h->min_seen = x; - } - if (x > h->max_seen) { - h->max_seen = x; - } - h->buckets[bucket_for(h, x)]++; -} - -int gpr_histogram_merge(gpr_histogram *dst, const gpr_histogram *src) { - if ((dst->num_buckets != src->num_buckets) || - (dst->multiplier != src->multiplier)) { - /* Fail because these histograms don't match */ - return 0; - } - gpr_histogram_merge_contents(dst, src->buckets, src->num_buckets, - src->min_seen, src->max_seen, src->sum, - src->sum_of_squares, src->count); - return 1; -} - -void gpr_histogram_merge_contents(gpr_histogram *dst, const uint32_t *data, - size_t data_count, double min_seen, - double max_seen, double sum, - double sum_of_squares, double count) { - size_t i; - GPR_ASSERT(dst->num_buckets == data_count); - dst->sum += sum; - dst->sum_of_squares += sum_of_squares; - dst->count += count; - if (min_seen < dst->min_seen) { - dst->min_seen = min_seen; - } - if (max_seen > dst->max_seen) { - dst->max_seen = max_seen; - } - for (i = 0; i < dst->num_buckets; i++) { - dst->buckets[i] += data[i]; - } -} - -static double threshold_for_count_below(gpr_histogram *h, double count_below) { - double count_so_far; - double lower_bound; - double upper_bound; - size_t lower_idx; - size_t upper_idx; - - if (h->count == 0) { - return 0.0; - } - - if (count_below <= 0) { - return h->min_seen; - } - if (count_below >= h->count) { - return h->max_seen; - } - - /* find the lowest bucket that gets us above count_below */ - count_so_far = 0.0; - for (lower_idx = 0; lower_idx < h->num_buckets; lower_idx++) { - count_so_far += h->buckets[lower_idx]; - if (count_so_far >= count_below) { - break; - } - } - if (count_so_far == count_below) { - /* this bucket hits the threshold exactly... we should be midway through - any run of zero values following the bucket */ - for (upper_idx = lower_idx + 1; upper_idx < h->num_buckets; upper_idx++) { - if (h->buckets[upper_idx]) { - break; - } - } - return (bucket_start(h, (double)lower_idx) + - bucket_start(h, (double)upper_idx)) / - 2.0; - } else { - /* treat values as uniform throughout the bucket, and find where this value - should lie */ - lower_bound = bucket_start(h, (double)lower_idx); - upper_bound = bucket_start(h, (double)(lower_idx + 1)); - return GPR_CLAMP(upper_bound - - (upper_bound - lower_bound) * - (count_so_far - count_below) / - h->buckets[lower_idx], - h->min_seen, h->max_seen); - } -} - -double gpr_histogram_percentile(gpr_histogram *h, double percentile) { - return threshold_for_count_below(h, h->count * percentile / 100.0); -} - -double gpr_histogram_mean(gpr_histogram *h) { - GPR_ASSERT(h->count != 0); - return h->sum / h->count; -} - -double gpr_histogram_stddev(gpr_histogram *h) { - return sqrt(gpr_histogram_variance(h)); -} - -double gpr_histogram_variance(gpr_histogram *h) { - if (h->count == 0) return 0.0; - return (h->sum_of_squares * h->count - h->sum * h->sum) / - (h->count * h->count); -} - -double gpr_histogram_maximum(gpr_histogram *h) { return h->max_seen; } - -double gpr_histogram_minimum(gpr_histogram *h) { return h->min_seen; } - -double gpr_histogram_count(gpr_histogram *h) { return h->count; } - -double gpr_histogram_sum(gpr_histogram *h) { return h->sum; } - -double gpr_histogram_sum_of_squares(gpr_histogram *h) { - return h->sum_of_squares; -} - -const uint32_t *gpr_histogram_get_contents(gpr_histogram *h, size_t *size) { - *size = h->num_buckets; - return h->buckets; -} diff --git a/src/core/support/host_port.c b/src/core/support/host_port.c deleted file mode 100644 index 31243a7221..0000000000 --- a/src/core/support/host_port.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include - -#include -#include -#include -#include "src/core/support/string.h" - -int gpr_join_host_port(char **out, const char *host, int port) { - if (host[0] != '[' && strchr(host, ':') != NULL) { - /* IPv6 literals must be enclosed in brackets. */ - return gpr_asprintf(out, "[%s]:%d", host, port); - } else { - /* Ordinary non-bracketed host:port. */ - return gpr_asprintf(out, "%s:%d", host, port); - } -} - -int gpr_split_host_port(const char *name, char **host, char **port) { - const char *host_start; - size_t host_len; - const char *port_start; - - *host = NULL; - *port = NULL; - - if (name[0] == '[') { - /* Parse a bracketed host, typically an IPv6 literal. */ - const char *rbracket = strchr(name, ']'); - if (rbracket == NULL) { - /* Unmatched [ */ - return 0; - } - if (rbracket[1] == '\0') { - /* ] */ - port_start = NULL; - } else if (rbracket[1] == ':') { - /* ]: */ - port_start = rbracket + 2; - } else { - /* ] */ - return 0; - } - host_start = name + 1; - host_len = (size_t)(rbracket - host_start); - if (memchr(host_start, ':', host_len) == NULL) { - /* Require all bracketed hosts to contain a colon, because a hostname or - IPv4 address should never use brackets. */ - return 0; - } - } else { - const char *colon = strchr(name, ':'); - if (colon != NULL && strchr(colon + 1, ':') == NULL) { - /* Exactly 1 colon. Split into host:port. */ - host_start = name; - host_len = (size_t)(colon - name); - port_start = colon + 1; - } else { - /* 0 or 2+ colons. Bare hostname or IPv6 litearal. */ - host_start = name; - host_len = strlen(name); - port_start = NULL; - } - } - - /* Allocate return values. */ - *host = gpr_malloc(host_len + 1); - memcpy(*host, host_start, host_len); - (*host)[host_len] = '\0'; - - if (port_start != NULL) { - *port = gpr_strdup(port_start); - } - - return 1; -} diff --git a/src/core/support/load_file.c b/src/core/support/load_file.c deleted file mode 100644 index 650bd62ccb..0000000000 --- a/src/core/support/load_file.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * Copyright 2015-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/support/load_file.h" - -#include -#include - -#include -#include -#include - -#include "src/core/support/block_annotate.h" -#include "src/core/support/string.h" - -gpr_slice gpr_load_file(const char *filename, int add_null_terminator, - int *success) { - unsigned char *contents = NULL; - size_t contents_size = 0; - char *error_msg = NULL; - gpr_slice result = gpr_empty_slice(); - FILE *file; - size_t bytes_read = 0; - - GRPC_SCHEDULING_START_BLOCKING_REGION; - file = fopen(filename, "rb"); - if (file == NULL) { - gpr_asprintf(&error_msg, "Could not open file %s (error = %s).", filename, - strerror(errno)); - GPR_ASSERT(error_msg != NULL); - goto end; - } - fseek(file, 0, SEEK_END); - /* Converting to size_t on the assumption that it will not fail */ - contents_size = (size_t)ftell(file); - fseek(file, 0, SEEK_SET); - contents = gpr_malloc(contents_size + (add_null_terminator ? 1 : 0)); - bytes_read = fread(contents, 1, contents_size, file); - if (bytes_read < contents_size) { - GPR_ASSERT(ferror(file)); - gpr_asprintf(&error_msg, "Error %s occured while reading file %s.", - strerror(errno), filename); - GPR_ASSERT(error_msg != NULL); - goto end; - } - if (success != NULL) *success = 1; - if (add_null_terminator) { - contents[contents_size++] = 0; - } - result = gpr_slice_new(contents, contents_size, gpr_free); - -end: - if (error_msg != NULL) { - gpr_log(GPR_ERROR, "%s", error_msg); - gpr_free(error_msg); - if (success != NULL) *success = 0; - } - if (file != NULL) fclose(file); - GRPC_SCHEDULING_END_BLOCKING_REGION; - return result; -} diff --git a/src/core/support/load_file.h b/src/core/support/load_file.h deleted file mode 100644 index 5896654e9a..0000000000 --- a/src/core/support/load_file.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright 2015-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_SUPPORT_LOAD_FILE_H -#define GRPC_CORE_SUPPORT_LOAD_FILE_H - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Loads the content of a file into a slice. add_null_terminator will add - a NULL terminator if non-zero. The success parameter, if not NULL, - will be set to 1 in case of success and 0 in case of failure. */ -gpr_slice gpr_load_file(const char *filename, int add_null_terminator, - int *success); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_SUPPORT_LOAD_FILE_H */ diff --git a/src/core/support/log.c b/src/core/support/log.c deleted file mode 100644 index 04156a5b1f..0000000000 --- a/src/core/support/log.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Copyright 2015, 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 -#include - -#include -#include - -extern void gpr_default_log(gpr_log_func_args *args); -static gpr_log_func g_log_func = gpr_default_log; - -const char *gpr_log_severity_string(gpr_log_severity severity) { - switch (severity) { - case GPR_LOG_SEVERITY_DEBUG: - return "D"; - case GPR_LOG_SEVERITY_INFO: - return "I"; - case GPR_LOG_SEVERITY_ERROR: - return "E"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -void gpr_log_message(const char *file, int line, gpr_log_severity severity, - const char *message) { - gpr_log_func_args lfargs; - memset(&lfargs, 0, sizeof(lfargs)); - lfargs.file = file; - lfargs.line = line; - lfargs.severity = severity; - lfargs.message = message; - g_log_func(&lfargs); -} - -void gpr_set_log_function(gpr_log_func f) { g_log_func = f; } diff --git a/src/core/support/log_android.c b/src/core/support/log_android.c deleted file mode 100644 index 640c9d7099..0000000000 --- a/src/core/support/log_android.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_ANDROID - -#include -#include -#include -#include -#include -#include - -static android_LogPriority severity_to_log_priority(gpr_log_severity severity) { - switch (severity) { - case GPR_LOG_SEVERITY_DEBUG: - return ANDROID_LOG_DEBUG; - case GPR_LOG_SEVERITY_INFO: - return ANDROID_LOG_INFO; - case GPR_LOG_SEVERITY_ERROR: - return ANDROID_LOG_ERROR; - } - return ANDROID_LOG_DEFAULT; -} - -void gpr_log(const char *file, int line, gpr_log_severity severity, - const char *format, ...) { - char *message = NULL; - va_list args; - va_start(args, format); - vasprintf(&message, format, args); - va_end(args); - gpr_log_message(file, line, severity, message); - free(message); -} - -void gpr_default_log(gpr_log_func_args *args) { - char *final_slash; - const char *display_file; - char *output = NULL; - - final_slash = strrchr(args->file, '/'); - if (final_slash == NULL) - display_file = args->file; - else - display_file = final_slash + 1; - - asprintf(&output, "%s:%d] %s", display_file, args->line, args->message); - - __android_log_write(severity_to_log_priority(args->severity), "GRPC", output); - - /* allocated by asprintf => use free, not gpr_free */ - free(output); -} - -#endif /* GPR_ANDROID */ diff --git a/src/core/support/log_linux.c b/src/core/support/log_linux.c deleted file mode 100644 index e60512c526..0000000000 --- a/src/core/support/log_linux.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * - * Copyright 2015-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 _POSIX_SOURCE -#define _POSIX_SOURCE -#endif - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include - -#ifdef GPR_LINUX - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static long gettid(void) { return syscall(__NR_gettid); } - -void gpr_log(const char *file, int line, gpr_log_severity severity, - const char *format, ...) { - char *message = NULL; - va_list args; - va_start(args, format); - if (vasprintf(&message, format, args) == -1) { - va_end(args); - return; - } - va_end(args); - gpr_log_message(file, line, severity, message); - free(message); -} - -void gpr_default_log(gpr_log_func_args *args) { - char *final_slash; - char *prefix; - const char *display_file; - char time_buffer[64]; - time_t timer; - gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); - struct tm tm; - - timer = (time_t)now.tv_sec; - final_slash = strrchr(args->file, '/'); - if (final_slash == NULL) - display_file = args->file; - else - display_file = final_slash + 1; - - if (!localtime_r(&timer, &tm)) { - strcpy(time_buffer, "error:localtime"); - } else if (0 == - strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { - strcpy(time_buffer, "error:strftime"); - } - - gpr_asprintf(&prefix, "%s%s.%09d %7tu %s:%d]", - gpr_log_severity_string(args->severity), time_buffer, - (int)(now.tv_nsec), gettid(), display_file, args->line); - - fprintf(stderr, "%-60s %s\n", prefix, args->message); - gpr_free(prefix); -} - -#endif diff --git a/src/core/support/log_posix.c b/src/core/support/log_posix.c deleted file mode 100644 index 7429dd0a2c..0000000000 --- a/src/core/support/log_posix.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * Copyright 2015-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 - -#if defined(GPR_POSIX_LOG) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static intptr_t gettid(void) { return (intptr_t)pthread_self(); } - -void gpr_log(const char *file, int line, gpr_log_severity severity, - const char *format, ...) { - char buf[64]; - char *allocated = NULL; - char *message = NULL; - int ret; - va_list args; - va_start(args, format); - ret = vsnprintf(buf, sizeof(buf), format, args); - va_end(args); - if (ret < 0) { - message = NULL; - } else if ((size_t)ret <= sizeof(buf) - 1) { - message = buf; - } else { - message = allocated = gpr_malloc((size_t)ret + 1); - va_start(args, format); - vsnprintf(message, (size_t)(ret + 1), format, args); - va_end(args); - } - gpr_log_message(file, line, severity, message); - gpr_free(allocated); -} - -void gpr_default_log(gpr_log_func_args *args) { - char *final_slash; - const char *display_file; - char time_buffer[64]; - time_t timer; - gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); - struct tm tm; - - timer = (time_t)now.tv_sec; - final_slash = strrchr(args->file, '/'); - if (final_slash == NULL) - display_file = args->file; - else - display_file = final_slash + 1; - - if (!localtime_r(&timer, &tm)) { - strcpy(time_buffer, "error:localtime"); - } else if (0 == - strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { - strcpy(time_buffer, "error:strftime"); - } - - fprintf(stderr, "%s%s.%09d %7tu %s:%d] %s\n", - gpr_log_severity_string(args->severity), time_buffer, - (int)(now.tv_nsec), gettid(), display_file, args->line, - args->message); -} - -#endif /* defined(GPR_POSIX_LOG) */ diff --git a/src/core/support/log_win32.c b/src/core/support/log_win32.c deleted file mode 100644 index 89ec0917d5..0000000000 --- a/src/core/support/log_win32.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_WIN32 - -#include -#include - -#include -#include -#include -#include -#include - -#include "src/core/support/string.h" -#include "src/core/support/string_win32.h" - -void gpr_log(const char *file, int line, gpr_log_severity severity, - const char *format, ...) { - char *message = NULL; - va_list args; - int ret; - - /* Determine the length. */ - va_start(args, format); - ret = _vscprintf(format, args); - va_end(args); - if (ret < 0) { - message = NULL; - } else { - /* Allocate a new buffer, with space for the NUL terminator. */ - size_t strp_buflen = (size_t)ret + 1; - message = gpr_malloc(strp_buflen); - - /* Print to the buffer. */ - va_start(args, format); - ret = vsnprintf_s(message, strp_buflen, _TRUNCATE, format, args); - va_end(args); - if ((size_t)ret != strp_buflen - 1) { - /* This should never happen. */ - gpr_free(message); - message = NULL; - } - } - - gpr_log_message(file, line, severity, message); - gpr_free(message); -} - -/* Simple starter implementation */ -void gpr_default_log(gpr_log_func_args *args) { - char *final_slash; - const char *display_file; - char time_buffer[64]; - time_t timer; - gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); - struct tm tm; - - timer = (time_t)now.tv_sec; - final_slash = strrchr(args->file, '\\'); - if (final_slash == NULL) - display_file = args->file; - else - display_file = final_slash + 1; - - if (localtime_s(&tm, &timer)) { - strcpy(time_buffer, "error:localtime"); - } else if (0 == - strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { - strcpy(time_buffer, "error:strftime"); - } - - fprintf(stderr, "%s%s.%09u %5lu %s:%d] %s\n", - gpr_log_severity_string(args->severity), time_buffer, - (int)(now.tv_nsec), GetCurrentThreadId(), display_file, args->line, - args->message); - fflush(stderr); -} - -char *gpr_format_message(int messageid) { - LPTSTR tmessage; - char *message; - DWORD status = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, (DWORD)messageid, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)(&tmessage), 0, NULL); - if (status == 0) return gpr_strdup("Unable to retrieve error string"); - message = gpr_tchar_to_char(tmessage); - LocalFree(tmessage); - return message; -} - -#endif /* GPR_WIN32 */ diff --git a/src/core/support/murmur_hash.c b/src/core/support/murmur_hash.c deleted file mode 100644 index a5261c0cc0..0000000000 --- a/src/core/support/murmur_hash.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * - * Copyright 2015, 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/support/murmur_hash.h" - -#define ROTL32(x, r) ((x) << (r)) | ((x) >> (32 - (r))) - -#define FMIX32(h) \ - (h) ^= (h) >> 16; \ - (h) *= 0x85ebca6b; \ - (h) ^= (h) >> 13; \ - (h) *= 0xc2b2ae35; \ - (h) ^= (h) >> 16; - -/* Block read - if your platform needs to do endian-swapping or can only - handle aligned reads, do the conversion here */ -#define GETBLOCK32(p, i) (p)[(i)] - -uint32_t gpr_murmur_hash3(const void *key, size_t len, uint32_t seed) { - const uint8_t *data = (const uint8_t *)key; - const size_t nblocks = len / 4; - int i; - - uint32_t h1 = seed; - uint32_t k1; - - const uint32_t c1 = 0xcc9e2d51; - const uint32_t c2 = 0x1b873593; - - const uint32_t *blocks = ((const uint32_t *)key) + nblocks; - const uint8_t *tail = (const uint8_t *)(data + nblocks * 4); - - /* body */ - for (i = -(int)nblocks; i; i++) { - k1 = GETBLOCK32(blocks, i); - - k1 *= c1; - k1 = ROTL32(k1, 15); - k1 *= c2; - - h1 ^= k1; - h1 = ROTL32(h1, 13); - h1 = h1 * 5 + 0xe6546b64; - } - - k1 = 0; - - /* tail */ - switch (len & 3) { - case 3: - k1 ^= ((uint32_t)tail[2]) << 16; - case 2: - k1 ^= ((uint32_t)tail[1]) << 8; - case 1: - k1 ^= tail[0]; - k1 *= c1; - k1 = ROTL32(k1, 15); - k1 *= c2; - h1 ^= k1; - }; - - /* finalization */ - h1 ^= (uint32_t)len; - FMIX32(h1); - return h1; -} diff --git a/src/core/support/murmur_hash.h b/src/core/support/murmur_hash.h deleted file mode 100644 index 0f0b399e5d..0000000000 --- a/src/core/support/murmur_hash.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * Copyright 2015-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_SUPPORT_MURMUR_HASH_H -#define GRPC_CORE_SUPPORT_MURMUR_HASH_H - -#include - -#include - -/* compute the hash of key (length len) */ -uint32_t gpr_murmur_hash3(const void *key, size_t len, uint32_t seed); - -#endif /* GRPC_CORE_SUPPORT_MURMUR_HASH_H */ diff --git a/src/core/support/slice.c b/src/core/support/slice.c deleted file mode 100644 index b9a7c77bda..0000000000 --- a/src/core/support/slice.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * - * Copyright 2015, 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 -#include -#include - -#include - -gpr_slice gpr_empty_slice(void) { - gpr_slice out; - out.refcount = 0; - out.data.inlined.length = 0; - return out; -} - -gpr_slice gpr_slice_ref(gpr_slice slice) { - if (slice.refcount) { - slice.refcount->ref(slice.refcount); - } - return slice; -} - -void gpr_slice_unref(gpr_slice slice) { - if (slice.refcount) { - slice.refcount->unref(slice.refcount); - } -} - -/* gpr_slice_from_static_string support structure - a refcount that does - nothing */ -static void noop_ref_or_unref(void *unused) {} - -static gpr_slice_refcount noop_refcount = {noop_ref_or_unref, - noop_ref_or_unref}; - -gpr_slice gpr_slice_from_static_string(const char *s) { - gpr_slice slice; - slice.refcount = &noop_refcount; - slice.data.refcounted.bytes = (uint8_t *)s; - slice.data.refcounted.length = strlen(s); - return slice; -} - -/* gpr_slice_new support structures - we create a refcount object extended - with the user provided data pointer & destroy function */ -typedef struct new_slice_refcount { - gpr_slice_refcount rc; - gpr_refcount refs; - void (*user_destroy)(void *); - void *user_data; -} new_slice_refcount; - -static void new_slice_ref(void *p) { - new_slice_refcount *r = p; - gpr_ref(&r->refs); -} - -static void new_slice_unref(void *p) { - new_slice_refcount *r = p; - if (gpr_unref(&r->refs)) { - r->user_destroy(r->user_data); - gpr_free(r); - } -} - -gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) { - gpr_slice slice; - new_slice_refcount *rc = gpr_malloc(sizeof(new_slice_refcount)); - gpr_ref_init(&rc->refs, 1); - rc->rc.ref = new_slice_ref; - rc->rc.unref = new_slice_unref; - rc->user_destroy = destroy; - rc->user_data = p; - - slice.refcount = &rc->rc; - slice.data.refcounted.bytes = p; - slice.data.refcounted.length = len; - return slice; -} - -/* gpr_slice_new_with_len support structures - we create a refcount object - extended with the user provided data pointer & destroy function */ -typedef struct new_with_len_slice_refcount { - gpr_slice_refcount rc; - gpr_refcount refs; - void *user_data; - size_t user_length; - void (*user_destroy)(void *, size_t); -} new_with_len_slice_refcount; - -static void new_with_len_ref(void *p) { - new_with_len_slice_refcount *r = p; - gpr_ref(&r->refs); -} - -static void new_with_len_unref(void *p) { - new_with_len_slice_refcount *r = p; - if (gpr_unref(&r->refs)) { - r->user_destroy(r->user_data, r->user_length); - gpr_free(r); - } -} - -gpr_slice gpr_slice_new_with_len(void *p, size_t len, - void (*destroy)(void *, size_t)) { - gpr_slice slice; - new_with_len_slice_refcount *rc = - gpr_malloc(sizeof(new_with_len_slice_refcount)); - gpr_ref_init(&rc->refs, 1); - rc->rc.ref = new_with_len_ref; - rc->rc.unref = new_with_len_unref; - rc->user_destroy = destroy; - rc->user_data = p; - rc->user_length = len; - - slice.refcount = &rc->rc; - slice.data.refcounted.bytes = p; - slice.data.refcounted.length = len; - return slice; -} - -gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t length) { - gpr_slice slice = gpr_slice_malloc(length); - memcpy(GPR_SLICE_START_PTR(slice), source, length); - return slice; -} - -gpr_slice gpr_slice_from_copied_string(const char *source) { - return gpr_slice_from_copied_buffer(source, strlen(source)); -} - -typedef struct { - gpr_slice_refcount base; - gpr_refcount refs; -} malloc_refcount; - -static void malloc_ref(void *p) { - malloc_refcount *r = p; - gpr_ref(&r->refs); -} - -static void malloc_unref(void *p) { - malloc_refcount *r = p; - if (gpr_unref(&r->refs)) { - gpr_free(r); - } -} - -gpr_slice gpr_slice_malloc(size_t length) { - gpr_slice slice; - - if (length > sizeof(slice.data.inlined.bytes)) { - /* Memory layout used by the slice created here: - - +-----------+----------------------------------------------------------+ - | refcount | bytes | - +-----------+----------------------------------------------------------+ - - refcount is a malloc_refcount - bytes is an array of bytes of the requested length - Both parts are placed in the same allocation returned from gpr_malloc */ - malloc_refcount *rc = gpr_malloc(sizeof(malloc_refcount) + length); - - /* Initial refcount on rc is 1 - and it's up to the caller to release - this reference. */ - gpr_ref_init(&rc->refs, 1); - - rc->base.ref = malloc_ref; - rc->base.unref = malloc_unref; - - /* Build up the slice to be returned. */ - /* The slices refcount points back to the allocated block. */ - slice.refcount = &rc->base; - /* The data bytes are placed immediately after the refcount struct */ - slice.data.refcounted.bytes = (uint8_t *)(rc + 1); - /* And the length of the block is set to the requested length */ - slice.data.refcounted.length = length; - } else { - /* small slice: just inline the data */ - slice.refcount = NULL; - slice.data.inlined.length = (uint8_t)length; - } - return slice; -} - -gpr_slice gpr_slice_sub_no_ref(gpr_slice source, size_t begin, size_t end) { - gpr_slice subset; - - GPR_ASSERT(end >= begin); - - if (source.refcount) { - /* Enforce preconditions */ - GPR_ASSERT(source.data.refcounted.length >= end); - - /* Build the result */ - subset.refcount = source.refcount; - /* Point into the source array */ - subset.data.refcounted.bytes = source.data.refcounted.bytes + begin; - subset.data.refcounted.length = end - begin; - } else { - /* Enforce preconditions */ - GPR_ASSERT(source.data.inlined.length >= end); - subset.refcount = NULL; - subset.data.inlined.length = (uint8_t)(end - begin); - memcpy(subset.data.inlined.bytes, source.data.inlined.bytes + begin, - end - begin); - } - return subset; -} - -gpr_slice gpr_slice_sub(gpr_slice source, size_t begin, size_t end) { - gpr_slice subset; - - if (end - begin <= sizeof(subset.data.inlined.bytes)) { - subset.refcount = NULL; - subset.data.inlined.length = (uint8_t)(end - begin); - memcpy(subset.data.inlined.bytes, GPR_SLICE_START_PTR(source) + begin, - end - begin); - } else { - subset = gpr_slice_sub_no_ref(source, begin, end); - /* Bump the refcount */ - subset.refcount->ref(subset.refcount); - } - return subset; -} - -gpr_slice gpr_slice_split_tail(gpr_slice *source, size_t split) { - gpr_slice tail; - - if (source->refcount == NULL) { - /* inlined data, copy it out */ - GPR_ASSERT(source->data.inlined.length >= split); - tail.refcount = NULL; - tail.data.inlined.length = (uint8_t)(source->data.inlined.length - split); - memcpy(tail.data.inlined.bytes, source->data.inlined.bytes + split, - tail.data.inlined.length); - source->data.inlined.length = (uint8_t)split; - } else { - size_t tail_length = source->data.refcounted.length - split; - GPR_ASSERT(source->data.refcounted.length >= split); - if (tail_length < sizeof(tail.data.inlined.bytes)) { - /* Copy out the bytes - it'll be cheaper than refcounting */ - tail.refcount = NULL; - tail.data.inlined.length = (uint8_t)tail_length; - memcpy(tail.data.inlined.bytes, source->data.refcounted.bytes + split, - tail_length); - } else { - /* Build the result */ - tail.refcount = source->refcount; - /* Bump the refcount */ - tail.refcount->ref(tail.refcount); - /* Point into the source array */ - tail.data.refcounted.bytes = source->data.refcounted.bytes + split; - tail.data.refcounted.length = tail_length; - } - source->data.refcounted.length = split; - } - - return tail; -} - -gpr_slice gpr_slice_split_head(gpr_slice *source, size_t split) { - gpr_slice head; - - if (source->refcount == NULL) { - GPR_ASSERT(source->data.inlined.length >= split); - - head.refcount = NULL; - head.data.inlined.length = (uint8_t)split; - memcpy(head.data.inlined.bytes, source->data.inlined.bytes, split); - source->data.inlined.length = - (uint8_t)(source->data.inlined.length - split); - memmove(source->data.inlined.bytes, source->data.inlined.bytes + split, - source->data.inlined.length); - } else if (split < sizeof(head.data.inlined.bytes)) { - GPR_ASSERT(source->data.refcounted.length >= split); - - head.refcount = NULL; - head.data.inlined.length = (uint8_t)split; - memcpy(head.data.inlined.bytes, source->data.refcounted.bytes, split); - source->data.refcounted.bytes += split; - source->data.refcounted.length -= split; - } else { - GPR_ASSERT(source->data.refcounted.length >= split); - - /* Build the result */ - head.refcount = source->refcount; - /* Bump the refcount */ - head.refcount->ref(head.refcount); - /* Point into the source array */ - head.data.refcounted.bytes = source->data.refcounted.bytes; - head.data.refcounted.length = split; - source->data.refcounted.bytes += split; - source->data.refcounted.length -= split; - } - - return head; -} - -int gpr_slice_cmp(gpr_slice a, gpr_slice b) { - int d = (int)(GPR_SLICE_LENGTH(a) - GPR_SLICE_LENGTH(b)); - if (d != 0) return d; - return memcmp(GPR_SLICE_START_PTR(a), GPR_SLICE_START_PTR(b), - GPR_SLICE_LENGTH(a)); -} - -int gpr_slice_str_cmp(gpr_slice a, const char *b) { - size_t b_length = strlen(b); - int d = (int)(GPR_SLICE_LENGTH(a) - b_length); - if (d != 0) return d; - return memcmp(GPR_SLICE_START_PTR(a), b, b_length); -} diff --git a/src/core/support/slice_buffer.c b/src/core/support/slice_buffer.c deleted file mode 100644 index 66f111d767..0000000000 --- a/src/core/support/slice_buffer.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * - * Copyright 2015, 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 -#include - -#include - -#include -#include -#include - -/* grow a buffer; requires GRPC_SLICE_BUFFER_INLINE_ELEMENTS > 1 */ -#define GROW(x) (3 * (x) / 2) - -static void maybe_embiggen(gpr_slice_buffer *sb) { - if (sb->count == sb->capacity) { - sb->capacity = GROW(sb->capacity); - GPR_ASSERT(sb->capacity > sb->count); - if (sb->slices == sb->inlined) { - sb->slices = gpr_malloc(sb->capacity * sizeof(gpr_slice)); - memcpy(sb->slices, sb->inlined, sb->count * sizeof(gpr_slice)); - } else { - sb->slices = gpr_realloc(sb->slices, sb->capacity * sizeof(gpr_slice)); - } - } -} - -void gpr_slice_buffer_init(gpr_slice_buffer *sb) { - sb->count = 0; - sb->length = 0; - sb->capacity = GRPC_SLICE_BUFFER_INLINE_ELEMENTS; - sb->slices = sb->inlined; -} - -void gpr_slice_buffer_destroy(gpr_slice_buffer *sb) { - gpr_slice_buffer_reset_and_unref(sb); - if (sb->slices != sb->inlined) { - gpr_free(sb->slices); - } -} - -uint8_t *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, size_t n) { - gpr_slice *back; - uint8_t *out; - - sb->length += n; - - if (sb->count == 0) goto add_new; - back = &sb->slices[sb->count - 1]; - if (back->refcount) goto add_new; - if ((back->data.inlined.length + n) > sizeof(back->data.inlined.bytes)) - goto add_new; - out = back->data.inlined.bytes + back->data.inlined.length; - back->data.inlined.length = (uint8_t)(back->data.inlined.length + n); - return out; - -add_new: - maybe_embiggen(sb); - back = &sb->slices[sb->count]; - sb->count++; - back->refcount = NULL; - back->data.inlined.length = (uint8_t)n; - return back->data.inlined.bytes; -} - -size_t gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb, gpr_slice s) { - size_t out = sb->count; - maybe_embiggen(sb); - sb->slices[out] = s; - sb->length += GPR_SLICE_LENGTH(s); - sb->count = out + 1; - return out; -} - -void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_slice s) { - size_t n = sb->count; - /* if both the last slice in the slice buffer and the slice being added - are inlined (that is, that they carry their data inside the slice data - structure), and the back slice is not full, then concatenate directly - into the back slice, preventing many small slices being passed into - writes */ - if (!s.refcount && n) { - gpr_slice *back = &sb->slices[n - 1]; - if (!back->refcount && back->data.inlined.length < GPR_SLICE_INLINED_SIZE) { - if (s.data.inlined.length + back->data.inlined.length <= - GPR_SLICE_INLINED_SIZE) { - memcpy(back->data.inlined.bytes + back->data.inlined.length, - s.data.inlined.bytes, s.data.inlined.length); - back->data.inlined.length = - (uint8_t)(back->data.inlined.length + s.data.inlined.length); - } else { - size_t cp1 = GPR_SLICE_INLINED_SIZE - back->data.inlined.length; - memcpy(back->data.inlined.bytes + back->data.inlined.length, - s.data.inlined.bytes, cp1); - back->data.inlined.length = GPR_SLICE_INLINED_SIZE; - maybe_embiggen(sb); - back = &sb->slices[n]; - sb->count = n + 1; - back->refcount = NULL; - back->data.inlined.length = (uint8_t)(s.data.inlined.length - cp1); - memcpy(back->data.inlined.bytes, s.data.inlined.bytes + cp1, - s.data.inlined.length - cp1); - } - sb->length += s.data.inlined.length; - return; /* early out */ - } - } - gpr_slice_buffer_add_indexed(sb, s); -} - -void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *s, size_t n) { - size_t i; - for (i = 0; i < n; i++) { - gpr_slice_buffer_add(sb, s[i]); - } -} - -void gpr_slice_buffer_pop(gpr_slice_buffer *sb) { - if (sb->count != 0) { - size_t count = --sb->count; - sb->length -= GPR_SLICE_LENGTH(sb->slices[count]); - } -} - -void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb) { - size_t i; - - for (i = 0; i < sb->count; i++) { - gpr_slice_unref(sb->slices[i]); - } - - sb->count = 0; - sb->length = 0; -} - -void gpr_slice_buffer_swap(gpr_slice_buffer *a, gpr_slice_buffer *b) { - GPR_SWAP(size_t, a->count, b->count); - GPR_SWAP(size_t, a->capacity, b->capacity); - GPR_SWAP(size_t, a->length, b->length); - - if (a->slices == a->inlined) { - if (b->slices == b->inlined) { - /* swap contents of inlined buffer */ - gpr_slice temp[GRPC_SLICE_BUFFER_INLINE_ELEMENTS]; - memcpy(temp, a->slices, b->count * sizeof(gpr_slice)); - memcpy(a->slices, b->slices, a->count * sizeof(gpr_slice)); - memcpy(b->slices, temp, b->count * sizeof(gpr_slice)); - } else { - /* a is inlined, b is not - copy a inlined into b, fix pointers */ - a->slices = b->slices; - b->slices = b->inlined; - memcpy(b->slices, a->inlined, b->count * sizeof(gpr_slice)); - } - } else if (b->slices == b->inlined) { - /* b is inlined, a is not - copy b inlined int a, fix pointers */ - b->slices = a->slices; - a->slices = a->inlined; - memcpy(a->slices, b->inlined, a->count * sizeof(gpr_slice)); - } else { - /* no inlining: easy swap */ - GPR_SWAP(gpr_slice *, a->slices, b->slices); - } -} - -void gpr_slice_buffer_move_into(gpr_slice_buffer *src, gpr_slice_buffer *dst) { - /* anything to move? */ - if (src->count == 0) { - return; - } - /* anything in dst? */ - if (dst->count == 0) { - gpr_slice_buffer_swap(src, dst); - return; - } - /* both buffers have data - copy, and reset src */ - gpr_slice_buffer_addn(dst, src->slices, src->count); - src->count = 0; - src->length = 0; -} - -void gpr_slice_buffer_move_first(gpr_slice_buffer *src, size_t n, - gpr_slice_buffer *dst) { - size_t src_idx; - size_t output_len = dst->length + n; - size_t new_input_len = src->length - n; - GPR_ASSERT(src->length >= n); - if (src->length == n) { - gpr_slice_buffer_move_into(src, dst); - return; - } - src_idx = 0; - while (src_idx < src->capacity) { - gpr_slice slice = src->slices[src_idx]; - size_t slice_len = GPR_SLICE_LENGTH(slice); - if (n > slice_len) { - gpr_slice_buffer_add(dst, slice); - n -= slice_len; - src_idx++; - } else if (n == slice_len) { - gpr_slice_buffer_add(dst, slice); - src_idx++; - break; - } else { /* n < slice_len */ - src->slices[src_idx] = gpr_slice_split_tail(&slice, n); - GPR_ASSERT(GPR_SLICE_LENGTH(slice) == n); - GPR_ASSERT(GPR_SLICE_LENGTH(src->slices[src_idx]) == slice_len - n); - gpr_slice_buffer_add(dst, slice); - break; - } - } - GPR_ASSERT(dst->length == output_len); - memmove(src->slices, src->slices + src_idx, - sizeof(gpr_slice) * (src->count - src_idx)); - src->count -= src_idx; - src->length = new_input_len; - GPR_ASSERT(src->count > 0); -} - -void gpr_slice_buffer_trim_end(gpr_slice_buffer *sb, size_t n, - gpr_slice_buffer *garbage) { - GPR_ASSERT(n <= sb->length); - sb->length -= n; - for (;;) { - size_t idx = sb->count - 1; - gpr_slice slice = sb->slices[idx]; - size_t slice_len = GPR_SLICE_LENGTH(slice); - if (slice_len > n) { - sb->slices[idx] = gpr_slice_split_head(&slice, slice_len - n); - gpr_slice_buffer_add_indexed(garbage, slice); - return; - } else if (slice_len == n) { - gpr_slice_buffer_add_indexed(garbage, slice); - sb->count = idx; - return; - } else { - gpr_slice_buffer_add_indexed(garbage, slice); - n -= slice_len; - sb->count = idx; - } - } -} - -gpr_slice gpr_slice_buffer_take_first(gpr_slice_buffer *sb) { - gpr_slice slice; - GPR_ASSERT(sb->count > 0); - slice = sb->slices[0]; - memmove(&sb->slices[0], &sb->slices[1], (sb->count - 1) * sizeof(gpr_slice)); - sb->count--; - sb->length -= GPR_SLICE_LENGTH(slice); - return slice; -} diff --git a/src/core/support/stack_lockfree.c b/src/core/support/stack_lockfree.c deleted file mode 100644 index 8e0bbfaee8..0000000000 --- a/src/core/support/stack_lockfree.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * - * Copyright 2015-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/support/stack_lockfree.h" - -#include -#include - -#include -#include -#include -#include - -/* The lockfree node structure is a single architecture-level - word that allows for an atomic CAS to set it up. */ -struct lockfree_node_contents { - /* next thing to look at. Actual index for head, next index otherwise */ - uint16_t index; -#ifdef GPR_ARCH_64 - uint16_t pad; - uint32_t aba_ctr; -#else -#ifdef GPR_ARCH_32 - uint16_t aba_ctr; -#else -#error Unsupported bit width architecture -#endif -#endif -}; - -/* Use a union to make sure that these are in the same bits as an atm word */ -typedef union lockfree_node { - gpr_atm atm; - struct lockfree_node_contents contents; -} lockfree_node; - -/* make sure that entries aligned to 8-bytes */ -#define ENTRY_ALIGNMENT_BITS 3 -/* reserve this entry as invalid */ -#define INVALID_ENTRY_INDEX ((1 << 16) - 1) - -struct gpr_stack_lockfree { - lockfree_node *entries; - lockfree_node head; /* An atomic entry describing curr head */ - -#ifndef NDEBUG - /* Bitmap of pushed entries to check for double-push or pop */ - gpr_atm pushed[(INVALID_ENTRY_INDEX + 1) / (8 * sizeof(gpr_atm))]; -#endif -}; - -gpr_stack_lockfree *gpr_stack_lockfree_create(size_t entries) { - gpr_stack_lockfree *stack; - stack = gpr_malloc(sizeof(*stack)); - /* Since we only allocate 16 bits to represent an entry number, - * make sure that we are within the desired range */ - /* Reserve the highest entry number as a dummy */ - GPR_ASSERT(entries < INVALID_ENTRY_INDEX); - stack->entries = gpr_malloc_aligned(entries * sizeof(stack->entries[0]), - ENTRY_ALIGNMENT_BITS); - /* Clear out all entries */ - memset(stack->entries, 0, entries * sizeof(stack->entries[0])); - memset(&stack->head, 0, sizeof(stack->head)); -#ifndef NDEBUG - memset(&stack->pushed, 0, sizeof(stack->pushed)); -#endif - - GPR_ASSERT(sizeof(stack->entries->atm) == sizeof(stack->entries->contents)); - - /* Point the head at reserved dummy entry */ - stack->head.contents.index = INVALID_ENTRY_INDEX; -/* Fill in the pad and aba_ctr to avoid confusing memcheck tools */ -#ifdef GPR_ARCH_64 - stack->head.contents.pad = 0; -#endif - stack->head.contents.aba_ctr = 0; - return stack; -} - -void gpr_stack_lockfree_destroy(gpr_stack_lockfree *stack) { - gpr_free_aligned(stack->entries); - gpr_free(stack); -} - -int gpr_stack_lockfree_push(gpr_stack_lockfree *stack, int entry) { - lockfree_node head; - lockfree_node newhead; - lockfree_node curent; - lockfree_node newent; - - /* First fill in the entry's index and aba ctr for new head */ - newhead.contents.index = (uint16_t)entry; -#ifdef GPR_ARCH_64 - /* Fill in the pad to avoid confusing memcheck tools */ - newhead.contents.pad = 0; -#endif - - /* Also post-increment the aba_ctr */ - curent.atm = gpr_atm_no_barrier_load(&stack->entries[entry].atm); - newhead.contents.aba_ctr = ++curent.contents.aba_ctr; - gpr_atm_no_barrier_store(&stack->entries[entry].atm, curent.atm); - -#ifndef NDEBUG - /* Check for double push */ - { - int pushed_index = entry / (int)(8 * sizeof(gpr_atm)); - int pushed_bit = entry % (int)(8 * sizeof(gpr_atm)); - gpr_atm old_val; - - old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index], - ((gpr_atm)1 << pushed_bit)); - GPR_ASSERT((old_val & (((gpr_atm)1) << pushed_bit)) == 0); - } -#endif - - do { - /* Atomically get the existing head value for use */ - head.atm = gpr_atm_no_barrier_load(&(stack->head.atm)); - /* Point to it */ - newent.atm = gpr_atm_no_barrier_load(&stack->entries[entry].atm); - newent.contents.index = head.contents.index; - gpr_atm_no_barrier_store(&stack->entries[entry].atm, newent.atm); - } while (!gpr_atm_rel_cas(&(stack->head.atm), head.atm, newhead.atm)); - /* Use rel_cas above to make sure that entry index is set properly */ - return head.contents.index == INVALID_ENTRY_INDEX; -} - -int gpr_stack_lockfree_pop(gpr_stack_lockfree *stack) { - lockfree_node head; - lockfree_node newhead; - - do { - head.atm = gpr_atm_acq_load(&(stack->head.atm)); - if (head.contents.index == INVALID_ENTRY_INDEX) { - return -1; - } - newhead.atm = - gpr_atm_no_barrier_load(&(stack->entries[head.contents.index].atm)); - - } while (!gpr_atm_no_barrier_cas(&(stack->head.atm), head.atm, newhead.atm)); -#ifndef NDEBUG - /* Check for valid pop */ - { - int pushed_index = head.contents.index / (8 * sizeof(gpr_atm)); - int pushed_bit = head.contents.index % (8 * sizeof(gpr_atm)); - gpr_atm old_val; - - old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index], - -((gpr_atm)1 << pushed_bit)); - GPR_ASSERT((old_val & (((gpr_atm)1) << pushed_bit)) != 0); - } -#endif - - return head.contents.index; -} diff --git a/src/core/support/stack_lockfree.h b/src/core/support/stack_lockfree.h deleted file mode 100644 index d6fd06d67c..0000000000 --- a/src/core/support/stack_lockfree.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Copyright 2015-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_SUPPORT_STACK_LOCKFREE_H -#define GRPC_CORE_SUPPORT_STACK_LOCKFREE_H - -#include - -typedef struct gpr_stack_lockfree gpr_stack_lockfree; - -/* This stack must specify the maximum number of entries to track. - The current implementation only allows up to 65534 entries */ -gpr_stack_lockfree *gpr_stack_lockfree_create(size_t entries); -void gpr_stack_lockfree_destroy(gpr_stack_lockfree *stack); - -/* Pass in a valid entry number for the next stack entry */ -/* Returns 1 if this is the first element on the stack, 0 otherwise */ -int gpr_stack_lockfree_push(gpr_stack_lockfree *, int entry); - -/* Returns -1 on empty or the actual entry number */ -int gpr_stack_lockfree_pop(gpr_stack_lockfree *stack); - -#endif /* GRPC_CORE_SUPPORT_STACK_LOCKFREE_H */ diff --git a/src/core/support/string.c b/src/core/support/string.c deleted file mode 100644 index 1f541de40f..0000000000 --- a/src/core/support/string.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * - * Copyright 2015, 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/support/string.h" - -#include -#include -#include - -#include -#include -#include -#include - -char *gpr_strdup(const char *src) { - char *dst; - size_t len; - - if (!src) { - return NULL; - } - - len = strlen(src) + 1; - dst = gpr_malloc(len); - - memcpy(dst, src, len); - - return dst; -} - -typedef struct { - size_t capacity; - size_t length; - char *data; -} dump_out; - -static dump_out dump_out_create(void) { - dump_out r = {0, 0, NULL}; - return r; -} - -static void dump_out_append(dump_out *out, char c) { - if (out->length == out->capacity) { - out->capacity = GPR_MAX(8, 2 * out->capacity); - out->data = gpr_realloc(out->data, out->capacity); - } - out->data[out->length++] = c; -} - -static void hexdump(dump_out *out, const char *buf, size_t len) { - static const char hex[16] = "0123456789abcdef"; - - const uint8_t *const beg = (const uint8_t *)buf; - const uint8_t *const end = beg + len; - const uint8_t *cur; - - for (cur = beg; cur != end; ++cur) { - if (cur != beg) dump_out_append(out, ' '); - dump_out_append(out, hex[*cur >> 4]); - dump_out_append(out, hex[*cur & 0xf]); - } -} - -static void asciidump(dump_out *out, const char *buf, size_t len) { - const uint8_t *const beg = (const uint8_t *)buf; - const uint8_t *const end = beg + len; - const uint8_t *cur; - int out_was_empty = (out->length == 0); - if (!out_was_empty) { - dump_out_append(out, ' '); - dump_out_append(out, '\''); - } - for (cur = beg; cur != end; ++cur) { - dump_out_append(out, (char)(isprint(*cur) ? *(char *)cur : '.')); - } - if (!out_was_empty) { - dump_out_append(out, '\''); - } -} - -char *gpr_dump(const char *buf, size_t len, uint32_t flags) { - dump_out out = dump_out_create(); - if (flags & GPR_DUMP_HEX) { - hexdump(&out, buf, len); - } - if (flags & GPR_DUMP_ASCII) { - asciidump(&out, buf, len); - } - dump_out_append(&out, 0); - return out.data; -} - -char *gpr_dump_slice(gpr_slice s, uint32_t flags) { - return gpr_dump((const char *)GPR_SLICE_START_PTR(s), GPR_SLICE_LENGTH(s), - flags); -} - -int gpr_parse_bytes_to_uint32(const char *buf, size_t len, uint32_t *result) { - uint32_t out = 0; - uint32_t new; - size_t i; - - if (len == 0) return 0; /* must have some bytes */ - - for (i = 0; i < len; i++) { - if (buf[i] < '0' || buf[i] > '9') return 0; /* bad char */ - new = 10 * out + (uint32_t)(buf[i] - '0'); - if (new < out) return 0; /* overflow */ - out = new; - } - - *result = out; - return 1; -} - -void gpr_reverse_bytes(char *str, int len) { - char *p1, *p2; - for (p1 = str, p2 = str + len - 1; p2 > p1; ++p1, --p2) { - char temp = *p1; - *p1 = *p2; - *p2 = temp; - } -} - -int gpr_ltoa(long value, char *string) { - long sign; - int i = 0; - - if (value == 0) { - string[0] = '0'; - string[1] = 0; - return 1; - } - - sign = value < 0 ? -1 : 1; - while (value) { - string[i++] = (char)('0' + sign * (value % 10)); - value /= 10; - } - if (sign < 0) string[i++] = '-'; - gpr_reverse_bytes(string, i); - string[i] = 0; - return i; -} - -int int64_ttoa(int64_t value, char *string) { - int64_t sign; - int i = 0; - - if (value == 0) { - string[0] = '0'; - string[1] = 0; - return 1; - } - - sign = value < 0 ? -1 : 1; - while (value) { - string[i++] = (char)('0' + sign * (value % 10)); - value /= 10; - } - if (sign < 0) string[i++] = '-'; - gpr_reverse_bytes(string, i); - string[i] = 0; - return i; -} - -char *gpr_strjoin(const char **strs, size_t nstrs, size_t *final_length) { - return gpr_strjoin_sep(strs, nstrs, "", final_length); -} - -char *gpr_strjoin_sep(const char **strs, size_t nstrs, const char *sep, - size_t *final_length) { - const size_t sep_len = strlen(sep); - size_t out_length = 0; - size_t i; - char *out; - for (i = 0; i < nstrs; i++) { - out_length += strlen(strs[i]); - } - out_length += 1; /* null terminator */ - if (nstrs > 0) { - out_length += sep_len * (nstrs - 1); /* separators */ - } - out = gpr_malloc(out_length); - out_length = 0; - for (i = 0; i < nstrs; i++) { - const size_t slen = strlen(strs[i]); - if (i != 0) { - memcpy(out + out_length, sep, sep_len); - out_length += sep_len; - } - memcpy(out + out_length, strs[i], slen); - out_length += slen; - } - out[out_length] = 0; - if (final_length != NULL) { - *final_length = out_length; - } - return out; -} - -/** Finds the initial (\a begin) and final (\a end) offsets of the next - * substring from \a str + \a read_offset until the next \a sep or the end of \a - * str. - * - * Returns 1 and updates \a begin and \a end. Returns 0 otherwise. */ -static int slice_find_separator_offset(const gpr_slice str, const char *sep, - const size_t read_offset, size_t *begin, - size_t *end) { - size_t i; - const uint8_t *str_ptr = GPR_SLICE_START_PTR(str) + read_offset; - const size_t str_len = GPR_SLICE_LENGTH(str) - read_offset; - const size_t sep_len = strlen(sep); - if (str_len < sep_len) { - return 0; - } - - for (i = 0; i <= str_len - sep_len; i++) { - if (memcmp(str_ptr + i, sep, sep_len) == 0) { - *begin = read_offset; - *end = read_offset + i; - return 1; - } - } - return 0; -} - -void gpr_slice_split(gpr_slice str, const char *sep, gpr_slice_buffer *dst) { - const size_t sep_len = strlen(sep); - size_t begin, end; - - GPR_ASSERT(sep_len > 0); - - if (slice_find_separator_offset(str, sep, 0, &begin, &end) != 0) { - do { - gpr_slice_buffer_add_indexed(dst, gpr_slice_sub(str, begin, end)); - } while (slice_find_separator_offset(str, sep, end + sep_len, &begin, - &end) != 0); - gpr_slice_buffer_add_indexed( - dst, gpr_slice_sub(str, end + sep_len, GPR_SLICE_LENGTH(str))); - } else { /* no sep found, add whole input */ - gpr_slice_buffer_add_indexed(dst, gpr_slice_ref(str)); - } -} - -void gpr_strvec_init(gpr_strvec *sv) { memset(sv, 0, sizeof(*sv)); } - -void gpr_strvec_destroy(gpr_strvec *sv) { - size_t i; - for (i = 0; i < sv->count; i++) { - gpr_free(sv->strs[i]); - } - gpr_free(sv->strs); -} - -void gpr_strvec_add(gpr_strvec *sv, char *str) { - if (sv->count == sv->capacity) { - sv->capacity = GPR_MAX(sv->capacity + 8, sv->capacity * 2); - sv->strs = gpr_realloc(sv->strs, sizeof(char *) * sv->capacity); - } - sv->strs[sv->count++] = str; -} - -char *gpr_strvec_flatten(gpr_strvec *sv, size_t *final_length) { - return gpr_strjoin((const char **)sv->strs, sv->count, final_length); -} diff --git a/src/core/support/string.h b/src/core/support/string.h deleted file mode 100644 index 8ff16882ab..0000000000 --- a/src/core/support/string.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * - * Copyright 2015-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_SUPPORT_STRING_H -#define GRPC_CORE_SUPPORT_STRING_H - -#include - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* String utility functions */ - -/* Flags for gpr_dump function. */ -#define GPR_DUMP_HEX 0x00000001 -#define GPR_DUMP_ASCII 0x00000002 - -/* Converts array buf, of length len, into a C string according to the flags. - Result should be freed with gpr_free() */ -char *gpr_dump(const char *buf, size_t len, uint32_t flags); - -/* Calls gpr_dump on a slice. */ -char *gpr_dump_slice(gpr_slice slice, uint32_t flags); - -/* Parses an array of bytes into an integer (base 10). Returns 1 on success, - 0 on failure. */ -int gpr_parse_bytes_to_uint32(const char *data, size_t length, - uint32_t *result); - -/* Minimum buffer size for calling ltoa */ -#define GPR_LTOA_MIN_BUFSIZE (3 * sizeof(long)) - -/* Convert a long to a string in base 10; returns the length of the - output string (or 0 on failure). - output must be at least GPR_LTOA_MIN_BUFSIZE bytes long. */ -int gpr_ltoa(long value, char *output); - -/* Minimum buffer size for calling int64toa */ -#define GPR_INT64TOA_MIN_BUFSIZE (3 * sizeof(int64_t)) - -/* Convert an int64 to a string in base 10; returns the length of the -output string (or 0 on failure). -output must be at least GPR_INT64TOA_MIN_BUFSIZE bytes long. -NOTE: This function ensures sufficient bit width even on Win x64, -where long is 32bit is size.*/ -int int64_ttoa(int64_t value, char *output); - -/* Reverse a run of bytes */ -void gpr_reverse_bytes(char *str, int len); - -/* Join a set of strings, returning the resulting string. - Total combined length (excluding null terminator) is returned in total_length - if it is non-null. */ -char *gpr_strjoin(const char **strs, size_t nstrs, size_t *total_length); - -/* Join a set of strings using a separator, returning the resulting string. - Total combined length (excluding null terminator) is returned in total_length - if it is non-null. */ -char *gpr_strjoin_sep(const char **strs, size_t nstrs, const char *sep, - size_t *total_length); - -/** Split \a str by the separator \a sep. Results are stored in \a dst, which - * should be a properly initialized instance. */ -void gpr_slice_split(gpr_slice str, const char *sep, gpr_slice_buffer *dst); - -/* A vector of strings... for building up a final string one piece at a time */ -typedef struct { - char **strs; - size_t count; - size_t capacity; -} gpr_strvec; - -/* Initialize/destroy */ -void gpr_strvec_init(gpr_strvec *strs); -void gpr_strvec_destroy(gpr_strvec *strs); -/* Add a string to a strvec, takes ownership of the string */ -void gpr_strvec_add(gpr_strvec *strs, char *add); -/* Return a joined string with all added substrings, optionally setting - total_length as per gpr_strjoin */ -char *gpr_strvec_flatten(gpr_strvec *strs, size_t *total_length); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_SUPPORT_STRING_H */ diff --git a/src/core/support/string_posix.c b/src/core/support/string_posix.c deleted file mode 100644 index a73b3106a5..0000000000 --- a/src/core/support/string_posix.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_STRING - -#include -#include -#include - -#include - -int gpr_asprintf(char **strp, const char *format, ...) { - va_list args; - int ret; - char buf[64]; - size_t strp_buflen; - - /* Use a constant-sized buffer to determine the length. */ - va_start(args, format); - ret = vsnprintf(buf, sizeof(buf), format, args); - va_end(args); - if (ret < 0) { - *strp = NULL; - return -1; - } - - /* Allocate a new buffer, with space for the NUL terminator. */ - strp_buflen = (size_t)ret + 1; - if ((*strp = gpr_malloc(strp_buflen)) == NULL) { - /* This shouldn't happen, because gpr_malloc() calls abort(). */ - return -1; - } - - /* Return early if we have all the bytes. */ - if (strp_buflen <= sizeof(buf)) { - memcpy(*strp, buf, strp_buflen); - return ret; - } - - /* Try again using the larger buffer. */ - va_start(args, format); - ret = vsnprintf(*strp, strp_buflen, format, args); - va_end(args); - if ((size_t)ret == strp_buflen - 1) { - return ret; - } - - /* This should never happen. */ - gpr_free(*strp); - *strp = NULL; - return -1; -} - -#endif /* GPR_POSIX_STRING */ diff --git a/src/core/support/string_win32.c b/src/core/support/string_win32.c deleted file mode 100644 index 0780907994..0000000000 --- a/src/core/support/string_win32.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* Posix code for gpr snprintf support. */ - -#include - -#ifdef GPR_WIN32 - -#include -#include -#include - -#include - -#include "src/core/support/string.h" - -int gpr_asprintf(char **strp, const char *format, ...) { - va_list args; - int ret; - size_t strp_buflen; - - /* Determine the length. */ - va_start(args, format); - ret = _vscprintf(format, args); - va_end(args); - if (ret < 0) { - *strp = NULL; - return -1; - } - - /* Allocate a new buffer, with space for the NUL terminator. */ - strp_buflen = (size_t)ret + 1; - if ((*strp = gpr_malloc(strp_buflen)) == NULL) { - /* This shouldn't happen, because gpr_malloc() calls abort(). */ - return -1; - } - - /* Print to the buffer. */ - va_start(args, format); - ret = vsnprintf_s(*strp, strp_buflen, _TRUNCATE, format, args); - va_end(args); - if ((size_t)ret == strp_buflen - 1) { - return ret; - } - - /* This should never happen. */ - gpr_free(*strp); - *strp = NULL; - return -1; -} - -#if defined UNICODE || defined _UNICODE -LPTSTR -gpr_char_to_tchar(LPCSTR input) { - LPTSTR ret; - int needed = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0); - if (needed <= 0) return NULL; - ret = gpr_malloc((unsigned)needed * sizeof(TCHAR)); - MultiByteToWideChar(CP_UTF8, 0, input, -1, ret, needed); - return ret; -} - -LPSTR -gpr_tchar_to_char(LPCTSTR input) { - LPSTR ret; - int needed = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL); - if (needed <= 0) return NULL; - ret = gpr_malloc((unsigned)needed); - WideCharToMultiByte(CP_UTF8, 0, input, -1, ret, needed, NULL, NULL); - return ret; -} -#else -char *gpr_tchar_to_char(LPTSTR input) { return gpr_strdup(input); } - -char *gpr_char_to_tchar(LPTSTR input) { return gpr_strdup(input); } -#endif - -#endif /* GPR_WIN32 */ diff --git a/src/core/support/string_win32.h b/src/core/support/string_win32.h deleted file mode 100644 index c9ae8d9932..0000000000 --- a/src/core/support/string_win32.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright 2015-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_SUPPORT_STRING_WIN32_H -#define GRPC_CORE_SUPPORT_STRING_WIN32_H - -#include - -#ifdef GPR_WIN32 - -/* These allocate new strings using gpr_malloc to convert from and to utf-8. */ -LPTSTR gpr_char_to_tchar(LPCSTR input); -LPSTR gpr_tchar_to_char(LPCTSTR input); - -#endif /* GPR_WIN32 */ - -#endif /* GRPC_CORE_SUPPORT_STRING_WIN32_H */ diff --git a/src/core/support/subprocess_posix.c b/src/core/support/subprocess_posix.c deleted file mode 100644 index 662e7dd999..0000000000 --- a/src/core/support/subprocess_posix.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_SUBPROCESS - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -struct gpr_subprocess { - int pid; - int joined; -}; - -const char *gpr_subprocess_binary_extension() { return ""; } - -gpr_subprocess *gpr_subprocess_create(int argc, const char **argv) { - gpr_subprocess *r; - int pid; - char **exec_args; - - pid = fork(); - if (pid == -1) { - return NULL; - } else if (pid == 0) { - exec_args = gpr_malloc(((size_t)argc + 1) * sizeof(char *)); - memcpy(exec_args, argv, (size_t)argc * sizeof(char *)); - exec_args[argc] = NULL; - execv(exec_args[0], exec_args); - /* if we reach here, an error has occurred */ - gpr_log(GPR_ERROR, "execv '%s' failed: %s", exec_args[0], strerror(errno)); - _exit(1); - return NULL; - } else { - r = gpr_malloc(sizeof(gpr_subprocess)); - memset(r, 0, sizeof(*r)); - r->pid = pid; - return r; - } -} - -void gpr_subprocess_destroy(gpr_subprocess *p) { - if (!p->joined) { - kill(p->pid, SIGKILL); - gpr_subprocess_join(p); - } - gpr_free(p); -} - -int gpr_subprocess_join(gpr_subprocess *p) { - int status; -retry: - if (waitpid(p->pid, &status, 0) == -1) { - if (errno == EINTR) { - goto retry; - } - gpr_log(GPR_ERROR, "waitpid failed: %s", strerror(errno)); - return -1; - } - return status; -} - -void gpr_subprocess_interrupt(gpr_subprocess *p) { - if (!p->joined) { - kill(p->pid, SIGINT); - } -} - -#endif /* GPR_POSIX_SUBPROCESS */ diff --git a/src/core/support/subprocess_windows.c b/src/core/support/subprocess_windows.c deleted file mode 100644 index 6afbefeb2b..0000000000 --- a/src/core/support/subprocess_windows.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * - * 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 - -#ifdef GPR_WINDOWS_SUBPROCESS - -#include -#include -#include - -#include -#include -#include -#include "src/core/support/string.h" -#include "src/core/support/string_win32.h" - -struct gpr_subprocess { - PROCESS_INFORMATION pi; - int joined; - int interrupted; -}; - -const char *gpr_subprocess_binary_extension() { return ".exe"; } - -gpr_subprocess *gpr_subprocess_create(int argc, const char **argv) { - gpr_subprocess *r; - - STARTUPINFO si; - PROCESS_INFORMATION pi; - - char *args = gpr_strjoin_sep(argv, (size_t)argc, " ", NULL); - TCHAR *args_tchar; - - args_tchar = gpr_char_to_tchar(args); - gpr_free(args); - - memset(&si, 0, sizeof(si)); - si.cb = sizeof(si); - memset(&pi, 0, sizeof(pi)); - - if (!CreateProcess(NULL, args_tchar, NULL, NULL, FALSE, - CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi)) { - gpr_free(args_tchar); - return NULL; - } - gpr_free(args_tchar); - - r = gpr_malloc(sizeof(gpr_subprocess)); - memset(r, 0, sizeof(*r)); - r->pi = pi; - return r; -} - -void gpr_subprocess_destroy(gpr_subprocess *p) { - if (p) { - if (!p->joined) { - gpr_subprocess_interrupt(p); - gpr_subprocess_join(p); - } - if (p->pi.hProcess) { - CloseHandle(p->pi.hProcess); - } - if (p->pi.hThread) { - CloseHandle(p->pi.hThread); - } - gpr_free(p); - } -} - -int gpr_subprocess_join(gpr_subprocess *p) { - DWORD dwExitCode; - if (GetExitCodeProcess(p->pi.hProcess, &dwExitCode)) { - if (dwExitCode == STILL_ACTIVE) { - if (WaitForSingleObject(p->pi.hProcess, INFINITE) == WAIT_OBJECT_0) { - p->joined = 1; - goto getExitCode; - } - return -1; // failed to join - } else { - goto getExitCode; - } - } else { - return -1; // failed to get exit code - } - -getExitCode: - if (p->interrupted) { - return 0; - } - if (GetExitCodeProcess(p->pi.hProcess, &dwExitCode)) { - return (int)dwExitCode; - } else { - return -1; // failed to get exit code - } -} - -void gpr_subprocess_interrupt(gpr_subprocess *p) { - DWORD dwExitCode; - if (GetExitCodeProcess(p->pi.hProcess, &dwExitCode)) { - if (dwExitCode == STILL_ACTIVE) { - gpr_log(GPR_INFO, "sending ctrl-break"); - GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, p->pi.dwProcessId); - p->joined = 1; - p->interrupted = 1; - } - } - return; -} - -#endif /* GPR_WINDOWS_SUBPROCESS */ diff --git a/src/core/support/sync.c b/src/core/support/sync.c deleted file mode 100644 index 800cf20287..0000000000 --- a/src/core/support/sync.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* Generic implementation of synchronization primitives. */ - -#include -#include -#include - -/* Number of mutexes to allocate for events, to avoid lock contention. - Should be a prime. */ -enum { event_sync_partitions = 31 }; - -/* Events are partitioned by address to avoid lock contention. */ -static struct sync_array_s { - gpr_mu mu; - gpr_cv cv; -} sync_array[event_sync_partitions]; - -/* This routine is executed once on first use, via event_once */ -static gpr_once event_once = GPR_ONCE_INIT; -static void event_initialize(void) { - int i; - for (i = 0; i != event_sync_partitions; i++) { - gpr_mu_init(&sync_array[i].mu); - gpr_cv_init(&sync_array[i].cv); - } -} - -/* Hash ev into an element of sync_array[]. */ -static struct sync_array_s *hash(gpr_event *ev) { - return &sync_array[((uintptr_t)ev) % event_sync_partitions]; -} - -void gpr_event_init(gpr_event *ev) { - gpr_once_init(&event_once, &event_initialize); - ev->state = 0; -} - -void gpr_event_set(gpr_event *ev, void *value) { - struct sync_array_s *s = hash(ev); - gpr_mu_lock(&s->mu); - GPR_ASSERT(gpr_atm_acq_load(&ev->state) == 0); - gpr_atm_rel_store(&ev->state, (gpr_atm)value); - gpr_cv_broadcast(&s->cv); - gpr_mu_unlock(&s->mu); - GPR_ASSERT(value != NULL); -} - -void *gpr_event_get(gpr_event *ev) { - return (void *)gpr_atm_acq_load(&ev->state); -} - -void *gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline) { - void *result = (void *)gpr_atm_acq_load(&ev->state); - if (result == NULL) { - struct sync_array_s *s = hash(ev); - gpr_mu_lock(&s->mu); - do { - result = (void *)gpr_atm_acq_load(&ev->state); - } while (result == NULL && !gpr_cv_wait(&s->cv, &s->mu, abs_deadline)); - gpr_mu_unlock(&s->mu); - } - return result; -} - -void gpr_ref_init(gpr_refcount *r, int n) { gpr_atm_rel_store(&r->count, n); } - -void gpr_ref(gpr_refcount *r) { gpr_atm_no_barrier_fetch_add(&r->count, 1); } - -void gpr_ref_non_zero(gpr_refcount *r) { - gpr_atm prior = gpr_atm_no_barrier_fetch_add(&r->count, 1); - GPR_ASSERT(prior > 0); -} - -void gpr_refn(gpr_refcount *r, int n) { - gpr_atm_no_barrier_fetch_add(&r->count, n); -} - -int gpr_unref(gpr_refcount *r) { - gpr_atm prior = gpr_atm_full_fetch_add(&r->count, -1); - GPR_ASSERT(prior > 0); - return prior == 1; -} - -void gpr_stats_init(gpr_stats_counter *c, intptr_t n) { - gpr_atm_rel_store(&c->value, n); -} - -void gpr_stats_inc(gpr_stats_counter *c, intptr_t inc) { - gpr_atm_no_barrier_fetch_add(&c->value, inc); -} - -intptr_t gpr_stats_read(const gpr_stats_counter *c) { - /* don't need acquire-load, but we have no no-barrier load yet */ - return gpr_atm_acq_load(&c->value); -} diff --git a/src/core/support/sync_posix.c b/src/core/support/sync_posix.c deleted file mode 100644 index be4d0ac1c9..0000000000 --- a/src/core/support/sync_posix.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_SYNC - -#include -#include -#include -#include -#include -#include "src/core/profiling/timers.h" - -void gpr_mu_init(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_init(mu, NULL) == 0); } - -void gpr_mu_destroy(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_destroy(mu) == 0); } - -void gpr_mu_lock(gpr_mu* mu) { - GPR_TIMER_BEGIN("gpr_mu_lock", 0); - GPR_ASSERT(pthread_mutex_lock(mu) == 0); - GPR_TIMER_END("gpr_mu_lock", 0); -} - -void gpr_mu_unlock(gpr_mu* mu) { - GPR_TIMER_BEGIN("gpr_mu_unlock", 0); - GPR_ASSERT(pthread_mutex_unlock(mu) == 0); - GPR_TIMER_END("gpr_mu_unlock", 0); -} - -int gpr_mu_trylock(gpr_mu* mu) { - int err; - GPR_TIMER_BEGIN("gpr_mu_trylock", 0); - err = pthread_mutex_trylock(mu); - GPR_ASSERT(err == 0 || err == EBUSY); - GPR_TIMER_END("gpr_mu_trylock", 0); - return err == 0; -} - -/*----------------------------------------*/ - -void gpr_cv_init(gpr_cv* cv) { GPR_ASSERT(pthread_cond_init(cv, NULL) == 0); } - -void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); } - -int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { - int err = 0; - if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) == - 0) { - err = pthread_cond_wait(cv, mu); - } else { - struct timespec abs_deadline_ts; - abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME); - abs_deadline_ts.tv_sec = (time_t)abs_deadline.tv_sec; - abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; - err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts); - } - GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); - return err == ETIMEDOUT; -} - -void gpr_cv_signal(gpr_cv* cv) { GPR_ASSERT(pthread_cond_signal(cv) == 0); } - -void gpr_cv_broadcast(gpr_cv* cv) { - GPR_ASSERT(pthread_cond_broadcast(cv) == 0); -} - -/*----------------------------------------*/ - -void gpr_once_init(gpr_once* once, void (*init_function)(void)) { - GPR_ASSERT(pthread_once(once, init_function) == 0); -} - -#endif /* GRP_POSIX_SYNC */ diff --git a/src/core/support/sync_win32.c b/src/core/support/sync_win32.c deleted file mode 100644 index 41998ebcb6..0000000000 --- a/src/core/support/sync_win32.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* Win32 code for gpr synchronization support. */ - -#include - -#ifdef GPR_WIN32 - -#include -#include -#include - -void gpr_mu_init(gpr_mu *mu) { - InitializeCriticalSection(&mu->cs); - mu->locked = 0; -} - -void gpr_mu_destroy(gpr_mu *mu) { DeleteCriticalSection(&mu->cs); } - -void gpr_mu_lock(gpr_mu *mu) { - EnterCriticalSection(&mu->cs); - GPR_ASSERT(!mu->locked); - mu->locked = 1; -} - -void gpr_mu_unlock(gpr_mu *mu) { - mu->locked = 0; - LeaveCriticalSection(&mu->cs); -} - -int gpr_mu_trylock(gpr_mu *mu) { - int result = TryEnterCriticalSection(&mu->cs); - if (result) { - if (mu->locked) { /* This thread already holds the lock. */ - LeaveCriticalSection(&mu->cs); /* Decrement lock count. */ - result = 0; /* Indicate failure */ - } - mu->locked = 1; - } - return result; -} - -/*----------------------------------------*/ - -void gpr_cv_init(gpr_cv *cv) { InitializeConditionVariable(cv); } - -void gpr_cv_destroy(gpr_cv *cv) { - /* Condition variables don't need destruction in Win32. */ -} - -int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline) { - int timeout = 0; - DWORD timeout_max_ms; - mu->locked = 0; - if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) == - 0) { - SleepConditionVariableCS(cv, &mu->cs, INFINITE); - } else { - abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME); - gpr_timespec now = gpr_now(abs_deadline.clock_type); - int64_t now_ms = (int64_t)now.tv_sec * 1000 + now.tv_nsec / 1000000; - int64_t deadline_ms = - (int64_t)abs_deadline.tv_sec * 1000 + abs_deadline.tv_nsec / 1000000; - if (now_ms >= deadline_ms) { - timeout = 1; - } else { - if ((deadline_ms - now_ms) >= INFINITE) { - timeout_max_ms = INFINITE - 1; - } else { - timeout_max_ms = (DWORD)(deadline_ms - now_ms); - } - timeout = (SleepConditionVariableCS(cv, &mu->cs, timeout_max_ms) == 0 && - GetLastError() == ERROR_TIMEOUT); - } - } - mu->locked = 1; - return timeout; -} - -void gpr_cv_signal(gpr_cv *cv) { WakeConditionVariable(cv); } - -void gpr_cv_broadcast(gpr_cv *cv) { WakeAllConditionVariable(cv); } - -/*----------------------------------------*/ - -static void *dummy; -struct run_once_func_arg { - void (*init_function)(void); -}; -static BOOL CALLBACK run_once_func(gpr_once *once, void *v, void **pv) { - struct run_once_func_arg *arg = v; - (*arg->init_function)(); - return 1; -} - -void gpr_once_init(gpr_once *once, void (*init_function)(void)) { - struct run_once_func_arg arg; - arg.init_function = init_function; - InitOnceExecuteOnce(once, run_once_func, &arg, &dummy); -} - -#endif /* GPR_WIN32 */ diff --git a/src/core/support/thd.c b/src/core/support/thd.c deleted file mode 100644 index 41daeb5d0e..0000000000 --- a/src/core/support/thd.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * Copyright 2015, 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. - * - */ - -/* Posix implementation for gpr threads. */ - -#include - -#include - -enum { GPR_THD_JOINABLE = 1 }; - -gpr_thd_options gpr_thd_options_default(void) { - gpr_thd_options options; - memset(&options, 0, sizeof(options)); - return options; -} - -void gpr_thd_options_set_detached(gpr_thd_options* options) { - options->flags &= ~GPR_THD_JOINABLE; -} - -void gpr_thd_options_set_joinable(gpr_thd_options* options) { - options->flags |= GPR_THD_JOINABLE; -} - -int gpr_thd_options_is_detached(const gpr_thd_options* options) { - if (!options) return 1; - return (options->flags & GPR_THD_JOINABLE) == 0; -} - -int gpr_thd_options_is_joinable(const gpr_thd_options* options) { - if (!options) return 0; - return (options->flags & GPR_THD_JOINABLE) == GPR_THD_JOINABLE; -} diff --git a/src/core/support/thd_internal.h b/src/core/support/thd_internal.h deleted file mode 100644 index 33b904e59b..0000000000 --- a/src/core/support/thd_internal.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * Copyright 2015-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_SUPPORT_THD_INTERNAL_H -#define GRPC_CORE_SUPPORT_THD_INTERNAL_H - -/* Internal interfaces between modules within the gpr support library. */ - -#endif /* GRPC_CORE_SUPPORT_THD_INTERNAL_H */ diff --git a/src/core/support/thd_posix.c b/src/core/support/thd_posix.c deleted file mode 100644 index 4d874d3656..0000000000 --- a/src/core/support/thd_posix.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* Posix implementation for gpr threads. */ - -#include - -#ifdef GPR_POSIX_SYNC - -#include -#include -#include -#include -#include -#include -#include - -struct thd_arg { - void (*body)(void *arg); /* body of a thread */ - void *arg; /* argument to a thread */ -}; - -/* Body of every thread started via gpr_thd_new. */ -static void *thread_body(void *v) { - struct thd_arg a = *(struct thd_arg *)v; - free(v); - (*a.body)(a.arg); - return NULL; -} - -int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, - const gpr_thd_options *options) { - int thread_started; - pthread_attr_t attr; - pthread_t p; - /* don't use gpr_malloc as we may cause an infinite recursion with - * the profiling code */ - struct thd_arg *a = malloc(sizeof(*a)); - GPR_ASSERT(a != NULL); - a->body = thd_body; - a->arg = arg; - - GPR_ASSERT(pthread_attr_init(&attr) == 0); - if (gpr_thd_options_is_detached(options)) { - GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == - 0); - } else { - GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == - 0); - } - thread_started = (pthread_create(&p, &attr, &thread_body, a) == 0); - GPR_ASSERT(pthread_attr_destroy(&attr) == 0); - if (!thread_started) { - free(a); - } - *t = (gpr_thd_id)p; - return thread_started; -} - -gpr_thd_id gpr_thd_currentid(void) { return (gpr_thd_id)pthread_self(); } - -void gpr_thd_join(gpr_thd_id t) { pthread_join((pthread_t)t, NULL); } - -#endif /* GPR_POSIX_SYNC */ diff --git a/src/core/support/thd_win32.c b/src/core/support/thd_win32.c deleted file mode 100644 index 630eb7f625..0000000000 --- a/src/core/support/thd_win32.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* Windows implementation for gpr threads. */ - -#include - -#ifdef GPR_WIN32 - -#include -#include -#include -#include - -#if defined(_MSC_VER) -#define thread_local __declspec(thread) -#elif defined(__GNUC__) -#define thread_local __thread -#else -#error "Unknown compiler - please file a bug report" -#endif - -struct thd_info { - void (*body)(void *arg); /* body of a thread */ - void *arg; /* argument to a thread */ - HANDLE join_event; /* if joinable, the join event */ - int joinable; /* true if not detached */ -}; - -static thread_local struct thd_info *g_thd_info; - -/* Destroys a thread info */ -static void destroy_thread(struct thd_info *t) { - if (t->joinable) CloseHandle(t->join_event); - gpr_free(t); -} - -/* Body of every thread started via gpr_thd_new. */ -static DWORD WINAPI thread_body(void *v) { - g_thd_info = (struct thd_info *)v; - g_thd_info->body(g_thd_info->arg); - if (g_thd_info->joinable) { - BOOL ret = SetEvent(g_thd_info->join_event); - GPR_ASSERT(ret); - } else { - destroy_thread(g_thd_info); - } - return 0; -} - -int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, - const gpr_thd_options *options) { - HANDLE handle; - struct thd_info *info = gpr_malloc(sizeof(*info)); - info->body = thd_body; - info->arg = arg; - *t = 0; - if (gpr_thd_options_is_joinable(options)) { - info->joinable = 1; - info->join_event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (info->join_event == NULL) { - gpr_free(info); - return 0; - } - } else { - info->joinable = 0; - } - handle = CreateThread(NULL, 64 * 1024, thread_body, info, 0, NULL); - if (handle == NULL) { - destroy_thread(info); - } else { - *t = (gpr_thd_id)info; - CloseHandle(handle); - } - return handle != NULL; -} - -gpr_thd_id gpr_thd_currentid(void) { return (gpr_thd_id)g_thd_info; } - -void gpr_thd_join(gpr_thd_id t) { - struct thd_info *info = (struct thd_info *)t; - DWORD ret = WaitForSingleObject(info->join_event, INFINITE); - GPR_ASSERT(ret == WAIT_OBJECT_0); - destroy_thread(info); -} - -#endif /* GPR_WIN32 */ diff --git a/src/core/support/time.c b/src/core/support/time.c deleted file mode 100644 index 0e2c8fcf1a..0000000000 --- a/src/core/support/time.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* Generic implementation of time calls. */ - -#include -#include -#include -#include -#include - -int gpr_time_cmp(gpr_timespec a, gpr_timespec b) { - int cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec); - GPR_ASSERT(a.clock_type == b.clock_type); - if (cmp == 0) { - cmp = (a.tv_nsec > b.tv_nsec) - (a.tv_nsec < b.tv_nsec); - } - return cmp; -} - -gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b) { - return gpr_time_cmp(a, b) < 0 ? a : b; -} - -gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b) { - return gpr_time_cmp(a, b) > 0 ? a : b; -} - -gpr_timespec gpr_time_0(gpr_clock_type type) { - gpr_timespec out; - out.tv_sec = 0; - out.tv_nsec = 0; - out.clock_type = type; - return out; -} - -gpr_timespec gpr_inf_future(gpr_clock_type type) { - gpr_timespec out; - out.tv_sec = INT64_MAX; - out.tv_nsec = 0; - out.clock_type = type; - return out; -} - -gpr_timespec gpr_inf_past(gpr_clock_type type) { - gpr_timespec out; - out.tv_sec = INT64_MIN; - out.tv_nsec = 0; - out.clock_type = type; - return out; -} - -/* TODO(ctiller): consider merging _nanos, _micros, _millis into a single - function for maintainability. Similarly for _seconds, _minutes, and _hours */ - -gpr_timespec gpr_time_from_nanos(int64_t ns, gpr_clock_type type) { - gpr_timespec result; - result.clock_type = type; - if (ns == INT64_MAX) { - result = gpr_inf_future(type); - } else if (ns == INT64_MIN) { - result = gpr_inf_past(type); - } else if (ns >= 0) { - result.tv_sec = ns / GPR_NS_PER_SEC; - result.tv_nsec = (int32_t)(ns - result.tv_sec * GPR_NS_PER_SEC); - } else { - /* Calculation carefully formulated to avoid any possible under/overflow. */ - result.tv_sec = (-(999999999 - (ns + GPR_NS_PER_SEC)) / GPR_NS_PER_SEC) - 1; - result.tv_nsec = (int32_t)(ns - result.tv_sec * GPR_NS_PER_SEC); - } - return result; -} - -gpr_timespec gpr_time_from_micros(int64_t us, gpr_clock_type type) { - gpr_timespec result; - result.clock_type = type; - if (us == INT64_MAX) { - result = gpr_inf_future(type); - } else if (us == INT64_MIN) { - result = gpr_inf_past(type); - } else if (us >= 0) { - result.tv_sec = us / 1000000; - result.tv_nsec = (int32_t)((us - result.tv_sec * 1000000) * 1000); - } else { - /* Calculation carefully formulated to avoid any possible under/overflow. */ - result.tv_sec = (-(999999 - (us + 1000000)) / 1000000) - 1; - result.tv_nsec = (int32_t)((us - result.tv_sec * 1000000) * 1000); - } - return result; -} - -gpr_timespec gpr_time_from_millis(int64_t ms, gpr_clock_type type) { - gpr_timespec result; - result.clock_type = type; - if (ms == INT64_MAX) { - result = gpr_inf_future(type); - } else if (ms == INT64_MIN) { - result = gpr_inf_past(type); - } else if (ms >= 0) { - result.tv_sec = ms / 1000; - result.tv_nsec = (int32_t)((ms - result.tv_sec * 1000) * 1000000); - } else { - /* Calculation carefully formulated to avoid any possible under/overflow. */ - result.tv_sec = (-(999 - (ms + 1000)) / 1000) - 1; - result.tv_nsec = (int32_t)((ms - result.tv_sec * 1000) * 1000000); - } - return result; -} - -gpr_timespec gpr_time_from_seconds(int64_t s, gpr_clock_type type) { - gpr_timespec result; - result.clock_type = type; - if (s == INT64_MAX) { - result = gpr_inf_future(type); - } else if (s == INT64_MIN) { - result = gpr_inf_past(type); - } else { - result.tv_sec = s; - result.tv_nsec = 0; - } - return result; -} - -gpr_timespec gpr_time_from_minutes(int64_t m, gpr_clock_type type) { - gpr_timespec result; - result.clock_type = type; - if (m >= INT64_MAX / 60) { - result = gpr_inf_future(type); - } else if (m <= INT64_MIN / 60) { - result = gpr_inf_past(type); - } else { - result.tv_sec = m * 60; - result.tv_nsec = 0; - } - return result; -} - -gpr_timespec gpr_time_from_hours(int64_t h, gpr_clock_type type) { - gpr_timespec result; - result.clock_type = type; - if (h >= INT64_MAX / 3600) { - result = gpr_inf_future(type); - } else if (h <= INT64_MIN / 3600) { - result = gpr_inf_past(type); - } else { - result.tv_sec = h * 3600; - result.tv_nsec = 0; - } - return result; -} - -gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) { - gpr_timespec sum; - int64_t inc = 0; - GPR_ASSERT(b.clock_type == GPR_TIMESPAN); - sum.clock_type = a.clock_type; - sum.tv_nsec = a.tv_nsec + b.tv_nsec; - if (sum.tv_nsec >= GPR_NS_PER_SEC) { - sum.tv_nsec -= GPR_NS_PER_SEC; - inc++; - } - if (a.tv_sec == INT64_MAX || a.tv_sec == INT64_MIN) { - sum = a; - } else if (b.tv_sec == INT64_MAX || - (b.tv_sec >= 0 && a.tv_sec >= INT64_MAX - b.tv_sec)) { - sum = gpr_inf_future(sum.clock_type); - } else if (b.tv_sec == INT64_MIN || - (b.tv_sec <= 0 && a.tv_sec <= INT64_MIN - b.tv_sec)) { - sum = gpr_inf_past(sum.clock_type); - } else { - sum.tv_sec = a.tv_sec + b.tv_sec; - if (inc != 0 && sum.tv_sec == INT64_MAX - 1) { - sum = gpr_inf_future(sum.clock_type); - } else { - sum.tv_sec += inc; - } - } - return sum; -} - -gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) { - gpr_timespec diff; - int64_t dec = 0; - if (b.clock_type == GPR_TIMESPAN) { - diff.clock_type = a.clock_type; - } else { - GPR_ASSERT(a.clock_type == b.clock_type); - diff.clock_type = GPR_TIMESPAN; - } - diff.tv_nsec = a.tv_nsec - b.tv_nsec; - if (diff.tv_nsec < 0) { - diff.tv_nsec += GPR_NS_PER_SEC; - dec++; - } - if (a.tv_sec == INT64_MAX || a.tv_sec == INT64_MIN) { - diff = a; - } else if (b.tv_sec == INT64_MIN || - (b.tv_sec <= 0 && a.tv_sec >= INT64_MAX + b.tv_sec)) { - diff = gpr_inf_future(GPR_CLOCK_REALTIME); - } else if (b.tv_sec == INT64_MAX || - (b.tv_sec >= 0 && a.tv_sec <= INT64_MIN + b.tv_sec)) { - diff = gpr_inf_past(GPR_CLOCK_REALTIME); - } else { - diff.tv_sec = a.tv_sec - b.tv_sec; - if (dec != 0 && diff.tv_sec == INT64_MIN + 1) { - diff = gpr_inf_past(GPR_CLOCK_REALTIME); - } else { - diff.tv_sec -= dec; - } - } - return diff; -} - -int gpr_time_similar(gpr_timespec a, gpr_timespec b, gpr_timespec threshold) { - int cmp_ab; - - GPR_ASSERT(a.clock_type == b.clock_type); - GPR_ASSERT(threshold.clock_type == GPR_TIMESPAN); - - cmp_ab = gpr_time_cmp(a, b); - if (cmp_ab == 0) return 1; - if (cmp_ab < 0) { - return gpr_time_cmp(gpr_time_sub(b, a), threshold) <= 0; - } else { - return gpr_time_cmp(gpr_time_sub(a, b), threshold) <= 0; - } -} - -int32_t gpr_time_to_millis(gpr_timespec t) { - if (t.tv_sec >= 2147483) { - if (t.tv_sec == 2147483 && t.tv_nsec < 648 * GPR_NS_PER_MS) { - return 2147483 * GPR_MS_PER_SEC + t.tv_nsec / GPR_NS_PER_MS; - } - return 2147483647; - } else if (t.tv_sec <= -2147483) { - /* TODO(ctiller): correct handling here (it's so far in the past do we - care?) */ - return -2147483647; - } else { - return (int32_t)(t.tv_sec * GPR_MS_PER_SEC + t.tv_nsec / GPR_NS_PER_MS); - } -} - -double gpr_timespec_to_micros(gpr_timespec t) { - return (double)t.tv_sec * GPR_US_PER_SEC + t.tv_nsec * 1e-3; -} - -gpr_timespec gpr_convert_clock_type(gpr_timespec t, gpr_clock_type clock_type) { - if (t.clock_type == clock_type) { - return t; - } - - if (t.tv_nsec == 0) { - if (t.tv_sec == INT64_MAX) { - t.clock_type = clock_type; - return t; - } - if (t.tv_sec == INT64_MIN) { - t.clock_type = clock_type; - return t; - } - } - - if (clock_type == GPR_TIMESPAN) { - return gpr_time_sub(t, gpr_now(t.clock_type)); - } - - if (t.clock_type == GPR_TIMESPAN) { - return gpr_time_add(gpr_now(clock_type), t); - } - - return gpr_time_add(gpr_now(clock_type), - gpr_time_sub(t, gpr_now(t.clock_type))); -} diff --git a/src/core/support/time_posix.c b/src/core/support/time_posix.c deleted file mode 100644 index f999e08cb0..0000000000 --- a/src/core/support/time_posix.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * - * Copyright 2015-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 -#include - -#ifdef GPR_POSIX_TIME - -#include -#include -#include -#ifdef __linux__ -#include -#endif -#include -#include -#include "src/core/support/block_annotate.h" - -static struct timespec timespec_from_gpr(gpr_timespec gts) { - struct timespec rv; - if (sizeof(time_t) < sizeof(int64_t)) { - /* fine to assert, as this is only used in gpr_sleep_until */ - GPR_ASSERT(gts.tv_sec <= INT32_MAX && gts.tv_sec >= INT32_MIN); - } - rv.tv_sec = (time_t)gts.tv_sec; - rv.tv_nsec = gts.tv_nsec; - return rv; -} - -#if _POSIX_TIMERS > 0 -static gpr_timespec gpr_from_timespec(struct timespec ts, - gpr_clock_type clock_type) { - /* - * timespec.tv_sec can have smaller size than gpr_timespec.tv_sec, - * but we are only using this function to implement gpr_now - * so there's no need to handle "infinity" values. - */ - gpr_timespec rv; - rv.tv_sec = ts.tv_sec; - rv.tv_nsec = (int32_t)ts.tv_nsec; - rv.clock_type = clock_type; - return rv; -} - -/** maps gpr_clock_type --> clockid_t for clock_gettime */ -static const clockid_t clockid_for_gpr_clock[] = {CLOCK_MONOTONIC, - CLOCK_REALTIME}; - -void gpr_time_init(void) { gpr_precise_clock_init(); } - -gpr_timespec gpr_now(gpr_clock_type clock_type) { - struct timespec now; - GPR_ASSERT(clock_type != GPR_TIMESPAN); - if (clock_type == GPR_CLOCK_PRECISE) { - gpr_timespec ret; - gpr_precise_clock_now(&ret); - return ret; - } else { -#if defined(GPR_BACKWARDS_COMPATIBILITY_MODE) && defined(__linux__) - /* avoid ABI problems by invoking syscalls directly */ - syscall(SYS_clock_gettime, clockid_for_gpr_clock[clock_type], &now); -#else - clock_gettime(clockid_for_gpr_clock[clock_type], &now); -#endif - return gpr_from_timespec(now, clock_type); - } -} -#else -/* For some reason Apple's OSes haven't implemented clock_gettime. */ - -#include -#include -#include - -static double g_time_scale; -static uint64_t g_time_start; - -void gpr_time_init(void) { - mach_timebase_info_data_t tb = {0, 1}; - gpr_precise_clock_init(); - mach_timebase_info(&tb); - g_time_scale = tb.numer; - g_time_scale /= tb.denom; - g_time_start = mach_absolute_time(); -} - -gpr_timespec gpr_now(gpr_clock_type clock) { - gpr_timespec now; - struct timeval now_tv; - double now_dbl; - - now.clock_type = clock; - switch (clock) { - case GPR_CLOCK_REALTIME: - gettimeofday(&now_tv, NULL); - now.tv_sec = now_tv.tv_sec; - now.tv_nsec = now_tv.tv_usec * 1000; - break; - case GPR_CLOCK_MONOTONIC: - now_dbl = (mach_absolute_time() - g_time_start) * g_time_scale; - now.tv_sec = (int64_t)(now_dbl * 1e-9); - now.tv_nsec = (int32_t)(now_dbl - ((double)now.tv_sec) * 1e9); - break; - case GPR_CLOCK_PRECISE: - gpr_precise_clock_now(&now); - break; - case GPR_TIMESPAN: - abort(); - } - - return now; -} -#endif - -void gpr_sleep_until(gpr_timespec until) { - gpr_timespec now; - gpr_timespec delta; - struct timespec delta_ts; - int ns_result; - - for (;;) { - /* We could simplify by using clock_nanosleep instead, but it might be - * slightly less portable. */ - now = gpr_now(until.clock_type); - if (gpr_time_cmp(until, now) <= 0) { - return; - } - - delta = gpr_time_sub(until, now); - delta_ts = timespec_from_gpr(delta); - GRPC_SCHEDULING_START_BLOCKING_REGION; - ns_result = nanosleep(&delta_ts, NULL); - GRPC_SCHEDULING_END_BLOCKING_REGION; - if (ns_result == 0) { - break; - } - } -} - -#endif /* GPR_POSIX_TIME */ diff --git a/src/core/support/time_precise.c b/src/core/support/time_precise.c deleted file mode 100644 index a2cf74bc84..0000000000 --- a/src/core/support/time_precise.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * Copyright 2015, 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 -#include -#include - -#ifdef GRPC_TIMERS_RDTSC -#if defined(__i386__) -static void gpr_get_cycle_counter(long long int *clk) { - long long int ret; - __asm__ volatile("rdtsc" : "=A"(ret)); - *clk = ret; -} - -// ---------------------------------------------------------------- -#elif defined(__x86_64__) || defined(__amd64__) -static void gpr_get_cycle_counter(long long int *clk) { - unsigned long long low, high; - __asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); - *clk = (long long)(high << 32) | (long long)low; -} -#endif - -static double cycles_per_second = 0; -static long long int start_cycle; -void gpr_precise_clock_init(void) { - time_t start; - long long end_cycle; - gpr_log(GPR_DEBUG, "Calibrating timers"); - start = time(NULL); - while (time(NULL) == start) - ; - gpr_get_cycle_counter(&start_cycle); - while (time(NULL) <= start + 10) - ; - gpr_get_cycle_counter(&end_cycle); - cycles_per_second = (double)(end_cycle - start_cycle) / 10.0; - gpr_log(GPR_DEBUG, "... cycles_per_second = %f\n", cycles_per_second); -} - -void gpr_precise_clock_now(gpr_timespec *clk) { - long long int counter; - double secs; - gpr_get_cycle_counter(&counter); - secs = (double)(counter - start_cycle) / cycles_per_second; - clk->clock_type = GPR_CLOCK_PRECISE; - clk->tv_sec = (int64_t)secs; - clk->tv_nsec = (int32_t)(1e9 * (secs - (double)clk->tv_sec)); -} - -#else /* GRPC_TIMERS_RDTSC */ -void gpr_precise_clock_init(void) {} - -void gpr_precise_clock_now(gpr_timespec *clk) { - *clk = gpr_now(GPR_CLOCK_REALTIME); - clk->clock_type = GPR_CLOCK_PRECISE; -} -#endif /* GRPC_TIMERS_RDTSC */ diff --git a/src/core/support/time_precise.h b/src/core/support/time_precise.h deleted file mode 100644 index 871c99a623..0000000000 --- a/src/core/support/time_precise.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright 2015-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_SUPPORT_TIME_PRECISE_H -#define GRPC_CORE_SUPPORT_TIME_PRECISE_H - -#include - -void gpr_precise_clock_init(void); -void gpr_precise_clock_now(gpr_timespec *clk); - -#endif /* GRPC_CORE_SUPPORT_TIME_PRECISE_H */ diff --git a/src/core/support/time_win32.c b/src/core/support/time_win32.c deleted file mode 100644 index 2c344d3f3b..0000000000 --- a/src/core/support/time_win32.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* Win32 code for gpr time support. */ - -#include - -#ifdef GPR_WIN32 - -#include -#include -#include -#include -#include -#include - -#include "src/core/support/block_annotate.h" - -static LARGE_INTEGER g_start_time; -static double g_time_scale; - -void gpr_time_init(void) { - LARGE_INTEGER frequency; - QueryPerformanceFrequency(&frequency); - QueryPerformanceCounter(&g_start_time); - g_time_scale = 1.0 / (double)frequency.QuadPart; -} - -gpr_timespec gpr_now(gpr_clock_type clock) { - gpr_timespec now_tv; - LONGLONG diff; - struct _timeb now_tb; - LARGE_INTEGER timestamp; - double now_dbl; - now_tv.clock_type = clock; - switch (clock) { - case GPR_CLOCK_REALTIME: - _ftime_s(&now_tb); - now_tv.tv_sec = (int64_t)now_tb.time; - now_tv.tv_nsec = now_tb.millitm * 1000000; - break; - case GPR_CLOCK_MONOTONIC: - case GPR_CLOCK_PRECISE: - QueryPerformanceCounter(×tamp); - diff = timestamp.QuadPart - g_start_time.QuadPart; - now_dbl = (double)diff * g_time_scale; - now_tv.tv_sec = (int64_t)now_dbl; - now_tv.tv_nsec = (int32_t)((now_dbl - (double)now_tv.tv_sec) * 1e9); - break; - case GPR_TIMESPAN: - abort(); - break; - } - return now_tv; -} - -void gpr_sleep_until(gpr_timespec until) { - gpr_timespec now; - gpr_timespec delta; - int64_t sleep_millis; - - for (;;) { - /* We could simplify by using clock_nanosleep instead, but it might be - * slightly less portable. */ - now = gpr_now(until.clock_type); - if (gpr_time_cmp(until, now) <= 0) { - return; - } - - delta = gpr_time_sub(until, now); - sleep_millis = - delta.tv_sec * GPR_MS_PER_SEC + delta.tv_nsec / GPR_NS_PER_MS; - GPR_ASSERT((sleep_millis >= 0) && (sleep_millis <= INT_MAX)); - GRPC_SCHEDULING_START_BLOCKING_REGION; - Sleep((DWORD)sleep_millis); - GRPC_SCHEDULING_END_BLOCKING_REGION; - } -} - -#endif /* GPR_WIN32 */ diff --git a/src/core/support/tls_pthread.c b/src/core/support/tls_pthread.c deleted file mode 100644 index 9683a6e547..0000000000 --- a/src/core/support/tls_pthread.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Copyright 2015, 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 - -#ifdef GPR_PTHREAD_TLS - -#include - -intptr_t gpr_tls_set(struct gpr_pthread_thread_local *tls, intptr_t value) { - GPR_ASSERT(0 == pthread_setspecific(tls->key, (void *)value)); - return value; -} - -#endif /* GPR_PTHREAD_TLS */ diff --git a/src/core/support/tmpfile.h b/src/core/support/tmpfile.h deleted file mode 100644 index df6f8692bb..0000000000 --- a/src/core/support/tmpfile.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright 2015-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_SUPPORT_TMPFILE_H -#define GRPC_CORE_SUPPORT_TMPFILE_H - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Creates a temporary file from a prefix. - If tmp_filename is not NULL, *tmp_filename is assigned the name of the - created file and it is the responsibility of the caller to gpr_free it - unless an error occurs in which case it will be set to NULL. */ -FILE *gpr_tmpfile(const char *prefix, char **tmp_filename); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_SUPPORT_TMPFILE_H */ diff --git a/src/core/support/tmpfile_posix.c b/src/core/support/tmpfile_posix.c deleted file mode 100644 index b16eeacf9d..0000000000 --- a/src/core/support/tmpfile_posix.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_POSIX_FILE - -#include "src/core/support/tmpfile.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include "src/core/support/string.h" - -FILE *gpr_tmpfile(const char *prefix, char **tmp_filename) { - FILE *result = NULL; - char *template; - int fd; - - if (tmp_filename != NULL) *tmp_filename = NULL; - - gpr_asprintf(&template, "/tmp/%s_XXXXXX", prefix); - GPR_ASSERT(template != NULL); - - fd = mkstemp(template); - if (fd == -1) { - gpr_log(GPR_ERROR, "mkstemp failed for template %s with error %s.", - template, strerror(errno)); - goto end; - } - result = fdopen(fd, "w+"); - if (result == NULL) { - gpr_log(GPR_ERROR, "Could not open file %s from fd %d (error = %s).", - template, fd, strerror(errno)); - unlink(template); - close(fd); - goto end; - } - -end: - if (result != NULL && tmp_filename != NULL) { - *tmp_filename = template; - } else { - gpr_free(template); - } - return result; -} - -#endif /* GPR_POSIX_FILE */ diff --git a/src/core/support/tmpfile_win32.c b/src/core/support/tmpfile_win32.c deleted file mode 100644 index 3000f0029f..0000000000 --- a/src/core/support/tmpfile_win32.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * - * Copyright 2015-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 - -#ifdef GPR_WIN32 - -#include -#include -#include -#include - -#include -#include -#include - -#include "src/core/support/string_win32.h" -#include "src/core/support/tmpfile.h" - -FILE *gpr_tmpfile(const char *prefix, char **tmp_filename_out) { - FILE *result = NULL; - LPTSTR template_string = NULL; - TCHAR tmp_path[MAX_PATH]; - TCHAR tmp_filename[MAX_PATH]; - DWORD status; - UINT success; - - if (tmp_filename_out != NULL) *tmp_filename_out = NULL; - - /* Convert our prefix to TCHAR. */ - template_string = gpr_char_to_tchar(prefix); - GPR_ASSERT(template_string); - - /* Get the path to the best temporary folder available. */ - status = GetTempPath(MAX_PATH, tmp_path); - if (status == 0 || status > MAX_PATH) goto end; - - /* Generate a unique filename with our template + temporary path. */ - success = GetTempFileName(tmp_path, template_string, 0, tmp_filename); - if (!success) goto end; - - /* Open a file there. */ - if (_tfopen_s(&result, tmp_filename, TEXT("wb+")) != 0) goto end; - -end: - if (result && tmp_filename_out) { - *tmp_filename_out = gpr_tchar_to_char(tmp_filename); - } - - gpr_free(template_string); - return result; -} - -#endif /* GPR_WIN32 */ diff --git a/src/core/support/wrap_memcpy.c b/src/core/support/wrap_memcpy.c deleted file mode 100644 index 15c289f7b8..0000000000 --- a/src/core/support/wrap_memcpy.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * 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 - -/* Provide a wrapped memcpy for targets that need to be backwards - * compatible with older libc's. - * - * Enable by setting LDFLAGS=-Wl,-wrap,memcpy when linking. - */ - -#ifdef __linux__ -#ifdef __x86_64__ -__asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); -void *__wrap_memcpy(void *destination, const void *source, size_t num) { - return memcpy(destination, source, num); -} -#else /* !__x86_64__ */ -void *__wrap_memcpy(void *destination, const void *source, size_t num) { - return memmove(destination, source, num); -} -#endif -#endif diff --git a/src/core/surface/alarm.c b/src/core/surface/alarm.c deleted file mode 100644 index 1085285f95..0000000000 --- a/src/core/surface/alarm.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * - * Copyright 2015-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 -#include -#include "src/core/iomgr/timer.h" -#include "src/core/surface/completion_queue.h" - -struct grpc_alarm { - grpc_timer alarm; - grpc_cq_completion completion; - /** completion queue where events about this alarm will be posted */ - grpc_completion_queue *cq; - /** user supplied tag */ - void *tag; -}; - -static void do_nothing_end_completion(grpc_exec_ctx *exec_ctx, void *arg, - grpc_cq_completion *c) {} - -static void alarm_cb(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - grpc_alarm *alarm = arg; - grpc_cq_end_op(exec_ctx, alarm->cq, alarm->tag, success, - do_nothing_end_completion, NULL, &alarm->completion); -} - -grpc_alarm *grpc_alarm_create(grpc_completion_queue *cq, gpr_timespec deadline, - void *tag) { - grpc_alarm *alarm = gpr_malloc(sizeof(grpc_alarm)); - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - GRPC_CQ_INTERNAL_REF(cq, "alarm"); - alarm->cq = cq; - alarm->tag = tag; - - grpc_cq_begin_op(cq, tag); - grpc_timer_init(&exec_ctx, &alarm->alarm, - gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC), - alarm_cb, alarm, gpr_now(GPR_CLOCK_MONOTONIC)); - grpc_exec_ctx_finish(&exec_ctx); - return alarm; -} - -void grpc_alarm_cancel(grpc_alarm *alarm) { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_timer_cancel(&exec_ctx, &alarm->alarm); - grpc_exec_ctx_finish(&exec_ctx); -} - -void grpc_alarm_destroy(grpc_alarm *alarm) { - grpc_alarm_cancel(alarm); - GRPC_CQ_INTERNAL_UNREF(alarm->cq, "alarm"); - gpr_free(alarm); -} diff --git a/src/core/surface/api_trace.c b/src/core/surface/api_trace.c deleted file mode 100644 index 9f0b900d46..0000000000 --- a/src/core/surface/api_trace.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * Copyright 2015, 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/surface/api_trace.h" - -int grpc_api_trace = 0; diff --git a/src/core/surface/api_trace.h b/src/core/surface/api_trace.h deleted file mode 100644 index af53829de4..0000000000 --- a/src/core/surface/api_trace.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * Copyright 2015-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_SURFACE_API_TRACE_H -#define GRPC_CORE_SURFACE_API_TRACE_H - -#include -#include "src/core/debug/trace.h" - -extern int grpc_api_trace; - -/* Provide unwrapping macros because we're in C89 and variadic macros weren't - introduced until C99... */ -#define GRPC_API_TRACE_UNWRAP0() -#define GRPC_API_TRACE_UNWRAP1(a) , a -#define GRPC_API_TRACE_UNWRAP2(a, b) , a, b -#define GRPC_API_TRACE_UNWRAP3(a, b, c) , a, b, c -#define GRPC_API_TRACE_UNWRAP4(a, b, c, d) , a, b, c, d -#define GRPC_API_TRACE_UNWRAP5(a, b, c, d, e) , a, b, c, d, e -#define GRPC_API_TRACE_UNWRAP6(a, b, c, d, e, f) , a, b, c, d, e, f -#define GRPC_API_TRACE_UNWRAP7(a, b, c, d, e, f, g) , a, b, c, d, e, f, g -#define GRPC_API_TRACE_UNWRAP8(a, b, c, d, e, f, g, h) , a, b, c, d, e, f, g, h -#define GRPC_API_TRACE_UNWRAP9(a, b, c, d, e, f, g, h, i) \ - , a, b, c, d, e, f, g, h, i -#define GRPC_API_TRACE_UNWRAP10(a, b, c, d, e, f, g, h, i, j) \ - , a, b, c, d, e, f, g, h, i, j - -/* Due to the limitations of C89's preprocessor, the arity of the var-arg list - 'nargs' must be specified. */ -#define GRPC_API_TRACE(fmt, nargs, args) \ - if (grpc_api_trace) { \ - gpr_log(GPR_INFO, fmt GRPC_API_TRACE_UNWRAP##nargs args); \ - } - -#endif /* GRPC_CORE_SURFACE_API_TRACE_H */ diff --git a/src/core/surface/byte_buffer.c b/src/core/surface/byte_buffer.c deleted file mode 100644 index fb39c4531d..0000000000 --- a/src/core/surface/byte_buffer.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * - * Copyright 2015, 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 -#include -#include - -grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices, - size_t nslices) { - return grpc_raw_compressed_byte_buffer_create(slices, nslices, - GRPC_COMPRESS_NONE); -} - -grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create( - gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression) { - size_t i; - grpc_byte_buffer *bb = malloc(sizeof(grpc_byte_buffer)); - bb->type = GRPC_BB_RAW; - bb->data.raw.compression = compression; - gpr_slice_buffer_init(&bb->data.raw.slice_buffer); - for (i = 0; i < nslices; i++) { - gpr_slice_ref(slices[i]); - gpr_slice_buffer_add(&bb->data.raw.slice_buffer, slices[i]); - } - return bb; -} - -grpc_byte_buffer *grpc_raw_byte_buffer_from_reader( - grpc_byte_buffer_reader *reader) { - grpc_byte_buffer *bb = malloc(sizeof(grpc_byte_buffer)); - gpr_slice slice; - bb->type = GRPC_BB_RAW; - bb->data.raw.compression = GRPC_COMPRESS_NONE; - gpr_slice_buffer_init(&bb->data.raw.slice_buffer); - - while (grpc_byte_buffer_reader_next(reader, &slice)) { - gpr_slice_buffer_add(&bb->data.raw.slice_buffer, slice); - } - return bb; -} - -grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb) { - switch (bb->type) { - case GRPC_BB_RAW: - return grpc_raw_byte_buffer_create(bb->data.raw.slice_buffer.slices, - bb->data.raw.slice_buffer.count); - } - GPR_UNREACHABLE_CODE(return NULL); -} - -void grpc_byte_buffer_destroy(grpc_byte_buffer *bb) { - if (!bb) return; - switch (bb->type) { - case GRPC_BB_RAW: - gpr_slice_buffer_destroy(&bb->data.raw.slice_buffer); - break; - } - free(bb); -} - -size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) { - switch (bb->type) { - case GRPC_BB_RAW: - return bb->data.raw.slice_buffer.length; - } - GPR_UNREACHABLE_CODE(return 0); -} diff --git a/src/core/surface/byte_buffer_reader.c b/src/core/surface/byte_buffer_reader.c deleted file mode 100644 index 4a418faaed..0000000000 --- a/src/core/surface/byte_buffer_reader.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * - * Copyright 2015-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 -#include - -#include -#include -#include -#include -#include -#include - -#include "src/core/compression/message_compress.h" - -static int is_compressed(grpc_byte_buffer *buffer) { - switch (buffer->type) { - case GRPC_BB_RAW: - if (buffer->data.raw.compression == GRPC_COMPRESS_NONE) { - return 0 /* GPR_FALSE */; - } - break; - } - return 1 /* GPR_TRUE */; -} - -void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader, - grpc_byte_buffer *buffer) { - gpr_slice_buffer decompressed_slices_buffer; - reader->buffer_in = buffer; - switch (reader->buffer_in->type) { - case GRPC_BB_RAW: - gpr_slice_buffer_init(&decompressed_slices_buffer); - if (is_compressed(reader->buffer_in)) { - grpc_msg_decompress(reader->buffer_in->data.raw.compression, - &reader->buffer_in->data.raw.slice_buffer, - &decompressed_slices_buffer); - reader->buffer_out = - grpc_raw_byte_buffer_create(decompressed_slices_buffer.slices, - decompressed_slices_buffer.count); - gpr_slice_buffer_destroy(&decompressed_slices_buffer); - } else { /* not compressed, use the input buffer as output */ - reader->buffer_out = reader->buffer_in; - } - reader->current.index = 0; - break; - } -} - -void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader) { - switch (reader->buffer_in->type) { - case GRPC_BB_RAW: - /* keeping the same if-else structure as in the init function */ - if (is_compressed(reader->buffer_in)) { - grpc_byte_buffer_destroy(reader->buffer_out); - } - break; - } -} - -int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader, - gpr_slice *slice) { - switch (reader->buffer_in->type) { - case GRPC_BB_RAW: { - gpr_slice_buffer *slice_buffer; - slice_buffer = &reader->buffer_out->data.raw.slice_buffer; - if (reader->current.index < slice_buffer->count) { - *slice = gpr_slice_ref(slice_buffer->slices[reader->current.index]); - reader->current.index += 1; - return 1; - } - break; - } - } - return 0; -} - -gpr_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader) { - gpr_slice in_slice; - size_t bytes_read = 0; - const size_t input_size = grpc_byte_buffer_length(reader->buffer_out); - gpr_slice out_slice = gpr_slice_malloc(input_size); - uint8_t *const outbuf = GPR_SLICE_START_PTR(out_slice); /* just an alias */ - - while (grpc_byte_buffer_reader_next(reader, &in_slice) != 0) { - const size_t slice_length = GPR_SLICE_LENGTH(in_slice); - memcpy(&(outbuf[bytes_read]), GPR_SLICE_START_PTR(in_slice), slice_length); - bytes_read += slice_length; - gpr_slice_unref(in_slice); - GPR_ASSERT(bytes_read <= input_size); - } - return out_slice; -} diff --git a/src/core/surface/call.c b/src/core/surface/call.c deleted file mode 100644 index 6f1cd1df10..0000000000 --- a/src/core/surface/call.c +++ /dev/null @@ -1,1491 +0,0 @@ -/* - * - * Copyright 2015-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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "src/core/channel/channel_stack.h" -#include "src/core/compression/algorithm_metadata.h" -#include "src/core/iomgr/timer.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/completion_queue.h" -#include "src/core/transport/static_metadata.h" - -/** The maximum number of concurrent batches possible. - Based upon the maximum number of individually queueable ops in the batch - api: - - initial metadata send - - message send - - status/close send (depending on client/server) - - initial metadata recv - - message recv - - status/close recv (depending on client/server) */ -#define MAX_CONCURRENT_BATCHES 6 - -typedef struct { - grpc_ioreq_completion_func on_complete; - void *user_data; - int success; -} completed_request; - -#define MAX_SEND_EXTRA_METADATA_COUNT 3 - -/* Status data for a request can come from several sources; this - enumerates them all, and acts as a priority sorting for which - status to return to the application - earlier entries override - later ones */ -typedef enum { - /* Status came from the application layer overriding whatever - the wire says */ - STATUS_FROM_API_OVERRIDE = 0, - /* Status was created by some internal channel stack operation */ - STATUS_FROM_CORE, - /* Status came from 'the wire' - or somewhere below the surface - layer */ - STATUS_FROM_WIRE, - /* Status came from the server sending status */ - STATUS_FROM_SERVER_STATUS, - STATUS_SOURCE_COUNT -} status_source; - -typedef struct { - uint8_t is_set; - grpc_status_code code; - grpc_mdstr *details; -} received_status; - -/* How far through the GRPC stream have we read? */ -typedef enum { - /* We are still waiting for initial metadata to complete */ - READ_STATE_INITIAL = 0, - /* We have gotten initial metadata, and are reading either - messages or trailing metadata */ - READ_STATE_GOT_INITIAL_METADATA, - /* The stream is closed for reading */ - READ_STATE_READ_CLOSED, - /* The stream is closed for reading & writing */ - READ_STATE_STREAM_CLOSED -} read_state; - -typedef enum { - WRITE_STATE_INITIAL = 0, - WRITE_STATE_STARTED, - WRITE_STATE_WRITE_CLOSED -} write_state; - -typedef struct batch_control { - grpc_call *call; - grpc_cq_completion cq_completion; - grpc_closure finish_batch; - void *notify_tag; - gpr_refcount steps_to_complete; - - uint8_t send_initial_metadata; - uint8_t send_message; - uint8_t send_final_op; - uint8_t recv_initial_metadata; - uint8_t recv_message; - uint8_t recv_final_op; - uint8_t is_notify_tag_closure; - uint8_t success; -} batch_control; - -struct grpc_call { - grpc_completion_queue *cq; - grpc_channel *channel; - grpc_call *parent; - grpc_call *first_child; - /* TODO(ctiller): share with cq if possible? */ - gpr_mu mu; - - /* client or server call */ - uint8_t is_client; - /* is the alarm set */ - uint8_t have_alarm; - /** has grpc_call_destroy been called */ - uint8_t destroy_called; - /** flag indicating that cancellation is inherited */ - uint8_t cancellation_is_inherited; - /** bitmask of live batches */ - uint8_t used_batches; - /** which ops are in-flight */ - uint8_t sent_initial_metadata; - uint8_t sending_message; - uint8_t sent_final_op; - uint8_t received_initial_metadata; - uint8_t receiving_message; - uint8_t received_final_op; - - /* have we received initial metadata */ - bool has_initial_md_been_received; - - batch_control active_batches[MAX_CONCURRENT_BATCHES]; - - /* first idx: is_receiving, second idx: is_trailing */ - grpc_metadata_batch metadata_batch[2][2]; - - /* Buffered read metadata waiting to be returned to the application. - Element 0 is initial metadata, element 1 is trailing metadata. */ - grpc_metadata_array *buffered_metadata[2]; - - /* Received call statuses from various sources */ - received_status status[STATUS_SOURCE_COUNT]; - - /* Compression algorithm for the call */ - grpc_compression_algorithm compression_algorithm; - /* Supported encodings (compression algorithms), a bitset */ - uint32_t encodings_accepted_by_peer; - - /* Contexts for various subsystems (security, tracing, ...). */ - grpc_call_context_element context[GRPC_CONTEXT_COUNT]; - - /* Deadline alarm - if have_alarm is non-zero */ - grpc_timer alarm; - - /* for the client, extra metadata is initial metadata; for the - server, it's trailing metadata */ - grpc_linked_mdelem send_extra_metadata[MAX_SEND_EXTRA_METADATA_COUNT]; - int send_extra_metadata_count; - gpr_timespec send_deadline; - - /** siblings: children of the same parent form a list, and this list is - protected under - parent->mu */ - grpc_call *sibling_next; - grpc_call *sibling_prev; - - grpc_slice_buffer_stream sending_stream; - grpc_byte_stream *receiving_stream; - grpc_byte_buffer **receiving_buffer; - gpr_slice receiving_slice; - grpc_closure receiving_slice_ready; - grpc_closure receiving_stream_ready; - grpc_closure receiving_initial_metadata_ready; - uint32_t test_only_last_message_flags; - - union { - struct { - grpc_status_code *status; - char **status_details; - size_t *status_details_capacity; - } client; - struct { - int *cancelled; - } server; - } final_op; - - struct { - void *bctlp; - bool success; - } saved_receiving_stream_ready_ctx; -}; - -#define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call) + 1)) -#define CALL_FROM_CALL_STACK(call_stack) (((grpc_call *)(call_stack)) - 1) -#define CALL_ELEM_FROM_CALL(call, idx) \ - grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx) -#define CALL_FROM_TOP_ELEM(top_elem) \ - CALL_FROM_CALL_STACK(grpc_call_stack_from_top_element(top_elem)) - -static void set_deadline_alarm(grpc_exec_ctx *exec_ctx, grpc_call *call, - gpr_timespec deadline); -static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call, - grpc_transport_stream_op *op); -static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c, - grpc_status_code status, - const char *description); -static void destroy_call(grpc_exec_ctx *exec_ctx, void *call_stack, - bool success); -static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, - bool success); - -grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call, - uint32_t propagation_mask, - grpc_completion_queue *cq, - const void *server_transport_data, - grpc_mdelem **add_initial_metadata, - size_t add_initial_metadata_count, - gpr_timespec send_deadline) { - size_t i, j; - grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel); - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_call *call; - GPR_TIMER_BEGIN("grpc_call_create", 0); - call = gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size); - memset(call, 0, sizeof(grpc_call)); - gpr_mu_init(&call->mu); - call->channel = channel; - call->cq = cq; - call->parent = parent_call; - call->is_client = server_transport_data == NULL; - if (call->is_client) { - GPR_ASSERT(add_initial_metadata_count < MAX_SEND_EXTRA_METADATA_COUNT); - for (i = 0; i < add_initial_metadata_count; i++) { - call->send_extra_metadata[i].md = add_initial_metadata[i]; - } - call->send_extra_metadata_count = (int)add_initial_metadata_count; - } else { - GPR_ASSERT(add_initial_metadata_count == 0); - call->send_extra_metadata_count = 0; - } - for (i = 0; i < 2; i++) { - for (j = 0; j < 2; j++) { - call->metadata_batch[i][j].deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); - } - } - call->send_deadline = send_deadline; - GRPC_CHANNEL_INTERNAL_REF(channel, "call"); - /* initial refcount dropped by grpc_call_destroy */ - grpc_call_stack_init(&exec_ctx, channel_stack, 1, destroy_call, call, - call->context, server_transport_data, - CALL_STACK_FROM_CALL(call)); - if (cq != NULL) { - GRPC_CQ_INTERNAL_REF(cq, "bind"); - grpc_call_stack_set_pollset(&exec_ctx, CALL_STACK_FROM_CALL(call), - grpc_cq_pollset(cq)); - } - if (parent_call != NULL) { - GRPC_CALL_INTERNAL_REF(parent_call, "child"); - GPR_ASSERT(call->is_client); - GPR_ASSERT(!parent_call->is_client); - - gpr_mu_lock(&parent_call->mu); - - if (propagation_mask & GRPC_PROPAGATE_DEADLINE) { - send_deadline = gpr_time_min( - gpr_convert_clock_type(send_deadline, - parent_call->send_deadline.clock_type), - parent_call->send_deadline); - } - /* for now GRPC_PROPAGATE_TRACING_CONTEXT *MUST* be passed with - * GRPC_PROPAGATE_STATS_CONTEXT */ - /* TODO(ctiller): This should change to use the appropriate census start_op - * call. */ - if (propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) { - GPR_ASSERT(propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT); - grpc_call_context_set(call, GRPC_CONTEXT_TRACING, - parent_call->context[GRPC_CONTEXT_TRACING].value, - NULL); - } else { - GPR_ASSERT(propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT); - } - if (propagation_mask & GRPC_PROPAGATE_CANCELLATION) { - call->cancellation_is_inherited = 1; - } - - if (parent_call->first_child == NULL) { - parent_call->first_child = call; - call->sibling_next = call->sibling_prev = call; - } else { - call->sibling_next = parent_call->first_child; - call->sibling_prev = parent_call->first_child->sibling_prev; - call->sibling_next->sibling_prev = call->sibling_prev->sibling_next = - call; - } - - gpr_mu_unlock(&parent_call->mu); - } - if (gpr_time_cmp(send_deadline, gpr_inf_future(send_deadline.clock_type)) != - 0) { - set_deadline_alarm(&exec_ctx, call, send_deadline); - } - grpc_exec_ctx_finish(&exec_ctx); - GPR_TIMER_END("grpc_call_create", 0); - return call; -} - -void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call, - grpc_completion_queue *cq) { - GPR_ASSERT(cq); - call->cq = cq; - GRPC_CQ_INTERNAL_REF(cq, "bind"); - grpc_call_stack_set_pollset(exec_ctx, CALL_STACK_FROM_CALL(call), - grpc_cq_pollset(cq)); -} - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -#define REF_REASON reason -#define REF_ARG , const char *reason -#else -#define REF_REASON "" -#define REF_ARG -#endif -void grpc_call_internal_ref(grpc_call *c REF_ARG) { - GRPC_CALL_STACK_REF(CALL_STACK_FROM_CALL(c), REF_REASON); -} -void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *c REF_ARG) { - GRPC_CALL_STACK_UNREF(exec_ctx, CALL_STACK_FROM_CALL(c), REF_REASON); -} - -static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, bool success) { - size_t i; - int ii; - grpc_call *c = call; - GPR_TIMER_BEGIN("destroy_call", 0); - for (i = 0; i < 2; i++) { - grpc_metadata_batch_destroy( - &c->metadata_batch[1 /* is_receiving */][i /* is_initial */]); - } - if (c->receiving_stream != NULL) { - grpc_byte_stream_destroy(exec_ctx, c->receiving_stream); - } - grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c)); - GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, c->channel, "call"); - gpr_mu_destroy(&c->mu); - for (i = 0; i < STATUS_SOURCE_COUNT; i++) { - if (c->status[i].details) { - GRPC_MDSTR_UNREF(c->status[i].details); - } - } - for (ii = 0; ii < c->send_extra_metadata_count; ii++) { - GRPC_MDELEM_UNREF(c->send_extra_metadata[ii].md); - } - for (i = 0; i < GRPC_CONTEXT_COUNT; i++) { - if (c->context[i].destroy) { - c->context[i].destroy(c->context[i].value); - } - } - if (c->cq) { - GRPC_CQ_INTERNAL_UNREF(c->cq, "bind"); - } - gpr_free(c); - GPR_TIMER_END("destroy_call", 0); -} - -static void set_status_code(grpc_call *call, status_source source, - uint32_t status) { - if (call->status[source].is_set) return; - - call->status[source].is_set = 1; - call->status[source].code = (grpc_status_code)status; - - /* TODO(ctiller): what to do about the flush that was previously here */ -} - -static void set_compression_algorithm(grpc_call *call, - grpc_compression_algorithm algo) { - call->compression_algorithm = algo; -} - -grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm( - grpc_call *call) { - grpc_compression_algorithm algorithm; - gpr_mu_lock(&call->mu); - algorithm = call->compression_algorithm; - gpr_mu_unlock(&call->mu); - return algorithm; -} - -uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) { - uint32_t flags; - gpr_mu_lock(&call->mu); - flags = call->test_only_last_message_flags; - gpr_mu_unlock(&call->mu); - return flags; -} - -static void destroy_encodings_accepted_by_peer(void *p) { return; } - -static void set_encodings_accepted_by_peer(grpc_call *call, grpc_mdelem *mdel) { - size_t i; - grpc_compression_algorithm algorithm; - gpr_slice_buffer accept_encoding_parts; - gpr_slice accept_encoding_slice; - void *accepted_user_data; - - accepted_user_data = - grpc_mdelem_get_user_data(mdel, destroy_encodings_accepted_by_peer); - if (accepted_user_data != NULL) { - call->encodings_accepted_by_peer = - (uint32_t)(((uintptr_t)accepted_user_data) - 1); - return; - } - - accept_encoding_slice = mdel->value->slice; - gpr_slice_buffer_init(&accept_encoding_parts); - gpr_slice_split(accept_encoding_slice, ",", &accept_encoding_parts); - - /* No need to zero call->encodings_accepted_by_peer: grpc_call_create already - * zeroes the whole grpc_call */ - /* Always support no compression */ - GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE); - for (i = 0; i < accept_encoding_parts.count; i++) { - const gpr_slice *accept_encoding_entry_slice = - &accept_encoding_parts.slices[i]; - if (grpc_compression_algorithm_parse( - (const char *)GPR_SLICE_START_PTR(*accept_encoding_entry_slice), - GPR_SLICE_LENGTH(*accept_encoding_entry_slice), &algorithm)) { - GPR_BITSET(&call->encodings_accepted_by_peer, algorithm); - } else { - char *accept_encoding_entry_str = - gpr_dump_slice(*accept_encoding_entry_slice, GPR_DUMP_ASCII); - gpr_log(GPR_ERROR, - "Invalid entry in accept encoding metadata: '%s'. Ignoring.", - accept_encoding_entry_str); - gpr_free(accept_encoding_entry_str); - } - } - - gpr_slice_buffer_destroy(&accept_encoding_parts); - - grpc_mdelem_set_user_data( - mdel, destroy_encodings_accepted_by_peer, - (void *)(((uintptr_t)call->encodings_accepted_by_peer) + 1)); -} - -uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) { - uint32_t encodings_accepted_by_peer; - gpr_mu_lock(&call->mu); - encodings_accepted_by_peer = call->encodings_accepted_by_peer; - gpr_mu_unlock(&call->mu); - return encodings_accepted_by_peer; -} - -static void set_status_details(grpc_call *call, status_source source, - grpc_mdstr *status) { - if (call->status[source].details != NULL) { - GRPC_MDSTR_UNREF(call->status[source].details); - } - call->status[source].details = status; -} - -static void get_final_status(grpc_call *call, - void (*set_value)(grpc_status_code code, - void *user_data), - void *set_value_user_data) { - int i; - for (i = 0; i < STATUS_SOURCE_COUNT; i++) { - if (call->status[i].is_set) { - set_value(call->status[i].code, set_value_user_data); - return; - } - } - if (call->is_client) { - set_value(GRPC_STATUS_UNKNOWN, set_value_user_data); - } else { - set_value(GRPC_STATUS_OK, set_value_user_data); - } -} - -static void get_final_details(grpc_call *call, char **out_details, - size_t *out_details_capacity) { - int i; - for (i = 0; i < STATUS_SOURCE_COUNT; i++) { - if (call->status[i].is_set) { - if (call->status[i].details) { - gpr_slice details = call->status[i].details->slice; - size_t len = GPR_SLICE_LENGTH(details); - if (len + 1 > *out_details_capacity) { - *out_details_capacity = - GPR_MAX(len + 1, *out_details_capacity * 3 / 2); - *out_details = gpr_realloc(*out_details, *out_details_capacity); - } - memcpy(*out_details, GPR_SLICE_START_PTR(details), len); - (*out_details)[len] = 0; - } else { - goto no_details; - } - return; - } - } - -no_details: - if (0 == *out_details_capacity) { - *out_details_capacity = 8; - *out_details = gpr_malloc(*out_details_capacity); - } - **out_details = 0; -} - -static grpc_linked_mdelem *linked_from_md(grpc_metadata *md) { - return (grpc_linked_mdelem *)&md->internal_data; -} - -static int prepare_application_metadata(grpc_call *call, int count, - grpc_metadata *metadata, - int is_trailing, - int prepend_extra_metadata) { - int i; - grpc_metadata_batch *batch = - &call->metadata_batch[0 /* is_receiving */][is_trailing]; - if (prepend_extra_metadata) { - if (call->send_extra_metadata_count == 0) { - prepend_extra_metadata = 0; - } else { - for (i = 0; i < call->send_extra_metadata_count; i++) { - GRPC_MDELEM_REF(call->send_extra_metadata[i].md); - } - for (i = 1; i < call->send_extra_metadata_count; i++) { - call->send_extra_metadata[i].prev = &call->send_extra_metadata[i - 1]; - } - for (i = 0; i < call->send_extra_metadata_count - 1; i++) { - call->send_extra_metadata[i].next = &call->send_extra_metadata[i + 1]; - } - } - } - for (i = 0; i < count; i++) { - grpc_metadata *md = &metadata[i]; - grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data; - GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data)); - l->md = grpc_mdelem_from_string_and_buffer( - md->key, (const uint8_t *)md->value, md->value_length); - if (!grpc_header_key_is_legal(grpc_mdstr_as_c_string(l->md->key), - GRPC_MDSTR_LENGTH(l->md->key))) { - gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s", - grpc_mdstr_as_c_string(l->md->key)); - return 0; - } else if (!grpc_is_binary_header(grpc_mdstr_as_c_string(l->md->key), - GRPC_MDSTR_LENGTH(l->md->key)) && - !grpc_header_nonbin_value_is_legal( - grpc_mdstr_as_c_string(l->md->value), - GRPC_MDSTR_LENGTH(l->md->value))) { - gpr_log(GPR_ERROR, "attempt to send invalid metadata value"); - return 0; - } - } - for (i = 1; i < count; i++) { - linked_from_md(&metadata[i])->prev = linked_from_md(&metadata[i - 1]); - } - for (i = 0; i < count - 1; i++) { - linked_from_md(&metadata[i])->next = linked_from_md(&metadata[i + 1]); - } - switch (prepend_extra_metadata * 2 + (count != 0)) { - case 0: - /* no prepend, no metadata => nothing to do */ - batch->list.head = batch->list.tail = NULL; - break; - case 1: - /* metadata, but no prepend */ - batch->list.head = linked_from_md(&metadata[0]); - batch->list.tail = linked_from_md(&metadata[count - 1]); - batch->list.head->prev = NULL; - batch->list.tail->next = NULL; - break; - case 2: - /* prepend, but no md */ - batch->list.head = &call->send_extra_metadata[0]; - batch->list.tail = - &call->send_extra_metadata[call->send_extra_metadata_count - 1]; - batch->list.head->prev = NULL; - batch->list.tail->next = NULL; - break; - case 3: - /* prepend AND md */ - batch->list.head = &call->send_extra_metadata[0]; - call->send_extra_metadata[call->send_extra_metadata_count - 1].next = - linked_from_md(&metadata[0]); - linked_from_md(&metadata[0])->prev = - &call->send_extra_metadata[call->send_extra_metadata_count - 1]; - batch->list.tail = linked_from_md(&metadata[count - 1]); - batch->list.head->prev = NULL; - batch->list.tail->next = NULL; - break; - default: - GPR_UNREACHABLE_CODE(return 0); - } - - return 1; -} - -void grpc_call_destroy(grpc_call *c) { - int cancel; - grpc_call *parent = c->parent; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - GPR_TIMER_BEGIN("grpc_call_destroy", 0); - GRPC_API_TRACE("grpc_call_destroy(c=%p)", 1, (c)); - - if (parent) { - gpr_mu_lock(&parent->mu); - if (c == parent->first_child) { - parent->first_child = c->sibling_next; - if (c == parent->first_child) { - parent->first_child = NULL; - } - c->sibling_prev->sibling_next = c->sibling_next; - c->sibling_next->sibling_prev = c->sibling_prev; - } - gpr_mu_unlock(&parent->mu); - GRPC_CALL_INTERNAL_UNREF(&exec_ctx, parent, "child"); - } - - gpr_mu_lock(&c->mu); - GPR_ASSERT(!c->destroy_called); - c->destroy_called = 1; - if (c->have_alarm) { - grpc_timer_cancel(&exec_ctx, &c->alarm); - } - cancel = !c->received_final_op; - gpr_mu_unlock(&c->mu); - if (cancel) grpc_call_cancel(c, NULL); - GRPC_CALL_INTERNAL_UNREF(&exec_ctx, c, "destroy"); - grpc_exec_ctx_finish(&exec_ctx); - GPR_TIMER_END("grpc_call_destroy", 0); -} - -grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved) { - GRPC_API_TRACE("grpc_call_cancel(call=%p, reserved=%p)", 2, (call, reserved)); - GPR_ASSERT(!reserved); - return grpc_call_cancel_with_status(call, GRPC_STATUS_CANCELLED, "Cancelled", - NULL); -} - -grpc_call_error grpc_call_cancel_with_status(grpc_call *c, - grpc_status_code status, - const char *description, - void *reserved) { - grpc_call_error r; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - GRPC_API_TRACE( - "grpc_call_cancel_with_status(" - "c=%p, status=%d, description=%s, reserved=%p)", - 4, (c, (int)status, description, reserved)); - GPR_ASSERT(reserved == NULL); - gpr_mu_lock(&c->mu); - r = cancel_with_status(&exec_ctx, c, status, description); - gpr_mu_unlock(&c->mu); - grpc_exec_ctx_finish(&exec_ctx); - return r; -} - -typedef struct cancel_closure { - grpc_closure closure; - grpc_call *call; - grpc_status_code status; -} cancel_closure; - -static void done_cancel(grpc_exec_ctx *exec_ctx, void *ccp, bool success) { - cancel_closure *cc = ccp; - GRPC_CALL_INTERNAL_UNREF(exec_ctx, cc->call, "cancel"); - gpr_free(cc); -} - -static void send_cancel(grpc_exec_ctx *exec_ctx, void *ccp, bool success) { - grpc_transport_stream_op op; - cancel_closure *cc = ccp; - memset(&op, 0, sizeof(op)); - op.cancel_with_status = cc->status; - /* reuse closure to catch completion */ - grpc_closure_init(&cc->closure, done_cancel, cc); - op.on_complete = &cc->closure; - execute_op(exec_ctx, cc->call, &op); -} - -static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c, - grpc_status_code status, - const char *description) { - grpc_mdstr *details = - description ? grpc_mdstr_from_string(description) : NULL; - cancel_closure *cc = gpr_malloc(sizeof(*cc)); - - GPR_ASSERT(status != GRPC_STATUS_OK); - - set_status_code(c, STATUS_FROM_API_OVERRIDE, (uint32_t)status); - set_status_details(c, STATUS_FROM_API_OVERRIDE, details); - - grpc_closure_init(&cc->closure, send_cancel, cc); - cc->call = c; - cc->status = status; - GRPC_CALL_INTERNAL_REF(c, "cancel"); - grpc_exec_ctx_enqueue(exec_ctx, &cc->closure, true, NULL); - - return GRPC_CALL_OK; -} - -static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call, - grpc_transport_stream_op *op) { - grpc_call_element *elem; - - GPR_TIMER_BEGIN("execute_op", 0); - elem = CALL_ELEM_FROM_CALL(call, 0); - op->context = call->context; - elem->filter->start_transport_stream_op(exec_ctx, elem, op); - GPR_TIMER_END("execute_op", 0); -} - -char *grpc_call_get_peer(grpc_call *call) { - grpc_call_element *elem = CALL_ELEM_FROM_CALL(call, 0); - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - char *result; - GRPC_API_TRACE("grpc_call_get_peer(%p)", 1, (call)); - result = elem->filter->get_peer(&exec_ctx, elem); - if (result == NULL) { - result = grpc_channel_get_target(call->channel); - } - if (result == NULL) { - result = gpr_strdup("unknown"); - } - grpc_exec_ctx_finish(&exec_ctx); - return result; -} - -grpc_call *grpc_call_from_top_element(grpc_call_element *elem) { - return CALL_FROM_TOP_ELEM(elem); -} - -static void call_alarm(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - grpc_call *call = arg; - gpr_mu_lock(&call->mu); - call->have_alarm = 0; - if (success) { - cancel_with_status(exec_ctx, call, GRPC_STATUS_DEADLINE_EXCEEDED, - "Deadline Exceeded"); - } - gpr_mu_unlock(&call->mu); - GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "alarm"); -} - -static void set_deadline_alarm(grpc_exec_ctx *exec_ctx, grpc_call *call, - gpr_timespec deadline) { - if (call->have_alarm) { - gpr_log(GPR_ERROR, "Attempt to set deadline alarm twice"); - assert(0); - return; - } - GRPC_CALL_INTERNAL_REF(call, "alarm"); - call->have_alarm = 1; - call->send_deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); - grpc_timer_init(exec_ctx, &call->alarm, call->send_deadline, call_alarm, call, - gpr_now(GPR_CLOCK_MONOTONIC)); -} - -/* we offset status by a small amount when storing it into transport metadata - as metadata cannot store a 0 value (which is used as OK for grpc_status_codes - */ -#define STATUS_OFFSET 1 -static void destroy_status(void *ignored) {} - -static uint32_t decode_status(grpc_mdelem *md) { - uint32_t status; - void *user_data; - if (md == GRPC_MDELEM_GRPC_STATUS_0) return 0; - if (md == GRPC_MDELEM_GRPC_STATUS_1) return 1; - if (md == GRPC_MDELEM_GRPC_STATUS_2) return 2; - user_data = grpc_mdelem_get_user_data(md, destroy_status); - if (user_data != NULL) { - status = ((uint32_t)(intptr_t)user_data) - STATUS_OFFSET; - } else { - if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value), - GPR_SLICE_LENGTH(md->value->slice), - &status)) { - status = GRPC_STATUS_UNKNOWN; /* could not parse status code */ - } - grpc_mdelem_set_user_data(md, destroy_status, - (void *)(intptr_t)(status + STATUS_OFFSET)); - } - return status; -} - -static uint32_t decode_compression(grpc_mdelem *md) { - grpc_compression_algorithm algorithm = - grpc_compression_algorithm_from_mdstr(md->value); - if (algorithm == GRPC_COMPRESS_ALGORITHMS_COUNT) { - const char *md_c_str = grpc_mdstr_as_c_string(md->value); - gpr_log(GPR_ERROR, "Invalid compression algorithm: '%s'", md_c_str); - } - return algorithm; -} - -static grpc_mdelem *recv_common_filter(grpc_call *call, grpc_mdelem *elem) { - if (elem->key == GRPC_MDSTR_GRPC_STATUS) { - GPR_TIMER_BEGIN("status", 0); - set_status_code(call, STATUS_FROM_WIRE, decode_status(elem)); - GPR_TIMER_END("status", 0); - return NULL; - } else if (elem->key == GRPC_MDSTR_GRPC_MESSAGE) { - GPR_TIMER_BEGIN("status-details", 0); - set_status_details(call, STATUS_FROM_WIRE, GRPC_MDSTR_REF(elem->value)); - GPR_TIMER_END("status-details", 0); - return NULL; - } - return elem; -} - -static grpc_mdelem *publish_app_metadata(grpc_call *call, grpc_mdelem *elem, - int is_trailing) { - grpc_metadata_array *dest; - grpc_metadata *mdusr; - GPR_TIMER_BEGIN("publish_app_metadata", 0); - dest = call->buffered_metadata[is_trailing]; - if (dest->count == dest->capacity) { - dest->capacity = GPR_MAX(dest->capacity + 8, dest->capacity * 2); - dest->metadata = - gpr_realloc(dest->metadata, sizeof(grpc_metadata) * dest->capacity); - } - mdusr = &dest->metadata[dest->count++]; - mdusr->key = grpc_mdstr_as_c_string(elem->key); - mdusr->value = grpc_mdstr_as_c_string(elem->value); - mdusr->value_length = GPR_SLICE_LENGTH(elem->value->slice); - GPR_TIMER_END("publish_app_metadata", 0); - return elem; -} - -static grpc_mdelem *recv_initial_filter(void *callp, grpc_mdelem *elem) { - grpc_call *call = callp; - elem = recv_common_filter(call, elem); - if (elem == NULL) { - return NULL; - } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) { - GPR_TIMER_BEGIN("compression_algorithm", 0); - set_compression_algorithm(call, decode_compression(elem)); - GPR_TIMER_END("compression_algorithm", 0); - return NULL; - } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) { - GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0); - set_encodings_accepted_by_peer(call, elem); - GPR_TIMER_END("encodings_accepted_by_peer", 0); - return NULL; - } else { - return publish_app_metadata(call, elem, 0); - } -} - -static grpc_mdelem *recv_trailing_filter(void *callp, grpc_mdelem *elem) { - grpc_call *call = callp; - elem = recv_common_filter(call, elem); - if (elem == NULL) { - return NULL; - } else { - return publish_app_metadata(call, elem, 1); - } -} - -grpc_call_stack *grpc_call_get_call_stack(grpc_call *call) { - return CALL_STACK_FROM_CALL(call); -} - -/* - * BATCH API IMPLEMENTATION - */ - -static void set_status_value_directly(grpc_status_code status, void *dest) { - *(grpc_status_code *)dest = status; -} - -static void set_cancelled_value(grpc_status_code status, void *dest) { - *(int *)dest = (status != GRPC_STATUS_OK); -} - -static int are_write_flags_valid(uint32_t flags) { - /* check that only bits in GRPC_WRITE_(INTERNAL?)_USED_MASK are set */ - const uint32_t allowed_write_positions = - (GRPC_WRITE_USED_MASK | GRPC_WRITE_INTERNAL_USED_MASK); - const uint32_t invalid_positions = ~allowed_write_positions; - return !(flags & invalid_positions); -} - -static batch_control *allocate_batch_control(grpc_call *call) { - size_t i; - for (i = 0; i < MAX_CONCURRENT_BATCHES; i++) { - if ((call->used_batches & (1 << i)) == 0) { - call->used_batches = (uint8_t)(call->used_batches | (uint8_t)(1 << i)); - return &call->active_batches[i]; - } - } - return NULL; -} - -static void finish_batch_completion(grpc_exec_ctx *exec_ctx, void *user_data, - grpc_cq_completion *storage) { - batch_control *bctl = user_data; - grpc_call *call = bctl->call; - gpr_mu_lock(&call->mu); - call->used_batches = (uint8_t)( - call->used_batches & ~(uint8_t)(1 << (bctl - call->active_batches))); - gpr_mu_unlock(&call->mu); - GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion"); -} - -static void post_batch_completion(grpc_exec_ctx *exec_ctx, - batch_control *bctl) { - grpc_call *call = bctl->call; - if (bctl->is_notify_tag_closure) { - grpc_exec_ctx_enqueue(exec_ctx, bctl->notify_tag, bctl->success, NULL); - gpr_mu_lock(&call->mu); - bctl->call->used_batches = - (uint8_t)(bctl->call->used_batches & - ~(uint8_t)(1 << (bctl - bctl->call->active_batches))); - gpr_mu_unlock(&call->mu); - GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion"); - } else { - grpc_cq_end_op(exec_ctx, bctl->call->cq, bctl->notify_tag, bctl->success, - finish_batch_completion, bctl, &bctl->cq_completion); - } -} - -static void continue_receiving_slices(grpc_exec_ctx *exec_ctx, - batch_control *bctl) { - grpc_call *call = bctl->call; - for (;;) { - size_t remaining = call->receiving_stream->length - - (*call->receiving_buffer)->data.raw.slice_buffer.length; - if (remaining == 0) { - call->receiving_message = 0; - grpc_byte_stream_destroy(exec_ctx, call->receiving_stream); - call->receiving_stream = NULL; - if (gpr_unref(&bctl->steps_to_complete)) { - post_batch_completion(exec_ctx, bctl); - } - return; - } - if (grpc_byte_stream_next(exec_ctx, call->receiving_stream, - &call->receiving_slice, remaining, - &call->receiving_slice_ready)) { - gpr_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, - call->receiving_slice); - } else { - return; - } - } -} - -static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, - bool success) { - batch_control *bctl = bctlp; - grpc_call *call = bctl->call; - - if (success) { - gpr_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, - call->receiving_slice); - continue_receiving_slices(exec_ctx, bctl); - } else { - grpc_byte_stream_destroy(exec_ctx, call->receiving_stream); - call->receiving_stream = NULL; - grpc_byte_buffer_destroy(*call->receiving_buffer); - *call->receiving_buffer = NULL; - if (gpr_unref(&bctl->steps_to_complete)) { - post_batch_completion(exec_ctx, bctl); - } - } -} - -static void process_data_after_md(grpc_exec_ctx *exec_ctx, batch_control *bctl, - bool success) { - grpc_call *call = bctl->call; - if (call->receiving_stream == NULL) { - *call->receiving_buffer = NULL; - call->receiving_message = 0; - if (gpr_unref(&bctl->steps_to_complete)) { - post_batch_completion(exec_ctx, bctl); - } - } else if (call->receiving_stream->length > - grpc_channel_get_max_message_length(call->channel)) { - cancel_with_status(exec_ctx, call, GRPC_STATUS_INTERNAL, - "Max message size exceeded"); - grpc_byte_stream_destroy(exec_ctx, call->receiving_stream); - call->receiving_stream = NULL; - *call->receiving_buffer = NULL; - call->receiving_message = 0; - if (gpr_unref(&bctl->steps_to_complete)) { - post_batch_completion(exec_ctx, bctl); - } - } else { - call->test_only_last_message_flags = call->receiving_stream->flags; - if ((call->receiving_stream->flags & GRPC_WRITE_INTERNAL_COMPRESS) && - (call->compression_algorithm > GRPC_COMPRESS_NONE)) { - *call->receiving_buffer = grpc_raw_compressed_byte_buffer_create( - NULL, 0, call->compression_algorithm); - } else { - *call->receiving_buffer = grpc_raw_byte_buffer_create(NULL, 0); - } - grpc_closure_init(&call->receiving_slice_ready, receiving_slice_ready, - bctl); - continue_receiving_slices(exec_ctx, bctl); - /* early out */ - return; - } -} - -static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp, - bool success) { - batch_control *bctl = bctlp; - grpc_call *call = bctl->call; - - gpr_mu_lock(&bctl->call->mu); - if (bctl->call->has_initial_md_been_received) { - gpr_mu_unlock(&bctl->call->mu); - process_data_after_md(exec_ctx, bctlp, success); - } else { - call->saved_receiving_stream_ready_ctx.bctlp = bctlp; - call->saved_receiving_stream_ready_ctx.success = success; - gpr_mu_unlock(&bctl->call->mu); - } -} - -static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx, - void *bctlp, bool success) { - batch_control *bctl = bctlp; - grpc_call *call = bctl->call; - - gpr_mu_lock(&call->mu); - - grpc_metadata_batch *md = - &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */]; - grpc_metadata_batch_filter(md, recv_initial_filter, call); - call->has_initial_md_been_received = true; - - if (gpr_time_cmp(md->deadline, gpr_inf_future(md->deadline.clock_type)) != - 0 && - !call->is_client) { - GPR_TIMER_BEGIN("set_deadline_alarm", 0); - set_deadline_alarm(exec_ctx, call, md->deadline); - GPR_TIMER_END("set_deadline_alarm", 0); - } - - if (call->saved_receiving_stream_ready_ctx.bctlp != NULL) { - grpc_closure *saved_rsr_closure = grpc_closure_create( - receiving_stream_ready, call->saved_receiving_stream_ready_ctx.bctlp); - grpc_exec_ctx_enqueue(exec_ctx, saved_rsr_closure, - call->saved_receiving_stream_ready_ctx.success, NULL); - call->saved_receiving_stream_ready_ctx.bctlp = NULL; - } - - gpr_mu_unlock(&call->mu); - - if (gpr_unref(&bctl->steps_to_complete)) { - post_batch_completion(exec_ctx, bctl); - } -} - -static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, bool success) { - batch_control *bctl = bctlp; - grpc_call *call = bctl->call; - grpc_call *child_call; - grpc_call *next_child_call; - - gpr_mu_lock(&call->mu); - if (bctl->send_initial_metadata) { - grpc_metadata_batch_destroy( - &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]); - } - if (bctl->send_message) { - call->sending_message = 0; - } - if (bctl->send_final_op) { - grpc_metadata_batch_destroy( - &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]); - } - if (bctl->recv_final_op) { - grpc_metadata_batch *md = - &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; - grpc_metadata_batch_filter(md, recv_trailing_filter, call); - - if (call->have_alarm) { - grpc_timer_cancel(exec_ctx, &call->alarm); - } - /* propagate cancellation to any interested children */ - child_call = call->first_child; - if (child_call != NULL) { - do { - next_child_call = child_call->sibling_next; - if (child_call->cancellation_is_inherited) { - GRPC_CALL_INTERNAL_REF(child_call, "propagate_cancel"); - grpc_call_cancel(child_call, NULL); - GRPC_CALL_INTERNAL_UNREF(exec_ctx, child_call, "propagate_cancel"); - } - child_call = next_child_call; - } while (child_call != call->first_child); - } - - if (call->is_client) { - get_final_status(call, set_status_value_directly, - call->final_op.client.status); - get_final_details(call, call->final_op.client.status_details, - call->final_op.client.status_details_capacity); - } else { - get_final_status(call, set_cancelled_value, - call->final_op.server.cancelled); - } - - success = 1; - } - bctl->success = success != 0; - gpr_mu_unlock(&call->mu); - if (gpr_unref(&bctl->steps_to_complete)) { - post_batch_completion(exec_ctx, bctl); - } -} - -static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, - grpc_call *call, const grpc_op *ops, - size_t nops, void *notify_tag, - int is_notify_tag_closure) { - grpc_transport_stream_op stream_op; - size_t i; - const grpc_op *op; - batch_control *bctl; - int num_completion_callbacks_needed = 1; - grpc_call_error error = GRPC_CALL_OK; - - GPR_TIMER_BEGIN("grpc_call_start_batch", 0); - - GRPC_CALL_LOG_BATCH(GPR_INFO, call, ops, nops, notify_tag); - - memset(&stream_op, 0, sizeof(stream_op)); - - /* TODO(ctiller): this feels like it could be made lock-free */ - gpr_mu_lock(&call->mu); - bctl = allocate_batch_control(call); - memset(bctl, 0, sizeof(*bctl)); - bctl->call = call; - bctl->notify_tag = notify_tag; - bctl->is_notify_tag_closure = (uint8_t)(is_notify_tag_closure != 0); - - if (nops == 0) { - GRPC_CALL_INTERNAL_REF(call, "completion"); - bctl->success = 1; - if (!is_notify_tag_closure) { - grpc_cq_begin_op(call->cq, notify_tag); - } - gpr_mu_unlock(&call->mu); - post_batch_completion(exec_ctx, bctl); - error = GRPC_CALL_OK; - goto done; - } - - /* rewrite batch ops into a transport op */ - for (i = 0; i < nops; i++) { - op = &ops[i]; - if (op->reserved != NULL) { - error = GRPC_CALL_ERROR; - goto done_with_error; - } - switch (op->op) { - case GRPC_OP_SEND_INITIAL_METADATA: - /* Flag validation: currently allow no flags */ - if (op->flags != 0) { - error = GRPC_CALL_ERROR_INVALID_FLAGS; - goto done_with_error; - } - if (call->sent_initial_metadata) { - error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; - goto done_with_error; - } - if (op->data.send_initial_metadata.count > INT_MAX) { - error = GRPC_CALL_ERROR_INVALID_METADATA; - goto done_with_error; - } - bctl->send_initial_metadata = 1; - call->sent_initial_metadata = 1; - if (!prepare_application_metadata( - call, (int)op->data.send_initial_metadata.count, - op->data.send_initial_metadata.metadata, 0, call->is_client)) { - error = GRPC_CALL_ERROR_INVALID_METADATA; - goto done_with_error; - } - /* TODO(ctiller): just make these the same variable? */ - call->metadata_batch[0][0].deadline = call->send_deadline; - stream_op.send_initial_metadata = - &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]; - break; - case GRPC_OP_SEND_MESSAGE: - if (!are_write_flags_valid(op->flags)) { - error = GRPC_CALL_ERROR_INVALID_FLAGS; - goto done_with_error; - } - if (op->data.send_message == NULL) { - error = GRPC_CALL_ERROR_INVALID_MESSAGE; - goto done_with_error; - } - if (call->sending_message) { - error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; - goto done_with_error; - } - bctl->send_message = 1; - call->sending_message = 1; - grpc_slice_buffer_stream_init( - &call->sending_stream, - &op->data.send_message->data.raw.slice_buffer, op->flags); - stream_op.send_message = &call->sending_stream.base; - break; - case GRPC_OP_SEND_CLOSE_FROM_CLIENT: - /* Flag validation: currently allow no flags */ - if (op->flags != 0) { - error = GRPC_CALL_ERROR_INVALID_FLAGS; - goto done_with_error; - } - if (!call->is_client) { - error = GRPC_CALL_ERROR_NOT_ON_SERVER; - goto done_with_error; - } - if (call->sent_final_op) { - error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; - goto done_with_error; - } - bctl->send_final_op = 1; - call->sent_final_op = 1; - stream_op.send_trailing_metadata = - &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]; - break; - case GRPC_OP_SEND_STATUS_FROM_SERVER: - /* Flag validation: currently allow no flags */ - if (op->flags != 0) { - error = GRPC_CALL_ERROR_INVALID_FLAGS; - goto done_with_error; - } - if (call->is_client) { - error = GRPC_CALL_ERROR_NOT_ON_CLIENT; - goto done_with_error; - } - if (call->sent_final_op) { - error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; - goto done_with_error; - } - if (op->data.send_status_from_server.trailing_metadata_count > - INT_MAX) { - error = GRPC_CALL_ERROR_INVALID_METADATA; - goto done_with_error; - } - bctl->send_final_op = 1; - call->sent_final_op = 1; - call->send_extra_metadata_count = 1; - call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem( - call->channel, op->data.send_status_from_server.status); - if (op->data.send_status_from_server.status_details != NULL) { - call->send_extra_metadata[1].md = grpc_mdelem_from_metadata_strings( - GRPC_MDSTR_GRPC_MESSAGE, - grpc_mdstr_from_string( - op->data.send_status_from_server.status_details)); - call->send_extra_metadata_count++; - set_status_details( - call, STATUS_FROM_API_OVERRIDE, - GRPC_MDSTR_REF(call->send_extra_metadata[1].md->value)); - } - set_status_code(call, STATUS_FROM_API_OVERRIDE, - (uint32_t)op->data.send_status_from_server.status); - if (!prepare_application_metadata( - call, - (int)op->data.send_status_from_server.trailing_metadata_count, - op->data.send_status_from_server.trailing_metadata, 1, 1)) { - error = GRPC_CALL_ERROR_INVALID_METADATA; - goto done_with_error; - } - stream_op.send_trailing_metadata = - &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]; - break; - case GRPC_OP_RECV_INITIAL_METADATA: - /* Flag validation: currently allow no flags */ - if (op->flags != 0) { - error = GRPC_CALL_ERROR_INVALID_FLAGS; - goto done_with_error; - } - if (call->received_initial_metadata) { - error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; - goto done_with_error; - } - call->received_initial_metadata = 1; - call->buffered_metadata[0] = op->data.recv_initial_metadata; - grpc_closure_init(&call->receiving_initial_metadata_ready, - receiving_initial_metadata_ready, bctl); - bctl->recv_initial_metadata = 1; - stream_op.recv_initial_metadata = - &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */]; - stream_op.recv_initial_metadata_ready = - &call->receiving_initial_metadata_ready; - num_completion_callbacks_needed++; - break; - case GRPC_OP_RECV_MESSAGE: - /* Flag validation: currently allow no flags */ - if (op->flags != 0) { - error = GRPC_CALL_ERROR_INVALID_FLAGS; - goto done_with_error; - } - if (call->receiving_message) { - error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; - goto done_with_error; - } - call->receiving_message = 1; - bctl->recv_message = 1; - call->receiving_buffer = op->data.recv_message; - stream_op.recv_message = &call->receiving_stream; - grpc_closure_init(&call->receiving_stream_ready, receiving_stream_ready, - bctl); - stream_op.recv_message_ready = &call->receiving_stream_ready; - num_completion_callbacks_needed++; - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - /* Flag validation: currently allow no flags */ - if (op->flags != 0) { - error = GRPC_CALL_ERROR_INVALID_FLAGS; - goto done_with_error; - } - if (!call->is_client) { - error = GRPC_CALL_ERROR_NOT_ON_SERVER; - goto done_with_error; - } - if (call->received_final_op) { - error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; - goto done_with_error; - } - call->received_final_op = 1; - call->buffered_metadata[1] = - op->data.recv_status_on_client.trailing_metadata; - call->final_op.client.status = op->data.recv_status_on_client.status; - call->final_op.client.status_details = - op->data.recv_status_on_client.status_details; - call->final_op.client.status_details_capacity = - op->data.recv_status_on_client.status_details_capacity; - bctl->recv_final_op = 1; - stream_op.recv_trailing_metadata = - &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; - break; - case GRPC_OP_RECV_CLOSE_ON_SERVER: - /* Flag validation: currently allow no flags */ - if (op->flags != 0) { - error = GRPC_CALL_ERROR_INVALID_FLAGS; - goto done_with_error; - } - if (call->is_client) { - error = GRPC_CALL_ERROR_NOT_ON_CLIENT; - goto done_with_error; - } - if (call->received_final_op) { - error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; - goto done_with_error; - } - call->received_final_op = 1; - call->final_op.server.cancelled = - op->data.recv_close_on_server.cancelled; - bctl->recv_final_op = 1; - stream_op.recv_trailing_metadata = - &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; - break; - } - } - - GRPC_CALL_INTERNAL_REF(call, "completion"); - if (!is_notify_tag_closure) { - grpc_cq_begin_op(call->cq, notify_tag); - } - gpr_ref_init(&bctl->steps_to_complete, num_completion_callbacks_needed); - - stream_op.context = call->context; - grpc_closure_init(&bctl->finish_batch, finish_batch, bctl); - stream_op.on_complete = &bctl->finish_batch; - gpr_mu_unlock(&call->mu); - - execute_op(exec_ctx, call, &stream_op); - -done: - GPR_TIMER_END("grpc_call_start_batch", 0); - return error; - -done_with_error: - /* reverse any mutations that occured */ - if (bctl->send_initial_metadata) { - call->sent_initial_metadata = 0; - grpc_metadata_batch_clear(&call->metadata_batch[0][0]); - } - if (bctl->send_message) { - call->sending_message = 0; - grpc_byte_stream_destroy(exec_ctx, &call->sending_stream.base); - } - if (bctl->send_final_op) { - call->sent_final_op = 0; - grpc_metadata_batch_clear(&call->metadata_batch[0][1]); - } - if (bctl->recv_initial_metadata) { - call->received_initial_metadata = 0; - } - if (bctl->recv_message) { - call->receiving_message = 0; - } - if (bctl->recv_final_op) { - call->received_final_op = 0; - } - gpr_mu_unlock(&call->mu); - goto done; -} - -grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops, - size_t nops, void *tag, void *reserved) { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_call_error err; - - GRPC_API_TRACE( - "grpc_call_start_batch(call=%p, ops=%p, nops=%lu, tag=%p, reserved=%p)", - 5, (call, ops, (unsigned long)nops, tag, reserved)); - - if (reserved != NULL) { - err = GRPC_CALL_ERROR; - } else { - err = call_start_batch(&exec_ctx, call, ops, nops, tag, 0); - } - - grpc_exec_ctx_finish(&exec_ctx); - return err; -} - -grpc_call_error grpc_call_start_batch_and_execute(grpc_exec_ctx *exec_ctx, - grpc_call *call, - const grpc_op *ops, - size_t nops, - grpc_closure *closure) { - return call_start_batch(exec_ctx, call, ops, nops, closure, 1); -} - -void grpc_call_context_set(grpc_call *call, grpc_context_index elem, - void *value, void (*destroy)(void *value)) { - if (call->context[elem].destroy) { - call->context[elem].destroy(call->context[elem].value); - } - call->context[elem].value = value; - call->context[elem].destroy = destroy; -} - -void *grpc_call_context_get(grpc_call *call, grpc_context_index elem) { - return call->context[elem].value; -} - -uint8_t grpc_call_is_client(grpc_call *call) { return call->is_client; } - -grpc_compression_algorithm grpc_call_compression_for_level( - grpc_call *call, grpc_compression_level level) { - gpr_mu_lock(&call->mu); - const uint32_t accepted_encodings = call->encodings_accepted_by_peer; - gpr_mu_unlock(&call->mu); - return grpc_compression_algorithm_for_level(level, accepted_encodings); -} diff --git a/src/core/surface/call.h b/src/core/surface/call.h deleted file mode 100644 index d2edf03d45..0000000000 --- a/src/core/surface/call.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * - * Copyright 2015-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_SURFACE_CALL_H -#define GRPC_CORE_SURFACE_CALL_H - -#include "src/core/channel/channel_stack.h" -#include "src/core/channel/context.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/surface_trace.h" - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*grpc_ioreq_completion_func)(grpc_exec_ctx *exec_ctx, - grpc_call *call, int success, - void *user_data); - -grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call, - uint32_t propagation_mask, - grpc_completion_queue *cq, - const void *server_transport_data, - grpc_mdelem **add_initial_metadata, - size_t add_initial_metadata_count, - gpr_timespec send_deadline); - -void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call, - grpc_completion_queue *cq); - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -void grpc_call_internal_ref(grpc_call *call, const char *reason); -void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *call, - const char *reason); -#define GRPC_CALL_INTERNAL_REF(call, reason) \ - grpc_call_internal_ref(call, reason) -#define GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, reason) \ - grpc_call_internal_unref(exec_ctx, call, reason) -#else -void grpc_call_internal_ref(grpc_call *call); -void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *call); -#define GRPC_CALL_INTERNAL_REF(call, reason) grpc_call_internal_ref(call) -#define GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, reason) \ - grpc_call_internal_unref(exec_ctx, call) -#endif - -grpc_call_stack *grpc_call_get_call_stack(grpc_call *call); - -grpc_call_error grpc_call_start_batch_and_execute(grpc_exec_ctx *exec_ctx, - grpc_call *call, - const grpc_op *ops, - size_t nops, - grpc_closure *closure); - -/* Given the top call_element, get the call object. */ -grpc_call *grpc_call_from_top_element(grpc_call_element *surface_element); - -void grpc_call_log_batch(char *file, int line, gpr_log_severity severity, - grpc_call *call, const grpc_op *ops, size_t nops, - void *tag); - -/* Set a context pointer. - No thread safety guarantees are made wrt this value. */ -void grpc_call_context_set(grpc_call *call, grpc_context_index elem, - void *value, void (*destroy)(void *value)); -/* Get a context pointer. */ -void *grpc_call_context_get(grpc_call *call, grpc_context_index elem); - -#define GRPC_CALL_LOG_BATCH(sev, call, ops, nops, tag) \ - if (grpc_api_trace) grpc_call_log_batch(sev, call, ops, nops, tag) - -uint8_t grpc_call_is_client(grpc_call *call); - -/* Return an appropriate compression algorithm for the requested compression \a - * level in the context of \a call. */ -grpc_compression_algorithm grpc_call_compression_for_level( - grpc_call *call, grpc_compression_level level); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_SURFACE_CALL_H */ diff --git a/src/core/surface/call_details.c b/src/core/surface/call_details.c deleted file mode 100644 index 60f0029819..0000000000 --- a/src/core/surface/call_details.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright 2015, 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 -#include - -#include - -#include "src/core/surface/api_trace.h" - -void grpc_call_details_init(grpc_call_details* cd) { - GRPC_API_TRACE("grpc_call_details_init(cd=%p)", 1, (cd)); - memset(cd, 0, sizeof(*cd)); -} - -void grpc_call_details_destroy(grpc_call_details* cd) { - GRPC_API_TRACE("grpc_call_details_destroy(cd=%p)", 1, (cd)); - gpr_free(cd->method); - gpr_free(cd->host); -} diff --git a/src/core/surface/call_log_batch.c b/src/core/surface/call_log_batch.c deleted file mode 100644 index 044211616c..0000000000 --- a/src/core/surface/call_log_batch.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * - * Copyright 2015-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/surface/call.h" - -#include -#include -#include "src/core/support/string.h" - -static void add_metadata(gpr_strvec *b, const grpc_metadata *md, size_t count) { - size_t i; - for (i = 0; i < count; i++) { - gpr_strvec_add(b, gpr_strdup("\nkey=")); - gpr_strvec_add(b, gpr_strdup(md[i].key)); - - gpr_strvec_add(b, gpr_strdup(" value=")); - gpr_strvec_add(b, gpr_dump(md[i].value, md[i].value_length, - GPR_DUMP_HEX | GPR_DUMP_ASCII)); - } -} - -char *grpc_op_string(const grpc_op *op) { - char *tmp; - char *out; - - gpr_strvec b; - gpr_strvec_init(&b); - - switch (op->op) { - case GRPC_OP_SEND_INITIAL_METADATA: - gpr_strvec_add(&b, gpr_strdup("SEND_INITIAL_METADATA")); - add_metadata(&b, op->data.send_initial_metadata.metadata, - op->data.send_initial_metadata.count); - break; - case GRPC_OP_SEND_MESSAGE: - gpr_asprintf(&tmp, "SEND_MESSAGE ptr=%p", op->data.send_message); - gpr_strvec_add(&b, tmp); - break; - case GRPC_OP_SEND_CLOSE_FROM_CLIENT: - gpr_strvec_add(&b, gpr_strdup("SEND_CLOSE_FROM_CLIENT")); - break; - case GRPC_OP_SEND_STATUS_FROM_SERVER: - gpr_asprintf(&tmp, "SEND_STATUS_FROM_SERVER status=%d details=%s", - op->data.send_status_from_server.status, - op->data.send_status_from_server.status_details); - gpr_strvec_add(&b, tmp); - add_metadata(&b, op->data.send_status_from_server.trailing_metadata, - op->data.send_status_from_server.trailing_metadata_count); - break; - case GRPC_OP_RECV_INITIAL_METADATA: - gpr_asprintf(&tmp, "RECV_INITIAL_METADATA ptr=%p", - op->data.recv_initial_metadata); - gpr_strvec_add(&b, tmp); - break; - case GRPC_OP_RECV_MESSAGE: - gpr_asprintf(&tmp, "RECV_MESSAGE ptr=%p", op->data.recv_message); - gpr_strvec_add(&b, tmp); - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - gpr_asprintf(&tmp, - "RECV_STATUS_ON_CLIENT metadata=%p status=%p details=%p", - op->data.recv_status_on_client.trailing_metadata, - op->data.recv_status_on_client.status, - op->data.recv_status_on_client.status_details); - gpr_strvec_add(&b, tmp); - break; - case GRPC_OP_RECV_CLOSE_ON_SERVER: - gpr_asprintf(&tmp, "RECV_CLOSE_ON_SERVER cancelled=%p", - op->data.recv_close_on_server.cancelled); - gpr_strvec_add(&b, tmp); - } - out = gpr_strvec_flatten(&b, NULL); - gpr_strvec_destroy(&b); - - return out; -} - -void grpc_call_log_batch(char *file, int line, gpr_log_severity severity, - grpc_call *call, const grpc_op *ops, size_t nops, - void *tag) { - char *tmp; - size_t i; - for (i = 0; i < nops; i++) { - tmp = grpc_op_string(&ops[i]); - gpr_log(file, line, severity, "ops[%d]: %s", i, tmp); - gpr_free(tmp); - } -} diff --git a/src/core/surface/call_test_only.h b/src/core/surface/call_test_only.h deleted file mode 100644 index fdc43a383b..0000000000 --- a/src/core/surface/call_test_only.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * Copyright 2015-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_SURFACE_CALL_TEST_ONLY_H -#define GRPC_CORE_SURFACE_CALL_TEST_ONLY_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Return the compression algorithm from \a call. - * - * \warning This function should \b only be used in test code. */ -grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm( - grpc_call *call); - -/** Return the message flags from \a call. - * - * \warning This function should \b only be used in test code. */ -uint32_t grpc_call_test_only_get_message_flags(grpc_call *call); - -/** Returns a bitset for the encodings (compression algorithms) supported by \a - * call's peer. - * - * To be indexed by grpc_compression_algorithm enum values. */ -uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_SURFACE_CALL_TEST_ONLY_H */ diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c deleted file mode 100644 index 0010b64c7d..0000000000 --- a/src/core/surface/channel.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * - * Copyright 2015-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/surface/channel.h" - -#include -#include - -#include -#include -#include - -#include "src/core/client_config/resolver_registry.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" -#include "src/core/surface/channel_init.h" -#include "src/core/surface/init.h" -#include "src/core/transport/static_metadata.h" - -/** Cache grpc-status: X mdelems for X = 0..NUM_CACHED_STATUS_ELEMS. - * Avoids needing to take a metadata context lock for sending status - * if the status code is <= NUM_CACHED_STATUS_ELEMS. - * Sized to allow the most commonly used codes to fit in - * (OK, Cancelled, Unknown). */ -#define NUM_CACHED_STATUS_ELEMS 3 - -typedef struct registered_call { - grpc_mdelem *path; - grpc_mdelem *authority; - struct registered_call *next; -} registered_call; - -struct grpc_channel { - int is_client; - uint32_t max_message_length; - grpc_mdelem *default_authority; - - gpr_mu registered_call_mu; - registered_call *registered_calls; - char *target; -}; - -#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c) + 1)) -#define CHANNEL_FROM_CHANNEL_STACK(channel_stack) \ - (((grpc_channel *)(channel_stack)) - 1) -#define CHANNEL_FROM_TOP_ELEM(top_elem) \ - CHANNEL_FROM_CHANNEL_STACK(grpc_channel_stack_from_top_element(top_elem)) - -/* the protobuf library will (by default) start warning at 100megs */ -#define DEFAULT_MAX_MESSAGE_LENGTH (100 * 1024 * 1024) - -static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg, bool success); - -grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, - const grpc_channel_args *args, - grpc_channel_stack_type channel_stack_type, - grpc_transport *optional_transport) { - bool is_client = grpc_channel_stack_type_is_client(channel_stack_type); - - grpc_channel *channel = grpc_channel_init_create_stack( - exec_ctx, channel_stack_type, sizeof(grpc_channel), args, 1, - destroy_channel, NULL, optional_transport); - - memset(channel, 0, sizeof(*channel)); - channel->target = gpr_strdup(target); - channel->is_client = is_client; - gpr_mu_init(&channel->registered_call_mu); - channel->registered_calls = NULL; - - channel->max_message_length = DEFAULT_MAX_MESSAGE_LENGTH; - if (args) { - for (size_t i = 0; i < args->num_args; i++) { - if (0 == strcmp(args->args[i].key, GRPC_ARG_MAX_MESSAGE_LENGTH)) { - if (args->args[i].type != GRPC_ARG_INTEGER) { - gpr_log(GPR_ERROR, "%s ignored: it must be an integer", - GRPC_ARG_MAX_MESSAGE_LENGTH); - } else if (args->args[i].value.integer < 0) { - gpr_log(GPR_ERROR, "%s ignored: it must be >= 0", - GRPC_ARG_MAX_MESSAGE_LENGTH); - } else { - channel->max_message_length = (uint32_t)args->args[i].value.integer; - } - } else if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) { - if (args->args[i].type != GRPC_ARG_STRING) { - gpr_log(GPR_ERROR, "%s ignored: it must be a string", - GRPC_ARG_DEFAULT_AUTHORITY); - } else { - if (channel->default_authority) { - /* setting this takes precedence over anything else */ - GRPC_MDELEM_UNREF(channel->default_authority); - } - channel->default_authority = grpc_mdelem_from_strings( - ":authority", args->args[i].value.string); - } - } else if (0 == - strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) { - if (args->args[i].type != GRPC_ARG_STRING) { - gpr_log(GPR_ERROR, "%s ignored: it must be a string", - GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); - } else { - if (channel->default_authority) { - /* other ways of setting this (notably ssl) take precedence */ - gpr_log(GPR_ERROR, - "%s ignored: default host already set some other way", - GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); - } else { - channel->default_authority = grpc_mdelem_from_strings( - ":authority", args->args[i].value.string); - } - } - } - } - } - - if (channel->is_client && channel->default_authority == NULL && - target != NULL) { - char *default_authority = grpc_get_default_authority(target); - if (default_authority) { - channel->default_authority = - grpc_mdelem_from_strings(":authority", default_authority); - } - gpr_free(default_authority); - } - - return channel; -} - -char *grpc_channel_get_target(grpc_channel *channel) { - GRPC_API_TRACE("grpc_channel_get_target(channel=%p)", 1, (channel)); - return gpr_strdup(channel->target); -} - -static grpc_call *grpc_channel_create_call_internal( - grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, - grpc_completion_queue *cq, grpc_mdelem *path_mdelem, - grpc_mdelem *authority_mdelem, gpr_timespec deadline) { - grpc_mdelem *send_metadata[2]; - size_t num_metadata = 0; - - GPR_ASSERT(channel->is_client); - - send_metadata[num_metadata++] = path_mdelem; - if (authority_mdelem != NULL) { - send_metadata[num_metadata++] = authority_mdelem; - } else if (channel->default_authority != NULL) { - send_metadata[num_metadata++] = GRPC_MDELEM_REF(channel->default_authority); - } - - return grpc_call_create(channel, parent_call, propagation_mask, cq, NULL, - send_metadata, num_metadata, deadline); -} - -grpc_call *grpc_channel_create_call(grpc_channel *channel, - grpc_call *parent_call, - uint32_t propagation_mask, - grpc_completion_queue *cq, - const char *method, const char *host, - gpr_timespec deadline, void *reserved) { - GRPC_API_TRACE( - "grpc_channel_create_call(" - "channel=%p, parent_call=%p, propagation_mask=%x, cq=%p, method=%s, " - "host=%s, " - "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " - "reserved=%p)", - 10, (channel, parent_call, (unsigned)propagation_mask, cq, method, host, - (long long)deadline.tv_sec, (int)deadline.tv_nsec, - (int)deadline.clock_type, reserved)); - GPR_ASSERT(!reserved); - return grpc_channel_create_call_internal( - channel, parent_call, propagation_mask, cq, - grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH, - grpc_mdstr_from_string(method)), - host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY, - grpc_mdstr_from_string(host)) - : NULL, - deadline); -} - -void *grpc_channel_register_call(grpc_channel *channel, const char *method, - const char *host, void *reserved) { - registered_call *rc = gpr_malloc(sizeof(registered_call)); - GRPC_API_TRACE( - "grpc_channel_register_call(channel=%p, method=%s, host=%s, reserved=%p)", - 4, (channel, method, host, reserved)); - GPR_ASSERT(!reserved); - rc->path = grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH, - grpc_mdstr_from_string(method)); - rc->authority = host ? grpc_mdelem_from_metadata_strings( - GRPC_MDSTR_AUTHORITY, grpc_mdstr_from_string(host)) - : NULL; - gpr_mu_lock(&channel->registered_call_mu); - rc->next = channel->registered_calls; - channel->registered_calls = rc; - gpr_mu_unlock(&channel->registered_call_mu); - return rc; -} - -grpc_call *grpc_channel_create_registered_call( - grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, - grpc_completion_queue *completion_queue, void *registered_call_handle, - gpr_timespec deadline, void *reserved) { - registered_call *rc = registered_call_handle; - GRPC_API_TRACE( - "grpc_channel_create_registered_call(" - "channel=%p, parent_call=%p, propagation_mask=%x, completion_queue=%p, " - "registered_call_handle=%p, " - "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " - "reserved=%p)", - 9, (channel, parent_call, (unsigned)propagation_mask, completion_queue, - registered_call_handle, (long long)deadline.tv_sec, - (int)deadline.tv_nsec, (int)deadline.clock_type, reserved)); - GPR_ASSERT(!reserved); - return grpc_channel_create_call_internal( - channel, parent_call, propagation_mask, completion_queue, - GRPC_MDELEM_REF(rc->path), - rc->authority ? GRPC_MDELEM_REF(rc->authority) : NULL, deadline); -} - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -#define REF_REASON reason -#define REF_ARG , const char *reason -#else -#define REF_REASON "" -#define REF_ARG -#endif -void grpc_channel_internal_ref(grpc_channel *c REF_ARG) { - GRPC_CHANNEL_STACK_REF(CHANNEL_STACK_FROM_CHANNEL(c), REF_REASON); -} - -void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, - grpc_channel *c REF_ARG) { - GRPC_CHANNEL_STACK_UNREF(exec_ctx, CHANNEL_STACK_FROM_CHANNEL(c), REF_REASON); -} - -static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_success) { - grpc_channel *channel = arg; - grpc_channel_stack_destroy(exec_ctx, CHANNEL_STACK_FROM_CHANNEL(channel)); - while (channel->registered_calls) { - registered_call *rc = channel->registered_calls; - channel->registered_calls = rc->next; - GRPC_MDELEM_UNREF(rc->path); - if (rc->authority) { - GRPC_MDELEM_UNREF(rc->authority); - } - gpr_free(rc); - } - if (channel->default_authority != NULL) { - GRPC_MDELEM_UNREF(channel->default_authority); - } - gpr_mu_destroy(&channel->registered_call_mu); - gpr_free(channel->target); - gpr_free(channel); -} - -void grpc_channel_destroy(grpc_channel *channel) { - grpc_transport_op op; - grpc_channel_element *elem; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - GRPC_API_TRACE("grpc_channel_destroy(channel=%p)", 1, (channel)); - memset(&op, 0, sizeof(op)); - op.disconnect = 1; - elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CHANNEL(channel), 0); - elem->filter->start_transport_op(&exec_ctx, elem, &op); - - GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, channel, "channel"); - - grpc_exec_ctx_finish(&exec_ctx); -} - -grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel) { - return CHANNEL_STACK_FROM_CHANNEL(channel); -} - -grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) { - char tmp[GPR_LTOA_MIN_BUFSIZE]; - switch (i) { - case 0: - return GRPC_MDELEM_GRPC_STATUS_0; - case 1: - return GRPC_MDELEM_GRPC_STATUS_1; - case 2: - return GRPC_MDELEM_GRPC_STATUS_2; - } - gpr_ltoa(i, tmp); - return grpc_mdelem_from_metadata_strings(GRPC_MDSTR_GRPC_STATUS, - grpc_mdstr_from_string(tmp)); -} - -uint32_t grpc_channel_get_max_message_length(grpc_channel *channel) { - return channel->max_message_length; -} diff --git a/src/core/surface/channel.h b/src/core/surface/channel.h deleted file mode 100644 index 6a803ffe23..0000000000 --- a/src/core/surface/channel.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Copyright 2015-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_SURFACE_CHANNEL_H -#define GRPC_CORE_SURFACE_CHANNEL_H - -#include "src/core/channel/channel_stack.h" -#include "src/core/client_config/subchannel_factory.h" -#include "src/core/surface/channel_stack_type.h" - -grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, - const grpc_channel_args *args, - grpc_channel_stack_type channel_stack_type, - grpc_transport *optional_transport); - -/** Get a (borrowed) pointer to this channels underlying channel stack */ -grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel); - -/** Get a grpc_mdelem of grpc-status: X where X is the numeric value of - status_code. - - The returned elem is owned by the caller. */ -grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, - int status_code); -uint32_t grpc_channel_get_max_message_length(grpc_channel *channel); - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -void grpc_channel_internal_ref(grpc_channel *channel, const char *reason); -void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, grpc_channel *channel, - const char *reason); -#define GRPC_CHANNEL_INTERNAL_REF(channel, reason) \ - grpc_channel_internal_ref(channel, reason) -#define GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, reason) \ - grpc_channel_internal_unref(exec_ctx, channel, reason) -#else -void grpc_channel_internal_ref(grpc_channel *channel); -void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, - grpc_channel *channel); -#define GRPC_CHANNEL_INTERNAL_REF(channel, reason) \ - grpc_channel_internal_ref(channel) -#define GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, reason) \ - grpc_channel_internal_unref(exec_ctx, channel) -#endif - -#endif /* GRPC_CORE_SURFACE_CHANNEL_H */ diff --git a/src/core/surface/channel_connectivity.c b/src/core/surface/channel_connectivity.c deleted file mode 100644 index 18267939ed..0000000000 --- a/src/core/surface/channel_connectivity.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * - * Copyright 2015-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/surface/channel.h" - -#include -#include - -#include "src/core/channel/client_channel.h" -#include "src/core/iomgr/timer.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/completion_queue.h" - -grpc_connectivity_state grpc_channel_check_connectivity_state( - grpc_channel *channel, int try_to_connect) { - /* forward through to the underlying client channel */ - grpc_channel_element *client_channel_elem = - grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_connectivity_state state; - GRPC_API_TRACE( - "grpc_channel_check_connectivity_state(channel=%p, try_to_connect=%d)", 2, - (channel, try_to_connect)); - if (client_channel_elem->filter == &grpc_client_channel_filter) { - state = grpc_client_channel_check_connectivity_state( - &exec_ctx, client_channel_elem, try_to_connect); - grpc_exec_ctx_finish(&exec_ctx); - return state; - } - gpr_log(GPR_ERROR, - "grpc_channel_check_connectivity_state called on something that is " - "not a (u)client channel, but '%s'", - client_channel_elem->filter->name); - grpc_exec_ctx_finish(&exec_ctx); - return GRPC_CHANNEL_FATAL_FAILURE; -} - -typedef enum { - WAITING, - CALLING_BACK, - CALLING_BACK_AND_FINISHED, - CALLED_BACK -} callback_phase; - -typedef struct { - gpr_mu mu; - callback_phase phase; - int success; - grpc_closure on_complete; - grpc_timer alarm; - grpc_connectivity_state state; - grpc_completion_queue *cq; - grpc_cq_completion completion_storage; - grpc_channel *channel; - void *tag; -} state_watcher; - -static void delete_state_watcher(grpc_exec_ctx *exec_ctx, state_watcher *w) { - grpc_channel_element *client_channel_elem = grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(w->channel)); - if (client_channel_elem->filter == &grpc_client_channel_filter) { - GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, w->channel, - "watch_channel_connectivity"); - } else { - abort(); - } - gpr_mu_destroy(&w->mu); - gpr_free(w); -} - -static void finished_completion(grpc_exec_ctx *exec_ctx, void *pw, - grpc_cq_completion *ignored) { - int delete = 0; - state_watcher *w = pw; - gpr_mu_lock(&w->mu); - switch (w->phase) { - case WAITING: - case CALLED_BACK: - GPR_UNREACHABLE_CODE(return ); - case CALLING_BACK: - w->phase = CALLED_BACK; - break; - case CALLING_BACK_AND_FINISHED: - delete = 1; - break; - } - gpr_mu_unlock(&w->mu); - - if (delete) { - delete_state_watcher(exec_ctx, w); - } -} - -static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w, - int due_to_completion) { - int delete = 0; - - if (due_to_completion) { - grpc_timer_cancel(exec_ctx, &w->alarm); - } - - gpr_mu_lock(&w->mu); - if (due_to_completion) { - w->success = 1; - } - switch (w->phase) { - case WAITING: - w->phase = CALLING_BACK; - grpc_cq_end_op(exec_ctx, w->cq, w->tag, w->success, finished_completion, - w, &w->completion_storage); - break; - case CALLING_BACK: - w->phase = CALLING_BACK_AND_FINISHED; - break; - case CALLING_BACK_AND_FINISHED: - GPR_UNREACHABLE_CODE(return ); - case CALLED_BACK: - delete = 1; - break; - } - gpr_mu_unlock(&w->mu); - - if (delete) { - delete_state_watcher(exec_ctx, w); - } -} - -static void watch_complete(grpc_exec_ctx *exec_ctx, void *pw, bool success) { - partly_done(exec_ctx, pw, 1); -} - -static void timeout_complete(grpc_exec_ctx *exec_ctx, void *pw, bool success) { - partly_done(exec_ctx, pw, 0); -} - -void grpc_channel_watch_connectivity_state( - grpc_channel *channel, grpc_connectivity_state last_observed_state, - gpr_timespec deadline, grpc_completion_queue *cq, void *tag) { - grpc_channel_element *client_channel_elem = - grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - state_watcher *w = gpr_malloc(sizeof(*w)); - - GRPC_API_TRACE( - "grpc_channel_watch_connectivity_state(" - "channel=%p, last_observed_state=%d, " - "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " - "cq=%p, tag=%p)", - 7, (channel, (int)last_observed_state, (long long)deadline.tv_sec, - (int)deadline.tv_nsec, (int)deadline.clock_type, cq, tag)); - - grpc_cq_begin_op(cq, tag); - - gpr_mu_init(&w->mu); - grpc_closure_init(&w->on_complete, watch_complete, w); - w->phase = WAITING; - w->state = last_observed_state; - w->success = 0; - w->cq = cq; - w->tag = tag; - w->channel = channel; - - grpc_timer_init(&exec_ctx, &w->alarm, - gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC), - timeout_complete, w, gpr_now(GPR_CLOCK_MONOTONIC)); - - if (client_channel_elem->filter == &grpc_client_channel_filter) { - GRPC_CHANNEL_INTERNAL_REF(channel, "watch_channel_connectivity"); - grpc_client_channel_watch_connectivity_state(&exec_ctx, client_channel_elem, - grpc_cq_pollset(cq), &w->state, - &w->on_complete); - } else { - abort(); - } - - grpc_exec_ctx_finish(&exec_ctx); -} diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c deleted file mode 100644 index 123447c8ed..0000000000 --- a/src/core/surface/channel_create.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include -#include - -#include -#include -#include - -#include "src/core/census/grpc_filter.h" -#include "src/core/channel/channel_args.h" -#include "src/core/channel/client_channel.h" -#include "src/core/channel/compress_filter.h" -#include "src/core/channel/http_client_filter.h" -#include "src/core/client_config/resolver_registry.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/channel.h" -#include "src/core/transport/chttp2_transport.h" - -typedef struct { - grpc_connector base; - gpr_refcount refs; - - grpc_closure *notify; - grpc_connect_in_args args; - grpc_connect_out_args *result; - grpc_closure initial_string_sent; - gpr_slice_buffer initial_string_buffer; - - grpc_endpoint *tcp; - - grpc_closure connected; -} connector; - -static void connector_ref(grpc_connector *con) { - connector *c = (connector *)con; - gpr_ref(&c->refs); -} - -static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { - connector *c = (connector *)con; - if (gpr_unref(&c->refs)) { - /* c->initial_string_buffer does not need to be destroyed */ - gpr_free(c); - } -} - -static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, - bool success) { - connector_unref(exec_ctx, arg); -} - -static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - connector *c = arg; - grpc_closure *notify; - grpc_endpoint *tcp = c->tcp; - if (tcp != NULL) { - if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) { - grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent, - c); - gpr_slice_buffer_init(&c->initial_string_buffer); - gpr_slice_buffer_add(&c->initial_string_buffer, - c->args.initial_connect_string); - connector_ref(arg); - grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, - &c->initial_string_sent); - } - c->result->transport = - grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, tcp, 1); - grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, - 0); - GPR_ASSERT(c->result->transport); - c->result->channel_args = c->args.channel_args; - } else { - memset(c->result, 0, sizeof(*c->result)); - } - notify = c->notify; - c->notify = NULL; - notify->cb(exec_ctx, notify->cb_arg, 1); -} - -static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) {} - -static void connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *con, - const grpc_connect_in_args *args, - grpc_connect_out_args *result, - grpc_closure *notify) { - connector *c = (connector *)con; - GPR_ASSERT(c->notify == NULL); - GPR_ASSERT(notify->cb); - c->notify = notify; - c->args = *args; - c->result = result; - c->tcp = NULL; - grpc_closure_init(&c->connected, connected, c); - grpc_tcp_client_connect(exec_ctx, &c->connected, &c->tcp, - args->interested_parties, args->addr, args->addr_len, - args->deadline); -} - -static const grpc_connector_vtable connector_vtable = { - connector_ref, connector_unref, connector_shutdown, connector_connect}; - -typedef struct { - grpc_subchannel_factory base; - gpr_refcount refs; - grpc_channel_args *merge_args; - grpc_channel *master; -} subchannel_factory; - -static void subchannel_factory_ref(grpc_subchannel_factory *scf) { - subchannel_factory *f = (subchannel_factory *)scf; - gpr_ref(&f->refs); -} - -static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx, - grpc_subchannel_factory *scf) { - subchannel_factory *f = (subchannel_factory *)scf; - if (gpr_unref(&f->refs)) { - GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory"); - grpc_channel_args_destroy(f->merge_args); - gpr_free(f); - } -} - -static grpc_subchannel *subchannel_factory_create_subchannel( - grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *scf, - grpc_subchannel_args *args) { - subchannel_factory *f = (subchannel_factory *)scf; - connector *c = gpr_malloc(sizeof(*c)); - grpc_channel_args *final_args = - grpc_channel_args_merge(args->args, f->merge_args); - grpc_subchannel *s; - memset(c, 0, sizeof(*c)); - c->base.vtable = &connector_vtable; - gpr_ref_init(&c->refs, 1); - args->args = final_args; - s = grpc_subchannel_create(exec_ctx, &c->base, args); - grpc_connector_unref(exec_ctx, &c->base); - grpc_channel_args_destroy(final_args); - return s; -} - -static const grpc_subchannel_factory_vtable subchannel_factory_vtable = { - subchannel_factory_ref, subchannel_factory_unref, - subchannel_factory_create_subchannel}; - -/* Create a client channel: - Asynchronously: - resolve target - - connect to it (trying alternatives as presented) - - perform handshakes */ -grpc_channel *grpc_insecure_channel_create(const char *target, - const grpc_channel_args *args, - void *reserved) { - grpc_channel *channel = NULL; - grpc_resolver *resolver; - subchannel_factory *f; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - GRPC_API_TRACE( - "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3, - (target, args, reserved)); - GPR_ASSERT(!reserved); - - channel = - grpc_channel_create(&exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL); - - f = gpr_malloc(sizeof(*f)); - f->base.vtable = &subchannel_factory_vtable; - gpr_ref_init(&f->refs, 1); - f->merge_args = grpc_channel_args_copy(args); - f->master = channel; - GRPC_CHANNEL_INTERNAL_REF(f->master, "subchannel_factory"); - resolver = grpc_resolver_create(target, &f->base); - if (!resolver) { - GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, f->master, "subchannel_factory"); - grpc_subchannel_factory_unref(&exec_ctx, &f->base); - grpc_exec_ctx_finish(&exec_ctx); - return NULL; - } - - grpc_client_channel_set_resolver( - &exec_ctx, grpc_channel_get_channel_stack(channel), resolver); - GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create"); - grpc_subchannel_factory_unref(&exec_ctx, &f->base); - - grpc_exec_ctx_finish(&exec_ctx); - - return channel; -} diff --git a/src/core/surface/channel_init.c b/src/core/surface/channel_init.c deleted file mode 100644 index ac962f3972..0000000000 --- a/src/core/surface/channel_init.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * - * 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/surface/channel_init.h" - -#include -#include - -typedef struct stage_slot { - grpc_channel_init_stage fn; - void *arg; - int priority; - size_t insertion_order; -} stage_slot; - -typedef struct stage_slots { - stage_slot *slots; - size_t num_slots; - size_t cap_slots; -} stage_slots; - -static stage_slots g_slots[GRPC_NUM_CHANNEL_STACK_TYPES]; -static bool g_finalized; - -void grpc_channel_init_init(void) { - for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) { - g_slots[i].slots = NULL; - g_slots[i].num_slots = 0; - g_slots[i].cap_slots = 0; - } - g_finalized = false; -} - -void grpc_channel_init_register_stage(grpc_channel_stack_type type, - int priority, - grpc_channel_init_stage stage, - void *stage_arg) { - GPR_ASSERT(!g_finalized); - if (g_slots[type].cap_slots == g_slots[type].num_slots) { - g_slots[type].cap_slots = GPR_MAX(8, 3 * g_slots[type].cap_slots / 2); - g_slots[type].slots = - gpr_realloc(g_slots[type].slots, - g_slots[type].cap_slots * sizeof(*g_slots[type].slots)); - } - stage_slot *s = &g_slots[type].slots[g_slots[type].num_slots++]; - s->insertion_order = g_slots[type].num_slots; - s->priority = priority; - s->fn = stage; - s->arg = stage_arg; -} - -static int compare_slots(const void *a, const void *b) { - const stage_slot *sa = a; - const stage_slot *sb = b; - - int c = GPR_ICMP(sa->priority, sb->priority); - if (c != 0) return c; - return GPR_ICMP(sa->insertion_order, sb->insertion_order); -} - -void grpc_channel_init_finalize(void) { - GPR_ASSERT(!g_finalized); - for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) { - qsort(g_slots[i].slots, g_slots[i].num_slots, sizeof(*g_slots[i].slots), - compare_slots); - } - g_finalized = true; -} - -void grpc_channel_init_shutdown(void) { - for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) { - gpr_free(g_slots[i].slots); - g_slots[i].slots = (void *)(uintptr_t)0xdeadbeef; - } -} - -static const char *name_for_type(grpc_channel_stack_type type) { - switch (type) { - case GRPC_CLIENT_CHANNEL: - return "CLIENT_CHANNEL"; - case GRPC_CLIENT_SUBCHANNEL: - return "CLIENT_SUBCHANNEL"; - case GRPC_SERVER_CHANNEL: - return "SERVER_CHANNEL"; - case GRPC_CLIENT_LAME_CHANNEL: - return "CLIENT_LAME_CHANNEL"; - case GRPC_CLIENT_DIRECT_CHANNEL: - return "CLIENT_DIRECT_CHANNEL"; - case GRPC_NUM_CHANNEL_STACK_TYPES: - break; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -void *grpc_channel_init_create_stack( - grpc_exec_ctx *exec_ctx, grpc_channel_stack_type type, size_t prefix_bytes, - const grpc_channel_args *args, int initial_refs, grpc_iomgr_cb_func destroy, - void *destroy_arg, grpc_transport *transport) { - GPR_ASSERT(g_finalized); - - grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create(); - grpc_channel_stack_builder_set_name(builder, name_for_type(type)); - grpc_channel_stack_builder_set_channel_arguments(builder, args); - grpc_channel_stack_builder_set_transport(builder, transport); - - for (size_t i = 0; i < g_slots[type].num_slots; i++) { - const stage_slot *slot = &g_slots[type].slots[i]; - if (!slot->fn(builder, slot->arg)) { - grpc_channel_stack_builder_destroy(builder); - return NULL; - } - } - - return grpc_channel_stack_builder_finish(exec_ctx, builder, prefix_bytes, - initial_refs, destroy, destroy_arg); -} diff --git a/src/core/surface/channel_init.h b/src/core/surface/channel_init.h deleted file mode 100644 index 06faef6ddb..0000000000 --- a/src/core/surface/channel_init.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * 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_SURFACE_CHANNEL_INIT_H -#define GRPC_CORE_SURFACE_CHANNEL_INIT_H - -#include "src/core/channel/channel_stack_builder.h" -#include "src/core/surface/channel_stack_type.h" -#include "src/core/transport/transport.h" - -/// This module provides a way for plugins (and the grpc core library itself) -/// to register mutators for channel stacks. -/// It also provides a universal entry path to run those mutators to build -/// a channel stack for various subsystems. - -/// One stage of mutation: call functions against \a builder to influence the -/// finally constructed channel stack -typedef bool (*grpc_channel_init_stage)(grpc_channel_stack_builder *builder, - void *arg); - -/// Global initialization of the system -void grpc_channel_init_init(void); - -/// Register one stage of mutators. -/// Stages are run in priority order (lowest to highest), and then in -/// registration order (in the case of a tie). -/// Stages are registered against one of the pre-determined channel stack -/// types. -void grpc_channel_init_register_stage(grpc_channel_stack_type type, - int priority, - grpc_channel_init_stage stage_fn, - void *stage_arg); - -/// Finalize registration. No more calls to grpc_channel_init_register_stage are -/// allowed. -void grpc_channel_init_finalize(void); -/// Shutdown the channel init system -void grpc_channel_init_shutdown(void); - -/// Construct a channel stack of some sort: see channel_stack.h for details -/// \a type is the type of channel stack to create -/// \a prefix_bytes is the number of bytes before the channel stack to allocate -/// \a args are configuration arguments for the channel stack -/// \a initial_refs is the initial refcount to give the channel stack -/// \a destroy and \a destroy_arg specify how to destroy the channel stack -/// if destroy_arg is NULL, the returned value from this function will be -/// substituted -/// \a optional_transport is either NULL or a constructed transport object -/// Returns a pointer to the base of the memory allocated (the actual channel -/// stack object will be prefix_bytes past that pointer) -void *grpc_channel_init_create_stack( - grpc_exec_ctx *exec_ctx, grpc_channel_stack_type type, size_t prefix_bytes, - const grpc_channel_args *args, int initial_refs, grpc_iomgr_cb_func destroy, - void *destroy_arg, grpc_transport *optional_transport); - -#endif /* GRPC_CORE_SURFACE_CHANNEL_INIT_H */ diff --git a/src/core/surface/channel_ping.c b/src/core/surface/channel_ping.c deleted file mode 100644 index 983f1c8a66..0000000000 --- a/src/core/surface/channel_ping.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * Copyright 2015-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/surface/channel.h" - -#include - -#include -#include - -#include "src/core/surface/api_trace.h" -#include "src/core/surface/completion_queue.h" - -typedef struct { - grpc_closure closure; - void *tag; - grpc_completion_queue *cq; - grpc_cq_completion completion_storage; -} ping_result; - -static void ping_destroy(grpc_exec_ctx *exec_ctx, void *arg, - grpc_cq_completion *storage) { - gpr_free(arg); -} - -static void ping_done(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - ping_result *pr = arg; - grpc_cq_end_op(exec_ctx, pr->cq, pr->tag, success, ping_destroy, pr, - &pr->completion_storage); -} - -void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq, - void *tag, void *reserved) { - grpc_transport_op op; - ping_result *pr = gpr_malloc(sizeof(*pr)); - grpc_channel_element *top_elem = - grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0); - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - GPR_ASSERT(reserved == NULL); - memset(&op, 0, sizeof(op)); - pr->tag = tag; - pr->cq = cq; - grpc_closure_init(&pr->closure, ping_done, pr); - op.send_ping = &pr->closure; - op.bind_pollset = grpc_cq_pollset(cq); - grpc_cq_begin_op(cq, tag); - top_elem->filter->start_transport_op(&exec_ctx, top_elem, &op); - grpc_exec_ctx_finish(&exec_ctx); -} diff --git a/src/core/surface/channel_stack_type.c b/src/core/surface/channel_stack_type.c deleted file mode 100644 index 1a6e949ffe..0000000000 --- a/src/core/surface/channel_stack_type.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * 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/surface/channel_stack_type.h" -#include -#include - -bool grpc_channel_stack_type_is_client(grpc_channel_stack_type type) { - switch (type) { - case GRPC_CLIENT_CHANNEL: - return true; - case GRPC_CLIENT_SUBCHANNEL: - return true; - case GRPC_CLIENT_LAME_CHANNEL: - return true; - case GRPC_CLIENT_DIRECT_CHANNEL: - return true; - case GRPC_SERVER_CHANNEL: - return false; - case GRPC_NUM_CHANNEL_STACK_TYPES: - break; - } - GPR_UNREACHABLE_CODE(return true;); -} diff --git a/src/core/surface/channel_stack_type.h b/src/core/surface/channel_stack_type.h deleted file mode 100644 index 75a1b9c072..0000000000 --- a/src/core/surface/channel_stack_type.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * Copyright 2015-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_SURFACE_CHANNEL_STACK_TYPE_H -#define GRPC_CORE_SURFACE_CHANNEL_STACK_TYPE_H - -#include - -typedef enum { - // normal top-half client channel with load-balancing, connection management - GRPC_CLIENT_CHANNEL, - // bottom-half of a client channel: everything that happens post-load - // balancing (bound to a specific transport) - GRPC_CLIENT_SUBCHANNEL, - // a permanently broken client channel - GRPC_CLIENT_LAME_CHANNEL, - // a directly connected client channel (without load-balancing, directly talks - // to a transport) - GRPC_CLIENT_DIRECT_CHANNEL, - // server side channel - GRPC_SERVER_CHANNEL, - // must be last - GRPC_NUM_CHANNEL_STACK_TYPES -} grpc_channel_stack_type; - -bool grpc_channel_stack_type_is_client(grpc_channel_stack_type type); - -#endif /* GRPC_CORE_SURFACE_CHANNEL_STACK_TYPE_H */ diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c deleted file mode 100644 index b22818ea87..0000000000 --- a/src/core/surface/completion_queue.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * - * Copyright 2015-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/surface/completion_queue.h" - -#include -#include - -#include -#include -#include -#include - -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/timer.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" -#include "src/core/surface/event_string.h" -#include "src/core/surface/surface_trace.h" - -typedef struct { - grpc_pollset_worker **worker; - void *tag; -} plucker; - -/* Completion queue structure */ -struct grpc_completion_queue { - /** owned by pollset */ - gpr_mu *mu; - /** completed events */ - grpc_cq_completion completed_head; - grpc_cq_completion *completed_tail; - /** Number of pending events (+1 if we're not shutdown) */ - gpr_refcount pending_events; - /** Once owning_refs drops to zero, we will destroy the cq */ - gpr_refcount owning_refs; - /** 0 initially, 1 once we've begun shutting down */ - int shutdown; - int shutdown_called; - int is_server_cq; - int num_pluckers; - plucker pluckers[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS]; - grpc_closure pollset_shutdown_done; - -#ifndef NDEBUG - void **outstanding_tags; - size_t outstanding_tag_count; - size_t outstanding_tag_capacity; -#endif - - grpc_completion_queue *next_free; -}; - -#define POLLSET_FROM_CQ(cq) ((grpc_pollset *)(cq + 1)) - -static gpr_mu g_freelist_mu; -static grpc_completion_queue *g_freelist; - -static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *cc, - bool success); - -void grpc_cq_global_init(void) { gpr_mu_init(&g_freelist_mu); } - -void grpc_cq_global_shutdown(void) { - gpr_mu_destroy(&g_freelist_mu); - while (g_freelist) { - grpc_completion_queue *next = g_freelist->next_free; - grpc_pollset_destroy(POLLSET_FROM_CQ(g_freelist)); -#ifndef NDEBUG - gpr_free(g_freelist->outstanding_tags); -#endif - gpr_free(g_freelist); - g_freelist = next; - } -} - -struct grpc_cq_alarm { - grpc_timer alarm; - grpc_cq_completion completion; - /** completion queue where events about this alarm will be posted */ - grpc_completion_queue *cq; - /** user supplied tag */ - void *tag; -}; - -grpc_completion_queue *grpc_completion_queue_create(void *reserved) { - grpc_completion_queue *cc; - GPR_ASSERT(!reserved); - - GPR_TIMER_BEGIN("grpc_completion_queue_create", 0); - - GRPC_API_TRACE("grpc_completion_queue_create(reserved=%p)", 1, (reserved)); - - gpr_mu_lock(&g_freelist_mu); - if (g_freelist == NULL) { - gpr_mu_unlock(&g_freelist_mu); - - cc = gpr_malloc(sizeof(grpc_completion_queue) + grpc_pollset_size()); - grpc_pollset_init(POLLSET_FROM_CQ(cc), &cc->mu); -#ifndef NDEBUG - cc->outstanding_tags = NULL; - cc->outstanding_tag_capacity = 0; -#endif - } else { - cc = g_freelist; - g_freelist = g_freelist->next_free; - gpr_mu_unlock(&g_freelist_mu); - /* pollset already initialized */ - } - - /* Initial ref is dropped by grpc_completion_queue_shutdown */ - gpr_ref_init(&cc->pending_events, 1); - /* One for destroy(), one for pollset_shutdown */ - gpr_ref_init(&cc->owning_refs, 2); - cc->completed_tail = &cc->completed_head; - cc->completed_head.next = (uintptr_t)cc->completed_tail; - cc->shutdown = 0; - cc->shutdown_called = 0; - cc->is_server_cq = 0; - cc->num_pluckers = 0; -#ifndef NDEBUG - cc->outstanding_tag_count = 0; -#endif - grpc_closure_init(&cc->pollset_shutdown_done, on_pollset_shutdown_done, cc); - - GPR_TIMER_END("grpc_completion_queue_create", 0); - - return cc; -} - -#ifdef GRPC_CQ_REF_COUNT_DEBUG -void grpc_cq_internal_ref(grpc_completion_queue *cc, const char *reason, - const char *file, int line) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p ref %d -> %d %s", cc, - (int)cc->owning_refs.count, (int)cc->owning_refs.count + 1, reason); -#else -void grpc_cq_internal_ref(grpc_completion_queue *cc) { -#endif - gpr_ref(&cc->owning_refs); -} - -static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *arg, - bool success) { - grpc_completion_queue *cc = arg; - GRPC_CQ_INTERNAL_UNREF(cc, "pollset_destroy"); -} - -#ifdef GRPC_CQ_REF_COUNT_DEBUG -void grpc_cq_internal_unref(grpc_completion_queue *cc, const char *reason, - const char *file, int line) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p unref %d -> %d %s", cc, - (int)cc->owning_refs.count, (int)cc->owning_refs.count - 1, reason); -#else -void grpc_cq_internal_unref(grpc_completion_queue *cc) { -#endif - if (gpr_unref(&cc->owning_refs)) { - GPR_ASSERT(cc->completed_head.next == (uintptr_t)&cc->completed_head); - grpc_pollset_reset(POLLSET_FROM_CQ(cc)); - gpr_mu_lock(&g_freelist_mu); - cc->next_free = g_freelist; - g_freelist = cc; - gpr_mu_unlock(&g_freelist_mu); - } -} - -void grpc_cq_begin_op(grpc_completion_queue *cc, void *tag) { -#ifndef NDEBUG - gpr_mu_lock(cc->mu); - GPR_ASSERT(!cc->shutdown_called); - if (cc->outstanding_tag_count == cc->outstanding_tag_capacity) { - cc->outstanding_tag_capacity = GPR_MAX(4, 2 * cc->outstanding_tag_capacity); - cc->outstanding_tags = - gpr_realloc(cc->outstanding_tags, sizeof(*cc->outstanding_tags) * - cc->outstanding_tag_capacity); - } - cc->outstanding_tags[cc->outstanding_tag_count++] = tag; - gpr_mu_unlock(cc->mu); -#endif - gpr_ref(&cc->pending_events); -} - -/* Signal the end of an operation - if this is the last waiting-to-be-queued - event, then enter shutdown mode */ -/* Queue a GRPC_OP_COMPLETED operation */ -void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, - void *tag, int success, - void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg, - grpc_cq_completion *storage), - void *done_arg, grpc_cq_completion *storage) { - int shutdown; - int i; - grpc_pollset_worker *pluck_worker; -#ifndef NDEBUG - int found = 0; -#endif - - GPR_TIMER_BEGIN("grpc_cq_end_op", 0); - - storage->tag = tag; - storage->done = done; - storage->done_arg = done_arg; - storage->next = - ((uintptr_t)&cc->completed_head) | ((uintptr_t)(success != 0)); - - gpr_mu_lock(cc->mu); -#ifndef NDEBUG - for (i = 0; i < (int)cc->outstanding_tag_count; i++) { - if (cc->outstanding_tags[i] == tag) { - cc->outstanding_tag_count--; - GPR_SWAP(void *, cc->outstanding_tags[i], - cc->outstanding_tags[cc->outstanding_tag_count]); - found = 1; - break; - } - } - GPR_ASSERT(found); -#endif - shutdown = gpr_unref(&cc->pending_events); - if (!shutdown) { - cc->completed_tail->next = - ((uintptr_t)storage) | (1u & (uintptr_t)cc->completed_tail->next); - cc->completed_tail = storage; - pluck_worker = NULL; - for (i = 0; i < cc->num_pluckers; i++) { - if (cc->pluckers[i].tag == tag) { - pluck_worker = *cc->pluckers[i].worker; - break; - } - } - grpc_pollset_kick(POLLSET_FROM_CQ(cc), pluck_worker); - gpr_mu_unlock(cc->mu); - } else { - cc->completed_tail->next = - ((uintptr_t)storage) | (1u & (uintptr_t)cc->completed_tail->next); - cc->completed_tail = storage; - GPR_ASSERT(!cc->shutdown); - GPR_ASSERT(cc->shutdown_called); - cc->shutdown = 1; - grpc_pollset_shutdown(exec_ctx, POLLSET_FROM_CQ(cc), - &cc->pollset_shutdown_done); - gpr_mu_unlock(cc->mu); - } - - GPR_TIMER_END("grpc_cq_end_op", 0); -} - -grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, - gpr_timespec deadline, void *reserved) { - grpc_event ret; - grpc_pollset_worker *worker = NULL; - int first_loop = 1; - gpr_timespec now; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - GPR_TIMER_BEGIN("grpc_completion_queue_next", 0); - - GRPC_API_TRACE( - "grpc_completion_queue_next(" - "cc=%p, " - "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " - "reserved=%p)", - 5, (cc, (long long)deadline.tv_sec, (int)deadline.tv_nsec, - (int)deadline.clock_type, reserved)); - GPR_ASSERT(!reserved); - - deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); - - GRPC_CQ_INTERNAL_REF(cc, "next"); - gpr_mu_lock(cc->mu); - for (;;) { - if (cc->completed_tail != &cc->completed_head) { - grpc_cq_completion *c = (grpc_cq_completion *)cc->completed_head.next; - cc->completed_head.next = c->next & ~(uintptr_t)1; - if (c == cc->completed_tail) { - cc->completed_tail = &cc->completed_head; - } - gpr_mu_unlock(cc->mu); - ret.type = GRPC_OP_COMPLETE; - ret.success = c->next & 1u; - ret.tag = c->tag; - c->done(&exec_ctx, c->done_arg, c); - break; - } - if (cc->shutdown) { - gpr_mu_unlock(cc->mu); - memset(&ret, 0, sizeof(ret)); - ret.type = GRPC_QUEUE_SHUTDOWN; - break; - } - now = gpr_now(GPR_CLOCK_MONOTONIC); - if (!first_loop && gpr_time_cmp(now, deadline) >= 0) { - gpr_mu_unlock(cc->mu); - memset(&ret, 0, sizeof(ret)); - ret.type = GRPC_QUEUE_TIMEOUT; - break; - } - first_loop = 0; - /* Check alarms - these are a global resource so we just ping - each time through on every pollset. - May update deadline to ensure timely wakeups. - TODO(ctiller): can this work be localized? */ - gpr_timespec iteration_deadline = deadline; - if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) { - GPR_TIMER_MARK("alarm_triggered", 0); - gpr_mu_unlock(cc->mu); - grpc_exec_ctx_flush(&exec_ctx); - gpr_mu_lock(cc->mu); - continue; - } else { - grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc), &worker, now, - iteration_deadline); - } - } - GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret); - GRPC_CQ_INTERNAL_UNREF(cc, "next"); - grpc_exec_ctx_finish(&exec_ctx); - - GPR_TIMER_END("grpc_completion_queue_next", 0); - - return ret; -} - -static int add_plucker(grpc_completion_queue *cc, void *tag, - grpc_pollset_worker **worker) { - if (cc->num_pluckers == GRPC_MAX_COMPLETION_QUEUE_PLUCKERS) { - return 0; - } - cc->pluckers[cc->num_pluckers].tag = tag; - cc->pluckers[cc->num_pluckers].worker = worker; - cc->num_pluckers++; - return 1; -} - -static void del_plucker(grpc_completion_queue *cc, void *tag, - grpc_pollset_worker **worker) { - int i; - for (i = 0; i < cc->num_pluckers; i++) { - if (cc->pluckers[i].tag == tag && cc->pluckers[i].worker == worker) { - cc->num_pluckers--; - GPR_SWAP(plucker, cc->pluckers[i], cc->pluckers[cc->num_pluckers]); - return; - } - } - GPR_UNREACHABLE_CODE(return ); -} - -grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, - gpr_timespec deadline, void *reserved) { - grpc_event ret; - grpc_cq_completion *c; - grpc_cq_completion *prev; - grpc_pollset_worker *worker = NULL; - gpr_timespec now; - int first_loop = 1; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - GPR_TIMER_BEGIN("grpc_completion_queue_pluck", 0); - - GRPC_API_TRACE( - "grpc_completion_queue_pluck(" - "cc=%p, tag=%p, " - "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " - "reserved=%p)", - 6, (cc, tag, (long long)deadline.tv_sec, (int)deadline.tv_nsec, - (int)deadline.clock_type, reserved)); - GPR_ASSERT(!reserved); - - deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); - - GRPC_CQ_INTERNAL_REF(cc, "pluck"); - gpr_mu_lock(cc->mu); - for (;;) { - prev = &cc->completed_head; - while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) != - &cc->completed_head) { - if (c->tag == tag) { - prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1); - if (c == cc->completed_tail) { - cc->completed_tail = prev; - } - gpr_mu_unlock(cc->mu); - ret.type = GRPC_OP_COMPLETE; - ret.success = c->next & 1u; - ret.tag = c->tag; - c->done(&exec_ctx, c->done_arg, c); - goto done; - } - prev = c; - } - if (cc->shutdown) { - gpr_mu_unlock(cc->mu); - memset(&ret, 0, sizeof(ret)); - ret.type = GRPC_QUEUE_SHUTDOWN; - break; - } - if (!add_plucker(cc, tag, &worker)) { - gpr_log(GPR_DEBUG, - "Too many outstanding grpc_completion_queue_pluck calls: maximum " - "is %d", - GRPC_MAX_COMPLETION_QUEUE_PLUCKERS); - gpr_mu_unlock(cc->mu); - memset(&ret, 0, sizeof(ret)); - /* TODO(ctiller): should we use a different result here */ - ret.type = GRPC_QUEUE_TIMEOUT; - break; - } - now = gpr_now(GPR_CLOCK_MONOTONIC); - if (!first_loop && gpr_time_cmp(now, deadline) >= 0) { - del_plucker(cc, tag, &worker); - gpr_mu_unlock(cc->mu); - memset(&ret, 0, sizeof(ret)); - ret.type = GRPC_QUEUE_TIMEOUT; - break; - } - first_loop = 0; - /* Check alarms - these are a global resource so we just ping - each time through on every pollset. - May update deadline to ensure timely wakeups. - TODO(ctiller): can this work be localized? */ - gpr_timespec iteration_deadline = deadline; - if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) { - GPR_TIMER_MARK("alarm_triggered", 0); - gpr_mu_unlock(cc->mu); - grpc_exec_ctx_flush(&exec_ctx); - gpr_mu_lock(cc->mu); - } else { - grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc), &worker, now, - iteration_deadline); - } - del_plucker(cc, tag, &worker); - } -done: - GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret); - GRPC_CQ_INTERNAL_UNREF(cc, "pluck"); - grpc_exec_ctx_finish(&exec_ctx); - - GPR_TIMER_END("grpc_completion_queue_pluck", 0); - - return ret; -} - -/* Shutdown simply drops a ref that we reserved at creation time; if we drop - to zero here, then enter shutdown mode and wake up any waiters */ -void grpc_completion_queue_shutdown(grpc_completion_queue *cc) { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - GPR_TIMER_BEGIN("grpc_completion_queue_shutdown", 0); - GRPC_API_TRACE("grpc_completion_queue_shutdown(cc=%p)", 1, (cc)); - gpr_mu_lock(cc->mu); - if (cc->shutdown_called) { - gpr_mu_unlock(cc->mu); - GPR_TIMER_END("grpc_completion_queue_shutdown", 0); - return; - } - cc->shutdown_called = 1; - if (gpr_unref(&cc->pending_events)) { - GPR_ASSERT(!cc->shutdown); - cc->shutdown = 1; - grpc_pollset_shutdown(&exec_ctx, POLLSET_FROM_CQ(cc), - &cc->pollset_shutdown_done); - } - gpr_mu_unlock(cc->mu); - grpc_exec_ctx_finish(&exec_ctx); - GPR_TIMER_END("grpc_completion_queue_shutdown", 0); -} - -void grpc_completion_queue_destroy(grpc_completion_queue *cc) { - GRPC_API_TRACE("grpc_completion_queue_destroy(cc=%p)", 1, (cc)); - GPR_TIMER_BEGIN("grpc_completion_queue_destroy", 0); - grpc_completion_queue_shutdown(cc); - GRPC_CQ_INTERNAL_UNREF(cc, "destroy"); - GPR_TIMER_END("grpc_completion_queue_destroy", 0); -} - -grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) { - return POLLSET_FROM_CQ(cc); -} - -void grpc_cq_mark_server_cq(grpc_completion_queue *cc) { cc->is_server_cq = 1; } - -int grpc_cq_is_server_cq(grpc_completion_queue *cc) { return cc->is_server_cq; } diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h deleted file mode 100644 index 213d89c079..0000000000 --- a/src/core/surface/completion_queue.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * Copyright 2015-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_SURFACE_COMPLETION_QUEUE_H -#define GRPC_CORE_SURFACE_COMPLETION_QUEUE_H - -/* Internal API for completion queues */ - -#include -#include "src/core/iomgr/pollset.h" - -typedef struct grpc_cq_completion { - /** user supplied tag */ - void *tag; - /** done callback - called when this queue element is no longer - needed by the completion queue */ - void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg, - struct grpc_cq_completion *c); - void *done_arg; - /** next pointer; low bit is used to indicate success or not */ - uintptr_t next; -} grpc_cq_completion; - -#ifdef GRPC_CQ_REF_COUNT_DEBUG -void grpc_cq_internal_ref(grpc_completion_queue *cc, const char *reason, - const char *file, int line); -void grpc_cq_internal_unref(grpc_completion_queue *cc, const char *reason, - const char *file, int line); -#define GRPC_CQ_INTERNAL_REF(cc, reason) \ - grpc_cq_internal_ref(cc, reason, __FILE__, __LINE__) -#define GRPC_CQ_INTERNAL_UNREF(cc, reason) \ - grpc_cq_internal_unref(cc, reason, __FILE__, __LINE__) -#else -void grpc_cq_internal_ref(grpc_completion_queue *cc); -void grpc_cq_internal_unref(grpc_completion_queue *cc); -#define GRPC_CQ_INTERNAL_REF(cc, reason) grpc_cq_internal_ref(cc) -#define GRPC_CQ_INTERNAL_UNREF(cc, reason) grpc_cq_internal_unref(cc) -#endif - -/* Flag that an operation is beginning: the completion channel will not finish - shutdown until a corrensponding grpc_cq_end_* call is made. - \a tag is currently used only in debug builds. */ -void grpc_cq_begin_op(grpc_completion_queue *cc, void *tag); - -/* Queue a GRPC_OP_COMPLETED operation; tag must correspond to the tag passed to - grpc_cq_begin_op */ -void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, - void *tag, int success, - void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg, - grpc_cq_completion *storage), - void *done_arg, grpc_cq_completion *storage); - -grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc); - -void grpc_cq_mark_server_cq(grpc_completion_queue *cc); -int grpc_cq_is_server_cq(grpc_completion_queue *cc); - -void grpc_cq_global_init(void); -void grpc_cq_global_shutdown(void); - -#endif /* GRPC_CORE_SURFACE_COMPLETION_QUEUE_H */ diff --git a/src/core/surface/event_string.c b/src/core/surface/event_string.c deleted file mode 100644 index 85a372b9ad..0000000000 --- a/src/core/surface/event_string.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * Copyright 2015-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/surface/event_string.h" - -#include - -#include -#include -#include "src/core/support/string.h" - -static void addhdr(gpr_strvec *buf, grpc_event *ev) { - char *tmp; - gpr_asprintf(&tmp, "tag:%p", ev->tag); - gpr_strvec_add(buf, tmp); -} - -static const char *errstr(int success) { return success ? "OK" : "ERROR"; } - -static void adderr(gpr_strvec *buf, int success) { - char *tmp; - gpr_asprintf(&tmp, " %s", errstr(success)); - gpr_strvec_add(buf, tmp); -} - -char *grpc_event_string(grpc_event *ev) { - char *out; - gpr_strvec buf; - - if (ev == NULL) return gpr_strdup("null"); - - gpr_strvec_init(&buf); - - switch (ev->type) { - case GRPC_QUEUE_TIMEOUT: - gpr_strvec_add(&buf, gpr_strdup("QUEUE_TIMEOUT")); - break; - case GRPC_QUEUE_SHUTDOWN: - gpr_strvec_add(&buf, gpr_strdup("QUEUE_SHUTDOWN")); - break; - case GRPC_OP_COMPLETE: - gpr_strvec_add(&buf, gpr_strdup("OP_COMPLETE: ")); - addhdr(&buf, ev); - adderr(&buf, ev->success); - break; - } - - out = gpr_strvec_flatten(&buf, NULL); - gpr_strvec_destroy(&buf); - return out; -} diff --git a/src/core/surface/event_string.h b/src/core/surface/event_string.h deleted file mode 100644 index d0598cecca..0000000000 --- a/src/core/surface/event_string.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright 2015-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_SURFACE_EVENT_STRING_H -#define GRPC_CORE_SURFACE_EVENT_STRING_H - -#include - -/* Returns a string describing an event. Must be later freed with gpr_free() */ -char *grpc_event_string(grpc_event *ev); - -#endif /* GRPC_CORE_SURFACE_EVENT_STRING_H */ diff --git a/src/core/surface/init.c b/src/core/surface/init.c deleted file mode 100644 index 3c4db3e6cc..0000000000 --- a/src/core/surface/init.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include -#include - -#include -#include -#include -/* TODO(ctiller): find another way? - better not to include census here */ -#include "src/core/census/grpc_plugin.h" -#include "src/core/channel/channel_stack.h" -#include "src/core/channel/client_channel.h" -#include "src/core/channel/compress_filter.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_client_filter.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/client_config/lb_policies/pick_first.h" -#include "src/core/client_config/lb_policies/round_robin.h" -#include "src/core/client_config/lb_policy_registry.h" -#include "src/core/client_config/resolver_registry.h" -#include "src/core/client_config/resolvers/dns_resolver.h" -#include "src/core/client_config/resolvers/sockaddr_resolver.h" -#include "src/core/client_config/subchannel.h" -#include "src/core/client_config/subchannel_index.h" -#include "src/core/debug/trace.h" -#include "src/core/iomgr/executor.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/profiling/timers.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" -#include "src/core/surface/channel_init.h" -#include "src/core/surface/completion_queue.h" -#include "src/core/surface/init.h" -#include "src/core/surface/lame_client.h" -#include "src/core/surface/server.h" -#include "src/core/surface/surface_trace.h" -#include "src/core/transport/chttp2_transport.h" -#include "src/core/transport/connectivity_state.h" -#include "src/core/transport/transport_impl.h" - -#ifndef GRPC_DEFAULT_NAME_PREFIX -#define GRPC_DEFAULT_NAME_PREFIX "dns:///" -#endif - -#define MAX_PLUGINS 128 - -static gpr_once g_basic_init = GPR_ONCE_INIT; -static gpr_mu g_init_mu; -static int g_initializations; - -static void do_basic_init(void) { - gpr_mu_init(&g_init_mu); - /* TODO(ctiller): ideally remove this strict linkage */ - grpc_register_plugin(census_grpc_plugin_init, census_grpc_plugin_destroy); - g_initializations = 0; -} - -static bool append_filter(grpc_channel_stack_builder *builder, void *arg) { - return grpc_channel_stack_builder_append_filter( - builder, (const grpc_channel_filter *)arg, NULL, NULL); -} - -static bool prepend_filter(grpc_channel_stack_builder *builder, void *arg) { - return grpc_channel_stack_builder_prepend_filter( - builder, (const grpc_channel_filter *)arg, NULL, NULL); -} - -static bool maybe_add_http_filter(grpc_channel_stack_builder *builder, - void *arg) { - grpc_transport *t = grpc_channel_stack_builder_get_transport(builder); - if (t && strstr(t->vtable->name, "http")) { - return grpc_channel_stack_builder_prepend_filter( - builder, (const grpc_channel_filter *)arg, NULL, NULL); - } - return true; -} - -static void register_builtin_channel_init() { - grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, prepend_filter, - (void *)&grpc_compress_filter); - grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, - prepend_filter, - (void *)&grpc_compress_filter); - grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter, - (void *)&grpc_compress_filter); - grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX, - maybe_add_http_filter, - (void *)&grpc_http_client_filter); - grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX, - grpc_add_connected_filter, NULL); - grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, - maybe_add_http_filter, - (void *)&grpc_http_client_filter); - grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, - grpc_add_connected_filter, NULL); - grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, - maybe_add_http_filter, - (void *)&grpc_http_server_filter); - grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, - grpc_add_connected_filter, NULL); - grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, append_filter, - (void *)&grpc_client_channel_filter); - grpc_channel_init_register_stage(GRPC_CLIENT_LAME_CHANNEL, INT_MAX, - append_filter, (void *)&grpc_lame_filter); - grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter, - (void *)&grpc_server_top_filter); -} - -typedef struct grpc_plugin { - void (*init)(); - void (*destroy)(); -} grpc_plugin; - -static grpc_plugin g_all_of_the_plugins[MAX_PLUGINS]; -static int g_number_of_plugins = 0; - -void grpc_register_plugin(void (*init)(void), void (*destroy)(void)) { - GRPC_API_TRACE("grpc_register_plugin(init=%p, destroy=%p)", 2, - ((void *)(intptr_t)init, (void *)(intptr_t)destroy)); - GPR_ASSERT(g_number_of_plugins != MAX_PLUGINS); - g_all_of_the_plugins[g_number_of_plugins].init = init; - g_all_of_the_plugins[g_number_of_plugins].destroy = destroy; - g_number_of_plugins++; -} - -void grpc_init(void) { - int i; - gpr_once_init(&g_basic_init, do_basic_init); - - gpr_mu_lock(&g_init_mu); - if (++g_initializations == 1) { - gpr_time_init(); - grpc_mdctx_global_init(); - grpc_channel_init_init(); - grpc_lb_policy_registry_init(grpc_pick_first_lb_factory_create()); - grpc_register_lb_policy(grpc_pick_first_lb_factory_create()); - grpc_register_lb_policy(grpc_round_robin_lb_factory_create()); - grpc_resolver_registry_init(GRPC_DEFAULT_NAME_PREFIX); - grpc_register_resolver_type(grpc_dns_resolver_factory_create()); - grpc_register_resolver_type(grpc_ipv4_resolver_factory_create()); - grpc_register_resolver_type(grpc_ipv6_resolver_factory_create()); -#ifdef GPR_POSIX_SOCKET - grpc_register_resolver_type(grpc_unix_resolver_factory_create()); -#endif - grpc_register_tracer("api", &grpc_api_trace); - grpc_register_tracer("channel", &grpc_trace_channel); - grpc_register_tracer("http", &grpc_http_trace); - grpc_register_tracer("flowctl", &grpc_flowctl_trace); - grpc_register_tracer("connectivity_state", &grpc_connectivity_state_trace); - grpc_register_tracer("channel_stack_builder", - &grpc_trace_channel_stack_builder); - grpc_security_pre_init(); - grpc_iomgr_init(); - grpc_executor_init(); - grpc_tracer_init("GRPC_TRACE"); - gpr_timers_global_init(); - grpc_cq_global_init(); - grpc_subchannel_index_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(); - } - } - /* register channel finalization AFTER all plugins, to ensure that it's run - * at the appropriate time */ - grpc_register_security_filters(); - register_builtin_channel_init(); - /* no more changes to channel init pipelines */ - grpc_channel_init_finalize(); - } - gpr_mu_unlock(&g_init_mu); - GRPC_API_TRACE("grpc_init(void)", 0, ()); -} - -void grpc_shutdown(void) { - int i; - GRPC_API_TRACE("grpc_shutdown(void)", 0, ()); - gpr_mu_lock(&g_init_mu); - if (--g_initializations == 0) { - grpc_executor_shutdown(); - grpc_cq_global_shutdown(); - grpc_iomgr_shutdown(); - grpc_subchannel_index_shutdown(); - gpr_timers_global_destroy(); - grpc_tracer_shutdown(); - grpc_resolver_registry_shutdown(); - grpc_lb_policy_registry_shutdown(); - for (i = 0; i < g_number_of_plugins; i++) { - if (g_all_of_the_plugins[i].destroy != NULL) { - g_all_of_the_plugins[i].destroy(); - } - } - grpc_channel_init_shutdown(); - grpc_mdctx_global_shutdown(); - } - gpr_mu_unlock(&g_init_mu); -} - -int grpc_is_initialized(void) { - int r; - gpr_once_init(&g_basic_init, do_basic_init); - gpr_mu_lock(&g_init_mu); - r = g_initializations > 0; - gpr_mu_unlock(&g_init_mu); - return r; -} diff --git a/src/core/surface/init.h b/src/core/surface/init.h deleted file mode 100644 index 5e358c7022..0000000000 --- a/src/core/surface/init.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * Copyright 2015-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_SURFACE_INIT_H -#define GRPC_CORE_SURFACE_INIT_H - -void grpc_register_security_filters(void); -void grpc_security_pre_init(void); -int grpc_is_initialized(void); - -#endif /* GRPC_CORE_SURFACE_INIT_H */ diff --git a/src/core/surface/init_secure.c b/src/core/surface/init_secure.c deleted file mode 100644 index e0d66a8d46..0000000000 --- a/src/core/surface/init_secure.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * Copyright 2015-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/surface/init.h" - -#include -#include - -#include "src/core/debug/trace.h" -#include "src/core/security/auth_filters.h" -#include "src/core/security/credentials.h" -#include "src/core/security/secure_endpoint.h" -#include "src/core/security/security_connector.h" -#include "src/core/surface/channel_init.h" -#include "src/core/tsi/transport_security_interface.h" - -void grpc_security_pre_init(void) { - grpc_register_tracer("secure_endpoint", &grpc_trace_secure_endpoint); - grpc_register_tracer("transport_security", &tsi_tracing_enabled); -} - -static bool maybe_prepend_client_auth_filter( - grpc_channel_stack_builder *builder, void *arg) { - const grpc_channel_args *args = - grpc_channel_stack_builder_get_channel_arguments(builder); - if (args) { - for (size_t i = 0; i < args->num_args; i++) { - if (0 == strcmp(GRPC_SECURITY_CONNECTOR_ARG, args->args[i].key)) { - return grpc_channel_stack_builder_prepend_filter( - builder, &grpc_client_auth_filter, NULL, NULL); - } - } - } - return true; -} - -static bool maybe_prepend_server_auth_filter( - grpc_channel_stack_builder *builder, void *arg) { - const grpc_channel_args *args = - grpc_channel_stack_builder_get_channel_arguments(builder); - if (args) { - for (size_t i = 0; i < args->num_args; i++) { - if (0 == strcmp(GRPC_SERVER_CREDENTIALS_ARG, args->args[i].key)) { - return grpc_channel_stack_builder_prepend_filter( - builder, &grpc_server_auth_filter, NULL, NULL); - } - } - } - return true; -} - -void grpc_register_security_filters(void) { - grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX, - maybe_prepend_client_auth_filter, NULL); - grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, - maybe_prepend_client_auth_filter, NULL); - grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, - maybe_prepend_server_auth_filter, NULL); -} diff --git a/src/core/surface/init_unsecure.c b/src/core/surface/init_unsecure.c deleted file mode 100644 index 278fcc83ac..0000000000 --- a/src/core/surface/init_unsecure.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * Copyright 2015-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/surface/init.h" - -void grpc_security_pre_init(void) {} - -void grpc_register_security_filters(void) {} diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c deleted file mode 100644 index 25f3a74349..0000000000 --- a/src/core/surface/lame_client.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * - * Copyright 2015-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/surface/lame_client.h" - -#include - -#include - -#include -#include -#include "src/core/channel/channel_stack.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" -#include "src/core/surface/channel.h" - -typedef struct { - grpc_linked_mdelem status; - grpc_linked_mdelem details; -} call_data; - -typedef struct { - grpc_status_code error_code; - const char *error_message; -} channel_data; - -static void fill_metadata(grpc_call_element *elem, grpc_metadata_batch *mdb) { - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - char tmp[GPR_LTOA_MIN_BUFSIZE]; - gpr_ltoa(chand->error_code, tmp); - calld->status.md = grpc_mdelem_from_strings("grpc-status", tmp); - calld->details.md = - grpc_mdelem_from_strings("grpc-message", chand->error_message); - calld->status.prev = calld->details.next = NULL; - calld->status.next = &calld->details; - calld->details.prev = &calld->status; - mdb->list.head = &calld->status; - mdb->list.tail = &calld->details; - mdb->deadline = gpr_inf_future(GPR_CLOCK_REALTIME); -} - -static void lame_start_transport_stream_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - GRPC_CALL_LOG_OP(GPR_INFO, elem, op); - if (op->recv_initial_metadata != NULL) { - fill_metadata(elem, op->recv_initial_metadata); - } else if (op->recv_trailing_metadata != NULL) { - fill_metadata(elem, op->recv_trailing_metadata); - } - grpc_transport_stream_op_finish_with_failure(exec_ctx, op); -} - -static char *lame_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { - return NULL; -} - -static void lame_start_transport_op(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_transport_op *op) { - if (op->on_connectivity_state_change) { - GPR_ASSERT(*op->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE); - *op->connectivity_state = GRPC_CHANNEL_FATAL_FAILURE; - op->on_connectivity_state_change->cb( - exec_ctx, op->on_connectivity_state_change->cb_arg, 1); - } - if (op->on_consumed != NULL) { - op->on_consumed->cb(exec_ctx, op->on_consumed->cb_arg, 1); - } -} - -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) {} - -static void destroy_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) {} - -static void init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - GPR_ASSERT(args->is_first); - GPR_ASSERT(args->is_last); -} - -static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) {} - -const grpc_channel_filter grpc_lame_filter = { - lame_start_transport_stream_op, - lame_start_transport_op, - sizeof(call_data), - init_call_elem, - grpc_call_stack_ignore_set_pollset, - destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - lame_get_peer, - "lame-client", -}; - -#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c) + 1)) - -grpc_channel *grpc_lame_client_channel_create(const char *target, - grpc_status_code error_code, - const char *error_message) { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_channel_element *elem; - channel_data *chand; - grpc_channel *channel = grpc_channel_create(&exec_ctx, target, NULL, - GRPC_CLIENT_LAME_CHANNEL, NULL); - elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0); - GRPC_API_TRACE( - "grpc_lame_client_channel_create(target=%s, error_code=%d, " - "error_message=%s)", - 3, (target, (int)error_code, error_message)); - GPR_ASSERT(elem->filter == &grpc_lame_filter); - chand = (channel_data *)elem->channel_data; - chand->error_code = error_code; - chand->error_message = error_message; - grpc_exec_ctx_finish(&exec_ctx); - return channel; -} diff --git a/src/core/surface/lame_client.h b/src/core/surface/lame_client.h deleted file mode 100644 index 3f3abd2ffe..0000000000 --- a/src/core/surface/lame_client.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * 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_SURFACE_LAME_CLIENT_H -#define GRPC_CORE_SURFACE_LAME_CLIENT_H - -#include "src/core/channel/channel_stack.h" - -extern const grpc_channel_filter grpc_lame_filter; - -#endif /* GRPC_CORE_SURFACE_LAME_CLIENT_H */ diff --git a/src/core/surface/metadata_array.c b/src/core/surface/metadata_array.c deleted file mode 100644 index 4c7bf17835..0000000000 --- a/src/core/surface/metadata_array.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright 2015, 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 -#include - -#include - -#include "src/core/surface/api_trace.h" - -void grpc_metadata_array_init(grpc_metadata_array* array) { - GRPC_API_TRACE("grpc_metadata_array_init(array=%p)", 1, (array)); - memset(array, 0, sizeof(*array)); -} - -void grpc_metadata_array_destroy(grpc_metadata_array* array) { - GRPC_API_TRACE("grpc_metadata_array_destroy(array=%p)", 1, (array)); - gpr_free(array->metadata); -} diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c deleted file mode 100644 index cc752227ee..0000000000 --- a/src/core/surface/secure_channel_create.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include -#include - -#include -#include -#include - -#include "src/core/channel/channel_args.h" -#include "src/core/channel/client_channel.h" -#include "src/core/client_config/resolver_registry.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/security/auth_filters.h" -#include "src/core/security/credentials.h" -#include "src/core/security/security_context.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/channel.h" -#include "src/core/transport/chttp2_transport.h" -#include "src/core/tsi/transport_security_interface.h" - -typedef struct { - grpc_connector base; - gpr_refcount refs; - - grpc_channel_security_connector *security_connector; - - grpc_closure *notify; - grpc_connect_in_args args; - grpc_connect_out_args *result; - grpc_closure initial_string_sent; - gpr_slice_buffer initial_string_buffer; - - gpr_mu mu; - grpc_endpoint *connecting_endpoint; - grpc_endpoint *newly_connecting_endpoint; - - grpc_closure connected_closure; -} connector; - -static void connector_ref(grpc_connector *con) { - connector *c = (connector *)con; - gpr_ref(&c->refs); -} - -static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { - connector *c = (connector *)con; - if (gpr_unref(&c->refs)) { - /* c->initial_string_buffer does not need to be destroyed */ - gpr_free(c); - } -} - -static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, - grpc_security_status status, - grpc_endpoint *secure_endpoint, - grpc_auth_context *auth_context) { - connector *c = arg; - grpc_closure *notify; - grpc_channel_args *args_copy = NULL; - gpr_mu_lock(&c->mu); - if (c->connecting_endpoint == NULL) { - memset(c->result, 0, sizeof(*c->result)); - gpr_mu_unlock(&c->mu); - } else if (status != GRPC_SECURITY_OK) { - gpr_log(GPR_ERROR, "Secure handshake failed with error %d.", status); - memset(c->result, 0, sizeof(*c->result)); - c->connecting_endpoint = NULL; - gpr_mu_unlock(&c->mu); - } else { - grpc_arg auth_context_arg; - c->connecting_endpoint = NULL; - gpr_mu_unlock(&c->mu); - c->result->transport = grpc_create_chttp2_transport( - exec_ctx, c->args.channel_args, secure_endpoint, 1); - grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, - 0); - auth_context_arg = grpc_auth_context_to_arg(auth_context); - args_copy = grpc_channel_args_copy_and_add(c->args.channel_args, - &auth_context_arg, 1); - c->result->channel_args = args_copy; - } - notify = c->notify; - c->notify = NULL; - /* look at c->args which are connector args. */ - notify->cb(exec_ctx, notify->cb_arg, 1); - if (args_copy != NULL) grpc_channel_args_destroy(args_copy); -} - -static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, - bool success) { - connector *c = arg; - grpc_channel_security_connector_do_handshake(exec_ctx, c->security_connector, - c->connecting_endpoint, - on_secure_handshake_done, c); -} - -static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) { - connector *c = arg; - grpc_closure *notify; - grpc_endpoint *tcp = c->newly_connecting_endpoint; - if (tcp != NULL) { - gpr_mu_lock(&c->mu); - GPR_ASSERT(c->connecting_endpoint == NULL); - c->connecting_endpoint = tcp; - gpr_mu_unlock(&c->mu); - if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) { - grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent, - c); - gpr_slice_buffer_init(&c->initial_string_buffer); - gpr_slice_buffer_add(&c->initial_string_buffer, - c->args.initial_connect_string); - grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, - &c->initial_string_sent); - } else { - grpc_channel_security_connector_do_handshake( - exec_ctx, c->security_connector, tcp, on_secure_handshake_done, c); - } - } else { - memset(c->result, 0, sizeof(*c->result)); - notify = c->notify; - c->notify = NULL; - notify->cb(exec_ctx, notify->cb_arg, 1); - } -} - -static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) { - connector *c = (connector *)con; - grpc_endpoint *ep; - gpr_mu_lock(&c->mu); - ep = c->connecting_endpoint; - c->connecting_endpoint = NULL; - gpr_mu_unlock(&c->mu); - if (ep) { - grpc_endpoint_shutdown(exec_ctx, ep); - } -} - -static void connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *con, - const grpc_connect_in_args *args, - grpc_connect_out_args *result, - grpc_closure *notify) { - connector *c = (connector *)con; - GPR_ASSERT(c->notify == NULL); - GPR_ASSERT(notify->cb); - c->notify = notify; - c->args = *args; - c->result = result; - gpr_mu_lock(&c->mu); - GPR_ASSERT(c->connecting_endpoint == NULL); - gpr_mu_unlock(&c->mu); - grpc_closure_init(&c->connected_closure, connected, c); - grpc_tcp_client_connect( - exec_ctx, &c->connected_closure, &c->newly_connecting_endpoint, - args->interested_parties, args->addr, args->addr_len, args->deadline); -} - -static const grpc_connector_vtable connector_vtable = { - connector_ref, connector_unref, connector_shutdown, connector_connect}; - -typedef struct { - grpc_subchannel_factory base; - gpr_refcount refs; - grpc_channel_args *merge_args; - grpc_channel_security_connector *security_connector; - grpc_channel *master; -} subchannel_factory; - -static void subchannel_factory_ref(grpc_subchannel_factory *scf) { - subchannel_factory *f = (subchannel_factory *)scf; - gpr_ref(&f->refs); -} - -static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx, - grpc_subchannel_factory *scf) { - subchannel_factory *f = (subchannel_factory *)scf; - if (gpr_unref(&f->refs)) { - GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base, - "subchannel_factory"); - GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory"); - grpc_channel_args_destroy(f->merge_args); - gpr_free(f); - } -} - -static grpc_subchannel *subchannel_factory_create_subchannel( - grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *scf, - grpc_subchannel_args *args) { - subchannel_factory *f = (subchannel_factory *)scf; - connector *c = gpr_malloc(sizeof(*c)); - grpc_channel_args *final_args = - grpc_channel_args_merge(args->args, f->merge_args); - grpc_subchannel *s; - memset(c, 0, sizeof(*c)); - c->base.vtable = &connector_vtable; - c->security_connector = f->security_connector; - gpr_mu_init(&c->mu); - gpr_ref_init(&c->refs, 1); - args->args = final_args; - s = grpc_subchannel_create(exec_ctx, &c->base, args); - grpc_connector_unref(exec_ctx, &c->base); - grpc_channel_args_destroy(final_args); - return s; -} - -static const grpc_subchannel_factory_vtable subchannel_factory_vtable = { - subchannel_factory_ref, subchannel_factory_unref, - subchannel_factory_create_subchannel}; - -/* Create a secure client channel: - Asynchronously: - resolve target - - connect to it (trying alternatives as presented) - - perform handshakes */ -grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds, - const char *target, - const grpc_channel_args *args, - void *reserved) { - grpc_channel *channel; - grpc_arg connector_arg; - grpc_channel_args *args_copy; - grpc_channel_args *new_args_from_connector; - grpc_channel_security_connector *security_connector; - grpc_resolver *resolver; - subchannel_factory *f; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - GRPC_API_TRACE( - "grpc_secure_channel_create(creds=%p, target=%s, args=%p, " - "reserved=%p)", - 4, (creds, target, args, reserved)); - GPR_ASSERT(reserved == NULL); - - if (grpc_find_security_connector_in_args(args) != NULL) { - gpr_log(GPR_ERROR, "Cannot set security context in channel args."); - grpc_exec_ctx_finish(&exec_ctx); - return grpc_lame_client_channel_create( - target, GRPC_STATUS_INVALID_ARGUMENT, - "Security connector exists in channel args."); - } - - if (grpc_channel_credentials_create_security_connector( - creds, target, args, &security_connector, &new_args_from_connector) != - GRPC_SECURITY_OK) { - grpc_exec_ctx_finish(&exec_ctx); - return grpc_lame_client_channel_create( - target, GRPC_STATUS_INVALID_ARGUMENT, - "Failed to create security connector."); - } - - connector_arg = grpc_security_connector_to_arg(&security_connector->base); - args_copy = grpc_channel_args_copy_and_add( - new_args_from_connector != NULL ? new_args_from_connector : args, - &connector_arg, 1); - - channel = grpc_channel_create(&exec_ctx, target, args_copy, - GRPC_CLIENT_CHANNEL, NULL); - - f = gpr_malloc(sizeof(*f)); - f->base.vtable = &subchannel_factory_vtable; - gpr_ref_init(&f->refs, 1); - GRPC_SECURITY_CONNECTOR_REF(&security_connector->base, "subchannel_factory"); - f->security_connector = security_connector; - f->merge_args = grpc_channel_args_copy(args_copy); - f->master = channel; - GRPC_CHANNEL_INTERNAL_REF(channel, "subchannel_factory"); - resolver = grpc_resolver_create(target, &f->base); - if (resolver) { - grpc_client_channel_set_resolver( - &exec_ctx, grpc_channel_get_channel_stack(channel), resolver); - GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create"); - } - grpc_subchannel_factory_unref(&exec_ctx, &f->base); - GRPC_SECURITY_CONNECTOR_UNREF(&security_connector->base, "channel_create"); - grpc_channel_args_destroy(args_copy); - if (new_args_from_connector != NULL) { - grpc_channel_args_destroy(new_args_from_connector); - } - - if (!resolver) { - GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, channel, "subchannel_factory"); - channel = NULL; - } - grpc_exec_ctx_finish(&exec_ctx); - - return channel; -} diff --git a/src/core/surface/server.c b/src/core/surface/server.c deleted file mode 100644 index a92f2b3e38..0000000000 --- a/src/core/surface/server.c +++ /dev/null @@ -1,1319 +0,0 @@ -/* - * - * Copyright 2015-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/surface/server.h" - -#include -#include -#include - -#include -#include -#include -#include - -#include "src/core/channel/channel_args.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/support/stack_lockfree.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/completion_queue.h" -#include "src/core/surface/init.h" -#include "src/core/transport/metadata.h" -#include "src/core/transport/static_metadata.h" - -typedef struct listener { - void *arg; - void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, - grpc_pollset **pollsets, size_t pollset_count); - void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, - grpc_closure *closure); - struct listener *next; - grpc_closure destroy_done; -} listener; - -typedef struct call_data call_data; -typedef struct channel_data channel_data; -typedef struct registered_method registered_method; - -typedef struct { - call_data *next; - call_data *prev; -} call_link; - -typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type; - -typedef struct requested_call { - requested_call_type type; - void *tag; - grpc_server *server; - grpc_completion_queue *cq_bound_to_call; - grpc_completion_queue *cq_for_notification; - grpc_call **call; - grpc_cq_completion completion; - grpc_metadata_array *initial_metadata; - union { - struct { - grpc_call_details *details; - } batch; - struct { - registered_method *registered_method; - gpr_timespec *deadline; - grpc_byte_buffer **optional_payload; - } registered; - } data; - grpc_closure publish; -} requested_call; - -typedef struct channel_registered_method { - registered_method *server_registered_method; - grpc_mdstr *method; - grpc_mdstr *host; -} channel_registered_method; - -struct channel_data { - grpc_server *server; - grpc_connectivity_state connectivity_state; - grpc_channel *channel; - /* linked list of all channels on a server */ - channel_data *next; - channel_data *prev; - channel_registered_method *registered_methods; - uint32_t registered_method_slots; - uint32_t registered_method_max_probes; - grpc_closure finish_destroy_channel_closure; - grpc_closure channel_connectivity_changed; -}; - -typedef struct shutdown_tag { - void *tag; - grpc_completion_queue *cq; - grpc_cq_completion completion; -} shutdown_tag; - -typedef enum { - /* waiting for metadata */ - NOT_STARTED, - /* inital metadata read, not flow controlled in yet */ - PENDING, - /* flow controlled in, on completion queue */ - ACTIVATED, - /* cancelled before being queued */ - ZOMBIED -} call_state; - -typedef struct request_matcher request_matcher; - -struct call_data { - grpc_call *call; - - /** protects state */ - gpr_mu mu_state; - /** the current state of a call - see call_state */ - call_state state; - - grpc_mdstr *path; - grpc_mdstr *host; - gpr_timespec deadline; - - grpc_completion_queue *cq_new; - - grpc_metadata_batch *recv_initial_metadata; - grpc_metadata_array initial_metadata; - - grpc_closure got_initial_metadata; - grpc_closure server_on_recv_initial_metadata; - grpc_closure kill_zombie_closure; - grpc_closure *on_done_recv_initial_metadata; - - call_data *pending_next; -}; - -struct request_matcher { - call_data *pending_head; - call_data *pending_tail; - gpr_stack_lockfree *requests; -}; - -struct registered_method { - char *method; - char *host; - request_matcher request_matcher; - registered_method *next; -}; - -typedef struct { - grpc_channel **channels; - size_t num_channels; -} channel_broadcaster; - -struct grpc_server { - grpc_channel_args *channel_args; - - grpc_completion_queue **cqs; - grpc_pollset **pollsets; - size_t cq_count; - - /* The two following mutexes control access to server-state - mu_global controls access to non-call-related state (e.g., channel state) - mu_call controls access to call-related state (e.g., the call lists) - - If they are ever required to be nested, you must lock mu_global - before mu_call. This is currently used in shutdown processing - (grpc_server_shutdown_and_notify and maybe_finish_shutdown) */ - gpr_mu mu_global; /* mutex for server and channel state */ - gpr_mu mu_call; /* mutex for call-specific state */ - - registered_method *registered_methods; - request_matcher unregistered_request_matcher; - /** free list of available requested_calls indices */ - gpr_stack_lockfree *request_freelist; - /** requested call backing data */ - requested_call *requested_calls; - size_t max_requested_calls; - - gpr_atm shutdown_flag; - uint8_t shutdown_published; - size_t num_shutdown_tags; - shutdown_tag *shutdown_tags; - - channel_data root_channel_data; - - listener *listeners; - int listeners_destroyed; - gpr_refcount internal_refcount; - - /** when did we print the last shutdown progress message */ - gpr_timespec last_shutdown_message_time; -}; - -#define SERVER_FROM_CALL_ELEM(elem) \ - (((channel_data *)(elem)->channel_data)->server) - -static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server, - call_data *calld, requested_call *rc); -static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server, - requested_call *rc); -/* Before calling maybe_finish_shutdown, we must hold mu_global and not - hold mu_call */ -static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_server *server); - -/* - * channel broadcaster - */ - -/* assumes server locked */ -static void channel_broadcaster_init(grpc_server *s, channel_broadcaster *cb) { - channel_data *c; - size_t count = 0; - for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { - count++; - } - cb->num_channels = count; - cb->channels = gpr_malloc(sizeof(*cb->channels) * cb->num_channels); - count = 0; - for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { - cb->channels[count++] = c->channel; - GRPC_CHANNEL_INTERNAL_REF(c->channel, "broadcast"); - } -} - -struct shutdown_cleanup_args { - grpc_closure closure; - gpr_slice slice; -}; - -static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_status_ignored) { - struct shutdown_cleanup_args *a = arg; - gpr_slice_unref(a->slice); - gpr_free(a); -} - -static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel, - int send_goaway, int send_disconnect) { - grpc_transport_op op; - struct shutdown_cleanup_args *sc; - grpc_channel_element *elem; - - memset(&op, 0, sizeof(op)); - op.send_goaway = send_goaway; - sc = gpr_malloc(sizeof(*sc)); - sc->slice = gpr_slice_from_copied_string("Server shutdown"); - op.goaway_message = &sc->slice; - op.goaway_status = GRPC_STATUS_OK; - op.disconnect = send_disconnect; - grpc_closure_init(&sc->closure, shutdown_cleanup, sc); - op.on_consumed = &sc->closure; - - elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0); - elem->filter->start_transport_op(exec_ctx, elem, &op); -} - -static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx, - channel_broadcaster *cb, - int send_goaway, - int force_disconnect) { - size_t i; - - for (i = 0; i < cb->num_channels; i++) { - send_shutdown(exec_ctx, cb->channels[i], send_goaway, force_disconnect); - GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, cb->channels[i], "broadcast"); - } - gpr_free(cb->channels); -} - -/* - * request_matcher - */ - -static void request_matcher_init(request_matcher *rm, size_t entries) { - memset(rm, 0, sizeof(*rm)); - rm->requests = gpr_stack_lockfree_create(entries); -} - -static void request_matcher_destroy(request_matcher *rm) { - GPR_ASSERT(gpr_stack_lockfree_pop(rm->requests) == -1); - gpr_stack_lockfree_destroy(rm->requests); -} - -static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, bool success) { - grpc_call_destroy(grpc_call_from_top_element(elem)); -} - -static void request_matcher_zombify_all_pending_calls(grpc_exec_ctx *exec_ctx, - request_matcher *rm) { - while (rm->pending_head) { - call_data *calld = rm->pending_head; - rm->pending_head = calld->pending_next; - gpr_mu_lock(&calld->mu_state); - calld->state = ZOMBIED; - gpr_mu_unlock(&calld->mu_state); - grpc_closure_init( - &calld->kill_zombie_closure, kill_zombie, - grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0)); - grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL); - } -} - -static void request_matcher_kill_requests(grpc_exec_ctx *exec_ctx, - grpc_server *server, - request_matcher *rm) { - int request_id; - while ((request_id = gpr_stack_lockfree_pop(rm->requests)) != -1) { - fail_call(exec_ctx, server, &server->requested_calls[request_id]); - } -} - -/* - * server proper - */ - -static void server_ref(grpc_server *server) { - gpr_ref(&server->internal_refcount); -} - -static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) { - registered_method *rm; - size_t i; - grpc_channel_args_destroy(server->channel_args); - gpr_mu_destroy(&server->mu_global); - gpr_mu_destroy(&server->mu_call); - while ((rm = server->registered_methods) != NULL) { - server->registered_methods = rm->next; - request_matcher_destroy(&rm->request_matcher); - gpr_free(rm->method); - gpr_free(rm->host); - gpr_free(rm); - } - for (i = 0; i < server->cq_count; i++) { - GRPC_CQ_INTERNAL_UNREF(server->cqs[i], "server"); - } - request_matcher_destroy(&server->unregistered_request_matcher); - gpr_stack_lockfree_destroy(server->request_freelist); - gpr_free(server->cqs); - gpr_free(server->pollsets); - gpr_free(server->shutdown_tags); - gpr_free(server->requested_calls); - gpr_free(server); -} - -static void server_unref(grpc_exec_ctx *exec_ctx, grpc_server *server) { - if (gpr_unref(&server->internal_refcount)) { - server_delete(exec_ctx, server); - } -} - -static int is_channel_orphaned(channel_data *chand) { - return chand->next == chand; -} - -static void orphan_channel(channel_data *chand) { - chand->next->prev = chand->prev; - chand->prev->next = chand->next; - chand->next = chand->prev = chand; -} - -static void finish_destroy_channel(grpc_exec_ctx *exec_ctx, void *cd, - bool success) { - channel_data *chand = cd; - grpc_server *server = chand->server; - GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "server"); - server_unref(exec_ctx, server); -} - -static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand) { - if (is_channel_orphaned(chand)) return; - GPR_ASSERT(chand->server != NULL); - orphan_channel(chand); - server_ref(chand->server); - maybe_finish_shutdown(exec_ctx, chand->server); - chand->finish_destroy_channel_closure.cb = finish_destroy_channel; - chand->finish_destroy_channel_closure.cb_arg = chand; - - grpc_transport_op op; - memset(&op, 0, sizeof(op)); - op.set_accept_stream = true; - op.on_consumed = &chand->finish_destroy_channel_closure; - grpc_channel_next_op(exec_ctx, - grpc_channel_stack_element( - grpc_channel_get_channel_stack(chand->channel), 0), - &op); -} - -static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server, - grpc_call_element *elem, request_matcher *rm) { - call_data *calld = elem->call_data; - int request_id; - - if (gpr_atm_acq_load(&server->shutdown_flag)) { - gpr_mu_lock(&calld->mu_state); - calld->state = ZOMBIED; - gpr_mu_unlock(&calld->mu_state); - grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem); - grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL); - return; - } - - request_id = gpr_stack_lockfree_pop(rm->requests); - if (request_id == -1) { - gpr_mu_lock(&server->mu_call); - gpr_mu_lock(&calld->mu_state); - calld->state = PENDING; - gpr_mu_unlock(&calld->mu_state); - if (rm->pending_head == NULL) { - rm->pending_tail = rm->pending_head = calld; - } else { - rm->pending_tail->pending_next = calld; - rm->pending_tail = calld; - } - calld->pending_next = NULL; - gpr_mu_unlock(&server->mu_call); - } else { - gpr_mu_lock(&calld->mu_state); - calld->state = ACTIVATED; - gpr_mu_unlock(&calld->mu_state); - begin_call(exec_ctx, server, calld, &server->requested_calls[request_id]); - } -} - -static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { - channel_data *chand = elem->channel_data; - call_data *calld = elem->call_data; - grpc_server *server = chand->server; - uint32_t i; - uint32_t hash; - channel_registered_method *rm; - - if (chand->registered_methods && calld->path && calld->host) { - /* TODO(ctiller): unify these two searches */ - /* check for an exact match with host */ - hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash); - for (i = 0; i <= chand->registered_method_max_probes; i++) { - rm = &chand->registered_methods[(hash + i) % - chand->registered_method_slots]; - if (!rm) break; - if (rm->host != calld->host) continue; - if (rm->method != calld->path) continue; - finish_start_new_rpc(exec_ctx, server, elem, - &rm->server_registered_method->request_matcher); - return; - } - /* check for a wildcard method definition (no host set) */ - hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash); - for (i = 0; i <= chand->registered_method_max_probes; i++) { - rm = &chand->registered_methods[(hash + i) % - chand->registered_method_slots]; - if (!rm) break; - if (rm->host != NULL) continue; - if (rm->method != calld->path) continue; - finish_start_new_rpc(exec_ctx, server, elem, - &rm->server_registered_method->request_matcher); - return; - } - } - finish_start_new_rpc(exec_ctx, server, elem, - &server->unregistered_request_matcher); -} - -static int num_listeners(grpc_server *server) { - listener *l; - int n = 0; - for (l = server->listeners; l; l = l->next) { - n++; - } - return n; -} - -static void done_shutdown_event(grpc_exec_ctx *exec_ctx, void *server, - grpc_cq_completion *completion) { - server_unref(exec_ctx, server); -} - -static int num_channels(grpc_server *server) { - channel_data *chand; - int n = 0; - for (chand = server->root_channel_data.next; - chand != &server->root_channel_data; chand = chand->next) { - n++; - } - return n; -} - -static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx, - grpc_server *server) { - registered_method *rm; - request_matcher_kill_requests(exec_ctx, server, - &server->unregistered_request_matcher); - request_matcher_zombify_all_pending_calls( - exec_ctx, &server->unregistered_request_matcher); - for (rm = server->registered_methods; rm; rm = rm->next) { - request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher); - request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher); - } -} - -static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, - grpc_server *server) { - size_t i; - if (!gpr_atm_acq_load(&server->shutdown_flag) || server->shutdown_published) { - return; - } - - kill_pending_work_locked(exec_ctx, server); - - if (server->root_channel_data.next != &server->root_channel_data || - server->listeners_destroyed < num_listeners(server)) { - if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), - server->last_shutdown_message_time), - gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) { - server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME); - gpr_log(GPR_DEBUG, - "Waiting for %d channels and %d/%d listeners to be destroyed" - " before shutting down server", - num_channels(server), - num_listeners(server) - server->listeners_destroyed, - num_listeners(server)); - } - return; - } - server->shutdown_published = 1; - for (i = 0; i < server->num_shutdown_tags; i++) { - server_ref(server); - grpc_cq_end_op(exec_ctx, server->shutdown_tags[i].cq, - server->shutdown_tags[i].tag, 1, done_shutdown_event, server, - &server->shutdown_tags[i].completion); - } -} - -static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) { - grpc_call_element *elem = user_data; - call_data *calld = elem->call_data; - if (md->key == GRPC_MDSTR_PATH) { - calld->path = GRPC_MDSTR_REF(md->value); - return NULL; - } else if (md->key == GRPC_MDSTR_AUTHORITY) { - calld->host = GRPC_MDSTR_REF(md->value); - return NULL; - } - return md; -} - -static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr, - bool success) { - grpc_call_element *elem = ptr; - call_data *calld = elem->call_data; - gpr_timespec op_deadline; - - grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem); - op_deadline = calld->recv_initial_metadata->deadline; - if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) { - calld->deadline = op_deadline; - } - if (calld->host && calld->path) { - /* do nothing */ - } else { - success = 0; - } - - calld->on_done_recv_initial_metadata->cb( - exec_ctx, calld->on_done_recv_initial_metadata->cb_arg, success); -} - -static void server_mutate_op(grpc_call_element *elem, - grpc_transport_stream_op *op) { - call_data *calld = elem->call_data; - - if (op->recv_initial_metadata != NULL) { - calld->recv_initial_metadata = op->recv_initial_metadata; - calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready; - op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata; - } -} - -static void server_start_transport_stream_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - GRPC_CALL_LOG_OP(GPR_INFO, elem, op); - server_mutate_op(elem, op); - grpc_call_next_op(exec_ctx, elem, op); -} - -static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr, - bool success) { - grpc_call_element *elem = ptr; - call_data *calld = elem->call_data; - if (success) { - start_new_rpc(exec_ctx, elem); - } else { - gpr_mu_lock(&calld->mu_state); - if (calld->state == NOT_STARTED) { - calld->state = ZOMBIED; - gpr_mu_unlock(&calld->mu_state); - grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem); - grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL); - } else if (calld->state == PENDING) { - calld->state = ZOMBIED; - gpr_mu_unlock(&calld->mu_state); - /* zombied call will be destroyed when it's removed from the pending - queue... later */ - } else { - gpr_mu_unlock(&calld->mu_state); - } - } -} - -static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd, - grpc_transport *transport, - const void *transport_server_data) { - channel_data *chand = cd; - /* create a call */ - grpc_call *call = - grpc_call_create(chand->channel, NULL, 0, NULL, transport_server_data, - NULL, 0, gpr_inf_future(GPR_CLOCK_MONOTONIC)); - grpc_call_element *elem = - grpc_call_stack_element(grpc_call_get_call_stack(call), 0); - call_data *calld = elem->call_data; - grpc_op op; - memset(&op, 0, sizeof(op)); - op.op = GRPC_OP_RECV_INITIAL_METADATA; - op.data.recv_initial_metadata = &calld->initial_metadata; - grpc_closure_init(&calld->got_initial_metadata, got_initial_metadata, elem); - grpc_call_start_batch_and_execute(exec_ctx, call, &op, 1, - &calld->got_initial_metadata); -} - -static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd, - bool iomgr_status_ignored) { - channel_data *chand = cd; - grpc_server *server = chand->server; - if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) { - grpc_transport_op op; - memset(&op, 0, sizeof(op)); - op.on_connectivity_state_change = &chand->channel_connectivity_changed, - op.connectivity_state = &chand->connectivity_state; - grpc_channel_next_op(exec_ctx, - grpc_channel_stack_element( - grpc_channel_get_channel_stack(chand->channel), 0), - &op); - } else { - gpr_mu_lock(&server->mu_global); - destroy_channel(exec_ctx, chand); - gpr_mu_unlock(&server->mu_global); - GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "connectivity"); - } -} - -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - memset(calld, 0, sizeof(call_data)); - calld->deadline = gpr_inf_future(GPR_CLOCK_REALTIME); - calld->call = grpc_call_from_top_element(elem); - gpr_mu_init(&calld->mu_state); - - grpc_closure_init(&calld->server_on_recv_initial_metadata, - server_on_recv_initial_metadata, elem); - - server_ref(chand->server); -} - -static void destroy_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - channel_data *chand = elem->channel_data; - call_data *calld = elem->call_data; - - GPR_ASSERT(calld->state != PENDING); - - if (calld->host) { - GRPC_MDSTR_UNREF(calld->host); - } - if (calld->path) { - GRPC_MDSTR_UNREF(calld->path); - } - grpc_metadata_array_destroy(&calld->initial_metadata); - - gpr_mu_destroy(&calld->mu_state); - - server_unref(exec_ctx, chand->server); -} - -static void init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - channel_data *chand = elem->channel_data; - GPR_ASSERT(args->is_first); - GPR_ASSERT(!args->is_last); - chand->server = NULL; - chand->channel = NULL; - chand->next = chand->prev = chand; - chand->registered_methods = NULL; - chand->connectivity_state = GRPC_CHANNEL_IDLE; - grpc_closure_init(&chand->channel_connectivity_changed, - channel_connectivity_changed, chand); -} - -static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) { - size_t i; - channel_data *chand = elem->channel_data; - if (chand->registered_methods) { - for (i = 0; i < chand->registered_method_slots; i++) { - if (chand->registered_methods[i].method) { - GRPC_MDSTR_UNREF(chand->registered_methods[i].method); - } - if (chand->registered_methods[i].host) { - GRPC_MDSTR_UNREF(chand->registered_methods[i].host); - } - } - gpr_free(chand->registered_methods); - } - if (chand->server) { - gpr_mu_lock(&chand->server->mu_global); - chand->next->prev = chand->prev; - chand->prev->next = chand->next; - chand->next = chand->prev = chand; - maybe_finish_shutdown(exec_ctx, chand->server); - gpr_mu_unlock(&chand->server->mu_global); - server_unref(exec_ctx, chand->server); - } -} - -const grpc_channel_filter grpc_server_top_filter = { - server_start_transport_stream_op, - grpc_channel_next_op, - sizeof(call_data), - init_call_elem, - grpc_call_stack_ignore_set_pollset, - destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - grpc_call_next_get_peer, - "server", -}; - -void grpc_server_register_completion_queue(grpc_server *server, - grpc_completion_queue *cq, - void *reserved) { - size_t i, n; - GRPC_API_TRACE( - "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3, - (server, cq, reserved)); - GPR_ASSERT(!reserved); - for (i = 0; i < server->cq_count; i++) { - if (server->cqs[i] == cq) return; - } - GRPC_CQ_INTERNAL_REF(cq, "server"); - grpc_cq_mark_server_cq(cq); - n = server->cq_count++; - server->cqs = gpr_realloc(server->cqs, - server->cq_count * sizeof(grpc_completion_queue *)); - server->cqs[n] = cq; -} - -grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) { - size_t i; - - GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved)); - - grpc_server *server = gpr_malloc(sizeof(grpc_server)); - - GPR_ASSERT(grpc_is_initialized() && "call grpc_init()"); - - memset(server, 0, sizeof(grpc_server)); - - gpr_mu_init(&server->mu_global); - gpr_mu_init(&server->mu_call); - - /* decremented by grpc_server_destroy */ - gpr_ref_init(&server->internal_refcount, 1); - server->root_channel_data.next = server->root_channel_data.prev = - &server->root_channel_data; - - /* TODO(ctiller): expose a channel_arg for this */ - server->max_requested_calls = 32768; - server->request_freelist = - gpr_stack_lockfree_create(server->max_requested_calls); - for (i = 0; i < (size_t)server->max_requested_calls; i++) { - gpr_stack_lockfree_push(server->request_freelist, (int)i); - } - request_matcher_init(&server->unregistered_request_matcher, - server->max_requested_calls); - server->requested_calls = gpr_malloc(server->max_requested_calls * - sizeof(*server->requested_calls)); - - server->channel_args = grpc_channel_args_copy(args); - - return server; -} - -static int streq(const char *a, const char *b) { - if (a == NULL && b == NULL) return 1; - if (a == NULL) return 0; - if (b == NULL) return 0; - return 0 == strcmp(a, b); -} - -void *grpc_server_register_method(grpc_server *server, const char *method, - const char *host) { - registered_method *m; - GRPC_API_TRACE("grpc_server_register_method(server=%p, method=%s, host=%s)", - 3, (server, method, host)); - if (!method) { - gpr_log(GPR_ERROR, - "grpc_server_register_method method string cannot be NULL"); - return NULL; - } - for (m = server->registered_methods; m; m = m->next) { - if (streq(m->method, method) && streq(m->host, host)) { - gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method, - host ? host : "*"); - return NULL; - } - } - m = gpr_malloc(sizeof(registered_method)); - memset(m, 0, sizeof(*m)); - request_matcher_init(&m->request_matcher, server->max_requested_calls); - m->method = gpr_strdup(method); - m->host = gpr_strdup(host); - m->next = server->registered_methods; - server->registered_methods = m; - return m; -} - -void grpc_server_start(grpc_server *server) { - listener *l; - size_t i; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server)); - - server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count); - for (i = 0; i < server->cq_count; i++) { - server->pollsets[i] = grpc_cq_pollset(server->cqs[i]); - } - - for (l = server->listeners; l; l = l->next) { - l->start(&exec_ctx, server, l->arg, server->pollsets, server->cq_count); - } - - grpc_exec_ctx_finish(&exec_ctx); -} - -void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s, - grpc_transport *transport, - const grpc_channel_args *args) { - size_t i; - size_t num_registered_methods; - size_t alloc; - registered_method *rm; - channel_registered_method *crm; - grpc_channel *channel; - channel_data *chand; - grpc_mdstr *host; - grpc_mdstr *method; - uint32_t hash; - size_t slots; - uint32_t probes; - uint32_t max_probes = 0; - grpc_transport_op op; - - for (i = 0; i < s->cq_count; i++) { - memset(&op, 0, sizeof(op)); - op.bind_pollset = grpc_cq_pollset(s->cqs[i]); - grpc_transport_perform_op(exec_ctx, transport, &op); - } - - channel = - grpc_channel_create(exec_ctx, NULL, args, GRPC_SERVER_CHANNEL, transport); - chand = (channel_data *)grpc_channel_stack_element( - grpc_channel_get_channel_stack(channel), 0) - ->channel_data; - chand->server = s; - server_ref(s); - chand->channel = channel; - - num_registered_methods = 0; - for (rm = s->registered_methods; rm; rm = rm->next) { - num_registered_methods++; - } - /* build a lookup table phrased in terms of mdstr's in this channels context - to quickly find registered methods */ - if (num_registered_methods > 0) { - slots = 2 * num_registered_methods; - alloc = sizeof(channel_registered_method) * slots; - chand->registered_methods = gpr_malloc(alloc); - memset(chand->registered_methods, 0, alloc); - for (rm = s->registered_methods; rm; rm = rm->next) { - host = rm->host ? grpc_mdstr_from_string(rm->host) : NULL; - method = grpc_mdstr_from_string(rm->method); - hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash); - for (probes = 0; chand->registered_methods[(hash + probes) % slots] - .server_registered_method != NULL; - probes++) - ; - if (probes > max_probes) max_probes = probes; - crm = &chand->registered_methods[(hash + probes) % slots]; - crm->server_registered_method = rm; - crm->host = host; - crm->method = method; - } - GPR_ASSERT(slots <= UINT32_MAX); - chand->registered_method_slots = (uint32_t)slots; - chand->registered_method_max_probes = max_probes; - } - - gpr_mu_lock(&s->mu_global); - chand->next = &s->root_channel_data; - chand->prev = chand->next->prev; - chand->next->prev = chand->prev->next = chand; - gpr_mu_unlock(&s->mu_global); - - GRPC_CHANNEL_INTERNAL_REF(channel, "connectivity"); - memset(&op, 0, sizeof(op)); - op.set_accept_stream = true; - op.set_accept_stream_fn = accept_stream; - op.set_accept_stream_user_data = chand; - op.on_connectivity_state_change = &chand->channel_connectivity_changed; - op.connectivity_state = &chand->connectivity_state; - op.disconnect = gpr_atm_acq_load(&s->shutdown_flag) != 0; - grpc_transport_perform_op(exec_ctx, transport, &op); -} - -void done_published_shutdown(grpc_exec_ctx *exec_ctx, void *done_arg, - grpc_cq_completion *storage) { - (void)done_arg; - gpr_free(storage); -} - -static void listener_destroy_done(grpc_exec_ctx *exec_ctx, void *s, - bool success) { - grpc_server *server = s; - gpr_mu_lock(&server->mu_global); - server->listeners_destroyed++; - maybe_finish_shutdown(exec_ctx, server); - gpr_mu_unlock(&server->mu_global); -} - -void grpc_server_shutdown_and_notify(grpc_server *server, - grpc_completion_queue *cq, void *tag) { - listener *l; - shutdown_tag *sdt; - channel_broadcaster broadcaster; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3, - (server, cq, tag)); - - /* lock, and gather up some stuff to do */ - gpr_mu_lock(&server->mu_global); - grpc_cq_begin_op(cq, tag); - if (server->shutdown_published) { - grpc_cq_end_op(&exec_ctx, cq, tag, 1, done_published_shutdown, NULL, - gpr_malloc(sizeof(grpc_cq_completion))); - gpr_mu_unlock(&server->mu_global); - goto done; - } - server->shutdown_tags = - gpr_realloc(server->shutdown_tags, - sizeof(shutdown_tag) * (server->num_shutdown_tags + 1)); - sdt = &server->shutdown_tags[server->num_shutdown_tags++]; - sdt->tag = tag; - sdt->cq = cq; - if (gpr_atm_acq_load(&server->shutdown_flag)) { - gpr_mu_unlock(&server->mu_global); - goto done; - } - - server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME); - - channel_broadcaster_init(server, &broadcaster); - - gpr_atm_rel_store(&server->shutdown_flag, 1); - - /* collect all unregistered then registered calls */ - gpr_mu_lock(&server->mu_call); - kill_pending_work_locked(&exec_ctx, server); - gpr_mu_unlock(&server->mu_call); - - maybe_finish_shutdown(&exec_ctx, server); - gpr_mu_unlock(&server->mu_global); - - /* Shutdown listeners */ - for (l = server->listeners; l; l = l->next) { - grpc_closure_init(&l->destroy_done, listener_destroy_done, server); - l->destroy(&exec_ctx, server, l->arg, &l->destroy_done); - } - - channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0); - -done: - grpc_exec_ctx_finish(&exec_ctx); -} - -void grpc_server_cancel_all_calls(grpc_server *server) { - channel_broadcaster broadcaster; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - GRPC_API_TRACE("grpc_server_cancel_all_calls(server=%p)", 1, (server)); - - gpr_mu_lock(&server->mu_global); - channel_broadcaster_init(server, &broadcaster); - gpr_mu_unlock(&server->mu_global); - - channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, 1); - grpc_exec_ctx_finish(&exec_ctx); -} - -void grpc_server_destroy(grpc_server *server) { - listener *l; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - GRPC_API_TRACE("grpc_server_destroy(server=%p)", 1, (server)); - - gpr_mu_lock(&server->mu_global); - GPR_ASSERT(gpr_atm_acq_load(&server->shutdown_flag) || !server->listeners); - GPR_ASSERT(server->listeners_destroyed == num_listeners(server)); - - while (server->listeners) { - l = server->listeners; - server->listeners = l->next; - gpr_free(l); - } - - gpr_mu_unlock(&server->mu_global); - - server_unref(&exec_ctx, server); - grpc_exec_ctx_finish(&exec_ctx); -} - -void grpc_server_add_listener( - grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, - void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, - grpc_pollset **pollsets, size_t pollset_count), - void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, - grpc_closure *on_done)) { - listener *l = gpr_malloc(sizeof(listener)); - l->arg = arg; - l->start = start; - l->destroy = destroy; - l->next = server->listeners; - server->listeners = l; -} - -static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx, - grpc_server *server, - requested_call *rc) { - call_data *calld = NULL; - request_matcher *rm = NULL; - int request_id; - if (gpr_atm_acq_load(&server->shutdown_flag)) { - fail_call(exec_ctx, server, rc); - return GRPC_CALL_OK; - } - request_id = gpr_stack_lockfree_pop(server->request_freelist); - if (request_id == -1) { - /* out of request ids: just fail this one */ - fail_call(exec_ctx, server, rc); - return GRPC_CALL_OK; - } - switch (rc->type) { - case BATCH_CALL: - rm = &server->unregistered_request_matcher; - break; - case REGISTERED_CALL: - rm = &rc->data.registered.registered_method->request_matcher; - break; - } - server->requested_calls[request_id] = *rc; - gpr_free(rc); - if (gpr_stack_lockfree_push(rm->requests, request_id)) { - /* this was the first queued request: we need to lock and start - matching calls */ - gpr_mu_lock(&server->mu_call); - while ((calld = rm->pending_head) != NULL) { - request_id = gpr_stack_lockfree_pop(rm->requests); - if (request_id == -1) break; - rm->pending_head = calld->pending_next; - gpr_mu_unlock(&server->mu_call); - gpr_mu_lock(&calld->mu_state); - if (calld->state == ZOMBIED) { - gpr_mu_unlock(&calld->mu_state); - grpc_closure_init( - &calld->kill_zombie_closure, kill_zombie, - grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0)); - grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, - NULL); - } else { - GPR_ASSERT(calld->state == PENDING); - calld->state = ACTIVATED; - gpr_mu_unlock(&calld->mu_state); - begin_call(exec_ctx, server, calld, - &server->requested_calls[request_id]); - } - gpr_mu_lock(&server->mu_call); - } - gpr_mu_unlock(&server->mu_call); - } - return GRPC_CALL_OK; -} - -grpc_call_error grpc_server_request_call( - grpc_server *server, grpc_call **call, grpc_call_details *details, - grpc_metadata_array *initial_metadata, - grpc_completion_queue *cq_bound_to_call, - grpc_completion_queue *cq_for_notification, void *tag) { - grpc_call_error error; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - requested_call *rc = gpr_malloc(sizeof(*rc)); - GRPC_API_TRACE( - "grpc_server_request_call(" - "server=%p, call=%p, details=%p, initial_metadata=%p, " - "cq_bound_to_call=%p, cq_for_notification=%p, tag=%p)", - 7, (server, call, details, initial_metadata, cq_bound_to_call, - cq_for_notification, tag)); - if (!grpc_cq_is_server_cq(cq_for_notification)) { - gpr_free(rc); - error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE; - goto done; - } - grpc_cq_begin_op(cq_for_notification, tag); - details->reserved = NULL; - rc->type = BATCH_CALL; - rc->server = server; - rc->tag = tag; - rc->cq_bound_to_call = cq_bound_to_call; - rc->cq_for_notification = cq_for_notification; - rc->call = call; - rc->data.batch.details = details; - rc->initial_metadata = initial_metadata; - error = queue_call_request(&exec_ctx, server, rc); -done: - grpc_exec_ctx_finish(&exec_ctx); - return error; -} - -grpc_call_error grpc_server_request_registered_call( - grpc_server *server, void *rmp, grpc_call **call, gpr_timespec *deadline, - grpc_metadata_array *initial_metadata, grpc_byte_buffer **optional_payload, - grpc_completion_queue *cq_bound_to_call, - grpc_completion_queue *cq_for_notification, void *tag) { - grpc_call_error error; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - requested_call *rc = gpr_malloc(sizeof(*rc)); - registered_method *rm = rmp; - GRPC_API_TRACE( - "grpc_server_request_registered_call(" - "server=%p, rmp=%p, call=%p, deadline=%p, initial_metadata=%p, " - "optional_payload=%p, cq_bound_to_call=%p, cq_for_notification=%p, " - "tag=%p)", - 9, (server, rmp, call, deadline, initial_metadata, optional_payload, - cq_bound_to_call, cq_for_notification, tag)); - if (!grpc_cq_is_server_cq(cq_for_notification)) { - gpr_free(rc); - error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE; - goto done; - } - grpc_cq_begin_op(cq_for_notification, tag); - rc->type = REGISTERED_CALL; - rc->server = server; - rc->tag = tag; - rc->cq_bound_to_call = cq_bound_to_call; - rc->cq_for_notification = cq_for_notification; - rc->call = call; - rc->data.registered.registered_method = rm; - rc->data.registered.deadline = deadline; - rc->initial_metadata = initial_metadata; - rc->data.registered.optional_payload = optional_payload; - error = queue_call_request(&exec_ctx, server, rc); -done: - grpc_exec_ctx_finish(&exec_ctx); - return error; -} - -static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, - void *user_data, bool success); - -static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) { - gpr_slice slice = value->slice; - size_t len = GPR_SLICE_LENGTH(slice); - - if (len + 1 > *capacity) { - *capacity = GPR_MAX(len + 1, *capacity * 2); - *dest = gpr_realloc(*dest, *capacity); - } - memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1); -} - -static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server, - call_data *calld, requested_call *rc) { - grpc_op ops[1]; - grpc_op *op = ops; - - memset(ops, 0, sizeof(ops)); - - /* called once initial metadata has been read by the call, but BEFORE - the ioreq to fetch it out of the call has been executed. - This means metadata related fields can be relied on in calld, but to - fill in the metadata array passed by the client, we need to perform - an ioreq op, that should complete immediately. */ - - grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call); - grpc_closure_init(&rc->publish, publish_registered_or_batch, rc); - *rc->call = calld->call; - calld->cq_new = rc->cq_for_notification; - GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata); - switch (rc->type) { - case BATCH_CALL: - GPR_ASSERT(calld->host != NULL); - GPR_ASSERT(calld->path != NULL); - cpstr(&rc->data.batch.details->host, - &rc->data.batch.details->host_capacity, calld->host); - cpstr(&rc->data.batch.details->method, - &rc->data.batch.details->method_capacity, calld->path); - rc->data.batch.details->deadline = calld->deadline; - break; - case REGISTERED_CALL: - *rc->data.registered.deadline = calld->deadline; - if (rc->data.registered.optional_payload) { - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message = rc->data.registered.optional_payload; - op++; - } - break; - default: - GPR_UNREACHABLE_CODE(return ); - } - - GRPC_CALL_INTERNAL_REF(calld->call, "server"); - grpc_call_start_batch_and_execute(exec_ctx, calld->call, ops, - (size_t)(op - ops), &rc->publish); -} - -static void done_request_event(grpc_exec_ctx *exec_ctx, void *req, - grpc_cq_completion *c) { - requested_call *rc = req; - grpc_server *server = rc->server; - - if (rc >= server->requested_calls && - rc < server->requested_calls + server->max_requested_calls) { - GPR_ASSERT(rc - server->requested_calls <= INT_MAX); - gpr_stack_lockfree_push(server->request_freelist, - (int)(rc - server->requested_calls)); - } else { - gpr_free(req); - } - - server_unref(exec_ctx, server); -} - -static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server, - requested_call *rc) { - *rc->call = NULL; - rc->initial_metadata->count = 0; - - server_ref(server); - grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0, - done_request_event, rc, &rc->completion); -} - -static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, void *prc, - bool success) { - requested_call *rc = prc; - grpc_call *call = *rc->call; - grpc_call_element *elem = - grpc_call_stack_element(grpc_call_get_call_stack(call), 0); - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - server_ref(chand->server); - grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, success, done_request_event, - rc, &rc->completion); - GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "server"); -} - -const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) { - return server->channel_args; -} - -int grpc_server_has_open_connections(grpc_server *server) { - int r; - gpr_mu_lock(&server->mu_global); - r = server->root_channel_data.next != &server->root_channel_data; - gpr_mu_unlock(&server->mu_global); - return r; -} diff --git a/src/core/surface/server.h b/src/core/surface/server.h deleted file mode 100644 index cd62eadd7f..0000000000 --- a/src/core/surface/server.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * Copyright 2015-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_SURFACE_SERVER_H -#define GRPC_CORE_SURFACE_SERVER_H - -#include -#include "src/core/channel/channel_stack.h" -#include "src/core/transport/transport.h" - -extern const grpc_channel_filter grpc_server_top_filter; - -/* Add a listener to the server: when the server starts, it will call start, - and when it shuts down, it will call destroy */ -void grpc_server_add_listener( - grpc_exec_ctx *exec_ctx, grpc_server *server, void *listener, - void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, - grpc_pollset **pollsets, size_t npollsets), - void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg, - grpc_closure *on_done)); - -/* Setup a transport - creates a channel stack, binds the transport to the - server */ -void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *server, - grpc_transport *transport, - const grpc_channel_args *args); - -const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server); - -int grpc_server_has_open_connections(grpc_server *server); - -#endif /* GRPC_CORE_SURFACE_SERVER_H */ diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c deleted file mode 100644 index 546760ecfa..0000000000 --- a/src/core/surface/server_chttp2.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * - * Copyright 2015-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 - -#include -#include -#include -#include "src/core/channel/http_server_filter.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/tcp_server.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" - -static void setup_transport(grpc_exec_ctx *exec_ctx, void *server, - grpc_transport *transport) { - grpc_server_setup_transport(exec_ctx, server, transport, - grpc_server_get_channel_args(server)); -} - -static void new_transport(grpc_exec_ctx *exec_ctx, void *server, - grpc_endpoint *tcp, - grpc_tcp_server_acceptor *acceptor) { - /* - * Beware that the call to grpc_create_chttp2_transport() has to happen before - * grpc_tcp_server_destroy(). This is fine here, but similar code - * asynchronously doing a handshake instead of calling grpc_tcp_server_start() - * (as in server_secure_chttp2.c) needs to add synchronization to avoid this - * case. - */ - grpc_transport *transport = grpc_create_chttp2_transport( - exec_ctx, grpc_server_get_channel_args(server), tcp, 0); - setup_transport(exec_ctx, server, transport); - grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); -} - -/* Server callback: start listening on our ports */ -static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, - grpc_pollset **pollsets, size_t pollset_count) { - grpc_tcp_server *tcp = tcpp; - grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, new_transport, - server); -} - -/* Server callback: destroy the tcp listener (so we don't generate further - callbacks) */ -static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, - grpc_closure *destroy_done) { - grpc_tcp_server *tcp = tcpp; - grpc_tcp_server_unref(exec_ctx, tcp); - grpc_exec_ctx_enqueue(exec_ctx, destroy_done, true, NULL); -} - -int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) { - grpc_resolved_addresses *resolved = NULL; - grpc_tcp_server *tcp = NULL; - size_t i; - unsigned count = 0; - int port_num = -1; - int port_temp; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - - GRPC_API_TRACE("grpc_server_add_insecure_http2_port(server=%p, addr=%s)", 2, - (server, addr)); - - resolved = grpc_blocking_resolve_address(addr, "http"); - if (!resolved) { - goto error; - } - - tcp = grpc_tcp_server_create(NULL); - GPR_ASSERT(tcp); - - for (i = 0; i < resolved->naddrs; i++) { - port_temp = grpc_tcp_server_add_port( - tcp, (struct sockaddr *)&resolved->addrs[i].addr, - resolved->addrs[i].len); - if (port_temp > 0) { - if (port_num == -1) { - port_num = port_temp; - } else { - GPR_ASSERT(port_num == port_temp); - } - count++; - } - } - if (count == 0) { - gpr_log(GPR_ERROR, "No address added out of total %d resolved", - resolved->naddrs); - goto error; - } - if (count != resolved->naddrs) { - gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved", - count, resolved->naddrs); - } - grpc_resolved_addresses_destroy(resolved); - - /* Register with the server only upon success */ - grpc_server_add_listener(&exec_ctx, server, tcp, start, destroy); - goto done; - -/* Error path: cleanup and return */ -error: - if (resolved) { - grpc_resolved_addresses_destroy(resolved); - } - if (tcp) { - grpc_tcp_server_unref(&exec_ctx, tcp); - } - port_num = 0; - -done: - grpc_exec_ctx_finish(&exec_ctx); - return port_num; -} diff --git a/src/core/surface/surface_trace.h b/src/core/surface/surface_trace.h deleted file mode 100644 index a55a88e44d..0000000000 --- a/src/core/surface/surface_trace.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright 2015-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_SURFACE_SURFACE_TRACE_H -#define GRPC_CORE_SURFACE_SURFACE_TRACE_H - -#include -#include "src/core/debug/trace.h" -#include "src/core/surface/api_trace.h" - -#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \ - if (grpc_api_trace) { \ - char *_ev = grpc_event_string(event); \ - gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \ - gpr_free(_ev); \ - } - -#endif /* GRPC_CORE_SURFACE_SURFACE_TRACE_H */ diff --git a/src/core/surface/validate_metadata.c b/src/core/surface/validate_metadata.c deleted file mode 100644 index bf4126867f..0000000000 --- a/src/core/surface/validate_metadata.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * - * 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 -#include - -#include - -static int conforms_to(const char *s, size_t len, const uint8_t *legal_bits) { - const char *p = s; - const char *e = s + len; - for (; p != e; p++) { - int idx = *p; - int byte = idx / 8; - int bit = idx % 8; - if ((legal_bits[byte] & (1 << bit)) == 0) return 0; - } - return 1; -} - -int grpc_header_key_is_legal(const char *key, size_t length) { - static const uint8_t legal_header_bits[256 / 8] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0x00, 0x00, 0x00, - 0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - if (length == 0) { - return 0; - } - return conforms_to(key, length, legal_header_bits); -} - -int grpc_header_nonbin_value_is_legal(const char *value, size_t length) { - static const uint8_t legal_header_bits[256 / 8] = { - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - return conforms_to(value, length, legal_header_bits); -} - -int grpc_is_binary_header(const char *key, size_t length) { - if (length < 5) return 0; - return 0 == memcmp(key + length - 4, "-bin", 4); -} diff --git a/src/core/surface/version.c b/src/core/surface/version.c deleted file mode 100644 index 7723f39401..0000000000 --- a/src/core/surface/version.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* This file is autogenerated from: - templates/src/core/surface/version.c.template */ - -#include - -const char *grpc_version_string(void) { return "0.14.0-dev"; } diff --git a/src/core/transport/byte_stream.c b/src/core/transport/byte_stream.c deleted file mode 100644 index 8e6fb2cbef..0000000000 --- a/src/core/transport/byte_stream.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/byte_stream.h" - -#include - -#include - -int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, gpr_slice *slice, - size_t max_size_hint, grpc_closure *on_complete) { - return byte_stream->next(exec_ctx, byte_stream, slice, max_size_hint, - on_complete); -} - -void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream) { - byte_stream->destroy(exec_ctx, byte_stream); -} - -/* slice_buffer_stream */ - -static int slice_buffer_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, - gpr_slice *slice, size_t max_size_hint, - grpc_closure *on_complete) { - grpc_slice_buffer_stream *stream = (grpc_slice_buffer_stream *)byte_stream; - GPR_ASSERT(stream->cursor < stream->backing_buffer->count); - *slice = gpr_slice_ref(stream->backing_buffer->slices[stream->cursor]); - stream->cursor++; - return 1; -} - -static void slice_buffer_stream_destroy(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream) {} - -void grpc_slice_buffer_stream_init(grpc_slice_buffer_stream *stream, - gpr_slice_buffer *slice_buffer, - uint32_t flags) { - GPR_ASSERT(slice_buffer->length <= UINT32_MAX); - stream->base.length = (uint32_t)slice_buffer->length; - stream->base.flags = flags; - stream->base.next = slice_buffer_stream_next; - stream->base.destroy = slice_buffer_stream_destroy; - stream->backing_buffer = slice_buffer; - stream->cursor = 0; -} diff --git a/src/core/transport/byte_stream.h b/src/core/transport/byte_stream.h deleted file mode 100644 index ab42d07e7e..0000000000 --- a/src/core/transport/byte_stream.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_BYTE_STREAM_H -#define GRPC_CORE_TRANSPORT_BYTE_STREAM_H - -#include -#include "src/core/iomgr/exec_ctx.h" - -/** Internal bit flag for grpc_begin_message's \a flags signaling the use of - * compression for the message */ -#define GRPC_WRITE_INTERNAL_COMPRESS (0x80000000u) -/** Mask of all valid internal flags. */ -#define GRPC_WRITE_INTERNAL_USED_MASK (GRPC_WRITE_INTERNAL_COMPRESS) - -struct grpc_byte_stream; -typedef struct grpc_byte_stream grpc_byte_stream; - -struct grpc_byte_stream { - uint32_t length; - uint32_t flags; - int (*next)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream, - gpr_slice *slice, size_t max_size_hint, - grpc_closure *on_complete); - void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_byte_stream *byte_stream); -}; - -/* returns 1 if the bytes are available immediately (in which case - * on_complete will not be called), 0 if the bytes will be available - * asynchronously. - * - * on entry, *remaining can be set as a hint as to the maximum number - * of bytes that would be acceptable to read. - * - * fills *buffer, *length, *remaining with the bytes, length of bytes - * and length of data remaining to be read before either returning 1 - * or calling on_complete. - * - * once a slice is returned into *slice, it is owned by the caller. - */ -int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, gpr_slice *slice, - size_t max_size_hint, grpc_closure *on_complete); - -void grpc_byte_stream_destroy(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream); - -/* grpc_byte_stream that wraps a slice buffer */ -typedef struct grpc_slice_buffer_stream { - grpc_byte_stream base; - gpr_slice_buffer *backing_buffer; - size_t cursor; -} grpc_slice_buffer_stream; - -void grpc_slice_buffer_stream_init(grpc_slice_buffer_stream *stream, - gpr_slice_buffer *slice_buffer, - uint32_t flags); - -#endif /* GRPC_CORE_TRANSPORT_BYTE_STREAM_H */ diff --git a/src/core/transport/chttp2/alpn.c b/src/core/transport/chttp2/alpn.c deleted file mode 100644 index 69da4e6718..0000000000 --- a/src/core/transport/chttp2/alpn.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/chttp2/alpn.h" -#include -#include - -/* in order of preference */ -static const char *const supported_versions[] = {"h2"}; - -int grpc_chttp2_is_alpn_version_supported(const char *version, size_t size) { - size_t i; - for (i = 0; i < GPR_ARRAY_SIZE(supported_versions); i++) { - if (!strncmp(version, supported_versions[i], size)) return 1; - } - return 0; -} - -size_t grpc_chttp2_num_alpn_versions(void) { - return GPR_ARRAY_SIZE(supported_versions); -} - -const char *grpc_chttp2_get_alpn_version_index(size_t i) { - GPR_ASSERT(i < GPR_ARRAY_SIZE(supported_versions)); - return supported_versions[i]; -} diff --git a/src/core/transport/chttp2/alpn.h b/src/core/transport/chttp2/alpn.h deleted file mode 100644 index 68010e3155..0000000000 --- a/src/core/transport/chttp2/alpn.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_ALPN_H -#define GRPC_CORE_TRANSPORT_CHTTP2_ALPN_H - -#include - -/* Retuns 1 if the version is supported, 0 otherwise. */ -int grpc_chttp2_is_alpn_version_supported(const char *version, size_t size); - -/* Returns the number of protocol versions to advertise */ -size_t grpc_chttp2_num_alpn_versions(void); - -/* Returns the protocol version at index i (0 <= i < - * grpc_chttp2_num_alpn_versions()) */ -const char *grpc_chttp2_get_alpn_version_index(size_t i); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_ALPN_H */ diff --git a/src/core/transport/chttp2/bin_encoder.c b/src/core/transport/chttp2/bin_encoder.c deleted file mode 100644 index 3d31162499..0000000000 --- a/src/core/transport/chttp2/bin_encoder.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * - * Copyright 2015-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/transport/chttp2/bin_encoder.h" - -#include - -#include -#include "src/core/transport/chttp2/huffsyms.h" - -static const char alphabet[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -typedef struct { - uint16_t bits; - uint8_t length; -} b64_huff_sym; - -static const b64_huff_sym huff_alphabet[64] = { - {0x21, 6}, {0x5d, 7}, {0x5e, 7}, {0x5f, 7}, {0x60, 7}, {0x61, 7}, - {0x62, 7}, {0x63, 7}, {0x64, 7}, {0x65, 7}, {0x66, 7}, {0x67, 7}, - {0x68, 7}, {0x69, 7}, {0x6a, 7}, {0x6b, 7}, {0x6c, 7}, {0x6d, 7}, - {0x6e, 7}, {0x6f, 7}, {0x70, 7}, {0x71, 7}, {0x72, 7}, {0xfc, 8}, - {0x73, 7}, {0xfd, 8}, {0x3, 5}, {0x23, 6}, {0x4, 5}, {0x24, 6}, - {0x5, 5}, {0x25, 6}, {0x26, 6}, {0x27, 6}, {0x6, 5}, {0x74, 7}, - {0x75, 7}, {0x28, 6}, {0x29, 6}, {0x2a, 6}, {0x7, 5}, {0x2b, 6}, - {0x76, 7}, {0x2c, 6}, {0x8, 5}, {0x9, 5}, {0x2d, 6}, {0x77, 7}, - {0x78, 7}, {0x79, 7}, {0x7a, 7}, {0x7b, 7}, {0x0, 5}, {0x1, 5}, - {0x2, 5}, {0x19, 6}, {0x1a, 6}, {0x1b, 6}, {0x1c, 6}, {0x1d, 6}, - {0x1e, 6}, {0x1f, 6}, {0x7fb, 11}, {0x18, 6}}; - -static const uint8_t tail_xtra[3] = {0, 2, 3}; - -gpr_slice grpc_chttp2_base64_encode(gpr_slice input) { - size_t input_length = GPR_SLICE_LENGTH(input); - size_t input_triplets = input_length / 3; - size_t tail_case = input_length % 3; - size_t output_length = input_triplets * 4 + tail_xtra[tail_case]; - gpr_slice output = gpr_slice_malloc(output_length); - uint8_t *in = GPR_SLICE_START_PTR(input); - char *out = (char *)GPR_SLICE_START_PTR(output); - size_t i; - - /* encode full triplets */ - for (i = 0; i < input_triplets; i++) { - out[0] = alphabet[in[0] >> 2]; - out[1] = alphabet[((in[0] & 0x3) << 4) | (in[1] >> 4)]; - out[2] = alphabet[((in[1] & 0xf) << 2) | (in[2] >> 6)]; - out[3] = alphabet[in[2] & 0x3f]; - out += 4; - in += 3; - } - - /* encode the remaining bytes */ - switch (tail_case) { - case 0: - break; - case 1: - out[0] = alphabet[in[0] >> 2]; - out[1] = alphabet[(in[0] & 0x3) << 4]; - out += 2; - in += 1; - break; - case 2: - out[0] = alphabet[in[0] >> 2]; - out[1] = alphabet[((in[0] & 0x3) << 4) | (in[1] >> 4)]; - out[2] = alphabet[(in[1] & 0xf) << 2]; - out += 3; - in += 2; - break; - } - - GPR_ASSERT(out == (char *)GPR_SLICE_END_PTR(output)); - GPR_ASSERT(in == GPR_SLICE_END_PTR(input)); - return output; -} - -gpr_slice grpc_chttp2_huffman_compress(gpr_slice input) { - size_t nbits; - uint8_t *in; - uint8_t *out; - gpr_slice output; - uint32_t temp = 0; - uint32_t temp_length = 0; - - nbits = 0; - for (in = GPR_SLICE_START_PTR(input); in != GPR_SLICE_END_PTR(input); ++in) { - nbits += grpc_chttp2_huffsyms[*in].length; - } - - output = gpr_slice_malloc(nbits / 8 + (nbits % 8 != 0)); - out = GPR_SLICE_START_PTR(output); - for (in = GPR_SLICE_START_PTR(input); in != GPR_SLICE_END_PTR(input); ++in) { - int sym = *in; - temp <<= grpc_chttp2_huffsyms[sym].length; - temp |= grpc_chttp2_huffsyms[sym].bits; - temp_length += grpc_chttp2_huffsyms[sym].length; - - while (temp_length > 8) { - temp_length -= 8; - *out++ = (uint8_t)(temp >> temp_length); - } - } - - if (temp_length) { - /* NB: the following integer arithmetic operation needs to be in its - * expanded form due to the "integral promotion" performed (see section - * 3.2.1.1 of the C89 draft standard). A cast to the smaller container type - * is then required to avoid the compiler warning */ - *out++ = (uint8_t)((uint8_t)(temp << (8u - temp_length)) | - (uint8_t)(0xffu >> temp_length)); - } - - GPR_ASSERT(out == GPR_SLICE_END_PTR(output)); - - return output; -} - -typedef struct { - uint32_t temp; - uint32_t temp_length; - uint8_t *out; -} huff_out; - -static void enc_flush_some(huff_out *out) { - while (out->temp_length > 8) { - out->temp_length -= 8; - *out->out++ = (uint8_t)(out->temp >> out->temp_length); - } -} - -static void enc_add2(huff_out *out, uint8_t a, uint8_t b) { - b64_huff_sym sa = huff_alphabet[a]; - b64_huff_sym sb = huff_alphabet[b]; - out->temp = (out->temp << (sa.length + sb.length)) | - ((uint32_t)sa.bits << sb.length) | sb.bits; - out->temp_length += (uint32_t)sa.length + (uint32_t)sb.length; - enc_flush_some(out); -} - -static void enc_add1(huff_out *out, uint8_t a) { - b64_huff_sym sa = huff_alphabet[a]; - out->temp = (out->temp << sa.length) | sa.bits; - out->temp_length += sa.length; - enc_flush_some(out); -} - -gpr_slice grpc_chttp2_base64_encode_and_huffman_compress(gpr_slice input) { - size_t input_length = GPR_SLICE_LENGTH(input); - size_t input_triplets = input_length / 3; - size_t tail_case = input_length % 3; - size_t output_syms = input_triplets * 4 + tail_xtra[tail_case]; - size_t max_output_bits = 11 * output_syms; - size_t max_output_length = max_output_bits / 8 + (max_output_bits % 8 != 0); - gpr_slice output = gpr_slice_malloc(max_output_length); - uint8_t *in = GPR_SLICE_START_PTR(input); - uint8_t *start_out = GPR_SLICE_START_PTR(output); - huff_out out; - size_t i; - - out.temp = 0; - out.temp_length = 0; - out.out = start_out; - - /* encode full triplets */ - for (i = 0; i < input_triplets; i++) { - enc_add2(&out, in[0] >> 2, (uint8_t)((in[0] & 0x3) << 4) | (in[1] >> 4)); - enc_add2(&out, (uint8_t)((in[1] & 0xf) << 2) | (in[2] >> 6), - (uint8_t)(in[2] & 0x3f)); - in += 3; - } - - /* encode the remaining bytes */ - switch (tail_case) { - case 0: - break; - case 1: - enc_add2(&out, in[0] >> 2, (uint8_t)((in[0] & 0x3) << 4)); - in += 1; - break; - case 2: - enc_add2(&out, in[0] >> 2, - (uint8_t)((in[0] & 0x3) << 4) | (uint8_t)(in[1] >> 4)); - enc_add1(&out, (uint8_t)((in[1] & 0xf) << 2)); - in += 2; - break; - } - - if (out.temp_length) { - /* NB: the following integer arithmetic operation needs to be in its - * expanded form due to the "integral promotion" performed (see section - * 3.2.1.1 of the C89 draft standard). A cast to the smaller container type - * is then required to avoid the compiler warning */ - *out.out++ = (uint8_t)((uint8_t)(out.temp << (8u - out.temp_length)) | - (uint8_t)(0xffu >> out.temp_length)); - } - - GPR_ASSERT(out.out <= GPR_SLICE_END_PTR(output)); - GPR_SLICE_SET_LENGTH(output, out.out - start_out); - - GPR_ASSERT(in == GPR_SLICE_END_PTR(input)); - return output; -} diff --git a/src/core/transport/chttp2/bin_encoder.h b/src/core/transport/chttp2/bin_encoder.h deleted file mode 100644 index edb6f2dad1..0000000000 --- a/src/core/transport/chttp2/bin_encoder.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_BIN_ENCODER_H -#define GRPC_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H - -#include - -/* base64 encode a slice. Returns a new slice, does not take ownership of the - input */ -gpr_slice grpc_chttp2_base64_encode(gpr_slice input); - -/* Compress a slice with the static huffman encoder detailed in the hpack - standard. Returns a new slice, does not take ownership of the input */ -gpr_slice grpc_chttp2_huffman_compress(gpr_slice input); - -/* equivalent to: - gpr_slice x = grpc_chttp2_base64_encode(input); - gpr_slice y = grpc_chttp2_huffman_compress(x); - gpr_slice_unref(x); - return y; */ -gpr_slice grpc_chttp2_base64_encode_and_huffman_compress(gpr_slice input); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H */ diff --git a/src/core/transport/chttp2/frame.h b/src/core/transport/chttp2/frame.h deleted file mode 100644 index 560a6675af..0000000000 --- a/src/core/transport/chttp2/frame.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_H - -#include -#include - -/* Common definitions for frame handling in the chttp2 transport */ - -typedef enum { - GRPC_CHTTP2_PARSE_OK, - GRPC_CHTTP2_STREAM_ERROR, - GRPC_CHTTP2_CONNECTION_ERROR -} grpc_chttp2_parse_error; - -/* defined in internal.h */ -typedef struct grpc_chttp2_stream_parsing grpc_chttp2_stream_parsing; -typedef struct grpc_chttp2_transport_parsing grpc_chttp2_transport_parsing; - -#define GRPC_CHTTP2_FRAME_DATA 0 -#define GRPC_CHTTP2_FRAME_HEADER 1 -#define GRPC_CHTTP2_FRAME_CONTINUATION 9 -#define GRPC_CHTTP2_FRAME_RST_STREAM 3 -#define GRPC_CHTTP2_FRAME_SETTINGS 4 -#define GRPC_CHTTP2_FRAME_PING 6 -#define GRPC_CHTTP2_FRAME_GOAWAY 7 -#define GRPC_CHTTP2_FRAME_WINDOW_UPDATE 8 - -#define GRPC_CHTTP2_MAX_PAYLOAD_LENGTH ((1 << 14) - 1) - -#define GRPC_CHTTP2_DATA_FLAG_END_STREAM 1 -#define GRPC_CHTTP2_FLAG_ACK 1 -#define GRPC_CHTTP2_DATA_FLAG_END_HEADERS 4 -#define GRPC_CHTTP2_DATA_FLAG_PADDED 8 -#define GRPC_CHTTP2_FLAG_HAS_PRIORITY 0x20 - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_H */ diff --git a/src/core/transport/chttp2/frame_data.c b/src/core/transport/chttp2/frame_data.c deleted file mode 100644 index 6cc6d4eaf2..0000000000 --- a/src/core/transport/chttp2/frame_data.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * - * Copyright 2015-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/transport/chttp2/frame_data.h" - -#include - -#include -#include -#include -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/internal.h" -#include "src/core/transport/transport.h" - -grpc_chttp2_parse_error grpc_chttp2_data_parser_init( - grpc_chttp2_data_parser *parser) { - parser->state = GRPC_CHTTP2_DATA_FH_0; - parser->parsing_frame = NULL; - return GRPC_CHTTP2_PARSE_OK; -} - -void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, - grpc_chttp2_data_parser *parser) { - grpc_byte_stream *bs; - if (parser->parsing_frame) { - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, parser->parsing_frame, - 0, 1); - } - while ( - (bs = grpc_chttp2_incoming_frame_queue_pop(&parser->incoming_frames))) { - grpc_byte_stream_destroy(exec_ctx, bs); - } -} - -grpc_chttp2_parse_error grpc_chttp2_data_parser_begin_frame( - grpc_chttp2_data_parser *parser, uint8_t flags) { - if (flags & ~GRPC_CHTTP2_DATA_FLAG_END_STREAM) { - gpr_log(GPR_ERROR, "unsupported data flags: 0x%02x", flags); - return GRPC_CHTTP2_STREAM_ERROR; - } - - if (flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) { - parser->is_last_frame = 1; - } else { - parser->is_last_frame = 0; - } - - return GRPC_CHTTP2_PARSE_OK; -} - -void grpc_chttp2_incoming_frame_queue_merge( - grpc_chttp2_incoming_frame_queue *head_dst, - grpc_chttp2_incoming_frame_queue *tail_src) { - if (tail_src->head == NULL) { - return; - } - - if (head_dst->head == NULL) { - *head_dst = *tail_src; - memset(tail_src, 0, sizeof(*tail_src)); - return; - } - - head_dst->tail->next_message = tail_src->head; - head_dst->tail = tail_src->tail; - memset(tail_src, 0, sizeof(*tail_src)); -} - -grpc_byte_stream *grpc_chttp2_incoming_frame_queue_pop( - grpc_chttp2_incoming_frame_queue *q) { - grpc_byte_stream *out; - if (q->head == NULL) { - return NULL; - } - out = &q->head->base; - if (q->head == q->tail) { - memset(q, 0, sizeof(*q)); - } else { - q->head = q->head->next_message; - } - return out; -} - -void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf, - uint32_t write_bytes, int is_eof, - gpr_slice_buffer *outbuf) { - gpr_slice hdr; - uint8_t *p; - - hdr = gpr_slice_malloc(9); - p = GPR_SLICE_START_PTR(hdr); - GPR_ASSERT(write_bytes < (1 << 24)); - *p++ = (uint8_t)(write_bytes >> 16); - *p++ = (uint8_t)(write_bytes >> 8); - *p++ = (uint8_t)(write_bytes); - *p++ = GRPC_CHTTP2_FRAME_DATA; - *p++ = is_eof ? GRPC_CHTTP2_DATA_FLAG_END_STREAM : 0; - *p++ = (uint8_t)(id >> 24); - *p++ = (uint8_t)(id >> 16); - *p++ = (uint8_t)(id >> 8); - *p++ = (uint8_t)(id); - gpr_slice_buffer_add(outbuf, hdr); - - gpr_slice_buffer_move_first(inbuf, write_bytes, outbuf); -} - -grpc_chttp2_parse_error grpc_chttp2_data_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { - uint8_t *const beg = GPR_SLICE_START_PTR(slice); - uint8_t *const end = GPR_SLICE_END_PTR(slice); - uint8_t *cur = beg; - grpc_chttp2_data_parser *p = parser; - uint32_t message_flags; - grpc_chttp2_incoming_byte_stream *incoming_byte_stream; - - if (is_last && p->is_last_frame) { - stream_parsing->received_close = 1; - } - - if (cur == end) { - return GRPC_CHTTP2_PARSE_OK; - } - - switch (p->state) { - fh_0: - case GRPC_CHTTP2_DATA_FH_0: - p->frame_type = *cur; - switch (p->frame_type) { - case 0: - p->is_frame_compressed = 0; /* GPR_FALSE */ - break; - case 1: - p->is_frame_compressed = 1; /* GPR_TRUE */ - break; - default: - gpr_log(GPR_ERROR, "Bad GRPC frame type 0x%02x", p->frame_type); - return GRPC_CHTTP2_STREAM_ERROR; - } - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_1; - return GRPC_CHTTP2_PARSE_OK; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_1: - p->frame_size = ((uint32_t)*cur) << 24; - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_2; - return GRPC_CHTTP2_PARSE_OK; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_2: - p->frame_size |= ((uint32_t)*cur) << 16; - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_3; - return GRPC_CHTTP2_PARSE_OK; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_3: - p->frame_size |= ((uint32_t)*cur) << 8; - if (++cur == end) { - p->state = GRPC_CHTTP2_DATA_FH_4; - return GRPC_CHTTP2_PARSE_OK; - } - /* fallthrough */ - case GRPC_CHTTP2_DATA_FH_4: - p->frame_size |= ((uint32_t)*cur); - p->state = GRPC_CHTTP2_DATA_FRAME; - ++cur; - message_flags = 0; - if (p->is_frame_compressed) { - message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; - } - p->parsing_frame = incoming_byte_stream = - grpc_chttp2_incoming_byte_stream_create( - exec_ctx, transport_parsing, stream_parsing, p->frame_size, - message_flags, &p->incoming_frames); - /* fallthrough */ - case GRPC_CHTTP2_DATA_FRAME: - if (cur == end) { - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, - stream_parsing); - return GRPC_CHTTP2_PARSE_OK; - } - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, - stream_parsing); - if ((uint32_t)(end - cur) == p->frame_size) { - grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - gpr_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, 1, - 1); - p->parsing_frame = NULL; - p->state = GRPC_CHTTP2_DATA_FH_0; - return GRPC_CHTTP2_PARSE_OK; - } else if ((uint32_t)(end - cur) > p->frame_size) { - grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - gpr_slice_sub(slice, (size_t)(cur - beg), - (size_t)(cur + p->frame_size - beg))); - grpc_chttp2_incoming_byte_stream_finished(exec_ctx, p->parsing_frame, 1, - 1); - p->parsing_frame = NULL; - cur += p->frame_size; - goto fh_0; /* loop */ - } else { - grpc_chttp2_incoming_byte_stream_push( - exec_ctx, p->parsing_frame, - gpr_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - GPR_ASSERT((size_t)(end - cur) <= p->frame_size); - p->frame_size -= (uint32_t)(end - cur); - return GRPC_CHTTP2_PARSE_OK; - } - } - - GPR_UNREACHABLE_CODE(return GRPC_CHTTP2_CONNECTION_ERROR); -} diff --git a/src/core/transport/chttp2/frame_data.h b/src/core/transport/chttp2/frame_data.h deleted file mode 100644 index 9dbaa60d44..0000000000 --- a/src/core/transport/chttp2/frame_data.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_DATA_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H - -/* Parser for GRPC streams embedded in DATA frames */ - -#include -#include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/byte_stream.h" -#include "src/core/transport/chttp2/frame.h" - -typedef enum { - GRPC_CHTTP2_DATA_FH_0, - GRPC_CHTTP2_DATA_FH_1, - GRPC_CHTTP2_DATA_FH_2, - GRPC_CHTTP2_DATA_FH_3, - GRPC_CHTTP2_DATA_FH_4, - GRPC_CHTTP2_DATA_FRAME -} grpc_chttp2_stream_state; - -typedef struct grpc_chttp2_incoming_byte_stream - grpc_chttp2_incoming_byte_stream; - -typedef struct grpc_chttp2_incoming_frame_queue { - grpc_chttp2_incoming_byte_stream *head; - grpc_chttp2_incoming_byte_stream *tail; -} grpc_chttp2_incoming_frame_queue; - -typedef struct { - grpc_chttp2_stream_state state; - uint8_t is_last_frame; - uint8_t frame_type; - uint32_t frame_size; - - int is_frame_compressed; - grpc_chttp2_incoming_frame_queue incoming_frames; - grpc_chttp2_incoming_byte_stream *parsing_frame; -} grpc_chttp2_data_parser; - -void grpc_chttp2_incoming_frame_queue_merge( - grpc_chttp2_incoming_frame_queue *head_dst, - grpc_chttp2_incoming_frame_queue *tail_src); -grpc_byte_stream *grpc_chttp2_incoming_frame_queue_pop( - grpc_chttp2_incoming_frame_queue *q); - -/* initialize per-stream state for data frame parsing */ -grpc_chttp2_parse_error grpc_chttp2_data_parser_init( - grpc_chttp2_data_parser *parser); - -void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, - grpc_chttp2_data_parser *parser); - -/* start processing a new data frame */ -grpc_chttp2_parse_error grpc_chttp2_data_parser_begin_frame( - grpc_chttp2_data_parser *parser, uint8_t flags); - -/* handle a slice of a data frame - is_last indicates the last slice of a - frame */ -grpc_chttp2_parse_error grpc_chttp2_data_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); - -void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf, - uint32_t write_bytes, int is_eof, - gpr_slice_buffer *outbuf); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H */ diff --git a/src/core/transport/chttp2/frame_goaway.c b/src/core/transport/chttp2/frame_goaway.c deleted file mode 100644 index 2fa525e989..0000000000 --- a/src/core/transport/chttp2/frame_goaway.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/chttp2/frame_goaway.h" -#include "src/core/transport/chttp2/internal.h" - -#include - -#include -#include - -void grpc_chttp2_goaway_parser_init(grpc_chttp2_goaway_parser *p) { - p->debug_data = NULL; -} - -void grpc_chttp2_goaway_parser_destroy(grpc_chttp2_goaway_parser *p) { - gpr_free(p->debug_data); -} - -grpc_chttp2_parse_error grpc_chttp2_goaway_parser_begin_frame( - grpc_chttp2_goaway_parser *p, uint32_t length, uint8_t flags) { - if (length < 8) { - gpr_log(GPR_ERROR, "goaway frame too short (%d bytes)", length); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - - gpr_free(p->debug_data); - p->debug_length = length - 8; - p->debug_data = gpr_malloc(p->debug_length); - p->debug_pos = 0; - p->state = GRPC_CHTTP2_GOAWAY_LSI0; - return GRPC_CHTTP2_PARSE_OK; -} - -grpc_chttp2_parse_error grpc_chttp2_goaway_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { - uint8_t *const beg = GPR_SLICE_START_PTR(slice); - uint8_t *const end = GPR_SLICE_END_PTR(slice); - uint8_t *cur = beg; - grpc_chttp2_goaway_parser *p = parser; - - switch (p->state) { - case GRPC_CHTTP2_GOAWAY_LSI0: - if (cur == end) { - p->state = GRPC_CHTTP2_GOAWAY_LSI0; - return GRPC_CHTTP2_PARSE_OK; - } - p->last_stream_id = ((uint32_t)*cur) << 24; - ++cur; - /* fallthrough */ - case GRPC_CHTTP2_GOAWAY_LSI1: - if (cur == end) { - p->state = GRPC_CHTTP2_GOAWAY_LSI1; - return GRPC_CHTTP2_PARSE_OK; - } - p->last_stream_id |= ((uint32_t)*cur) << 16; - ++cur; - /* fallthrough */ - case GRPC_CHTTP2_GOAWAY_LSI2: - if (cur == end) { - p->state = GRPC_CHTTP2_GOAWAY_LSI2; - return GRPC_CHTTP2_PARSE_OK; - } - p->last_stream_id |= ((uint32_t)*cur) << 8; - ++cur; - /* fallthrough */ - case GRPC_CHTTP2_GOAWAY_LSI3: - if (cur == end) { - p->state = GRPC_CHTTP2_GOAWAY_LSI3; - return GRPC_CHTTP2_PARSE_OK; - } - p->last_stream_id |= ((uint32_t)*cur); - ++cur; - /* fallthrough */ - case GRPC_CHTTP2_GOAWAY_ERR0: - if (cur == end) { - p->state = GRPC_CHTTP2_GOAWAY_ERR0; - return GRPC_CHTTP2_PARSE_OK; - } - p->error_code = ((uint32_t)*cur) << 24; - ++cur; - /* fallthrough */ - case GRPC_CHTTP2_GOAWAY_ERR1: - if (cur == end) { - p->state = GRPC_CHTTP2_GOAWAY_ERR1; - return GRPC_CHTTP2_PARSE_OK; - } - p->error_code |= ((uint32_t)*cur) << 16; - ++cur; - /* fallthrough */ - case GRPC_CHTTP2_GOAWAY_ERR2: - if (cur == end) { - p->state = GRPC_CHTTP2_GOAWAY_ERR2; - return GRPC_CHTTP2_PARSE_OK; - } - p->error_code |= ((uint32_t)*cur) << 8; - ++cur; - /* fallthrough */ - case GRPC_CHTTP2_GOAWAY_ERR3: - if (cur == end) { - p->state = GRPC_CHTTP2_GOAWAY_ERR3; - return GRPC_CHTTP2_PARSE_OK; - } - p->error_code |= ((uint32_t)*cur); - ++cur; - /* fallthrough */ - case GRPC_CHTTP2_GOAWAY_DEBUG: - memcpy(p->debug_data + p->debug_pos, cur, (size_t)(end - cur)); - GPR_ASSERT((size_t)(end - cur) < UINT32_MAX - p->debug_pos); - p->debug_pos += (uint32_t)(end - cur); - p->state = GRPC_CHTTP2_GOAWAY_DEBUG; - if (is_last) { - transport_parsing->goaway_received = 1; - transport_parsing->goaway_last_stream_index = p->last_stream_id; - gpr_slice_unref(transport_parsing->goaway_text); - transport_parsing->goaway_error = (grpc_status_code)p->error_code; - transport_parsing->goaway_text = - gpr_slice_new(p->debug_data, p->debug_length, gpr_free); - p->debug_data = NULL; - } - return GRPC_CHTTP2_PARSE_OK; - } - GPR_UNREACHABLE_CODE(return GRPC_CHTTP2_CONNECTION_ERROR); -} - -void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code, - gpr_slice debug_data, - gpr_slice_buffer *slice_buffer) { - gpr_slice header = gpr_slice_malloc(9 + 4 + 4); - uint8_t *p = GPR_SLICE_START_PTR(header); - uint32_t frame_length; - GPR_ASSERT(GPR_SLICE_LENGTH(debug_data) < UINT32_MAX - 4 - 4); - frame_length = 4 + 4 + (uint32_t)GPR_SLICE_LENGTH(debug_data); - - /* frame header: length */ - *p++ = (uint8_t)(frame_length >> 16); - *p++ = (uint8_t)(frame_length >> 8); - *p++ = (uint8_t)(frame_length); - /* frame header: type */ - *p++ = GRPC_CHTTP2_FRAME_GOAWAY; - /* frame header: flags */ - *p++ = 0; - /* frame header: stream id */ - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - /* payload: last stream id */ - *p++ = (uint8_t)(last_stream_id >> 24); - *p++ = (uint8_t)(last_stream_id >> 16); - *p++ = (uint8_t)(last_stream_id >> 8); - *p++ = (uint8_t)(last_stream_id); - /* payload: error code */ - *p++ = (uint8_t)(error_code >> 24); - *p++ = (uint8_t)(error_code >> 16); - *p++ = (uint8_t)(error_code >> 8); - *p++ = (uint8_t)(error_code); - GPR_ASSERT(p == GPR_SLICE_END_PTR(header)); - gpr_slice_buffer_add(slice_buffer, header); - gpr_slice_buffer_add(slice_buffer, debug_data); -} diff --git a/src/core/transport/chttp2/frame_goaway.h b/src/core/transport/chttp2/frame_goaway.h deleted file mode 100644 index b980e47723..0000000000 --- a/src/core/transport/chttp2/frame_goaway.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_GOAWAY_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H - -#include -#include -#include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" - -typedef enum { - GRPC_CHTTP2_GOAWAY_LSI0, - GRPC_CHTTP2_GOAWAY_LSI1, - GRPC_CHTTP2_GOAWAY_LSI2, - GRPC_CHTTP2_GOAWAY_LSI3, - GRPC_CHTTP2_GOAWAY_ERR0, - GRPC_CHTTP2_GOAWAY_ERR1, - GRPC_CHTTP2_GOAWAY_ERR2, - GRPC_CHTTP2_GOAWAY_ERR3, - GRPC_CHTTP2_GOAWAY_DEBUG -} grpc_chttp2_goaway_parse_state; - -typedef struct { - grpc_chttp2_goaway_parse_state state; - uint32_t last_stream_id; - uint32_t error_code; - char *debug_data; - uint32_t debug_length; - uint32_t debug_pos; -} grpc_chttp2_goaway_parser; - -void grpc_chttp2_goaway_parser_init(grpc_chttp2_goaway_parser *p); -void grpc_chttp2_goaway_parser_destroy(grpc_chttp2_goaway_parser *p); -grpc_chttp2_parse_error grpc_chttp2_goaway_parser_begin_frame( - grpc_chttp2_goaway_parser *parser, uint32_t length, uint8_t flags); -grpc_chttp2_parse_error grpc_chttp2_goaway_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); - -void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code, - gpr_slice debug_data, - gpr_slice_buffer *slice_buffer); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H */ diff --git a/src/core/transport/chttp2/frame_ping.c b/src/core/transport/chttp2/frame_ping.c deleted file mode 100644 index c6ab522283..0000000000 --- a/src/core/transport/chttp2/frame_ping.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/chttp2/frame_ping.h" -#include "src/core/transport/chttp2/internal.h" - -#include - -#include -#include - -gpr_slice grpc_chttp2_ping_create(uint8_t ack, uint8_t *opaque_8bytes) { - gpr_slice slice = gpr_slice_malloc(9 + 8); - uint8_t *p = GPR_SLICE_START_PTR(slice); - - *p++ = 0; - *p++ = 0; - *p++ = 8; - *p++ = GRPC_CHTTP2_FRAME_PING; - *p++ = ack ? 1 : 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - memcpy(p, opaque_8bytes, 8); - - return slice; -} - -grpc_chttp2_parse_error grpc_chttp2_ping_parser_begin_frame( - grpc_chttp2_ping_parser *parser, uint32_t length, uint8_t flags) { - if (flags & 0xfe || length != 8) { - gpr_log(GPR_ERROR, "invalid ping: length=%d, flags=%02x", length, flags); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - parser->byte = 0; - parser->is_ack = flags; - return GRPC_CHTTP2_PARSE_OK; -} - -grpc_chttp2_parse_error grpc_chttp2_ping_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { - uint8_t *const beg = GPR_SLICE_START_PTR(slice); - uint8_t *const end = GPR_SLICE_END_PTR(slice); - uint8_t *cur = beg; - grpc_chttp2_ping_parser *p = parser; - - while (p->byte != 8 && cur != end) { - p->opaque_8bytes[p->byte] = *cur; - cur++; - p->byte++; - } - - if (p->byte == 8) { - GPR_ASSERT(is_last); - if (p->is_ack) { - grpc_chttp2_ack_ping(exec_ctx, transport_parsing, p->opaque_8bytes); - } else { - gpr_slice_buffer_add(&transport_parsing->qbuf, - grpc_chttp2_ping_create(1, p->opaque_8bytes)); - } - } - - return GRPC_CHTTP2_PARSE_OK; -} diff --git a/src/core/transport/chttp2/frame_ping.h b/src/core/transport/chttp2/frame_ping.h deleted file mode 100644 index 2412cd7a6f..0000000000 --- a/src/core/transport/chttp2/frame_ping.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_PING_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_PING_H - -#include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" - -typedef struct { - uint8_t byte; - uint8_t is_ack; - uint8_t opaque_8bytes[8]; -} grpc_chttp2_ping_parser; - -gpr_slice grpc_chttp2_ping_create(uint8_t ack, uint8_t *opaque_8bytes); - -grpc_chttp2_parse_error grpc_chttp2_ping_parser_begin_frame( - grpc_chttp2_ping_parser *parser, uint32_t length, uint8_t flags); -grpc_chttp2_parse_error grpc_chttp2_ping_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_PING_H */ diff --git a/src/core/transport/chttp2/frame_rst_stream.c b/src/core/transport/chttp2/frame_rst_stream.c deleted file mode 100644 index 754529e4b9..0000000000 --- a/src/core/transport/chttp2/frame_rst_stream.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/chttp2/frame_rst_stream.h" -#include "src/core/transport/chttp2/internal.h" - -#include - -#include "src/core/transport/chttp2/frame.h" - -gpr_slice grpc_chttp2_rst_stream_create(uint32_t id, uint32_t code) { - gpr_slice slice = gpr_slice_malloc(13); - uint8_t *p = GPR_SLICE_START_PTR(slice); - - *p++ = 0; - *p++ = 0; - *p++ = 4; - *p++ = GRPC_CHTTP2_FRAME_RST_STREAM; - *p++ = 0; - *p++ = (uint8_t)(id >> 24); - *p++ = (uint8_t)(id >> 16); - *p++ = (uint8_t)(id >> 8); - *p++ = (uint8_t)(id); - *p++ = (uint8_t)(code >> 24); - *p++ = (uint8_t)(code >> 16); - *p++ = (uint8_t)(code >> 8); - *p++ = (uint8_t)(code); - - return slice; -} - -grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_begin_frame( - grpc_chttp2_rst_stream_parser *parser, uint32_t length, uint8_t flags) { - if (length != 4) { - gpr_log(GPR_ERROR, "invalid rst_stream: length=%d, flags=%02x", length, - flags); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - parser->byte = 0; - return GRPC_CHTTP2_PARSE_OK; -} - -grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { - uint8_t *const beg = GPR_SLICE_START_PTR(slice); - uint8_t *const end = GPR_SLICE_END_PTR(slice); - uint8_t *cur = beg; - grpc_chttp2_rst_stream_parser *p = parser; - - while (p->byte != 4 && cur != end) { - p->reason_bytes[p->byte] = *cur; - cur++; - p->byte++; - } - - if (p->byte == 4) { - GPR_ASSERT(is_last); - stream_parsing->received_close = 1; - stream_parsing->saw_rst_stream = 1; - stream_parsing->rst_stream_reason = (((uint32_t)p->reason_bytes[0]) << 24) | - (((uint32_t)p->reason_bytes[1]) << 16) | - (((uint32_t)p->reason_bytes[2]) << 8) | - (((uint32_t)p->reason_bytes[3])); - } - - return GRPC_CHTTP2_PARSE_OK; -} diff --git a/src/core/transport/chttp2/frame_rst_stream.h b/src/core/transport/chttp2/frame_rst_stream.h deleted file mode 100644 index f725c5d767..0000000000 --- a/src/core/transport/chttp2/frame_rst_stream.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H - -#include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" - -typedef struct { - uint8_t byte; - uint8_t reason_bytes[4]; -} grpc_chttp2_rst_stream_parser; - -gpr_slice grpc_chttp2_rst_stream_create(uint32_t stream_id, uint32_t code); - -grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_begin_frame( - grpc_chttp2_rst_stream_parser *parser, uint32_t length, uint8_t flags); -grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H */ diff --git a/src/core/transport/chttp2/frame_settings.c b/src/core/transport/chttp2/frame_settings.c deleted file mode 100644 index cc49dd4f69..0000000000 --- a/src/core/transport/chttp2/frame_settings.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/chttp2/frame_settings.h" -#include "src/core/transport/chttp2/internal.h" - -#include - -#include -#include - -#include "src/core/debug/trace.h" -#include "src/core/transport/chttp2/frame.h" -#include "src/core/transport/chttp2/http2_errors.h" -#include "src/core/transport/chttp2_transport.h" - -#define MAX_MAX_HEADER_LIST_SIZE (1024 * 1024 * 1024) - -/* HTTP/2 mandated initial connection settings */ -const grpc_chttp2_setting_parameters - grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = { - {NULL, 0, 0, 0, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, - GRPC_CHTTP2_PROTOCOL_ERROR}, - {"HEADER_TABLE_SIZE", 4096, 0, 0xffffffff, - GRPC_CHTTP2_CLAMP_INVALID_VALUE, GRPC_CHTTP2_PROTOCOL_ERROR}, - {"ENABLE_PUSH", 1, 0, 1, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, - GRPC_CHTTP2_PROTOCOL_ERROR}, - {"MAX_CONCURRENT_STREAMS", 0xffffffffu, 0, 0xffffffffu, - GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_CHTTP2_PROTOCOL_ERROR}, - {"INITIAL_WINDOW_SIZE", 65535, 0, 0x7fffffffu, - GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, - GRPC_CHTTP2_FLOW_CONTROL_ERROR}, - {"MAX_FRAME_SIZE", 16384, 16384, 16777215, - GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE, GRPC_CHTTP2_PROTOCOL_ERROR}, - {"MAX_HEADER_LIST_SIZE", MAX_MAX_HEADER_LIST_SIZE, 0, - MAX_MAX_HEADER_LIST_SIZE, GRPC_CHTTP2_CLAMP_INVALID_VALUE, - GRPC_CHTTP2_PROTOCOL_ERROR}, -}; - -static uint8_t *fill_header(uint8_t *out, uint32_t length, uint8_t flags) { - *out++ = (uint8_t)(length >> 16); - *out++ = (uint8_t)(length >> 8); - *out++ = (uint8_t)(length); - *out++ = GRPC_CHTTP2_FRAME_SETTINGS; - *out++ = flags; - *out++ = 0; - *out++ = 0; - *out++ = 0; - *out++ = 0; - return out; -} - -gpr_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *new, - uint32_t force_mask, size_t count) { - size_t i; - uint32_t n = 0; - gpr_slice output; - uint8_t *p; - - for (i = 0; i < count; i++) { - n += (new[i] != old[i] || (force_mask & (1u << i)) != 0); - } - - output = gpr_slice_malloc(9 + 6 * n); - p = fill_header(GPR_SLICE_START_PTR(output), 6 * n, 0); - - for (i = 0; i < count; i++) { - if (new[i] != old[i] || (force_mask & (1u << i)) != 0) { - GPR_ASSERT(i); - *p++ = (uint8_t)(i >> 8); - *p++ = (uint8_t)(i); - *p++ = (uint8_t)(new[i] >> 24); - *p++ = (uint8_t)(new[i] >> 16); - *p++ = (uint8_t)(new[i] >> 8); - *p++ = (uint8_t)(new[i]); - old[i] = new[i]; - } - } - - GPR_ASSERT(p == GPR_SLICE_END_PTR(output)); - - return output; -} - -gpr_slice grpc_chttp2_settings_ack_create(void) { - gpr_slice output = gpr_slice_malloc(9); - fill_header(GPR_SLICE_START_PTR(output), 0, GRPC_CHTTP2_FLAG_ACK); - return output; -} - -grpc_chttp2_parse_error grpc_chttp2_settings_parser_begin_frame( - grpc_chttp2_settings_parser *parser, uint32_t length, uint8_t flags, - uint32_t *settings) { - parser->target_settings = settings; - memcpy(parser->incoming_settings, settings, - GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); - parser->is_ack = 0; - parser->state = GRPC_CHTTP2_SPS_ID0; - if (flags == GRPC_CHTTP2_FLAG_ACK) { - parser->is_ack = 1; - if (length != 0) { - gpr_log(GPR_ERROR, "non-empty settings ack frame received"); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - return GRPC_CHTTP2_PARSE_OK; - } else if (flags != 0) { - gpr_log(GPR_ERROR, "invalid flags on settings frame"); - return GRPC_CHTTP2_CONNECTION_ERROR; - } else if (length % 6 != 0) { - gpr_log(GPR_ERROR, "settings frames must be a multiple of six bytes"); - return GRPC_CHTTP2_CONNECTION_ERROR; - } else { - return GRPC_CHTTP2_PARSE_OK; - } -} - -grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse( - grpc_exec_ctx *exec_ctx, void *p, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { - grpc_chttp2_settings_parser *parser = p; - const uint8_t *cur = GPR_SLICE_START_PTR(slice); - const uint8_t *end = GPR_SLICE_END_PTR(slice); - - if (parser->is_ack) { - return GRPC_CHTTP2_PARSE_OK; - } - - for (;;) { - switch (parser->state) { - case GRPC_CHTTP2_SPS_ID0: - if (cur == end) { - parser->state = GRPC_CHTTP2_SPS_ID0; - if (is_last) { - transport_parsing->settings_updated = 1; - memcpy(parser->target_settings, parser->incoming_settings, - GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); - gpr_slice_buffer_add(&transport_parsing->qbuf, - grpc_chttp2_settings_ack_create()); - } - return GRPC_CHTTP2_PARSE_OK; - } - parser->id = (uint16_t)(((uint16_t)*cur) << 8); - cur++; - /* fallthrough */ - case GRPC_CHTTP2_SPS_ID1: - if (cur == end) { - parser->state = GRPC_CHTTP2_SPS_ID1; - return GRPC_CHTTP2_PARSE_OK; - } - parser->id = (uint16_t)(parser->id | (*cur)); - cur++; - /* fallthrough */ - case GRPC_CHTTP2_SPS_VAL0: - if (cur == end) { - parser->state = GRPC_CHTTP2_SPS_VAL0; - return GRPC_CHTTP2_PARSE_OK; - } - parser->value = ((uint32_t)*cur) << 24; - cur++; - /* fallthrough */ - case GRPC_CHTTP2_SPS_VAL1: - if (cur == end) { - parser->state = GRPC_CHTTP2_SPS_VAL1; - return GRPC_CHTTP2_PARSE_OK; - } - parser->value |= ((uint32_t)*cur) << 16; - cur++; - /* fallthrough */ - case GRPC_CHTTP2_SPS_VAL2: - if (cur == end) { - parser->state = GRPC_CHTTP2_SPS_VAL2; - return GRPC_CHTTP2_PARSE_OK; - } - parser->value |= ((uint32_t)*cur) << 8; - cur++; - /* fallthrough */ - case GRPC_CHTTP2_SPS_VAL3: - if (cur == end) { - parser->state = GRPC_CHTTP2_SPS_VAL3; - return GRPC_CHTTP2_PARSE_OK; - } else { - parser->state = GRPC_CHTTP2_SPS_ID0; - } - parser->value |= *cur; - cur++; - - if (parser->id > 0 && parser->id < GRPC_CHTTP2_NUM_SETTINGS) { - const grpc_chttp2_setting_parameters *sp = - &grpc_chttp2_settings_parameters[parser->id]; - if (parser->value < sp->min_value || parser->value > sp->max_value) { - switch (sp->invalid_value_behavior) { - case GRPC_CHTTP2_CLAMP_INVALID_VALUE: - parser->value = - GPR_CLAMP(parser->value, sp->min_value, sp->max_value); - break; - case GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE: - grpc_chttp2_goaway_append( - transport_parsing->last_incoming_stream_id, sp->error_value, - gpr_slice_from_static_string("HTTP2 settings error"), - &transport_parsing->qbuf); - gpr_log(GPR_ERROR, "invalid value %u passed for %s", - parser->value, sp->name); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - } - if (parser->id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE && - parser->incoming_settings[parser->id] != parser->value) { - transport_parsing->initial_window_update = - (int64_t)parser->value - parser->incoming_settings[parser->id]; - if (grpc_http_trace) { - gpr_log(GPR_DEBUG, "adding %d for initial_window change", - (int)transport_parsing->initial_window_update); - } - } - parser->incoming_settings[parser->id] = parser->value; - if (grpc_http_trace) { - gpr_log(GPR_DEBUG, "CHTTP2:%s: got setting %d = %d", - transport_parsing->is_client ? "CLI" : "SVR", parser->id, - parser->value); - } - } else { - gpr_log(GPR_ERROR, "CHTTP2: Ignoring unknown setting %d (value %d)", - parser->id, parser->value); - } - break; - } - } -} diff --git a/src/core/transport/chttp2/frame_settings.h b/src/core/transport/chttp2/frame_settings.h deleted file mode 100644 index 59dbff9b40..0000000000 --- a/src/core/transport/chttp2/frame_settings.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_SETTINGS_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H - -#include -#include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" - -typedef enum { - GRPC_CHTTP2_SPS_ID0, - GRPC_CHTTP2_SPS_ID1, - GRPC_CHTTP2_SPS_VAL0, - GRPC_CHTTP2_SPS_VAL1, - GRPC_CHTTP2_SPS_VAL2, - GRPC_CHTTP2_SPS_VAL3 -} grpc_chttp2_settings_parse_state; - -/* The things HTTP/2 defines as connection level settings */ -typedef enum { - GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE = 1, - GRPC_CHTTP2_SETTINGS_ENABLE_PUSH = 2, - GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 3, - GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 4, - GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE = 5, - GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 6, - GRPC_CHTTP2_NUM_SETTINGS -} grpc_chttp2_setting_id; - -typedef struct { - grpc_chttp2_settings_parse_state state; - uint32_t *target_settings; - uint8_t is_ack; - uint16_t id; - uint32_t value; - uint32_t incoming_settings[GRPC_CHTTP2_NUM_SETTINGS]; -} grpc_chttp2_settings_parser; - -typedef enum { - GRPC_CHTTP2_CLAMP_INVALID_VALUE, - GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE -} grpc_chttp2_invalid_value_behavior; - -typedef struct { - const char *name; - uint32_t default_value; - uint32_t min_value; - uint32_t max_value; - grpc_chttp2_invalid_value_behavior invalid_value_behavior; - uint32_t error_value; -} grpc_chttp2_setting_parameters; - -/* HTTP/2 mandated connection setting parameters */ -extern const grpc_chttp2_setting_parameters - grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS]; - -/* Create a settings frame by diffing old & new, and updating old to be new */ -gpr_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *new, - uint32_t force_mask, size_t count); -/* Create an ack settings frame */ -gpr_slice grpc_chttp2_settings_ack_create(void); - -grpc_chttp2_parse_error grpc_chttp2_settings_parser_begin_frame( - grpc_chttp2_settings_parser *parser, uint32_t length, uint8_t flags, - uint32_t *settings); -grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H */ diff --git a/src/core/transport/chttp2/frame_window_update.c b/src/core/transport/chttp2/frame_window_update.c deleted file mode 100644 index 62d9bac117..0000000000 --- a/src/core/transport/chttp2/frame_window_update.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/chttp2/frame_window_update.h" -#include "src/core/transport/chttp2/internal.h" - -#include - -gpr_slice grpc_chttp2_window_update_create(uint32_t id, - uint32_t window_update) { - gpr_slice slice = gpr_slice_malloc(13); - uint8_t *p = GPR_SLICE_START_PTR(slice); - - GPR_ASSERT(window_update); - - *p++ = 0; - *p++ = 0; - *p++ = 4; - *p++ = GRPC_CHTTP2_FRAME_WINDOW_UPDATE; - *p++ = 0; - *p++ = (uint8_t)(id >> 24); - *p++ = (uint8_t)(id >> 16); - *p++ = (uint8_t)(id >> 8); - *p++ = (uint8_t)(id); - *p++ = (uint8_t)(window_update >> 24); - *p++ = (uint8_t)(window_update >> 16); - *p++ = (uint8_t)(window_update >> 8); - *p++ = (uint8_t)(window_update); - - return slice; -} - -grpc_chttp2_parse_error grpc_chttp2_window_update_parser_begin_frame( - grpc_chttp2_window_update_parser *parser, uint32_t length, uint8_t flags) { - if (flags || length != 4) { - gpr_log(GPR_ERROR, "invalid window update: length=%d, flags=%02x", length, - flags); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - parser->byte = 0; - parser->amount = 0; - return GRPC_CHTTP2_PARSE_OK; -} - -grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { - uint8_t *const beg = GPR_SLICE_START_PTR(slice); - uint8_t *const end = GPR_SLICE_END_PTR(slice); - uint8_t *cur = beg; - grpc_chttp2_window_update_parser *p = parser; - - while (p->byte != 4 && cur != end) { - p->amount |= ((uint32_t)*cur) << (8 * (3 - p->byte)); - cur++; - p->byte++; - } - - if (p->byte == 4) { - uint32_t received_update = p->amount; - if (received_update == 0 || (received_update & 0x80000000u)) { - gpr_log(GPR_ERROR, "invalid window update bytes: %d", p->amount); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - GPR_ASSERT(is_last); - - if (transport_parsing->incoming_stream_id != 0) { - if (stream_parsing != NULL) { - GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", transport_parsing, - stream_parsing, outgoing_window, - received_update); - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, - stream_parsing); - } - } else { - GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parse", transport_parsing, - outgoing_window, received_update); - } - } - - return GRPC_CHTTP2_PARSE_OK; -} diff --git a/src/core/transport/chttp2/frame_window_update.h b/src/core/transport/chttp2/frame_window_update.h deleted file mode 100644 index 9b7ca3ce63..0000000000 --- a/src/core/transport/chttp2/frame_window_update.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H - -#include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" - -typedef struct { - uint8_t byte; - uint8_t is_connection_update; - uint32_t amount; -} grpc_chttp2_window_update_parser; - -gpr_slice grpc_chttp2_window_update_create(uint32_t id, uint32_t window_delta); - -grpc_chttp2_parse_error grpc_chttp2_window_update_parser_begin_frame( - grpc_chttp2_window_update_parser *parser, uint32_t length, uint8_t flags); -grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H */ diff --git a/src/core/transport/chttp2/hpack_encoder.c b/src/core/transport/chttp2/hpack_encoder.c deleted file mode 100644 index f30f574d06..0000000000 --- a/src/core/transport/chttp2/hpack_encoder.c +++ /dev/null @@ -1,568 +0,0 @@ -/* - * - * Copyright 2015-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/transport/chttp2/hpack_encoder.h" - -#include -#include - -/* This is here for grpc_is_binary_header - * TODO(murgatroid99): Remove this - */ -#include - -#include -#include -#include - -#include "src/core/transport/chttp2/bin_encoder.h" -#include "src/core/transport/chttp2/hpack_table.h" -#include "src/core/transport/chttp2/timeout_encoding.h" -#include "src/core/transport/chttp2/varint.h" -#include "src/core/transport/static_metadata.h" - -#define HASH_FRAGMENT_1(x) ((x)&255) -#define HASH_FRAGMENT_2(x) ((x >> 8) & 255) -#define HASH_FRAGMENT_3(x) ((x >> 16) & 255) -#define HASH_FRAGMENT_4(x) ((x >> 24) & 255) - -/* if the probability of this item being seen again is < 1/x then don't add - it to the table */ -#define ONE_ON_ADD_PROBABILITY 128 -/* don't consider adding anything bigger than this to the hpack table */ -#define MAX_DECODER_SPACE_USAGE 512 - -typedef struct { - int is_first_frame; - /* number of bytes in 'output' when we started the frame - used to calculate - frame length */ - size_t output_length_at_start_of_frame; - /* index (in output) of the header for the current frame */ - size_t header_idx; - /* have we seen a regular (non-colon-prefixed) header yet? */ - uint8_t seen_regular_header; - /* output stream id */ - uint32_t stream_id; - gpr_slice_buffer *output; -} framer_state; - -/* fills p (which is expected to be 9 bytes long) with a data frame header */ -static void fill_header(uint8_t *p, uint8_t type, uint32_t id, size_t len, - uint8_t flags) { - GPR_ASSERT(len < 16777316); - *p++ = (uint8_t)(len >> 16); - *p++ = (uint8_t)(len >> 8); - *p++ = (uint8_t)(len); - *p++ = type; - *p++ = flags; - *p++ = (uint8_t)(id >> 24); - *p++ = (uint8_t)(id >> 16); - *p++ = (uint8_t)(id >> 8); - *p++ = (uint8_t)(id); -} - -/* finish a frame - fill in the previously reserved header */ -static void finish_frame(framer_state *st, int is_header_boundary, - int is_last_in_stream) { - uint8_t type = 0xff; - type = st->is_first_frame ? GRPC_CHTTP2_FRAME_HEADER - : GRPC_CHTTP2_FRAME_CONTINUATION; - fill_header( - GPR_SLICE_START_PTR(st->output->slices[st->header_idx]), type, - st->stream_id, st->output->length - st->output_length_at_start_of_frame, - (uint8_t)((is_last_in_stream ? GRPC_CHTTP2_DATA_FLAG_END_STREAM : 0) | - (is_header_boundary ? GRPC_CHTTP2_DATA_FLAG_END_HEADERS : 0))); - st->is_first_frame = 0; -} - -/* begin a new frame: reserve off header space, remember how many bytes we'd - output before beginning */ -static void begin_frame(framer_state *st) { - st->header_idx = - gpr_slice_buffer_add_indexed(st->output, gpr_slice_malloc(9)); - st->output_length_at_start_of_frame = st->output->length; -} - -/* make sure that the current frame is of the type desired, and has sufficient - space to add at least about_to_add bytes -- finishes the current frame if - needed */ -static void ensure_space(framer_state *st, size_t need_bytes) { - if (st->output->length - st->output_length_at_start_of_frame + need_bytes <= - GRPC_CHTTP2_MAX_PAYLOAD_LENGTH) { - return; - } - finish_frame(st, 0, 0); - begin_frame(st); -} - -/* increment a filter count, halve all counts if one element reaches max */ -static void inc_filter(uint8_t idx, uint32_t *sum, uint8_t *elems) { - elems[idx]++; - if (elems[idx] < 255) { - (*sum)++; - } else { - int i; - *sum = 0; - for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_FILTERS; i++) { - elems[i] /= 2; - (*sum) += elems[i]; - } - } -} - -static void add_header_data(framer_state *st, gpr_slice slice) { - size_t len = GPR_SLICE_LENGTH(slice); - size_t remaining; - if (len == 0) return; - remaining = GRPC_CHTTP2_MAX_PAYLOAD_LENGTH + - st->output_length_at_start_of_frame - st->output->length; - if (len <= remaining) { - gpr_slice_buffer_add(st->output, slice); - } else { - gpr_slice_buffer_add(st->output, gpr_slice_split_head(&slice, remaining)); - finish_frame(st, 0, 0); - begin_frame(st); - add_header_data(st, slice); - } -} - -static uint8_t *add_tiny_header_data(framer_state *st, size_t len) { - ensure_space(st, len); - return gpr_slice_buffer_tiny_add(st->output, len); -} - -static void evict_entry(grpc_chttp2_hpack_compressor *c) { - c->tail_remote_index++; - GPR_ASSERT(c->tail_remote_index > 0); - GPR_ASSERT(c->table_size >= - c->table_elem_size[c->tail_remote_index % c->cap_table_elems]); - GPR_ASSERT(c->table_elems > 0); - c->table_size = - (uint16_t)(c->table_size - - c->table_elem_size[c->tail_remote_index % c->cap_table_elems]); - c->table_elems--; -} - -/* add an element to the decoder table */ -static void add_elem(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem) { - uint32_t key_hash = elem->key->hash; - uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash); - uint32_t new_index = c->tail_remote_index + c->table_elems + 1; - size_t elem_size = 32 + GPR_SLICE_LENGTH(elem->key->slice) + - GPR_SLICE_LENGTH(elem->value->slice); - - GPR_ASSERT(elem_size < 65536); - - if (elem_size > c->max_table_size) { - while (c->table_size > 0) { - evict_entry(c); - } - return; - } - - /* Reserve space for this element in the remote table: if this overflows - the current table, drop elements until it fits, matching the decompressor - algorithm */ - while (c->table_size + elem_size > c->max_table_size) { - evict_entry(c); - } - GPR_ASSERT(c->table_elems < c->max_table_size); - c->table_elem_size[new_index % c->cap_table_elems] = (uint16_t)elem_size; - c->table_size = (uint16_t)(c->table_size + elem_size); - c->table_elems++; - - /* Store this element into {entries,indices}_elem */ - if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == elem) { - /* already there: update with new index */ - c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index; - } else if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == elem) { - /* already there (cuckoo): update with new index */ - c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index; - } else if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == NULL) { - /* not there, but a free element: add */ - c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem); - c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index; - } else if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == NULL) { - /* not there (cuckoo), but a free element: add */ - c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem); - c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index; - } else if (c->indices_elems[HASH_FRAGMENT_2(elem_hash)] < - c->indices_elems[HASH_FRAGMENT_3(elem_hash)]) { - /* not there: replace oldest */ - GRPC_MDELEM_UNREF(c->entries_elems[HASH_FRAGMENT_2(elem_hash)]); - c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem); - c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index; - } else { - /* not there: replace oldest */ - GRPC_MDELEM_UNREF(c->entries_elems[HASH_FRAGMENT_3(elem_hash)]); - c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem); - c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index; - } - - /* do exactly the same for the key (so we can find by that again too) */ - - if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == elem->key) { - c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index; - } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == elem->key) { - c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index; - } else if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == NULL) { - c->entries_keys[HASH_FRAGMENT_2(key_hash)] = GRPC_MDSTR_REF(elem->key); - c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index; - } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == NULL) { - c->entries_keys[HASH_FRAGMENT_3(key_hash)] = GRPC_MDSTR_REF(elem->key); - c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index; - } else if (c->indices_keys[HASH_FRAGMENT_2(key_hash)] < - c->indices_keys[HASH_FRAGMENT_3(key_hash)]) { - GRPC_MDSTR_UNREF(c->entries_keys[HASH_FRAGMENT_2(key_hash)]); - c->entries_keys[HASH_FRAGMENT_2(key_hash)] = GRPC_MDSTR_REF(elem->key); - c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index; - } else { - GRPC_MDSTR_UNREF(c->entries_keys[HASH_FRAGMENT_3(key_hash)]); - c->entries_keys[HASH_FRAGMENT_3(key_hash)] = GRPC_MDSTR_REF(elem->key); - c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index; - } -} - -static void emit_indexed(grpc_chttp2_hpack_compressor *c, uint32_t elem_index, - framer_state *st) { - uint32_t len = GRPC_CHTTP2_VARINT_LENGTH(elem_index, 1); - GRPC_CHTTP2_WRITE_VARINT(elem_index, 1, 0x80, add_tiny_header_data(st, len), - len); -} - -static gpr_slice get_wire_value(grpc_mdelem *elem, uint8_t *huffman_prefix) { - if (grpc_is_binary_header((const char *)GPR_SLICE_START_PTR(elem->key->slice), - GPR_SLICE_LENGTH(elem->key->slice))) { - *huffman_prefix = 0x80; - return grpc_mdstr_as_base64_encoded_and_huffman_compressed(elem->value); - } - /* TODO(ctiller): opportunistically compress non-binary headers */ - *huffman_prefix = 0x00; - return elem->value->slice; -} - -static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor *c, - uint32_t key_index, grpc_mdelem *elem, - framer_state *st) { - uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 2); - uint8_t huffman_prefix; - gpr_slice value_slice = get_wire_value(elem, &huffman_prefix); - size_t len_val = GPR_SLICE_LENGTH(value_slice); - uint32_t len_val_len; - GPR_ASSERT(len_val <= UINT32_MAX); - len_val_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)len_val, 1); - GRPC_CHTTP2_WRITE_VARINT(key_index, 2, 0x40, - add_tiny_header_data(st, len_pfx), len_pfx); - GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix, - add_tiny_header_data(st, len_val_len), len_val_len); - add_header_data(st, gpr_slice_ref(value_slice)); -} - -static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor *c, - uint32_t key_index, grpc_mdelem *elem, - framer_state *st) { - uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 4); - uint8_t huffman_prefix; - gpr_slice value_slice = get_wire_value(elem, &huffman_prefix); - size_t len_val = GPR_SLICE_LENGTH(value_slice); - uint32_t len_val_len; - GPR_ASSERT(len_val <= UINT32_MAX); - len_val_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)len_val, 1); - GRPC_CHTTP2_WRITE_VARINT(key_index, 4, 0x00, - add_tiny_header_data(st, len_pfx), len_pfx); - GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix, - add_tiny_header_data(st, len_val_len), len_val_len); - add_header_data(st, gpr_slice_ref(value_slice)); -} - -static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c, - grpc_mdelem *elem, framer_state *st) { - uint32_t len_key = (uint32_t)GPR_SLICE_LENGTH(elem->key->slice); - uint8_t huffman_prefix; - gpr_slice value_slice = get_wire_value(elem, &huffman_prefix); - uint32_t len_val = (uint32_t)GPR_SLICE_LENGTH(value_slice); - uint32_t len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1); - uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1); - GPR_ASSERT(len_key <= UINT32_MAX); - GPR_ASSERT(GPR_SLICE_LENGTH(value_slice) <= UINT32_MAX); - *add_tiny_header_data(st, 1) = 0x40; - GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, - add_tiny_header_data(st, len_key_len), len_key_len); - add_header_data(st, gpr_slice_ref(elem->key->slice)); - GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix, - add_tiny_header_data(st, len_val_len), len_val_len); - add_header_data(st, gpr_slice_ref(value_slice)); -} - -static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c, - grpc_mdelem *elem, framer_state *st) { - uint32_t len_key = (uint32_t)GPR_SLICE_LENGTH(elem->key->slice); - uint8_t huffman_prefix; - gpr_slice value_slice = get_wire_value(elem, &huffman_prefix); - uint32_t len_val = (uint32_t)GPR_SLICE_LENGTH(value_slice); - uint32_t len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1); - uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1); - GPR_ASSERT(len_key <= UINT32_MAX); - GPR_ASSERT(GPR_SLICE_LENGTH(value_slice) <= UINT32_MAX); - *add_tiny_header_data(st, 1) = 0x00; - GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, - add_tiny_header_data(st, len_key_len), len_key_len); - add_header_data(st, gpr_slice_ref(elem->key->slice)); - GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix, - add_tiny_header_data(st, len_val_len), len_val_len); - add_header_data(st, gpr_slice_ref(value_slice)); -} - -static void emit_advertise_table_size_change(grpc_chttp2_hpack_compressor *c, - framer_state *st) { - uint32_t len = GRPC_CHTTP2_VARINT_LENGTH(c->max_table_size, 3); - GRPC_CHTTP2_WRITE_VARINT(c->max_table_size, 3, 0x20, - add_tiny_header_data(st, len), len); - c->advertise_table_size_change = 0; -} - -static uint32_t dynidx(grpc_chttp2_hpack_compressor *c, uint32_t elem_index) { - return 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY + c->tail_remote_index + - c->table_elems - elem_index; -} - -/* encode an mdelem */ -static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem, - framer_state *st) { - uint32_t key_hash = elem->key->hash; - uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash); - size_t decoder_space_usage; - uint32_t indices_key; - int should_add_elem; - - GPR_ASSERT(GPR_SLICE_LENGTH(elem->key->slice) > 0); - if (GPR_SLICE_START_PTR(elem->key->slice)[0] != ':') { /* regular header */ - st->seen_regular_header = 1; - } else { - GPR_ASSERT( - st->seen_regular_header == 0 && - "Reserved header (colon-prefixed) happening after regular ones."); - } - - inc_filter(HASH_FRAGMENT_1(elem_hash), &c->filter_elems_sum, c->filter_elems); - - /* is this elem currently in the decoders table? */ - - if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == elem && - c->indices_elems[HASH_FRAGMENT_2(elem_hash)] > c->tail_remote_index) { - /* HIT: complete element (first cuckoo hash) */ - emit_indexed(c, dynidx(c, c->indices_elems[HASH_FRAGMENT_2(elem_hash)]), - st); - return; - } - - if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == elem && - c->indices_elems[HASH_FRAGMENT_3(elem_hash)] > c->tail_remote_index) { - /* HIT: complete element (second cuckoo hash) */ - emit_indexed(c, dynidx(c, c->indices_elems[HASH_FRAGMENT_3(elem_hash)]), - st); - return; - } - - /* should this elem be in the table? */ - decoder_space_usage = 32 + GPR_SLICE_LENGTH(elem->key->slice) + - GPR_SLICE_LENGTH(elem->value->slice); - should_add_elem = decoder_space_usage < MAX_DECODER_SPACE_USAGE && - c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >= - c->filter_elems_sum / ONE_ON_ADD_PROBABILITY; - - /* no hits for the elem... maybe there's a key? */ - - indices_key = c->indices_keys[HASH_FRAGMENT_2(key_hash)]; - if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == elem->key && - indices_key > c->tail_remote_index) { - /* HIT: key (first cuckoo hash) */ - if (should_add_elem) { - emit_lithdr_incidx(c, dynidx(c, indices_key), elem, st); - add_elem(c, elem); - return; - } else { - emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st); - return; - } - GPR_UNREACHABLE_CODE(return ); - } - - indices_key = c->indices_keys[HASH_FRAGMENT_3(key_hash)]; - if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == elem->key && - indices_key > c->tail_remote_index) { - /* HIT: key (first cuckoo hash) */ - if (should_add_elem) { - emit_lithdr_incidx(c, dynidx(c, indices_key), elem, st); - add_elem(c, elem); - return; - } else { - emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st); - return; - } - GPR_UNREACHABLE_CODE(return ); - } - - /* no elem, key in the table... fall back to literal emission */ - - if (should_add_elem) { - emit_lithdr_incidx_v(c, elem, st); - add_elem(c, elem); - return; - } else { - emit_lithdr_noidx_v(c, elem, st); - return; - } - GPR_UNREACHABLE_CODE(return ); -} - -#define STRLEN_LIT(x) (sizeof(x) - 1) -#define TIMEOUT_KEY "grpc-timeout" - -static void deadline_enc(grpc_chttp2_hpack_compressor *c, gpr_timespec deadline, - framer_state *st) { - char timeout_str[GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; - grpc_mdelem *mdelem; - grpc_chttp2_encode_timeout( - gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str); - mdelem = grpc_mdelem_from_metadata_strings( - GRPC_MDSTR_GRPC_TIMEOUT, grpc_mdstr_from_string(timeout_str)); - hpack_enc(c, mdelem, st); - GRPC_MDELEM_UNREF(mdelem); -} - -static uint32_t elems_for_bytes(uint32_t bytes) { return (bytes + 31) / 32; } - -void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c) { - memset(c, 0, sizeof(*c)); - c->max_table_size = GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE; - c->cap_table_elems = elems_for_bytes(c->max_table_size); - c->max_table_elems = c->cap_table_elems; - c->max_usable_size = GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE; - c->table_elem_size = - gpr_malloc(sizeof(*c->table_elem_size) * c->cap_table_elems); - memset(c->table_elem_size, 0, - sizeof(*c->table_elem_size) * c->cap_table_elems); -} - -void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) { - int i; - for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_VALUES; i++) { - if (c->entries_keys[i]) GRPC_MDSTR_UNREF(c->entries_keys[i]); - if (c->entries_elems[i]) GRPC_MDELEM_UNREF(c->entries_elems[i]); - } - gpr_free(c->table_elem_size); -} - -void grpc_chttp2_hpack_compressor_set_max_usable_size( - grpc_chttp2_hpack_compressor *c, uint32_t max_table_size) { - c->max_usable_size = max_table_size; - grpc_chttp2_hpack_compressor_set_max_table_size( - c, GPR_MIN(c->max_table_size, max_table_size)); -} - -static void rebuild_elems(grpc_chttp2_hpack_compressor *c, uint32_t new_cap) { - uint16_t *table_elem_size = gpr_malloc(sizeof(*table_elem_size) * new_cap); - uint32_t i; - - memset(table_elem_size, 0, sizeof(*table_elem_size) * new_cap); - GPR_ASSERT(c->table_elems <= new_cap); - - for (i = 0; i < c->table_elems; i++) { - uint32_t ofs = c->tail_remote_index + i + 1; - table_elem_size[ofs % new_cap] = - c->table_elem_size[ofs % c->cap_table_elems]; - } - - c->cap_table_elems = new_cap; - gpr_free(c->table_elem_size); - c->table_elem_size = table_elem_size; -} - -void grpc_chttp2_hpack_compressor_set_max_table_size( - grpc_chttp2_hpack_compressor *c, uint32_t max_table_size) { - max_table_size = GPR_MIN(max_table_size, c->max_usable_size); - if (max_table_size == c->max_table_size) { - return; - } - while (c->table_size > 0 && c->table_size > max_table_size) { - evict_entry(c); - } - c->max_table_size = max_table_size; - c->max_table_elems = elems_for_bytes(max_table_size); - if (c->max_table_elems > c->cap_table_elems) { - rebuild_elems(c, GPR_MAX(c->max_table_elems, 2 * c->cap_table_elems)); - } else if (c->max_table_elems < c->cap_table_elems / 3) { - uint32_t new_cap = GPR_MAX(c->max_table_elems, 16); - if (new_cap != c->cap_table_elems) { - rebuild_elems(c, new_cap); - } - } - c->advertise_table_size_change = 1; - gpr_log(GPR_DEBUG, "set max table size from encoder to %d", max_table_size); -} - -void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, - uint32_t stream_id, - grpc_metadata_batch *metadata, int is_eof, - gpr_slice_buffer *outbuf) { - framer_state st; - grpc_linked_mdelem *l; - gpr_timespec deadline; - - GPR_ASSERT(stream_id != 0); - - st.seen_regular_header = 0; - st.stream_id = stream_id; - st.output = outbuf; - st.is_first_frame = 1; - - /* Encode a metadata batch; store the returned values, representing - a metadata element that needs to be unreffed back into the metadata - slot. THIS MAY NOT BE THE SAME ELEMENT (if a decoder table slot got - updated). After this loop, we'll do a batch unref of elements. */ - begin_frame(&st); - if (c->advertise_table_size_change != 0) { - emit_advertise_table_size_change(c, &st); - } - grpc_metadata_batch_assert_ok(metadata); - for (l = metadata->list.head; l; l = l->next) { - hpack_enc(c, l->md, &st); - } - deadline = metadata->deadline; - if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) != 0) { - deadline_enc(c, deadline, &st); - } - - finish_frame(&st, 1, is_eof); -} diff --git a/src/core/transport/chttp2/hpack_encoder.h b/src/core/transport/chttp2/hpack_encoder.h deleted file mode 100644 index 6d86eb7c83..0000000000 --- a/src/core/transport/chttp2/hpack_encoder.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_HPACK_ENCODER_H -#define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H - -#include -#include -#include -#include "src/core/transport/chttp2/frame.h" -#include "src/core/transport/metadata.h" -#include "src/core/transport/metadata_batch.h" - -#define GRPC_CHTTP2_HPACKC_NUM_FILTERS 256 -#define GRPC_CHTTP2_HPACKC_NUM_VALUES 256 -/* initial table size, per spec */ -#define GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE 4096 -/* maximum table size we'll actually use */ -#define GRPC_CHTTP2_HPACKC_MAX_TABLE_SIZE (1024 * 1024) - -typedef struct { - uint32_t filter_elems_sum; - uint32_t max_table_size; - uint32_t max_table_elems; - uint32_t cap_table_elems; - /** if non-zero, advertise to the decoder that we'll start using a table - of this size */ - uint8_t advertise_table_size_change; - /** maximum number of bytes we'll use for the decode table (to guard against - peers ooming us by setting decode table size high) */ - uint32_t max_usable_size; - /* one before the lowest usable table index */ - uint32_t tail_remote_index; - uint32_t table_size; - uint32_t table_elems; - - /* filter tables for elems: this tables provides an approximate - popularity count for particular hashes, and are used to determine whether - a new literal should be added to the compression table or not. - They track a single integer that counts how often a particular value has - been seen. When that count reaches max (255), all values are halved. */ - uint8_t filter_elems[GRPC_CHTTP2_HPACKC_NUM_FILTERS]; - - /* entry tables for keys & elems: these tables track values that have been - seen and *may* be in the decompressor table */ - grpc_mdstr *entries_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES]; - grpc_mdelem *entries_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES]; - uint32_t indices_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES]; - uint32_t indices_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES]; - - uint16_t *table_elem_size; -} grpc_chttp2_hpack_compressor; - -void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c); -void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c); -void grpc_chttp2_hpack_compressor_set_max_table_size( - grpc_chttp2_hpack_compressor *c, uint32_t max_table_size); -void grpc_chttp2_hpack_compressor_set_max_usable_size( - grpc_chttp2_hpack_compressor *c, uint32_t max_table_size); - -void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, uint32_t id, - grpc_metadata_batch *metadata, int is_eof, - gpr_slice_buffer *outbuf); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H */ diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c deleted file mode 100644 index b6e36923cb..0000000000 --- a/src/core/transport/chttp2/hpack_parser.c +++ /dev/null @@ -1,1449 +0,0 @@ -/* - * - * Copyright 2015-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/transport/chttp2/hpack_parser.h" -#include "src/core/transport/chttp2/internal.h" - -#include -#include -#include - -/* This is here for grpc_is_binary_header - * TODO(murgatroid99): Remove this - */ -#include - -#include -#include -#include -#include - -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/bin_encoder.h" - -typedef enum { - NOT_BINARY, - B64_BYTE0, - B64_BYTE1, - B64_BYTE2, - B64_BYTE3 -} binary_state; - -/* How parsing works: - - The parser object keeps track of a function pointer which represents the - current parse state. - - Each time new bytes are presented, we call into the current state, which - recursively parses until all bytes in the given chunk are exhausted. - - The parse state that terminates then saves its function pointer to be the - current state so that it can resume when more bytes are available. - - It's expected that most optimizing compilers will turn this code into - a set of indirect jumps, and so not waste stack space. */ - -/* forward declarations for parsing states */ -static int parse_begin(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_error(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_illegal_op(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); - -static int parse_string_prefix(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_key_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_value_string_with_indexed_key(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, - const uint8_t *end); -static int parse_value_string_with_literal_key(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, - const uint8_t *end); - -static int parse_value0(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_value1(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_value2(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_value3(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_value4(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_value5up(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); - -static int parse_indexed_field(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_indexed_field_x(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end); -static int parse_lithdr_incidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end); -static int parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end); -static int parse_lithdr_notidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end); -static int parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end); -static int parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end); -static int parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end); -static int parse_max_tbl_size(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); -static int parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end); - -/* we translate the first byte of a hpack field into one of these decoding - cases, then use a lookup table to jump directly to the appropriate parser. - - _X => the integer index is all ones, meaning we need to do varint decoding - _V => the integer index is all zeros, meaning we need to decode an additional - string value */ -typedef enum { - INDEXED_FIELD, - INDEXED_FIELD_X, - LITHDR_INCIDX, - LITHDR_INCIDX_X, - LITHDR_INCIDX_V, - LITHDR_NOTIDX, - LITHDR_NOTIDX_X, - LITHDR_NOTIDX_V, - LITHDR_NVRIDX, - LITHDR_NVRIDX_X, - LITHDR_NVRIDX_V, - MAX_TBL_SIZE, - MAX_TBL_SIZE_X, - ILLEGAL -} first_byte_type; - -/* jump table of parse state functions -- order must match first_byte_type - above */ -static const grpc_chttp2_hpack_parser_state first_byte_action[] = { - parse_indexed_field, parse_indexed_field_x, parse_lithdr_incidx, - parse_lithdr_incidx_x, parse_lithdr_incidx_v, parse_lithdr_notidx, - parse_lithdr_notidx_x, parse_lithdr_notidx_v, parse_lithdr_nvridx, - parse_lithdr_nvridx_x, parse_lithdr_nvridx_v, parse_max_tbl_size, - parse_max_tbl_size_x, parse_illegal_op}; - -/* indexes the first byte to a parse state function - generated by - gen_hpack_tables.c */ -static const uint8_t first_byte_lut[256] = { - LITHDR_NOTIDX_V, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, - LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, - LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, - LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX_X, - LITHDR_NVRIDX_V, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, - LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, - LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, - LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX_X, - MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, - MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, - MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, - MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, - MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, - MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, - MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, - MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE_X, - LITHDR_INCIDX_V, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, - LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX_X, - ILLEGAL, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, - INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD_X, -}; - -/* state table for huffman decoding: given a state, gives an index/16 into - next_sub_tbl. Taking that index and adding the value of the nibble being - considered returns the next state. - - generated by gen_hpack_tables.c */ -static const uint8_t next_tbl[256] = { - 0, 1, 2, 3, 4, 1, 2, 5, 6, 1, 7, 8, 1, 3, 3, 9, 10, 11, 1, 1, - 1, 12, 1, 2, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 14, 1, 15, 16, 1, 17, 1, 15, 2, 7, 3, 18, 19, 1, 1, 1, 1, 20, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 15, 2, 2, 7, 21, 1, 22, 1, 1, 1, 1, 1, - 1, 1, 1, 15, 2, 2, 2, 2, 2, 2, 23, 24, 25, 1, 1, 1, 1, 2, 2, 2, - 26, 3, 3, 27, 10, 28, 1, 1, 1, 1, 1, 1, 2, 3, 29, 10, 30, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 2, 2, 2, 2, 2, 2, 32, 1, 1, 15, 33, 1, 34, 35, 9, 36, 1, 1, 1, - 1, 1, 1, 1, 37, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 26, 9, - 38, 1, 1, 1, 1, 1, 1, 1, 15, 2, 2, 2, 2, 26, 3, 3, 39, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 7, 3, 3, 3, 40, 2, - 41, 1, 1, 1, 42, 43, 1, 1, 44, 1, 1, 1, 1, 15, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 45, 46, 1, 1, 2, 2, 2, 35, 3, 3, 18, 47, 2, -}; - -/* next state, based upon current state and the current nibble: see above. - generated by gen_hpack_tables.c */ -static const int16_t next_sub_tbl[48 * 16] = { - 1, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 2, 6, 10, 13, 14, 15, 16, 17, 2, 6, 10, 13, 14, 15, - 16, 17, 3, 7, 11, 24, 3, 7, 11, 24, 3, 7, 11, 24, 3, - 7, 11, 24, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, - 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 199, 200, 201, 202, 203, 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 3, 7, 11, 24, 3, 7, 11, 24, - 4, 8, 4, 8, 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 12, 132, 4, 8, 4, 8, 4, 8, - 4, 8, 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 21, 4, 8, 4, - 8, 4, 8, 4, 8, 4, 8, 0, 0, 0, 22, 23, 91, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 3, - 7, 11, 24, 3, 7, 11, 24, 0, 0, 0, 0, 0, 41, 42, 43, - 2, 6, 10, 13, 14, 15, 16, 17, 3, 7, 11, 24, 3, 7, 11, - 24, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 0, 0, - 44, 45, 2, 6, 10, 13, 14, 15, 16, 17, 46, 47, 48, 49, 50, - 51, 52, 57, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 53, 54, 55, 56, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 73, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 3, 7, 11, 24, 3, 7, 11, - 24, 3, 7, 11, 24, 0, 0, 0, 0, 3, 7, 11, 24, 3, 7, - 11, 24, 4, 8, 4, 8, 0, 0, 0, 92, 0, 0, 0, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 3, 7, 11, 24, - 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, - 8, 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 4, - 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 0, 0, - 0, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 2, 6, 10, 13, 14, 15, 16, 17, 4, 8, 4, 8, 4, 8, - 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 148, - 149, 150, 151, 3, 7, 11, 24, 4, 8, 4, 8, 0, 0, 0, 0, - 0, 0, 152, 153, 3, 7, 11, 24, 3, 7, 11, 24, 3, 7, 11, - 24, 154, 155, 156, 164, 3, 7, 11, 24, 3, 7, 11, 24, 3, 7, - 11, 24, 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 157, 158, 159, 160, 161, 162, 163, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 4, 8, 4, 8, 4, 8, - 4, 8, 4, 8, 4, 8, 4, 8, 197, 198, 4, 8, 4, 8, 4, - 8, 4, 8, 0, 0, 0, 0, 0, 0, 219, 220, 3, 7, 11, 24, - 4, 8, 4, 8, 4, 8, 0, 0, 221, 222, 223, 224, 3, 7, 11, - 24, 3, 7, 11, 24, 4, 8, 4, 8, 4, 8, 225, 228, 4, 8, - 4, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 226, 227, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, -}; - -/* emission table: indexed like next_tbl, ultimately gives the byte to be - emitted, or -1 for no byte, or 256 for end of stream - - generated by gen_hpack_tables.c */ -static const uint16_t emit_tbl[256] = { - 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 0, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 0, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 0, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, - 0, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 0, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, -}; - -/* generated by gen_hpack_tables.c */ -static const int16_t emit_sub_tbl[249 * 16] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, - 49, 49, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 97, - 97, 97, 97, 48, 48, 49, 49, 50, 50, 97, 97, 99, 99, 101, 101, - 105, 105, 111, 111, 48, 49, 50, 97, 99, 101, 105, 111, 115, 116, -1, - -1, -1, -1, -1, -1, 32, 32, 32, 32, 32, 32, 32, 32, 37, 37, - 37, 37, 37, 37, 37, 37, 99, 99, 99, 99, 101, 101, 101, 101, 105, - 105, 105, 105, 111, 111, 111, 111, 115, 115, 116, 116, 32, 37, 45, 46, - 47, 51, 52, 53, 54, 55, 56, 57, 61, 61, 61, 61, 61, 61, 61, - 61, 65, 65, 65, 65, 65, 65, 65, 65, 115, 115, 115, 115, 116, 116, - 116, 116, 32, 32, 37, 37, 45, 45, 46, 46, 61, 65, 95, 98, 100, - 102, 103, 104, 108, 109, 110, 112, 114, 117, -1, -1, 58, 58, 58, 58, - 58, 58, 58, 58, 66, 66, 66, 66, 66, 66, 66, 66, 47, 47, 51, - 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 61, 61, - 65, 65, 95, 95, 98, 98, 100, 100, 102, 102, 103, 103, 104, 104, 108, - 108, 109, 109, 110, 110, 112, 112, 114, 114, 117, 117, 58, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 89, 106, 107, 113, 118, 119, 120, 121, 122, -1, -1, - -1, -1, 38, 38, 38, 38, 38, 38, 38, 38, 42, 42, 42, 42, 42, - 42, 42, 42, 44, 44, 44, 44, 44, 44, 44, 44, 59, 59, 59, 59, - 59, 59, 59, 59, 88, 88, 88, 88, 88, 88, 88, 88, 90, 90, 90, - 90, 90, 90, 90, 90, 33, 33, 34, 34, 40, 40, 41, 41, 63, 63, - 39, 43, 124, -1, -1, -1, 35, 35, 35, 35, 35, 35, 35, 35, 62, - 62, 62, 62, 62, 62, 62, 62, 0, 0, 0, 0, 36, 36, 36, 36, - 64, 64, 64, 64, 91, 91, 91, 91, 69, 69, 69, 69, 69, 69, 69, - 69, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, - 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, - 73, 73, 73, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, - 75, 75, 75, 75, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, - 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, - 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, 80, 80, 80, 80, 81, - 81, 81, 81, 81, 81, 81, 81, 82, 82, 82, 82, 82, 82, 82, 82, - 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, 84, 84, 84, - 84, 85, 85, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 86, 86, - 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 89, 89, 89, 89, 89, - 89, 89, 89, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, - 107, 107, 107, 107, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118, - 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 120, 120, - 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 122, - 122, 122, 122, 122, 122, 122, 122, 38, 38, 38, 38, 42, 42, 42, 42, - 44, 44, 44, 44, 59, 59, 59, 59, 88, 88, 88, 88, 90, 90, 90, - 90, 33, 34, 40, 41, 63, -1, -1, -1, 39, 39, 39, 39, 39, 39, - 39, 39, 43, 43, 43, 43, 43, 43, 43, 43, 124, 124, 124, 124, 124, - 124, 124, 124, 35, 35, 35, 35, 62, 62, 62, 62, 0, 0, 36, 36, - 64, 64, 91, 91, 93, 93, 126, 126, 94, 125, -1, -1, 60, 60, 60, - 60, 60, 60, 60, 60, 96, 96, 96, 96, 96, 96, 96, 96, 123, 123, - 123, 123, 123, 123, 123, 123, -1, -1, -1, -1, -1, -1, -1, -1, 92, - 92, 92, 92, 92, 92, 92, 92, 195, 195, 195, 195, 195, 195, 195, 195, - 208, 208, 208, 208, 208, 208, 208, 208, 128, 128, 128, 128, 130, 130, 130, - 130, 131, 131, 131, 131, 162, 162, 162, 162, 184, 184, 184, 184, 194, 194, - 194, 194, 224, 224, 224, 224, 226, 226, 226, 226, 153, 153, 161, 161, 167, - 167, 172, 172, 176, 176, 177, 177, 179, 179, 209, 209, 216, 216, 217, 217, - 227, 227, 229, 229, 230, 230, 129, 132, 133, 134, 136, 146, 154, 156, 160, - 163, 164, 169, 170, 173, 178, 181, 185, 186, 187, 189, 190, 196, 198, 228, - 232, 233, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 135, - 135, 135, 135, 135, 135, 135, 135, 137, 137, 137, 137, 137, 137, 137, 137, - 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139, 139, 139, 139, - 139, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141, 141, - 141, 141, 143, 143, 143, 143, 143, 143, 143, 143, 147, 147, 147, 147, 147, - 147, 147, 147, 149, 149, 149, 149, 149, 149, 149, 149, 150, 150, 150, 150, - 150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 151, 151, 152, 152, 152, - 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 157, 157, - 157, 157, 157, 157, 157, 157, 158, 158, 158, 158, 158, 158, 158, 158, 165, - 165, 165, 165, 165, 165, 165, 165, 166, 166, 166, 166, 166, 166, 166, 166, - 168, 168, 168, 168, 168, 168, 168, 168, 174, 174, 174, 174, 174, 174, 174, - 174, 175, 175, 175, 175, 175, 175, 175, 175, 180, 180, 180, 180, 180, 180, - 180, 180, 182, 182, 182, 182, 182, 182, 182, 182, 183, 183, 183, 183, 183, - 183, 183, 183, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191, - 191, 191, 191, 191, 197, 197, 197, 197, 197, 197, 197, 197, 231, 231, 231, - 231, 231, 231, 231, 231, 239, 239, 239, 239, 239, 239, 239, 239, 9, 9, - 9, 9, 142, 142, 142, 142, 144, 144, 144, 144, 145, 145, 145, 145, 148, - 148, 148, 148, 159, 159, 159, 159, 171, 171, 171, 171, 206, 206, 206, 206, - 215, 215, 215, 215, 225, 225, 225, 225, 236, 236, 236, 236, 237, 237, 237, - 237, 199, 199, 207, 207, 234, 234, 235, 235, 192, 193, 200, 201, 202, 205, - 210, 213, 218, 219, 238, 240, 242, 243, 255, -1, 203, 203, 203, 203, 203, - 203, 203, 203, 204, 204, 204, 204, 204, 204, 204, 204, 211, 211, 211, 211, - 211, 211, 211, 211, 212, 212, 212, 212, 212, 212, 212, 212, 214, 214, 214, - 214, 214, 214, 214, 214, 221, 221, 221, 221, 221, 221, 221, 221, 222, 222, - 222, 222, 222, 222, 222, 222, 223, 223, 223, 223, 223, 223, 223, 223, 241, - 241, 241, 241, 241, 241, 241, 241, 244, 244, 244, 244, 244, 244, 244, 244, - 245, 245, 245, 245, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, - 246, 247, 247, 247, 247, 247, 247, 247, 247, 248, 248, 248, 248, 248, 248, - 248, 248, 250, 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, 251, 251, - 251, 251, 251, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, - 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 2, 2, 2, - 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, - 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 11, 11, 11, 11, 12, - 12, 12, 12, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, - 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, - 20, 21, 21, 21, 21, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, - 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, - 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 127, 127, 127, 127, - 220, 220, 220, 220, 249, 249, 249, 249, 10, 13, 22, 256, 93, 93, 93, - 93, 126, 126, 126, 126, 94, 94, 125, 125, 60, 96, 123, -1, 92, 195, - 208, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 128, - 128, 128, 128, 128, 128, 128, 128, 130, 130, 130, 130, 130, 130, 130, 130, - 131, 131, 131, 131, 131, 131, 131, 131, 162, 162, 162, 162, 162, 162, 162, - 162, 184, 184, 184, 184, 184, 184, 184, 184, 194, 194, 194, 194, 194, 194, - 194, 194, 224, 224, 224, 224, 224, 224, 224, 224, 226, 226, 226, 226, 226, - 226, 226, 226, 153, 153, 153, 153, 161, 161, 161, 161, 167, 167, 167, 167, - 172, 172, 172, 172, 176, 176, 176, 176, 177, 177, 177, 177, 179, 179, 179, - 179, 209, 209, 209, 209, 216, 216, 216, 216, 217, 217, 217, 217, 227, 227, - 227, 227, 229, 229, 229, 229, 230, 230, 230, 230, 129, 129, 132, 132, 133, - 133, 134, 134, 136, 136, 146, 146, 154, 154, 156, 156, 160, 160, 163, 163, - 164, 164, 169, 169, 170, 170, 173, 173, 178, 178, 181, 181, 185, 185, 186, - 186, 187, 187, 189, 189, 190, 190, 196, 196, 198, 198, 228, 228, 232, 232, - 233, 233, 1, 135, 137, 138, 139, 140, 141, 143, 147, 149, 150, 151, 152, - 155, 157, 158, 165, 166, 168, 174, 175, 180, 182, 183, 188, 191, 197, 231, - 239, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 9, 9, - 9, 9, 9, 9, 9, 142, 142, 142, 142, 142, 142, 142, 142, 144, 144, - 144, 144, 144, 144, 144, 144, 145, 145, 145, 145, 145, 145, 145, 145, 148, - 148, 148, 148, 148, 148, 148, 148, 159, 159, 159, 159, 159, 159, 159, 159, - 171, 171, 171, 171, 171, 171, 171, 171, 206, 206, 206, 206, 206, 206, 206, - 206, 215, 215, 215, 215, 215, 215, 215, 215, 225, 225, 225, 225, 225, 225, - 225, 225, 236, 236, 236, 236, 236, 236, 236, 236, 237, 237, 237, 237, 237, - 237, 237, 237, 199, 199, 199, 199, 207, 207, 207, 207, 234, 234, 234, 234, - 235, 235, 235, 235, 192, 192, 193, 193, 200, 200, 201, 201, 202, 202, 205, - 205, 210, 210, 213, 213, 218, 218, 219, 219, 238, 238, 240, 240, 242, 242, - 243, 243, 255, 255, 203, 204, 211, 212, 214, 221, 222, 223, 241, 244, 245, - 246, 247, 248, 250, 251, 252, 253, 254, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, 2, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, - 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, - 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, - 12, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, - 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, - 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, - 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, - 20, 21, 21, 21, 21, 21, 21, 21, 21, 23, 23, 23, 23, 23, 23, - 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, - 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, - 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, - 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, - 31, 31, 31, 31, 31, 31, 127, 127, 127, 127, 127, 127, 127, 127, 220, - 220, 220, 220, 220, 220, 220, 220, 249, 249, 249, 249, 249, 249, 249, 249, - 10, 10, 13, 13, 22, 22, 256, 256, 67, 67, 67, 67, 67, 67, 67, - 67, 68, 68, 68, 68, 68, 68, 68, 68, 95, 95, 95, 95, 95, 95, - 95, 95, 98, 98, 98, 98, 98, 98, 98, 98, 100, 100, 100, 100, 100, - 100, 100, 100, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, - 103, 103, 103, 103, 104, 104, 104, 104, 104, 104, 104, 104, 108, 108, 108, - 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 110, 110, - 110, 110, 110, 110, 110, 110, 112, 112, 112, 112, 112, 112, 112, 112, 114, - 114, 114, 114, 114, 114, 114, 114, 117, 117, 117, 117, 117, 117, 117, 117, - 58, 58, 58, 58, 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, - 68, 69, 69, 69, 69, 70, 70, 70, 70, 71, 71, 71, 71, 72, 72, - 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 76, - 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 79, - 80, 80, 80, 80, 81, 81, 81, 81, 82, 82, 82, 82, 83, 83, 83, - 83, 84, 84, 84, 84, 85, 85, 85, 85, 86, 86, 86, 86, 87, 87, - 87, 87, 89, 89, 89, 89, 106, 106, 106, 106, 107, 107, 107, 107, 113, - 113, 113, 113, 118, 118, 118, 118, 119, 119, 119, 119, 120, 120, 120, 120, - 121, 121, 121, 121, 122, 122, 122, 122, 38, 38, 42, 42, 44, 44, 59, - 59, 88, 88, 90, 90, -1, -1, -1, -1, 33, 33, 33, 33, 33, 33, - 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 40, 40, 40, 40, 40, - 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 63, 63, 63, 63, - 63, 63, 63, 63, 39, 39, 39, 39, 43, 43, 43, 43, 124, 124, 124, - 124, 35, 35, 62, 62, 0, 36, 64, 91, 93, 126, -1, -1, 94, 94, - 94, 94, 94, 94, 94, 94, 125, 125, 125, 125, 125, 125, 125, 125, 60, - 60, 60, 60, 96, 96, 96, 96, 123, 123, 123, 123, -1, -1, -1, -1, - 92, 92, 92, 92, 195, 195, 195, 195, 208, 208, 208, 208, 128, 128, 130, - 130, 131, 131, 162, 162, 184, 184, 194, 194, 224, 224, 226, 226, 153, 161, - 167, 172, 176, 177, 179, 209, 216, 217, 227, 229, 230, -1, -1, -1, -1, - -1, -1, -1, 129, 129, 129, 129, 129, 129, 129, 129, 132, 132, 132, 132, - 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 134, 134, 134, - 134, 134, 134, 134, 134, 136, 136, 136, 136, 136, 136, 136, 136, 146, 146, - 146, 146, 146, 146, 146, 146, 154, 154, 154, 154, 154, 154, 154, 154, 156, - 156, 156, 156, 156, 156, 156, 156, 160, 160, 160, 160, 160, 160, 160, 160, - 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, - 164, 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, - 170, 170, 173, 173, 173, 173, 173, 173, 173, 173, 178, 178, 178, 178, 178, - 178, 178, 178, 181, 181, 181, 181, 181, 181, 181, 181, 185, 185, 185, 185, - 185, 185, 185, 185, 186, 186, 186, 186, 186, 186, 186, 186, 187, 187, 187, - 187, 187, 187, 187, 187, 189, 189, 189, 189, 189, 189, 189, 189, 190, 190, - 190, 190, 190, 190, 190, 190, 196, 196, 196, 196, 196, 196, 196, 196, 198, - 198, 198, 198, 198, 198, 198, 198, 228, 228, 228, 228, 228, 228, 228, 228, - 232, 232, 232, 232, 232, 232, 232, 232, 233, 233, 233, 233, 233, 233, 233, - 233, 1, 1, 1, 1, 135, 135, 135, 135, 137, 137, 137, 137, 138, 138, - 138, 138, 139, 139, 139, 139, 140, 140, 140, 140, 141, 141, 141, 141, 143, - 143, 143, 143, 147, 147, 147, 147, 149, 149, 149, 149, 150, 150, 150, 150, - 151, 151, 151, 151, 152, 152, 152, 152, 155, 155, 155, 155, 157, 157, 157, - 157, 158, 158, 158, 158, 165, 165, 165, 165, 166, 166, 166, 166, 168, 168, - 168, 168, 174, 174, 174, 174, 175, 175, 175, 175, 180, 180, 180, 180, 182, - 182, 182, 182, 183, 183, 183, 183, 188, 188, 188, 188, 191, 191, 191, 191, - 197, 197, 197, 197, 231, 231, 231, 231, 239, 239, 239, 239, 9, 9, 142, - 142, 144, 144, 145, 145, 148, 148, 159, 159, 171, 171, 206, 206, 215, 215, - 225, 225, 236, 236, 237, 237, 199, 207, 234, 235, 192, 192, 192, 192, 192, - 192, 192, 192, 193, 193, 193, 193, 193, 193, 193, 193, 200, 200, 200, 200, - 200, 200, 200, 200, 201, 201, 201, 201, 201, 201, 201, 201, 202, 202, 202, - 202, 202, 202, 202, 202, 205, 205, 205, 205, 205, 205, 205, 205, 210, 210, - 210, 210, 210, 210, 210, 210, 213, 213, 213, 213, 213, 213, 213, 213, 218, - 218, 218, 218, 218, 218, 218, 218, 219, 219, 219, 219, 219, 219, 219, 219, - 238, 238, 238, 238, 238, 238, 238, 238, 240, 240, 240, 240, 240, 240, 240, - 240, 242, 242, 242, 242, 242, 242, 242, 242, 243, 243, 243, 243, 243, 243, - 243, 243, 255, 255, 255, 255, 255, 255, 255, 255, 203, 203, 203, 203, 204, - 204, 204, 204, 211, 211, 211, 211, 212, 212, 212, 212, 214, 214, 214, 214, - 221, 221, 221, 221, 222, 222, 222, 222, 223, 223, 223, 223, 241, 241, 241, - 241, 244, 244, 244, 244, 245, 245, 245, 245, 246, 246, 246, 246, 247, 247, - 247, 247, 248, 248, 248, 248, 250, 250, 250, 250, 251, 251, 251, 251, 252, - 252, 252, 252, 253, 253, 253, 253, 254, 254, 254, 254, 2, 2, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 11, 11, 12, 12, 14, - 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, - 30, 31, 31, 127, 127, 220, 220, 249, 249, -1, -1, 10, 10, 10, 10, - 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 22, 22, 22, - 22, 22, 22, 22, 22, 256, 256, 256, 256, 256, 256, 256, 256, 45, 45, - 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 47, - 47, 47, 47, 47, 47, 47, 47, 51, 51, 51, 51, 51, 51, 51, 51, - 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, - 53, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, - 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, - 57, 57, 57, 50, 50, 50, 50, 50, 50, 50, 50, 97, 97, 97, 97, - 97, 97, 97, 97, 99, 99, 99, 99, 99, 99, 99, 99, 101, 101, 101, - 101, 101, 101, 101, 101, 105, 105, 105, 105, 105, 105, 105, 105, 111, 111, - 111, 111, 111, 111, 111, 111, 115, 115, 115, 115, 115, 115, 115, 115, 116, - 116, 116, 116, 116, 116, 116, 116, 32, 32, 32, 32, 37, 37, 37, 37, - 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 51, 51, 51, - 51, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, - 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, 61, 61, 61, 61, 65, - 65, 65, 65, 95, 95, 95, 95, 98, 98, 98, 98, 100, 100, 100, 100, - 102, 102, 102, 102, 103, 103, 103, 103, 104, 104, 104, 104, 108, 108, 108, - 108, 109, 109, 109, 109, 110, 110, 110, 110, 112, 112, 112, 112, 114, 114, - 114, 114, 117, 117, 117, 117, 58, 58, 66, 66, 67, 67, 68, 68, 69, - 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, - 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, - 84, 85, 85, 86, 86, 87, 87, 89, 89, 106, 106, 107, 107, 113, 113, - 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 38, 42, 44, 59, 88, - 90, -1, -1, 33, 33, 33, 33, 34, 34, 34, 34, 40, 40, 40, 40, - 41, 41, 41, 41, 63, 63, 63, 63, 39, 39, 43, 43, 124, 124, 35, - 62, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36, - 36, 36, 36, 36, 36, 36, 64, 64, 64, 64, 64, 64, 64, 64, 91, - 91, 91, 91, 91, 91, 91, 91, 93, 93, 93, 93, 93, 93, 93, 93, - 126, 126, 126, 126, 126, 126, 126, 126, 94, 94, 94, 94, 125, 125, 125, - 125, 60, 60, 96, 96, 123, 123, -1, -1, 92, 92, 195, 195, 208, 208, - 128, 130, 131, 162, 184, 194, 224, 226, -1, -1, 153, 153, 153, 153, 153, - 153, 153, 153, 161, 161, 161, 161, 161, 161, 161, 161, 167, 167, 167, 167, - 167, 167, 167, 167, 172, 172, 172, 172, 172, 172, 172, 172, 176, 176, 176, - 176, 176, 176, 176, 176, 177, 177, 177, 177, 177, 177, 177, 177, 179, 179, - 179, 179, 179, 179, 179, 179, 209, 209, 209, 209, 209, 209, 209, 209, 216, - 216, 216, 216, 216, 216, 216, 216, 217, 217, 217, 217, 217, 217, 217, 217, - 227, 227, 227, 227, 227, 227, 227, 227, 229, 229, 229, 229, 229, 229, 229, - 229, 230, 230, 230, 230, 230, 230, 230, 230, 129, 129, 129, 129, 132, 132, - 132, 132, 133, 133, 133, 133, 134, 134, 134, 134, 136, 136, 136, 136, 146, - 146, 146, 146, 154, 154, 154, 154, 156, 156, 156, 156, 160, 160, 160, 160, - 163, 163, 163, 163, 164, 164, 164, 164, 169, 169, 169, 169, 170, 170, 170, - 170, 173, 173, 173, 173, 178, 178, 178, 178, 181, 181, 181, 181, 185, 185, - 185, 185, 186, 186, 186, 186, 187, 187, 187, 187, 189, 189, 189, 189, 190, - 190, 190, 190, 196, 196, 196, 196, 198, 198, 198, 198, 228, 228, 228, 228, - 232, 232, 232, 232, 233, 233, 233, 233, 1, 1, 135, 135, 137, 137, 138, - 138, 139, 139, 140, 140, 141, 141, 143, 143, 147, 147, 149, 149, 150, 150, - 151, 151, 152, 152, 155, 155, 157, 157, 158, 158, 165, 165, 166, 166, 168, - 168, 174, 174, 175, 175, 180, 180, 182, 182, 183, 183, 188, 188, 191, 191, - 197, 197, 231, 231, 239, 239, 9, 142, 144, 145, 148, 159, 171, 206, 215, - 225, 236, 237, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 199, 199, - 199, 199, 199, 199, 199, 199, 207, 207, 207, 207, 207, 207, 207, 207, 234, - 234, 234, 234, 234, 234, 234, 234, 235, 235, 235, 235, 235, 235, 235, 235, - 192, 192, 192, 192, 193, 193, 193, 193, 200, 200, 200, 200, 201, 201, 201, - 201, 202, 202, 202, 202, 205, 205, 205, 205, 210, 210, 210, 210, 213, 213, - 213, 213, 218, 218, 218, 218, 219, 219, 219, 219, 238, 238, 238, 238, 240, - 240, 240, 240, 242, 242, 242, 242, 243, 243, 243, 243, 255, 255, 255, 255, - 203, 203, 204, 204, 211, 211, 212, 212, 214, 214, 221, 221, 222, 222, 223, - 223, 241, 241, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 250, 250, - 251, 251, 252, 252, 253, 253, 254, 254, 2, 3, 4, 5, 6, 7, 8, - 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 127, 220, 249, -1, 10, 10, 10, 10, 13, 13, 13, - 13, 22, 22, 22, 22, 256, 256, 256, 256, -}; - -static const uint8_t inverse_base64[256] = { - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, - 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, - 255, 64, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, -}; - -/* emission helpers */ -static int on_hdr(grpc_chttp2_hpack_parser *p, grpc_mdelem *md, - int add_to_table) { - if (add_to_table) { - if (!grpc_chttp2_hptbl_add(&p->table, md)) { - return 0; - } - } - p->on_header(p->on_header_user_data, md); - return 1; -} - -static grpc_mdstr *take_string(grpc_chttp2_hpack_parser *p, - grpc_chttp2_hpack_parser_string *str) { - grpc_mdstr *s = grpc_mdstr_from_buffer((uint8_t *)str->str, str->length); - str->length = 0; - return s; -} - -/* jump to the next state */ -static int parse_next(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - p->state = *p->next_state++; - return p->state(p, cur, end); -} - -/* begin parsing a header: all functionality is encoded into lookup tables - above */ -static int parse_begin(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (cur == end) { - p->state = parse_begin; - return 1; - } - - return first_byte_action[first_byte_lut[*cur]](p, cur, end); -} - -/* stream dependency and prioritization data: we just skip it */ -static int parse_stream_weight(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (cur == end) { - p->state = parse_stream_weight; - return 1; - } - - return p->after_prioritization(p, cur + 1, end); -} - -static int parse_stream_dep3(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (cur == end) { - p->state = parse_stream_dep3; - return 1; - } - - return parse_stream_weight(p, cur + 1, end); -} - -static int parse_stream_dep2(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (cur == end) { - p->state = parse_stream_dep2; - return 1; - } - - return parse_stream_dep3(p, cur + 1, end); -} - -static int parse_stream_dep1(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (cur == end) { - p->state = parse_stream_dep1; - return 1; - } - - return parse_stream_dep2(p, cur + 1, end); -} - -static int parse_stream_dep0(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (cur == end) { - p->state = parse_stream_dep0; - return 1; - } - - return parse_stream_dep1(p, cur + 1, end); -} - -/* emit an indexed field; for now just logs it to console; jumps to - begin the next field on completion */ -static int finish_indexed_field(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); - if (md == NULL) { - gpr_log(GPR_ERROR, "Invalid HPACK index received: %d", p->index); - return 0; - } - GRPC_MDELEM_REF(md); - return on_hdr(p, md, 0) && parse_begin(p, cur, end); -} - -/* parse an indexed field with index < 127 */ -static int parse_indexed_field(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - p->dynamic_table_update_allowed = 0; - p->index = (*cur) & 0x7f; - return finish_indexed_field(p, cur + 1, end); -} - -/* parse an indexed field with index >= 127 */ -static int parse_indexed_field_x(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end) { - static const grpc_chttp2_hpack_parser_state and_then[] = { - finish_indexed_field}; - p->dynamic_table_update_allowed = 0; - p->next_state = and_then; - p->index = 0x7f; - p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); -} - -/* finish a literal header with incremental indexing: just log, and jump to ' - begin */ -static int finish_lithdr_incidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); - GPR_ASSERT(md != NULL); /* handled in string parsing */ - return on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key), - take_string(p, &p->value)), - 1) && - parse_begin(p, cur, end); -} - -/* finish a literal header with incremental indexing with no index */ -static int finish_lithdr_incidx_v(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end) { - return on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key), - take_string(p, &p->value)), - 1) && - parse_begin(p, cur, end); -} - -/* parse a literal header with incremental indexing; index < 63 */ -static int parse_lithdr_incidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - static const grpc_chttp2_hpack_parser_state and_then[] = { - parse_value_string_with_indexed_key, finish_lithdr_incidx}; - p->dynamic_table_update_allowed = 0; - p->next_state = and_then; - p->index = (*cur) & 0x3f; - return parse_string_prefix(p, cur + 1, end); -} - -/* parse a literal header with incremental indexing; index >= 63 */ -static int parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end) { - static const grpc_chttp2_hpack_parser_state and_then[] = { - parse_string_prefix, parse_value_string_with_indexed_key, - finish_lithdr_incidx}; - p->dynamic_table_update_allowed = 0; - p->next_state = and_then; - p->index = 0x3f; - p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); -} - -/* parse a literal header with incremental indexing; index = 0 */ -static int parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end) { - static const grpc_chttp2_hpack_parser_state and_then[] = { - parse_key_string, parse_string_prefix, - parse_value_string_with_literal_key, finish_lithdr_incidx_v}; - p->dynamic_table_update_allowed = 0; - p->next_state = and_then; - return parse_string_prefix(p, cur + 1, end); -} - -/* finish a literal header without incremental indexing */ -static int finish_lithdr_notidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); - GPR_ASSERT(md != NULL); /* handled in string parsing */ - return on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key), - take_string(p, &p->value)), - 0) && - parse_begin(p, cur, end); -} - -/* finish a literal header without incremental indexing with index = 0 */ -static int finish_lithdr_notidx_v(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end) { - return on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key), - take_string(p, &p->value)), - 0) && - parse_begin(p, cur, end); -} - -/* parse a literal header without incremental indexing; index < 15 */ -static int parse_lithdr_notidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - static const grpc_chttp2_hpack_parser_state and_then[] = { - parse_value_string_with_indexed_key, finish_lithdr_notidx}; - p->dynamic_table_update_allowed = 0; - p->next_state = and_then; - p->index = (*cur) & 0xf; - return parse_string_prefix(p, cur + 1, end); -} - -/* parse a literal header without incremental indexing; index >= 15 */ -static int parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end) { - static const grpc_chttp2_hpack_parser_state and_then[] = { - parse_string_prefix, parse_value_string_with_indexed_key, - finish_lithdr_notidx}; - p->dynamic_table_update_allowed = 0; - p->next_state = and_then; - p->index = 0xf; - p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); -} - -/* parse a literal header without incremental indexing; index == 0 */ -static int parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end) { - static const grpc_chttp2_hpack_parser_state and_then[] = { - parse_key_string, parse_string_prefix, - parse_value_string_with_literal_key, finish_lithdr_notidx_v}; - p->dynamic_table_update_allowed = 0; - p->next_state = and_then; - return parse_string_prefix(p, cur + 1, end); -} - -/* finish a literal header that is never indexed */ -static int finish_lithdr_nvridx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); - GPR_ASSERT(md != NULL); /* handled in string parsing */ - return on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key), - take_string(p, &p->value)), - 0) && - parse_begin(p, cur, end); -} - -/* finish a literal header that is never indexed with an extra value */ -static int finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end) { - return on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key), - take_string(p, &p->value)), - 0) && - parse_begin(p, cur, end); -} - -/* parse a literal header that is never indexed; index < 15 */ -static int parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - static const grpc_chttp2_hpack_parser_state and_then[] = { - parse_value_string_with_indexed_key, finish_lithdr_nvridx}; - p->dynamic_table_update_allowed = 0; - p->next_state = and_then; - p->index = (*cur) & 0xf; - return parse_string_prefix(p, cur + 1, end); -} - -/* parse a literal header that is never indexed; index >= 15 */ -static int parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end) { - static const grpc_chttp2_hpack_parser_state and_then[] = { - parse_string_prefix, parse_value_string_with_indexed_key, - finish_lithdr_nvridx}; - p->dynamic_table_update_allowed = 0; - p->next_state = and_then; - p->index = 0xf; - p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); -} - -/* parse a literal header that is never indexed; index == 0 */ -static int parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, const uint8_t *end) { - static const grpc_chttp2_hpack_parser_state and_then[] = { - parse_key_string, parse_string_prefix, - parse_value_string_with_literal_key, finish_lithdr_nvridx_v}; - p->dynamic_table_update_allowed = 0; - p->next_state = and_then; - return parse_string_prefix(p, cur + 1, end); -} - -/* finish parsing a max table size change */ -static int finish_max_tbl_size(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", p->index); - return grpc_chttp2_hptbl_set_current_table_size(&p->table, p->index) && - parse_begin(p, cur, end); -} - -/* parse a max table size change, max size < 15 */ -static int parse_max_tbl_size(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (p->dynamic_table_update_allowed == 0) { - return 0; - } - p->dynamic_table_update_allowed--; - p->index = (*cur) & 0x1f; - return finish_max_tbl_size(p, cur + 1, end); -} - -/* parse a max table size change, max size >= 15 */ -static int parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - static const grpc_chttp2_hpack_parser_state and_then[] = { - finish_max_tbl_size}; - if (p->dynamic_table_update_allowed == 0) { - return 0; - } - p->dynamic_table_update_allowed--; - p->next_state = and_then; - p->index = 0x1f; - p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); -} - -/* a parse error: jam the parse state into parse_error, and return error */ -static int parse_error(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - p->state = parse_error; - return 0; -} - -static int parse_illegal_op(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - GPR_ASSERT(cur != end); - gpr_log(GPR_DEBUG, "Illegal hpack op code %d", *cur); - return parse_error(p, cur, end); -} - -/* parse the 1st byte of a varint into p->parsing.value - no overflow is possible */ -static int parse_value0(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (cur == end) { - p->state = parse_value0; - return 1; - } - - *p->parsing.value += (*cur) & 0x7f; - - if ((*cur) & 0x80) { - return parse_value1(p, cur + 1, end); - } else { - return parse_next(p, cur + 1, end); - } -} - -/* parse the 2nd byte of a varint into p->parsing.value - no overflow is possible */ -static int parse_value1(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (cur == end) { - p->state = parse_value1; - return 1; - } - - *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 7; - - if ((*cur) & 0x80) { - return parse_value2(p, cur + 1, end); - } else { - return parse_next(p, cur + 1, end); - } -} - -/* parse the 3rd byte of a varint into p->parsing.value - no overflow is possible */ -static int parse_value2(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (cur == end) { - p->state = parse_value2; - return 1; - } - - *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 14; - - if ((*cur) & 0x80) { - return parse_value3(p, cur + 1, end); - } else { - return parse_next(p, cur + 1, end); - } -} - -/* parse the 4th byte of a varint into p->parsing.value - no overflow is possible */ -static int parse_value3(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (cur == end) { - p->state = parse_value3; - return 1; - } - - *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 21; - - if ((*cur) & 0x80) { - return parse_value4(p, cur + 1, end); - } else { - return parse_next(p, cur + 1, end); - } -} - -/* parse the 5th byte of a varint into p->parsing.value - depending on the byte, we may overflow, and care must be taken */ -static int parse_value4(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - uint8_t c; - uint32_t cur_value; - uint32_t add_value; - - if (cur == end) { - p->state = parse_value4; - return 1; - } - - c = (*cur) & 0x7f; - if (c > 0xf) { - goto error; - } - - cur_value = *p->parsing.value; - add_value = ((uint32_t)c) << 28; - if (add_value > 0xffffffffu - cur_value) { - goto error; - } - - *p->parsing.value = cur_value + add_value; - - if ((*cur) & 0x80) { - return parse_value5up(p, cur + 1, end); - } else { - return parse_next(p, cur + 1, end); - } - -error: - gpr_log(GPR_ERROR, - "integer overflow in hpack integer decoding: have 0x%08x, " - "got byte 0x%02x on byte 5", - *p->parsing.value, *cur); - return parse_error(p, cur, end); -} - -/* parse any trailing bytes in a varint: it's possible to append an arbitrary - number of 0x80's and not affect the value - a zero will terminate - and - anything else will overflow */ -static int parse_value5up(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - while (cur != end && *cur == 0x80) { - ++cur; - } - - if (cur == end) { - p->state = parse_value5up; - return 1; - } - - if (*cur == 0) { - return parse_next(p, cur + 1, end); - } - - gpr_log(GPR_ERROR, - "integer overflow in hpack integer decoding: have 0x%08x, " - "got byte 0x%02x sometime after byte 5", - *p->parsing.value, *cur); - return parse_error(p, cur, end); -} - -/* parse a string prefix */ -static int parse_string_prefix(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (cur == end) { - p->state = parse_string_prefix; - return 1; - } - - p->strlen = (*cur) & 0x7f; - p->huff = (*cur) >> 7; - if (p->strlen == 0x7f) { - p->parsing.value = &p->strlen; - return parse_value0(p, cur + 1, end); - } else { - return parse_next(p, cur + 1, end); - } -} - -/* append some bytes to a string */ -static void append_bytes(grpc_chttp2_hpack_parser_string *str, - const uint8_t *data, size_t length) { - if (length + str->length > str->capacity) { - GPR_ASSERT(str->length + length <= UINT32_MAX); - str->capacity = (uint32_t)(str->length + length); - str->str = gpr_realloc(str->str, str->capacity); - } - memcpy(str->str + str->length, data, length); - GPR_ASSERT(length <= UINT32_MAX - str->length); - str->length += (uint32_t)length; -} - -static int append_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - grpc_chttp2_hpack_parser_string *str = p->parsing.str; - uint32_t bits; - uint8_t decoded[3]; - switch ((binary_state)p->binary) { - case NOT_BINARY: - append_bytes(str, cur, (size_t)(end - cur)); - return 1; - b64_byte0: - case B64_BYTE0: - if (cur == end) { - p->binary = B64_BYTE0; - return 1; - } - bits = inverse_base64[*cur]; - ++cur; - if (bits == 255) - return 0; - else if (bits == 64) - goto b64_byte0; - p->base64_buffer = bits << 18; - /* fallthrough */ - b64_byte1: - case B64_BYTE1: - if (cur == end) { - p->binary = B64_BYTE1; - return 1; - } - bits = inverse_base64[*cur]; - ++cur; - if (bits == 255) - return 0; - else if (bits == 64) - goto b64_byte1; - p->base64_buffer |= bits << 12; - /* fallthrough */ - b64_byte2: - case B64_BYTE2: - if (cur == end) { - p->binary = B64_BYTE2; - return 1; - } - bits = inverse_base64[*cur]; - ++cur; - if (bits == 255) - return 0; - else if (bits == 64) - goto b64_byte2; - p->base64_buffer |= bits << 6; - /* fallthrough */ - b64_byte3: - case B64_BYTE3: - if (cur == end) { - p->binary = B64_BYTE3; - return 1; - } - bits = inverse_base64[*cur]; - ++cur; - if (bits == 255) - return 0; - else if (bits == 64) - goto b64_byte3; - p->base64_buffer |= bits; - bits = p->base64_buffer; - decoded[0] = (uint8_t)(bits >> 16); - decoded[1] = (uint8_t)(bits >> 8); - decoded[2] = (uint8_t)(bits); - append_bytes(str, decoded, 3); - goto b64_byte0; - } - GPR_UNREACHABLE_CODE(return 1); -} - -/* append a null terminator to a string */ -static int finish_str(grpc_chttp2_hpack_parser *p) { - uint8_t terminator = 0; - uint8_t decoded[2]; - uint32_t bits; - grpc_chttp2_hpack_parser_string *str = p->parsing.str; - switch ((binary_state)p->binary) { - case NOT_BINARY: - break; - case B64_BYTE0: - break; - case B64_BYTE1: - gpr_log(GPR_ERROR, "illegal base64 encoding"); - return 0; /* illegal encoding */ - case B64_BYTE2: - bits = p->base64_buffer; - if (bits & 0xffff) { - gpr_log(GPR_ERROR, "trailing bits in base64 encoding: 0x%04x", - bits & 0xffff); - return 0; - } - decoded[0] = (uint8_t)(bits >> 16); - append_bytes(str, decoded, 1); - break; - case B64_BYTE3: - bits = p->base64_buffer; - if (bits & 0xff) { - gpr_log(GPR_ERROR, "trailing bits in base64 encoding: 0x%02x", - bits & 0xff); - return 0; - } - decoded[0] = (uint8_t)(bits >> 16); - decoded[1] = (uint8_t)(bits >> 8); - append_bytes(str, decoded, 2); - break; - } - append_bytes(str, &terminator, 1); - p->parsing.str->length--; /* don't actually count the null terminator */ - return 1; -} - -/* decode a nibble from a huffman encoded stream */ -static int huff_nibble(grpc_chttp2_hpack_parser *p, uint8_t nibble) { - int16_t emit = emit_sub_tbl[16 * emit_tbl[p->huff_state] + nibble]; - int16_t next = next_sub_tbl[16 * next_tbl[p->huff_state] + nibble]; - if (emit != -1) { - if (emit >= 0 && emit < 256) { - uint8_t c = (uint8_t)emit; - if (!append_string(p, &c, (&c) + 1)) return 0; - } else { - assert(emit == 256); - } - } - p->huff_state = next; - return 1; -} - -/* decode full bytes from a huffman encoded stream */ -static int add_huff_bytes(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - for (; cur != end; ++cur) { - if (!huff_nibble(p, *cur >> 4) || !huff_nibble(p, *cur & 0xf)) return 0; - } - return 1; -} - -/* decode some string bytes based on the current decoding mode - (huffman or not) */ -static int add_str_bytes(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - if (p->huff) { - return add_huff_bytes(p, cur, end); - } else { - return append_string(p, cur, end); - } -} - -/* parse a string - tries to do large chunks at a time */ -static int parse_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - size_t remaining = p->strlen - p->strgot; - size_t given = (size_t)(end - cur); - if (remaining <= given) { - return add_str_bytes(p, cur, cur + remaining) && finish_str(p) && - parse_next(p, cur + remaining, end); - } else { - if (!add_str_bytes(p, cur, cur + given)) return 0; - GPR_ASSERT(given <= UINT32_MAX - p->strgot); - p->strgot += (uint32_t)given; - p->state = parse_string; - return 1; - } -} - -/* begin parsing a string - performs setup, calls parse_string */ -static int begin_parse_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end, uint8_t binary, - grpc_chttp2_hpack_parser_string *str) { - p->strgot = 0; - str->length = 0; - p->parsing.str = str; - p->huff_state = 0; - p->binary = binary; - return parse_string(p, cur, end); -} - -/* parse the key string */ -static int parse_key_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end) { - return begin_parse_string(p, cur, end, NOT_BINARY, &p->key); -} - -/* check if a key represents a binary header or not */ -typedef enum { BINARY_HEADER, PLAINTEXT_HEADER, ERROR_HEADER } is_binary_header; - -static is_binary_header is_binary_literal_header(grpc_chttp2_hpack_parser *p) { - return grpc_is_binary_header(p->key.str, p->key.length) ? BINARY_HEADER - : PLAINTEXT_HEADER; -} - -static is_binary_header is_binary_indexed_header(grpc_chttp2_hpack_parser *p) { - grpc_mdelem *elem = grpc_chttp2_hptbl_lookup(&p->table, p->index); - if (!elem) { - gpr_log(GPR_ERROR, "Invalid HPACK index received: %d", p->index); - return ERROR_HEADER; - } - return grpc_is_binary_header( - (const char *)GPR_SLICE_START_PTR(elem->key->slice), - GPR_SLICE_LENGTH(elem->key->slice)) - ? BINARY_HEADER - : PLAINTEXT_HEADER; -} - -/* parse the value string */ -static int parse_value_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur, - const uint8_t *end, is_binary_header type) { - switch (type) { - case BINARY_HEADER: - return begin_parse_string(p, cur, end, B64_BYTE0, &p->value); - case PLAINTEXT_HEADER: - return begin_parse_string(p, cur, end, NOT_BINARY, &p->value); - case ERROR_HEADER: - return 0; - } - /* Add code to prevent return without value error */ - GPR_UNREACHABLE_CODE(return 0); -} - -static int parse_value_string_with_indexed_key(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, - const uint8_t *end) { - return parse_value_string(p, cur, end, is_binary_indexed_header(p)); -} - -static int parse_value_string_with_literal_key(grpc_chttp2_hpack_parser *p, - const uint8_t *cur, - const uint8_t *end) { - return parse_value_string(p, cur, end, is_binary_literal_header(p)); -} - -/* PUBLIC INTERFACE */ - -static void on_header_not_set(void *user_data, grpc_mdelem *md) { - GPR_UNREACHABLE_CODE(return ); -} - -void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p) { - p->on_header = on_header_not_set; - p->on_header_user_data = NULL; - p->state = parse_begin; - p->key.str = NULL; - p->key.capacity = 0; - p->key.length = 0; - p->value.str = NULL; - p->value.capacity = 0; - p->value.length = 0; - p->dynamic_table_update_allowed = 2; - grpc_chttp2_hptbl_init(&p->table); -} - -void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p) { - p->after_prioritization = p->state; - p->state = parse_stream_dep0; -} - -void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p) { - grpc_chttp2_hptbl_destroy(&p->table); - gpr_free(p->key.str); - gpr_free(p->value.str); -} - -int grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p, - const uint8_t *beg, const uint8_t *end) { - /* TODO(ctiller): limit the distance of end from beg, and perform multiple - steps in the event of a large chunk of data to limit - stack space usage when no tail call optimization is - available */ - return p->state(p, beg, end); -} - -grpc_chttp2_parse_error grpc_chttp2_header_parser_parse( - grpc_exec_ctx *exec_ctx, void *hpack_parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { - grpc_chttp2_hpack_parser *parser = hpack_parser; - GPR_TIMER_BEGIN("grpc_chttp2_hpack_parser_parse", 0); - if (!grpc_chttp2_hpack_parser_parse(parser, GPR_SLICE_START_PTR(slice), - GPR_SLICE_END_PTR(slice))) { - GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - if (is_last) { - if (parser->is_boundary && parser->state != parse_begin) { - gpr_log(GPR_ERROR, - "end of header frame not aligned with a hpack record boundary"); - GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - /* need to check for null stream: this can occur if we receive an invalid - stream id on a header */ - if (stream_parsing != NULL) { - if (parser->is_boundary) { - stream_parsing - ->got_metadata_on_parse[stream_parsing->header_frames_received] = 1; - stream_parsing->header_frames_received++; - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, - stream_parsing); - } - if (parser->is_eof) { - stream_parsing->received_close = 1; - } - } - parser->on_header = on_header_not_set; - parser->on_header_user_data = NULL; - parser->is_boundary = 0xde; - parser->is_eof = 0xde; - parser->dynamic_table_update_allowed = 2; - } - GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0); - return GRPC_CHTTP2_PARSE_OK; -} diff --git a/src/core/transport/chttp2/hpack_parser.h b/src/core/transport/chttp2/hpack_parser.h deleted file mode 100644 index 6a6d136da2..0000000000 --- a/src/core/transport/chttp2/hpack_parser.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_HPACK_PARSER_H -#define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H - -#include - -#include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" -#include "src/core/transport/chttp2/hpack_table.h" -#include "src/core/transport/metadata.h" - -typedef struct grpc_chttp2_hpack_parser grpc_chttp2_hpack_parser; - -typedef int (*grpc_chttp2_hpack_parser_state)(grpc_chttp2_hpack_parser *p, - const uint8_t *beg, - const uint8_t *end); - -typedef struct { - char *str; - uint32_t length; - uint32_t capacity; -} grpc_chttp2_hpack_parser_string; - -struct grpc_chttp2_hpack_parser { - /* user specified callback for each header output */ - void (*on_header)(void *user_data, grpc_mdelem *md); - void *on_header_user_data; - - /* current parse state - or a function that implements it */ - grpc_chttp2_hpack_parser_state state; - /* future states dependent on the opening op code */ - const grpc_chttp2_hpack_parser_state *next_state; - /* what to do after skipping prioritization data */ - grpc_chttp2_hpack_parser_state after_prioritization; - /* the value we're currently parsing */ - union { - uint32_t *value; - grpc_chttp2_hpack_parser_string *str; - } parsing; - /* string parameters for each chunk */ - grpc_chttp2_hpack_parser_string key; - grpc_chttp2_hpack_parser_string value; - /* parsed index */ - uint32_t index; - /* length of source bytes for the currently parsing string */ - uint32_t strlen; - /* number of source bytes read for the currently parsing string */ - uint32_t strgot; - /* huffman decoding state */ - int16_t huff_state; - /* is the string being decoded binary? */ - uint8_t binary; - /* is the current string huffman encoded? */ - uint8_t huff; - /* is a dynamic table update allowed? */ - uint8_t dynamic_table_update_allowed; - /* set by higher layers, used by grpc_chttp2_header_parser_parse to signal - it should append a metadata boundary at the end of frame */ - uint8_t is_boundary; - uint8_t is_eof; - uint32_t base64_buffer; - - /* hpack table */ - grpc_chttp2_hptbl table; -}; - -void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p); -void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p); - -void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p); - -/* returns 1 on success, 0 on error */ -int grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p, - const uint8_t *beg, const uint8_t *end); - -/* wraps grpc_chttp2_hpack_parser_parse to provide a frame level parser for - the transport */ -grpc_chttp2_parse_error grpc_chttp2_header_parser_parse( - grpc_exec_ctx *exec_ctx, void *hpack_parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H */ diff --git a/src/core/transport/chttp2/hpack_table.c b/src/core/transport/chttp2/hpack_table.c deleted file mode 100644 index f1ce3b84fd..0000000000 --- a/src/core/transport/chttp2/hpack_table.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/chttp2/hpack_table.h" - -#include -#include - -#include -#include - -#include "src/core/support/murmur_hash.h" - -static struct { - const char *key; - const char *value; -} static_table[] = { - /* 0: */ - {NULL, NULL}, - /* 1: */ - {":authority", ""}, - /* 2: */ - {":method", "GET"}, - /* 3: */ - {":method", "POST"}, - /* 4: */ - {":path", "/"}, - /* 5: */ - {":path", "/index.html"}, - /* 6: */ - {":scheme", "http"}, - /* 7: */ - {":scheme", "https"}, - /* 8: */ - {":status", "200"}, - /* 9: */ - {":status", "204"}, - /* 10: */ - {":status", "206"}, - /* 11: */ - {":status", "304"}, - /* 12: */ - {":status", "400"}, - /* 13: */ - {":status", "404"}, - /* 14: */ - {":status", "500"}, - /* 15: */ - {"accept-charset", ""}, - /* 16: */ - {"accept-encoding", "gzip, deflate"}, - /* 17: */ - {"accept-language", ""}, - /* 18: */ - {"accept-ranges", ""}, - /* 19: */ - {"accept", ""}, - /* 20: */ - {"access-control-allow-origin", ""}, - /* 21: */ - {"age", ""}, - /* 22: */ - {"allow", ""}, - /* 23: */ - {"authorization", ""}, - /* 24: */ - {"cache-control", ""}, - /* 25: */ - {"content-disposition", ""}, - /* 26: */ - {"content-encoding", ""}, - /* 27: */ - {"content-language", ""}, - /* 28: */ - {"content-length", ""}, - /* 29: */ - {"content-location", ""}, - /* 30: */ - {"content-range", ""}, - /* 31: */ - {"content-type", ""}, - /* 32: */ - {"cookie", ""}, - /* 33: */ - {"date", ""}, - /* 34: */ - {"etag", ""}, - /* 35: */ - {"expect", ""}, - /* 36: */ - {"expires", ""}, - /* 37: */ - {"from", ""}, - /* 38: */ - {"host", ""}, - /* 39: */ - {"if-match", ""}, - /* 40: */ - {"if-modified-since", ""}, - /* 41: */ - {"if-none-match", ""}, - /* 42: */ - {"if-range", ""}, - /* 43: */ - {"if-unmodified-since", ""}, - /* 44: */ - {"last-modified", ""}, - /* 45: */ - {"link", ""}, - /* 46: */ - {"location", ""}, - /* 47: */ - {"max-forwards", ""}, - /* 48: */ - {"proxy-authenticate", ""}, - /* 49: */ - {"proxy-authorization", ""}, - /* 50: */ - {"range", ""}, - /* 51: */ - {"referer", ""}, - /* 52: */ - {"refresh", ""}, - /* 53: */ - {"retry-after", ""}, - /* 54: */ - {"server", ""}, - /* 55: */ - {"set-cookie", ""}, - /* 56: */ - {"strict-transport-security", ""}, - /* 57: */ - {"transfer-encoding", ""}, - /* 58: */ - {"user-agent", ""}, - /* 59: */ - {"vary", ""}, - /* 60: */ - {"via", ""}, - /* 61: */ - {"www-authenticate", ""}, -}; - -static uint32_t entries_for_bytes(uint32_t bytes) { - return (bytes + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD - 1) / - GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD; -} - -void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl) { - size_t i; - - memset(tbl, 0, sizeof(*tbl)); - tbl->current_table_bytes = tbl->max_bytes = - GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE; - tbl->max_entries = tbl->cap_entries = - entries_for_bytes(tbl->current_table_bytes); - tbl->ents = gpr_malloc(sizeof(*tbl->ents) * tbl->cap_entries); - memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries); - for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { - tbl->static_ents[i - 1] = - grpc_mdelem_from_strings(static_table[i].key, static_table[i].value); - } -} - -void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl) { - size_t i; - for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { - GRPC_MDELEM_UNREF(tbl->static_ents[i]); - } - for (i = 0; i < tbl->num_ents; i++) { - GRPC_MDELEM_UNREF(tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]); - } - gpr_free(tbl->ents); -} - -grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl, - uint32_t tbl_index) { - /* Static table comes first, just return an entry from it */ - if (tbl_index <= GRPC_CHTTP2_LAST_STATIC_ENTRY) { - return tbl->static_ents[tbl_index - 1]; - } - /* Otherwise, find the value in the list of valid entries */ - tbl_index -= (GRPC_CHTTP2_LAST_STATIC_ENTRY + 1); - if (tbl_index < tbl->num_ents) { - uint32_t offset = - (tbl->num_ents - 1u - tbl_index + tbl->first_ent) % tbl->cap_entries; - return tbl->ents[offset]; - } - /* Invalid entry: return error */ - return NULL; -} - -/* Evict one element from the table */ -static void evict1(grpc_chttp2_hptbl *tbl) { - grpc_mdelem *first_ent = tbl->ents[tbl->first_ent]; - size_t elem_bytes = GPR_SLICE_LENGTH(first_ent->key->slice) + - GPR_SLICE_LENGTH(first_ent->value->slice) + - GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD; - GPR_ASSERT(elem_bytes <= tbl->mem_used); - tbl->mem_used -= (uint32_t)elem_bytes; - tbl->first_ent = ((tbl->first_ent + 1) % tbl->cap_entries); - tbl->num_ents--; - GRPC_MDELEM_UNREF(first_ent); -} - -static void rebuild_ents(grpc_chttp2_hptbl *tbl, uint32_t new_cap) { - grpc_mdelem **ents = gpr_malloc(sizeof(*ents) * new_cap); - uint32_t i; - - for (i = 0; i < tbl->num_ents; i++) { - ents[i] = tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]; - } - gpr_free(tbl->ents); - tbl->ents = ents; - tbl->cap_entries = new_cap; - tbl->first_ent = 0; -} - -void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl, - uint32_t max_bytes) { - if (tbl->max_bytes == max_bytes) { - return; - } - gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes); - while (tbl->mem_used > max_bytes) { - evict1(tbl); - } - tbl->max_bytes = max_bytes; -} - -int grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl, - uint32_t bytes) { - if (tbl->current_table_bytes == bytes) { - return 1; - } - if (bytes > tbl->max_bytes) { - gpr_log(GPR_ERROR, - "Attempt to make hpack table %d bytes when max is %d bytes", bytes, - tbl->max_bytes); - return 0; - } - gpr_log(GPR_DEBUG, "Update hpack parser table size to %d", bytes); - while (tbl->mem_used > bytes) { - evict1(tbl); - } - tbl->current_table_bytes = bytes; - tbl->max_entries = entries_for_bytes(bytes); - if (tbl->max_entries > tbl->cap_entries) { - rebuild_ents(tbl, GPR_MAX(tbl->max_entries, 2 * tbl->cap_entries)); - } else if (tbl->max_entries < tbl->cap_entries / 3) { - uint32_t new_cap = GPR_MAX(tbl->max_entries, 16u); - if (new_cap != tbl->cap_entries) { - rebuild_ents(tbl, new_cap); - } - } - return 1; -} - -int grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md) { - /* determine how many bytes of buffer this entry represents */ - size_t elem_bytes = GPR_SLICE_LENGTH(md->key->slice) + - GPR_SLICE_LENGTH(md->value->slice) + - GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD; - - if (tbl->current_table_bytes > tbl->max_bytes) { - gpr_log(GPR_ERROR, - "HPACK max table size reduced to %d but not reflected by hpack " - "stream (still at %d)", - tbl->max_bytes, tbl->current_table_bytes); - return 0; - } - - /* we can't add elements bigger than the max table size */ - if (elem_bytes > tbl->current_table_bytes) { - /* HPACK draft 10 section 4.4 states: - * If the size of the new entry is less than or equal to the maximum - * size, that entry is added to the table. It is not an error to - * attempt to add an entry that is larger than the maximum size; an - * attempt to add an entry larger than the entire table causes - * the table - * to be emptied of all existing entries, and results in an - * empty table. - */ - while (tbl->num_ents) { - evict1(tbl); - } - return 1; - } - - /* evict entries to ensure no overflow */ - while (elem_bytes > (size_t)tbl->current_table_bytes - tbl->mem_used) { - evict1(tbl); - } - - /* copy the finalized entry in */ - tbl->ents[(tbl->first_ent + tbl->num_ents) % tbl->cap_entries] = - GRPC_MDELEM_REF(md); - - /* update accounting values */ - tbl->num_ents++; - tbl->mem_used += (uint32_t)elem_bytes; - return 1; -} - -grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find( - const grpc_chttp2_hptbl *tbl, grpc_mdelem *md) { - grpc_chttp2_hptbl_find_result r = {0, 0}; - uint32_t i; - - /* See if the string is in the static table */ - for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { - grpc_mdelem *ent = tbl->static_ents[i]; - if (md->key != ent->key) continue; - r.index = i + 1u; - r.has_value = md->value == ent->value; - if (r.has_value) return r; - } - - /* Scan the dynamic table */ - for (i = 0; i < tbl->num_ents; i++) { - uint32_t idx = - (uint32_t)(tbl->num_ents - i + GRPC_CHTTP2_LAST_STATIC_ENTRY); - grpc_mdelem *ent = tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]; - if (md->key != ent->key) continue; - r.index = idx; - r.has_value = md->value == ent->value; - if (r.has_value) return r; - } - - return r; -} diff --git a/src/core/transport/chttp2/hpack_table.h b/src/core/transport/chttp2/hpack_table.h deleted file mode 100644 index c984ca35e4..0000000000 --- a/src/core/transport/chttp2/hpack_table.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_HPACK_TABLE_H -#define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H - -#include -#include -#include "src/core/transport/metadata.h" - -/* HPACK header table */ - -/* last index in the static table */ -#define GRPC_CHTTP2_LAST_STATIC_ENTRY 61 - -/* Initial table size as per the spec */ -#define GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE 4096 -/* Maximum table size that we'll use */ -#define GRPC_CHTTP2_MAX_HPACK_TABLE_SIZE GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE -/* Per entry overhead bytes as per the spec */ -#define GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD 32 -#if 0 -/* Maximum number of entries we could possibly fit in the table, given defined - overheads */ -#define GRPC_CHTTP2_MAX_TABLE_COUNT \ - ((GRPC_CHTTP2_MAX_HPACK_TABLE_SIZE + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD - 1) / \ - GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD) -#endif - -/* hpack decoder table */ -typedef struct { - /* the first used entry in ents */ - uint32_t first_ent; - /* how many entries are in the table */ - uint32_t num_ents; - /* the amount of memory used by the table, according to the hpack algorithm */ - uint32_t mem_used; - /* the max memory allowed to be used by the table, according to the hpack - algorithm */ - uint32_t max_bytes; - /* the currently agreed size of the table, according to the hpack algorithm */ - uint32_t current_table_bytes; - /* Maximum number of entries we could possibly fit in the table, given defined - overheads */ - uint32_t max_entries; - /* Number of entries allocated in ents */ - uint32_t cap_entries; - /* a circular buffer of headers - this is stored in the opposite order to - what hpack specifies, in order to simplify table management a little... - meaning lookups need to SUBTRACT from the end position */ - grpc_mdelem **ents; - grpc_mdelem *static_ents[GRPC_CHTTP2_LAST_STATIC_ENTRY]; -} grpc_chttp2_hptbl; - -/* initialize a hpack table */ -void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl); -void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl); -void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl, - uint32_t max_bytes); -int grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl, - uint32_t bytes); - -/* lookup a table entry based on its hpack index */ -grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl, - uint32_t index); -/* add a table entry to the index */ -int grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, - grpc_mdelem *md) GRPC_MUST_USE_RESULT; -/* Find a key/value pair in the table... returns the index in the table of the - most similar entry, or 0 if the value was not found */ -typedef struct { - uint32_t index; - int has_value; -} grpc_chttp2_hptbl_find_result; -grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find( - const grpc_chttp2_hptbl *tbl, grpc_mdelem *md); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H */ diff --git a/src/core/transport/chttp2/hpack_tables.txt b/src/core/transport/chttp2/hpack_tables.txt deleted file mode 100644 index 08842a0267..0000000000 --- a/src/core/transport/chttp2/hpack_tables.txt +++ /dev/null @@ -1,66 +0,0 @@ -Static table, from the spec: - +-------+-----------------------------+---------------+ - | Index | Header Name | Header Value | - +-------+-----------------------------+---------------+ - | 1 | :authority | | - | 2 | :method | GET | - | 3 | :method | POST | - | 4 | :path | / | - | 5 | :path | /index.html | - | 6 | :scheme | http | - | 7 | :scheme | https | - | 8 | :status | 200 | - | 9 | :status | 204 | - | 10 | :status | 206 | - | 11 | :status | 304 | - | 12 | :status | 400 | - | 13 | :status | 404 | - | 14 | :status | 500 | - | 15 | accept-charset | | - | 16 | accept-encoding | gzip, deflate | - | 17 | accept-language | | - | 18 | accept-ranges | | - | 19 | accept | | - | 20 | access-control-allow-origin | | - | 21 | age | | - | 22 | allow | | - | 23 | authorization | | - | 24 | cache-control | | - | 25 | content-disposition | | - | 26 | content-encoding | | - | 27 | content-language | | - | 28 | content-length | | - | 29 | content-location | | - | 30 | content-range | | - | 31 | content-type | | - | 32 | cookie | | - | 33 | date | | - | 34 | etag | | - | 35 | expect | | - | 36 | expires | | - | 37 | from | | - | 38 | host | | - | 39 | if-match | | - | 40 | if-modified-since | | - | 41 | if-none-match | | - | 42 | if-range | | - | 43 | if-unmodified-since | | - | 44 | last-modified | | - | 45 | link | | - | 46 | location | | - | 47 | max-forwards | | - | 48 | proxy-authenticate | | - | 49 | proxy-authorization | | - | 50 | range | | - | 51 | referer | | - | 52 | refresh | | - | 53 | retry-after | | - | 54 | server | | - | 55 | set-cookie | | - | 56 | strict-transport-security | | - | 57 | transfer-encoding | | - | 58 | user-agent | | - | 59 | vary | | - | 60 | via | | - | 61 | www-authenticate | | - +-------+-----------------------------+---------------+ diff --git a/src/core/transport/chttp2/http2_errors.h b/src/core/transport/chttp2/http2_errors.h deleted file mode 100644 index 4290df3d89..0000000000 --- a/src/core/transport/chttp2/http2_errors.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_HTTP2_ERRORS_H -#define GRPC_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H - -/* error codes for RST_STREAM from http2 draft 14 section 7 */ -typedef enum { - GRPC_CHTTP2_NO_ERROR = 0x0, - GRPC_CHTTP2_PROTOCOL_ERROR = 0x1, - GRPC_CHTTP2_INTERNAL_ERROR = 0x2, - GRPC_CHTTP2_FLOW_CONTROL_ERROR = 0x3, - GRPC_CHTTP2_SETTINGS_TIMEOUT = 0x4, - GRPC_CHTTP2_STREAM_CLOSED = 0x5, - GRPC_CHTTP2_FRAME_SIZE_ERROR = 0x6, - GRPC_CHTTP2_REFUSED_STREAM = 0x7, - GRPC_CHTTP2_CANCEL = 0x8, - GRPC_CHTTP2_COMPRESSION_ERROR = 0x9, - GRPC_CHTTP2_CONNECT_ERROR = 0xa, - GRPC_CHTTP2_ENHANCE_YOUR_CALM = 0xb, - GRPC_CHTTP2_INADEQUATE_SECURITY = 0xc, - /* force use of a default clause */ - GRPC_CHTTP2__ERROR_DO_NOT_USE = -1 -} grpc_chttp2_error_code; - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H */ diff --git a/src/core/transport/chttp2/huffsyms.c b/src/core/transport/chttp2/huffsyms.c deleted file mode 100644 index ebc85d3378..0000000000 --- a/src/core/transport/chttp2/huffsyms.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * - * Copyright 2015-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/transport/chttp2/huffsyms.h" - -/* Constants pulled from the HPACK spec, and converted to C using the vim - command: - :%s/.* \([0-9a-f]\+\) \[ *\([0-9]\+\)\]/{0x\1, \2},/g */ -const grpc_chttp2_huffsym grpc_chttp2_huffsyms[GRPC_CHTTP2_NUM_HUFFSYMS] = { - {0x1ff8, 13}, {0x7fffd8, 23}, {0xfffffe2, 28}, {0xfffffe3, 28}, - {0xfffffe4, 28}, {0xfffffe5, 28}, {0xfffffe6, 28}, {0xfffffe7, 28}, - {0xfffffe8, 28}, {0xffffea, 24}, {0x3ffffffc, 30}, {0xfffffe9, 28}, - {0xfffffea, 28}, {0x3ffffffd, 30}, {0xfffffeb, 28}, {0xfffffec, 28}, - {0xfffffed, 28}, {0xfffffee, 28}, {0xfffffef, 28}, {0xffffff0, 28}, - {0xffffff1, 28}, {0xffffff2, 28}, {0x3ffffffe, 30}, {0xffffff3, 28}, - {0xffffff4, 28}, {0xffffff5, 28}, {0xffffff6, 28}, {0xffffff7, 28}, - {0xffffff8, 28}, {0xffffff9, 28}, {0xffffffa, 28}, {0xffffffb, 28}, - {0x14, 6}, {0x3f8, 10}, {0x3f9, 10}, {0xffa, 12}, - {0x1ff9, 13}, {0x15, 6}, {0xf8, 8}, {0x7fa, 11}, - {0x3fa, 10}, {0x3fb, 10}, {0xf9, 8}, {0x7fb, 11}, - {0xfa, 8}, {0x16, 6}, {0x17, 6}, {0x18, 6}, - {0x0, 5}, {0x1, 5}, {0x2, 5}, {0x19, 6}, - {0x1a, 6}, {0x1b, 6}, {0x1c, 6}, {0x1d, 6}, - {0x1e, 6}, {0x1f, 6}, {0x5c, 7}, {0xfb, 8}, - {0x7ffc, 15}, {0x20, 6}, {0xffb, 12}, {0x3fc, 10}, - {0x1ffa, 13}, {0x21, 6}, {0x5d, 7}, {0x5e, 7}, - {0x5f, 7}, {0x60, 7}, {0x61, 7}, {0x62, 7}, - {0x63, 7}, {0x64, 7}, {0x65, 7}, {0x66, 7}, - {0x67, 7}, {0x68, 7}, {0x69, 7}, {0x6a, 7}, - {0x6b, 7}, {0x6c, 7}, {0x6d, 7}, {0x6e, 7}, - {0x6f, 7}, {0x70, 7}, {0x71, 7}, {0x72, 7}, - {0xfc, 8}, {0x73, 7}, {0xfd, 8}, {0x1ffb, 13}, - {0x7fff0, 19}, {0x1ffc, 13}, {0x3ffc, 14}, {0x22, 6}, - {0x7ffd, 15}, {0x3, 5}, {0x23, 6}, {0x4, 5}, - {0x24, 6}, {0x5, 5}, {0x25, 6}, {0x26, 6}, - {0x27, 6}, {0x6, 5}, {0x74, 7}, {0x75, 7}, - {0x28, 6}, {0x29, 6}, {0x2a, 6}, {0x7, 5}, - {0x2b, 6}, {0x76, 7}, {0x2c, 6}, {0x8, 5}, - {0x9, 5}, {0x2d, 6}, {0x77, 7}, {0x78, 7}, - {0x79, 7}, {0x7a, 7}, {0x7b, 7}, {0x7ffe, 15}, - {0x7fc, 11}, {0x3ffd, 14}, {0x1ffd, 13}, {0xffffffc, 28}, - {0xfffe6, 20}, {0x3fffd2, 22}, {0xfffe7, 20}, {0xfffe8, 20}, - {0x3fffd3, 22}, {0x3fffd4, 22}, {0x3fffd5, 22}, {0x7fffd9, 23}, - {0x3fffd6, 22}, {0x7fffda, 23}, {0x7fffdb, 23}, {0x7fffdc, 23}, - {0x7fffdd, 23}, {0x7fffde, 23}, {0xffffeb, 24}, {0x7fffdf, 23}, - {0xffffec, 24}, {0xffffed, 24}, {0x3fffd7, 22}, {0x7fffe0, 23}, - {0xffffee, 24}, {0x7fffe1, 23}, {0x7fffe2, 23}, {0x7fffe3, 23}, - {0x7fffe4, 23}, {0x1fffdc, 21}, {0x3fffd8, 22}, {0x7fffe5, 23}, - {0x3fffd9, 22}, {0x7fffe6, 23}, {0x7fffe7, 23}, {0xffffef, 24}, - {0x3fffda, 22}, {0x1fffdd, 21}, {0xfffe9, 20}, {0x3fffdb, 22}, - {0x3fffdc, 22}, {0x7fffe8, 23}, {0x7fffe9, 23}, {0x1fffde, 21}, - {0x7fffea, 23}, {0x3fffdd, 22}, {0x3fffde, 22}, {0xfffff0, 24}, - {0x1fffdf, 21}, {0x3fffdf, 22}, {0x7fffeb, 23}, {0x7fffec, 23}, - {0x1fffe0, 21}, {0x1fffe1, 21}, {0x3fffe0, 22}, {0x1fffe2, 21}, - {0x7fffed, 23}, {0x3fffe1, 22}, {0x7fffee, 23}, {0x7fffef, 23}, - {0xfffea, 20}, {0x3fffe2, 22}, {0x3fffe3, 22}, {0x3fffe4, 22}, - {0x7ffff0, 23}, {0x3fffe5, 22}, {0x3fffe6, 22}, {0x7ffff1, 23}, - {0x3ffffe0, 26}, {0x3ffffe1, 26}, {0xfffeb, 20}, {0x7fff1, 19}, - {0x3fffe7, 22}, {0x7ffff2, 23}, {0x3fffe8, 22}, {0x1ffffec, 25}, - {0x3ffffe2, 26}, {0x3ffffe3, 26}, {0x3ffffe4, 26}, {0x7ffffde, 27}, - {0x7ffffdf, 27}, {0x3ffffe5, 26}, {0xfffff1, 24}, {0x1ffffed, 25}, - {0x7fff2, 19}, {0x1fffe3, 21}, {0x3ffffe6, 26}, {0x7ffffe0, 27}, - {0x7ffffe1, 27}, {0x3ffffe7, 26}, {0x7ffffe2, 27}, {0xfffff2, 24}, - {0x1fffe4, 21}, {0x1fffe5, 21}, {0x3ffffe8, 26}, {0x3ffffe9, 26}, - {0xffffffd, 28}, {0x7ffffe3, 27}, {0x7ffffe4, 27}, {0x7ffffe5, 27}, - {0xfffec, 20}, {0xfffff3, 24}, {0xfffed, 20}, {0x1fffe6, 21}, - {0x3fffe9, 22}, {0x1fffe7, 21}, {0x1fffe8, 21}, {0x7ffff3, 23}, - {0x3fffea, 22}, {0x3fffeb, 22}, {0x1ffffee, 25}, {0x1ffffef, 25}, - {0xfffff4, 24}, {0xfffff5, 24}, {0x3ffffea, 26}, {0x7ffff4, 23}, - {0x3ffffeb, 26}, {0x7ffffe6, 27}, {0x3ffffec, 26}, {0x3ffffed, 26}, - {0x7ffffe7, 27}, {0x7ffffe8, 27}, {0x7ffffe9, 27}, {0x7ffffea, 27}, - {0x7ffffeb, 27}, {0xffffffe, 28}, {0x7ffffec, 27}, {0x7ffffed, 27}, - {0x7ffffee, 27}, {0x7ffffef, 27}, {0x7fffff0, 27}, {0x3ffffee, 26}, - {0x3fffffff, 30}, -}; diff --git a/src/core/transport/chttp2/huffsyms.h b/src/core/transport/chttp2/huffsyms.h deleted file mode 100644 index 9c4f09dcf6..0000000000 --- a/src/core/transport/chttp2/huffsyms.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_HUFFSYMS_H -#define GRPC_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H - -/* HPACK static huffman table */ - -#define GRPC_CHTTP2_NUM_HUFFSYMS 257 - -typedef struct { - unsigned bits; - unsigned length; -} grpc_chttp2_huffsym; - -extern const grpc_chttp2_huffsym grpc_chttp2_huffsyms[GRPC_CHTTP2_NUM_HUFFSYMS]; - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H */ diff --git a/src/core/transport/chttp2/incoming_metadata.c b/src/core/transport/chttp2/incoming_metadata.c deleted file mode 100644 index 315bc2faa1..0000000000 --- a/src/core/transport/chttp2/incoming_metadata.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/chttp2/incoming_metadata.h" - -#include - -#include "src/core/transport/chttp2/internal.h" - -#include -#include - -void grpc_chttp2_incoming_metadata_buffer_init( - grpc_chttp2_incoming_metadata_buffer *buffer) { - buffer->deadline = gpr_inf_future(GPR_CLOCK_REALTIME); -} - -void grpc_chttp2_incoming_metadata_buffer_destroy( - grpc_chttp2_incoming_metadata_buffer *buffer) { - size_t i; - if (!buffer->published) { - for (i = 0; i < buffer->count; i++) { - GRPC_MDELEM_UNREF(buffer->elems[i].md); - } - } - gpr_free(buffer->elems); -} - -void grpc_chttp2_incoming_metadata_buffer_add( - grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem *elem) { - GPR_ASSERT(!buffer->published); - if (buffer->capacity == buffer->count) { - buffer->capacity = GPR_MAX(8, 2 * buffer->capacity); - buffer->elems = - gpr_realloc(buffer->elems, sizeof(*buffer->elems) * buffer->capacity); - } - buffer->elems[buffer->count++].md = elem; -} - -void grpc_chttp2_incoming_metadata_buffer_set_deadline( - grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline) { - GPR_ASSERT(!buffer->published); - buffer->deadline = deadline; -} - -void grpc_chttp2_incoming_metadata_buffer_publish( - grpc_chttp2_incoming_metadata_buffer *buffer, grpc_metadata_batch *batch) { - GPR_ASSERT(!buffer->published); - buffer->published = 1; - if (buffer->count > 0) { - size_t i; - for (i = 1; i < buffer->count; i++) { - buffer->elems[i].prev = &buffer->elems[i - 1]; - } - for (i = 0; i < buffer->count - 1; i++) { - buffer->elems[i].next = &buffer->elems[i + 1]; - } - buffer->elems[0].prev = NULL; - buffer->elems[buffer->count - 1].next = NULL; - batch->list.head = &buffer->elems[0]; - batch->list.tail = &buffer->elems[buffer->count - 1]; - } else { - batch->list.head = batch->list.tail = NULL; - } - batch->deadline = buffer->deadline; -} diff --git a/src/core/transport/chttp2/incoming_metadata.h b/src/core/transport/chttp2/incoming_metadata.h deleted file mode 100644 index 52454f348c..0000000000 --- a/src/core/transport/chttp2/incoming_metadata.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_INCOMING_METADATA_H -#define GRPC_CORE_TRANSPORT_CHTTP2_INCOMING_METADATA_H - -#include "src/core/transport/transport.h" - -typedef struct { - grpc_linked_mdelem *elems; - size_t count; - size_t capacity; - gpr_timespec deadline; - int published; -} grpc_chttp2_incoming_metadata_buffer; - -/** assumes everything initially zeroed */ -void grpc_chttp2_incoming_metadata_buffer_init( - grpc_chttp2_incoming_metadata_buffer *buffer); -void grpc_chttp2_incoming_metadata_buffer_destroy( - grpc_chttp2_incoming_metadata_buffer *buffer); -void grpc_chttp2_incoming_metadata_buffer_publish( - grpc_chttp2_incoming_metadata_buffer *buffer, grpc_metadata_batch *batch); - -void grpc_chttp2_incoming_metadata_buffer_add( - grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem *elem); -void grpc_chttp2_incoming_metadata_buffer_set_deadline( - grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_INCOMING_METADATA_H */ diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h deleted file mode 100644 index 0690cb37cd..0000000000 --- a/src/core/transport/chttp2/internal.h +++ /dev/null @@ -1,780 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_INTERNAL_H -#define GRPC_CORE_TRANSPORT_CHTTP2_INTERNAL_H - -#include -#include - -#include "src/core/iomgr/endpoint.h" -#include "src/core/transport/chttp2/frame.h" -#include "src/core/transport/chttp2/frame_data.h" -#include "src/core/transport/chttp2/frame_goaway.h" -#include "src/core/transport/chttp2/frame_ping.h" -#include "src/core/transport/chttp2/frame_rst_stream.h" -#include "src/core/transport/chttp2/frame_settings.h" -#include "src/core/transport/chttp2/frame_window_update.h" -#include "src/core/transport/chttp2/hpack_encoder.h" -#include "src/core/transport/chttp2/hpack_parser.h" -#include "src/core/transport/chttp2/incoming_metadata.h" -#include "src/core/transport/chttp2/stream_map.h" -#include "src/core/transport/connectivity_state.h" -#include "src/core/transport/transport_impl.h" - -typedef struct grpc_chttp2_transport grpc_chttp2_transport; -typedef struct grpc_chttp2_stream grpc_chttp2_stream; - -/* streams are kept in various linked lists depending on what things need to - happen to them... this enum labels each list */ -typedef enum { - GRPC_CHTTP2_LIST_ALL_STREAMS, - GRPC_CHTTP2_LIST_CHECK_READ_OPS, - GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE, - GRPC_CHTTP2_LIST_WRITABLE, - GRPC_CHTTP2_LIST_WRITING, - GRPC_CHTTP2_LIST_WRITTEN, - GRPC_CHTTP2_LIST_PARSING_SEEN, - GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING, - GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING, - GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT, - /* streams waiting for the outgoing window in the writing path, they will be - * merged to the stalled list or writable list under transport lock. */ - GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT, - /** streams that are waiting to start because there are too many concurrent - streams on the connection */ - GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY, - STREAM_LIST_COUNT /* must be last */ -} grpc_chttp2_stream_list_id; - -/* deframer state for the overall http2 stream of bytes */ -typedef enum { - /* prefix: one entry per http2 connection prefix byte */ - GRPC_DTS_CLIENT_PREFIX_0 = 0, - GRPC_DTS_CLIENT_PREFIX_1, - GRPC_DTS_CLIENT_PREFIX_2, - GRPC_DTS_CLIENT_PREFIX_3, - GRPC_DTS_CLIENT_PREFIX_4, - GRPC_DTS_CLIENT_PREFIX_5, - GRPC_DTS_CLIENT_PREFIX_6, - GRPC_DTS_CLIENT_PREFIX_7, - GRPC_DTS_CLIENT_PREFIX_8, - GRPC_DTS_CLIENT_PREFIX_9, - GRPC_DTS_CLIENT_PREFIX_10, - GRPC_DTS_CLIENT_PREFIX_11, - GRPC_DTS_CLIENT_PREFIX_12, - GRPC_DTS_CLIENT_PREFIX_13, - GRPC_DTS_CLIENT_PREFIX_14, - GRPC_DTS_CLIENT_PREFIX_15, - GRPC_DTS_CLIENT_PREFIX_16, - GRPC_DTS_CLIENT_PREFIX_17, - GRPC_DTS_CLIENT_PREFIX_18, - GRPC_DTS_CLIENT_PREFIX_19, - GRPC_DTS_CLIENT_PREFIX_20, - GRPC_DTS_CLIENT_PREFIX_21, - GRPC_DTS_CLIENT_PREFIX_22, - GRPC_DTS_CLIENT_PREFIX_23, - /* frame header byte 0... */ - /* must follow from the prefix states */ - GRPC_DTS_FH_0, - GRPC_DTS_FH_1, - GRPC_DTS_FH_2, - GRPC_DTS_FH_3, - GRPC_DTS_FH_4, - GRPC_DTS_FH_5, - GRPC_DTS_FH_6, - GRPC_DTS_FH_7, - /* ... frame header byte 8 */ - GRPC_DTS_FH_8, - /* inside a http2 frame */ - GRPC_DTS_FRAME -} grpc_chttp2_deframe_transport_state; - -typedef struct { - grpc_chttp2_stream *head; - grpc_chttp2_stream *tail; -} grpc_chttp2_stream_list; - -typedef struct { - grpc_chttp2_stream *next; - grpc_chttp2_stream *prev; -} grpc_chttp2_stream_link; - -/* We keep several sets of connection wide parameters */ -typedef enum { - /* The settings our peer has asked for (and we have acked) */ - GRPC_PEER_SETTINGS = 0, - /* The settings we'd like to have */ - GRPC_LOCAL_SETTINGS, - /* The settings we've published to our peer */ - GRPC_SENT_SETTINGS, - /* The settings the peer has acked */ - GRPC_ACKED_SETTINGS, - GRPC_NUM_SETTING_SETS -} grpc_chttp2_setting_set; - -/* Outstanding ping request data */ -typedef struct grpc_chttp2_outstanding_ping { - uint8_t id[8]; - grpc_closure *on_recv; - struct grpc_chttp2_outstanding_ping *next; - struct grpc_chttp2_outstanding_ping *prev; -} grpc_chttp2_outstanding_ping; - -/* forward declared in frame_data.h */ -struct grpc_chttp2_incoming_byte_stream { - grpc_byte_stream base; - gpr_refcount refs; - struct grpc_chttp2_incoming_byte_stream *next_message; - int failed; - - grpc_chttp2_transport *transport; - grpc_chttp2_stream *stream; - int is_tail; - gpr_slice_buffer slices; - grpc_closure *on_next; - gpr_slice *next; -}; - -typedef struct { - /** data to write next write */ - gpr_slice_buffer qbuf; - - /** window available for us to send to peer */ - int64_t outgoing_window; - /** window available to announce to peer */ - int64_t announce_incoming_window; - /** how much window would we like to have for incoming_window */ - uint32_t connection_window_target; - - /** have we seen a goaway */ - uint8_t seen_goaway; - /** have we sent a goaway */ - uint8_t sent_goaway; - - /** is this transport a client? */ - uint8_t is_client; - /** are the local settings dirty and need to be sent? */ - uint8_t dirtied_local_settings; - /** have local settings been sent? */ - uint8_t sent_local_settings; - /** bitmask of setting indexes to send out */ - uint32_t force_send_settings; - /** settings values */ - uint32_t settings[GRPC_NUM_SETTING_SETS][GRPC_CHTTP2_NUM_SETTINGS]; - - /** what is the next stream id to be allocated by this peer? - copied to next_stream_id in parsing when parsing commences */ - uint32_t next_stream_id; - - /** how far to lookahead in a stream? */ - uint32_t stream_lookahead; - - /** last received stream id */ - uint32_t last_incoming_stream_id; - - /** pings awaiting responses */ - grpc_chttp2_outstanding_ping pings; - /** next payload for an outgoing ping */ - uint64_t ping_counter; - - /** concurrent stream count: updated when not parsing, - so this is a strict over-estimation on the client */ - uint32_t concurrent_stream_count; -} grpc_chttp2_transport_global; - -typedef struct { - /** data to write now */ - gpr_slice_buffer outbuf; - /** hpack encoding */ - grpc_chttp2_hpack_compressor hpack_compressor; - int64_t outgoing_window; - /** is this a client? */ - uint8_t is_client; - /** callback for when writing is done */ - grpc_closure done_cb; -} grpc_chttp2_transport_writing; - -struct grpc_chttp2_transport_parsing { - /** is this transport a client? (boolean) */ - uint8_t is_client; - - /** were settings updated? */ - uint8_t settings_updated; - /** was a settings ack received? */ - uint8_t settings_ack_received; - /** was a goaway frame received? */ - uint8_t goaway_received; - - /** the last sent max_table_size setting */ - uint32_t last_sent_max_table_size; - - /** initial window change */ - int64_t initial_window_update; - - /** data to write later - after parsing */ - gpr_slice_buffer qbuf; - /** parser for headers */ - grpc_chttp2_hpack_parser hpack_parser; - /** simple one shot parsers */ - union { - grpc_chttp2_window_update_parser window_update; - grpc_chttp2_settings_parser settings; - grpc_chttp2_ping_parser ping; - grpc_chttp2_rst_stream_parser rst_stream; - } simple; - /** parser for goaway frames */ - grpc_chttp2_goaway_parser goaway_parser; - - /** window available for peer to send to us */ - int64_t incoming_window; - - /** next stream id available at the time of beginning parsing */ - uint32_t next_stream_id; - uint32_t last_incoming_stream_id; - - /* deframing */ - grpc_chttp2_deframe_transport_state deframe_state; - uint8_t incoming_frame_type; - uint8_t incoming_frame_flags; - uint8_t header_eof; - uint32_t expect_continuation_stream_id; - uint32_t incoming_frame_size; - uint32_t incoming_stream_id; - - /* active parser */ - void *parser_data; - grpc_chttp2_stream_parsing *incoming_stream; - grpc_chttp2_parse_error (*parser)( - grpc_exec_ctx *exec_ctx, void *parser_user_data, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); - - /* received settings */ - uint32_t settings[GRPC_CHTTP2_NUM_SETTINGS]; - - /* goaway data */ - grpc_status_code goaway_error; - uint32_t goaway_last_stream_index; - gpr_slice goaway_text; - - int64_t outgoing_window; -}; - -struct grpc_chttp2_transport { - grpc_transport base; /* must be first */ - grpc_endpoint *ep; - gpr_refcount refs; - char *peer_string; - - /** when this drops to zero it's safe to shutdown the endpoint */ - gpr_refcount shutdown_ep_refs; - - gpr_mu mu; - - /** is the transport destroying itself? */ - uint8_t destroying; - /** has the upper layer closed the transport? */ - uint8_t closed; - - /** is a thread currently writing */ - uint8_t writing_active; - /** is a thread currently parsing */ - uint8_t parsing_active; - - /** is there a read request to the endpoint outstanding? */ - uint8_t endpoint_reading; - - /** various lists of streams */ - grpc_chttp2_stream_list lists[STREAM_LIST_COUNT]; - - /** global state for reading/writing */ - grpc_chttp2_transport_global global; - /** state only accessible by the chain of execution that - set writing_active=1 */ - grpc_chttp2_transport_writing writing; - /** state only accessible by the chain of execution that - set parsing_active=1 */ - grpc_chttp2_transport_parsing parsing; - - /** maps stream id to grpc_chttp2_stream objects; - owned by the parsing thread when parsing */ - grpc_chttp2_stream_map parsing_stream_map; - - /** streams created by the client (possibly during parsing); - merged with parsing_stream_map during unlock when no - parsing is occurring */ - grpc_chttp2_stream_map new_stream_map; - - /** closure to execute writing */ - grpc_closure writing_action; - /** closure to finish reading from the endpoint */ - grpc_closure recv_data; - - /** incoming read bytes */ - gpr_slice_buffer read_buffer; - - /** address to place a newly accepted stream - set and unset by - grpc_chttp2_parsing_accept_stream; used by init_stream to - publish the accepted server stream */ - grpc_chttp2_stream **accepting_stream; - - struct { - /* accept stream callback */ - void (*accept_stream)(grpc_exec_ctx *exec_ctx, void *user_data, - grpc_transport *transport, const void *server_data); - void *accept_stream_user_data; - - /** connectivity tracking */ - grpc_connectivity_state_tracker state_tracker; - } channel_callback; - - /** Transport op to be applied post-parsing */ - grpc_transport_op *post_parsing_op; -}; - -typedef struct { - /** HTTP2 stream id for this stream, or zero if one has not been assigned */ - uint32_t id; - - /** window available for us to send to peer */ - int64_t outgoing_window; - /** The number of bytes the upper layers have offered to receive. - As the upper layer offers more bytes, this value increases. - As bytes are read, this value decreases. */ - uint32_t max_recv_bytes; - /** The number of bytes the upper layer has offered to read but we have - not yet announced to HTTP2 flow control. - As the upper layers offer to read more bytes, this value increases. - As we advertise incoming flow control window, this value decreases. */ - uint32_t unannounced_incoming_window_for_parse; - uint32_t unannounced_incoming_window_for_writing; - /** things the upper layers would like to send */ - grpc_metadata_batch *send_initial_metadata; - grpc_closure *send_initial_metadata_finished; - grpc_byte_stream *send_message; - grpc_closure *send_message_finished; - grpc_metadata_batch *send_trailing_metadata; - grpc_closure *send_trailing_metadata_finished; - - grpc_metadata_batch *recv_initial_metadata; - grpc_closure *recv_initial_metadata_ready; - grpc_byte_stream **recv_message; - grpc_closure *recv_message_ready; - grpc_metadata_batch *recv_trailing_metadata; - grpc_closure *recv_trailing_metadata_finished; - - /** when the application requests writes be closed, the write_closed is - 'queued'; when the close is flow controlled into the send path, we are - 'sending' it; when the write has been performed it is 'sent' */ - uint8_t write_closed; - /** is this stream reading half-closed (boolean) */ - uint8_t read_closed; - /** is this stream in the stream map? (boolean) */ - uint8_t in_stream_map; - /** has this stream seen an error? if 1, then pending incoming frames - can be thrown away */ - uint8_t seen_error; - - uint8_t published_initial_metadata; - uint8_t published_trailing_metadata; - uint8_t faked_trailing_metadata; - - grpc_chttp2_incoming_metadata_buffer received_initial_metadata; - grpc_chttp2_incoming_metadata_buffer received_trailing_metadata; - - grpc_chttp2_incoming_frame_queue incoming_frames; -} grpc_chttp2_stream_global; - -typedef struct { - /** HTTP2 stream id for this stream, or zero if one has not been assigned */ - uint32_t id; - uint8_t fetching; - bool sent_initial_metadata; - uint8_t sent_message; - uint8_t sent_trailing_metadata; - uint8_t read_closed; - /** send this initial metadata */ - grpc_metadata_batch *send_initial_metadata; - grpc_byte_stream *send_message; - grpc_metadata_batch *send_trailing_metadata; - int64_t outgoing_window; - /** how much window should we announce? */ - uint32_t announce_window; - gpr_slice_buffer flow_controlled_buffer; - gpr_slice fetching_slice; - size_t stream_fetched; - grpc_closure finished_fetch; -} grpc_chttp2_stream_writing; - -struct grpc_chttp2_stream_parsing { - /** HTTP2 stream id for this stream, or zero if one has not been assigned */ - uint32_t id; - /** has this stream received a close */ - uint8_t received_close; - /** saw a rst_stream */ - uint8_t saw_rst_stream; - /** how many header frames have we received? */ - uint8_t header_frames_received; - /** which metadata did we get (on this parse) */ - uint8_t got_metadata_on_parse[2]; - /** should we raise the seen_error flag in transport_global */ - uint8_t seen_error; - /** window available for peer to send to us */ - int64_t incoming_window; - /** parsing state for data frames */ - grpc_chttp2_data_parser data_parser; - /** reason give to rst_stream */ - uint32_t rst_stream_reason; - /** amount of window given */ - int64_t outgoing_window; - /** number of bytes received - reset at end of parse thread execution */ - int64_t received_bytes; - - /** incoming metadata */ - grpc_chttp2_incoming_metadata_buffer metadata_buffer[2]; -}; - -struct grpc_chttp2_stream { - grpc_stream_refcount *refcount; - grpc_chttp2_stream_global global; - grpc_chttp2_stream_writing writing; - grpc_chttp2_stream_parsing parsing; - - grpc_chttp2_stream_link links[STREAM_LIST_COUNT]; - uint8_t included[STREAM_LIST_COUNT]; -}; - -/** Transport writing call flow: - chttp2_transport.c calls grpc_chttp2_unlocking_check_writes to see if writes - are required; - if they are, chttp2_transport.c calls grpc_chttp2_perform_writes to do the - writes. - Once writes have been completed (meaning another write could potentially be - started), - grpc_chttp2_terminate_writing is called. This will call - grpc_chttp2_cleanup_writing, at which - point the write phase is complete. */ - -/** Someone is unlocking the transport mutex: check to see if writes - are required, and schedule them if so */ -int grpc_chttp2_unlocking_check_writes(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *global, - grpc_chttp2_transport_writing *writing, - int is_parsing); -void grpc_chttp2_perform_writes( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, - grpc_endpoint *endpoint); -void grpc_chttp2_terminate_writing(grpc_exec_ctx *exec_ctx, - void *transport_writing, bool success); -void grpc_chttp2_cleanup_writing(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *global, - grpc_chttp2_transport_writing *writing); - -void grpc_chttp2_prepare_to_read(grpc_chttp2_transport_global *global, - grpc_chttp2_transport_parsing *parsing); -/** Process one slice of incoming data; return 1 if the connection is still - viable after reading, or 0 if the connection should be torn down */ -int grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *transport_parsing, - gpr_slice slice); -void grpc_chttp2_publish_reads(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *global, - grpc_chttp2_transport_parsing *parsing); - -bool grpc_chttp2_list_add_writable_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -/** Get a writable stream - returns non-zero if there was a stream available */ -int grpc_chttp2_list_pop_writable_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_writing **stream_writing); -bool grpc_chttp2_list_remove_writable_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) GRPC_MUST_USE_RESULT; - -void grpc_chttp2_list_add_writing_stream( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing); -int grpc_chttp2_list_have_writing_streams( - grpc_chttp2_transport_writing *transport_writing); -int grpc_chttp2_list_pop_writing_stream( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing **stream_writing); - -void grpc_chttp2_list_add_written_stream( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing); -int grpc_chttp2_list_pop_written_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_writing **stream_writing); - -void grpc_chttp2_list_add_parsing_seen_stream( - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing); -int grpc_chttp2_list_pop_parsing_seen_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_parsing **stream_parsing); - -void grpc_chttp2_list_add_waiting_for_concurrency( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -int grpc_chttp2_list_pop_waiting_for_concurrency( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global); - -void grpc_chttp2_list_add_check_read_ops( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -int grpc_chttp2_list_pop_check_read_ops( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global); - -void grpc_chttp2_list_add_writing_stalled_by_transport( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing); -void grpc_chttp2_list_flush_writing_stalled_by_transport( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, - bool is_window_available); - -void grpc_chttp2_list_add_stalled_by_transport( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing); -int grpc_chttp2_list_pop_stalled_by_transport( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global); -void grpc_chttp2_list_remove_stalled_by_transport( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); - -void grpc_chttp2_list_add_unannounced_incoming_window_available( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -void grpc_chttp2_list_remove_unannounced_incoming_window_available( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -int grpc_chttp2_list_pop_unannounced_incoming_window_available( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_parsing **stream_parsing); - -void grpc_chttp2_list_add_closed_waiting_for_parsing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -int grpc_chttp2_list_pop_closed_waiting_for_parsing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global); - -void grpc_chttp2_list_add_closed_waiting_for_writing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); -int grpc_chttp2_list_pop_closed_waiting_for_writing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global); - -grpc_chttp2_stream_parsing *grpc_chttp2_parsing_lookup_stream( - grpc_chttp2_transport_parsing *transport_parsing, uint32_t id); -grpc_chttp2_stream_parsing *grpc_chttp2_parsing_accept_stream( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - uint32_t id); - -void grpc_chttp2_add_incoming_goaway( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - uint32_t goaway_error, gpr_slice goaway_text); - -void grpc_chttp2_register_stream(grpc_chttp2_transport *t, - grpc_chttp2_stream *s); -/* returns 1 if this is the last stream, 0 otherwise */ -int grpc_chttp2_unregister_stream(grpc_chttp2_transport *t, - grpc_chttp2_stream *s) GRPC_MUST_USE_RESULT; -int grpc_chttp2_has_streams(grpc_chttp2_transport *t); -void grpc_chttp2_for_all_streams( - grpc_chttp2_transport_global *transport_global, void *user_data, - void (*cb)(grpc_chttp2_transport_global *transport_global, void *user_data, - grpc_chttp2_stream_global *stream_global)); - -void grpc_chttp2_parsing_become_skip_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); - -void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, - grpc_closure **pclosure, int success); - -#define GRPC_CHTTP2_CLIENT_CONNECT_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" -#define GRPC_CHTTP2_CLIENT_CONNECT_STRLEN \ - (sizeof(GRPC_CHTTP2_CLIENT_CONNECT_STRING) - 1) - -extern int grpc_http_trace; -extern int grpc_flowctl_trace; - -#define GRPC_CHTTP2_IF_TRACING(stmt) \ - if (!(grpc_http_trace)) \ - ; \ - else \ - stmt - -typedef enum { - GRPC_CHTTP2_FLOWCTL_MOVE, - GRPC_CHTTP2_FLOWCTL_CREDIT, - GRPC_CHTTP2_FLOWCTL_DEBIT -} grpc_chttp2_flowctl_op; - -#define GRPC_CHTTP2_FLOW_MOVE_COMMON(phase, transport, id1, id2, dst_context, \ - dst_var, src_context, src_var) \ - do { \ - assert(id1 == id2); \ - if (grpc_flowctl_trace) { \ - grpc_chttp2_flowctl_trace( \ - __FILE__, __LINE__, phase, GRPC_CHTTP2_FLOWCTL_MOVE, #dst_context, \ - #dst_var, #src_context, #src_var, transport->is_client, id1, \ - dst_context->dst_var, src_context->src_var); \ - } \ - dst_context->dst_var += src_context->src_var; \ - src_context->src_var = 0; \ - } while (0) - -#define GRPC_CHTTP2_FLOW_MOVE_STREAM(phase, transport, dst_context, dst_var, \ - src_context, src_var) \ - GRPC_CHTTP2_FLOW_MOVE_COMMON(phase, transport, dst_context->id, \ - src_context->id, dst_context, dst_var, \ - src_context, src_var) -#define GRPC_CHTTP2_FLOW_MOVE_TRANSPORT(phase, dst_context, dst_var, \ - src_context, src_var) \ - GRPC_CHTTP2_FLOW_MOVE_COMMON(phase, dst_context, 0, 0, dst_context, dst_var, \ - src_context, src_var) - -#define GRPC_CHTTP2_FLOW_CREDIT_COMMON(phase, transport, id, dst_context, \ - dst_var, amount) \ - do { \ - if (grpc_flowctl_trace) { \ - grpc_chttp2_flowctl_trace(__FILE__, __LINE__, phase, \ - GRPC_CHTTP2_FLOWCTL_CREDIT, #dst_context, \ - #dst_var, NULL, #amount, transport->is_client, \ - id, dst_context->dst_var, amount); \ - } \ - dst_context->dst_var += amount; \ - } while (0) - -#define GRPC_CHTTP2_FLOW_CREDIT_STREAM(phase, transport, dst_context, dst_var, \ - amount) \ - GRPC_CHTTP2_FLOW_CREDIT_COMMON(phase, transport, dst_context->id, \ - dst_context, dst_var, amount) -#define GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT(phase, dst_context, dst_var, amount) \ - GRPC_CHTTP2_FLOW_CREDIT_COMMON(phase, dst_context, 0, dst_context, dst_var, \ - amount) - -#define GRPC_CHTTP2_FLOW_DEBIT_COMMON(phase, transport, id, dst_context, \ - dst_var, amount) \ - do { \ - if (grpc_flowctl_trace) { \ - grpc_chttp2_flowctl_trace(__FILE__, __LINE__, phase, \ - GRPC_CHTTP2_FLOWCTL_DEBIT, #dst_context, \ - #dst_var, NULL, #amount, transport->is_client, \ - id, dst_context->dst_var, amount); \ - } \ - dst_context->dst_var -= amount; \ - } while (0) - -#define GRPC_CHTTP2_FLOW_DEBIT_STREAM(phase, transport, dst_context, dst_var, \ - amount) \ - GRPC_CHTTP2_FLOW_DEBIT_COMMON(phase, transport, dst_context->id, \ - dst_context, dst_var, amount) -#define GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT(phase, dst_context, dst_var, amount) \ - GRPC_CHTTP2_FLOW_DEBIT_COMMON(phase, dst_context, 0, dst_context, dst_var, \ - amount) - -void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase, - grpc_chttp2_flowctl_op op, const char *context1, - const char *var1, const char *context2, - const char *var2, int is_client, - uint32_t stream_id, int64_t val1, int64_t val2); - -void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream, - grpc_status_code status, gpr_slice *details); -void grpc_chttp2_mark_stream_closed( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, int close_reads, - int close_writes); -void grpc_chttp2_start_writing(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global); - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -#define GRPC_CHTTP2_STREAM_REF(stream_global, reason) \ - grpc_chttp2_stream_ref(stream_global, reason) -#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, reason) \ - grpc_chttp2_stream_unref(exec_ctx, stream_global, reason) -void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global, - const char *reason); -void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, - grpc_chttp2_stream_global *stream_global, - const char *reason); -#else -#define GRPC_CHTTP2_STREAM_REF(stream_global, reason) \ - grpc_chttp2_stream_ref(stream_global) -#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, reason) \ - grpc_chttp2_stream_unref(exec_ctx, stream_global) -void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global); -void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, - grpc_chttp2_stream_global *stream_global); -#endif - -grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, uint32_t frame_size, - uint32_t flags, grpc_chttp2_incoming_frame_queue *add_to_queue); -void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, - grpc_chttp2_incoming_byte_stream *bs, - gpr_slice slice); -void grpc_chttp2_incoming_byte_stream_finished( - grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, int success, - int from_parsing_thread); - -void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *parsing, - const uint8_t *opaque_8bytes); - -/** add a ref to the stream and add it to the writable list; - ref will be dropped in writing.c */ -void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_INTERNAL_H */ diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c deleted file mode 100644 index 0516f39fa9..0000000000 --- a/src/core/transport/chttp2/parsing.c +++ /dev/null @@ -1,866 +0,0 @@ -/* - * - * Copyright 2015-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/transport/chttp2/internal.h" - -#include - -#include -#include -#include - -#include "src/core/profiling/timers.h" -#include "src/core/transport/chttp2/http2_errors.h" -#include "src/core/transport/chttp2/status_conversion.h" -#include "src/core/transport/chttp2/timeout_encoding.h" -#include "src/core/transport/static_metadata.h" - -static int init_frame_parser(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *transport_parsing); -static int init_header_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - int is_continuation); -static int init_data_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); -static int init_rst_stream_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); -static int init_settings_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); -static int init_window_update_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); -static int init_ping_parser(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *transport_parsing); -static int init_goaway_parser(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *transport_parsing); -static int init_skip_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - int is_header); - -static int parse_frame_slice(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *transport_parsing, - gpr_slice slice, int is_last); - -void grpc_chttp2_prepare_to_read( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_parsing *transport_parsing) { - grpc_chttp2_stream_global *stream_global; - grpc_chttp2_stream_parsing *stream_parsing; - - GPR_TIMER_BEGIN("grpc_chttp2_prepare_to_read", 0); - - transport_parsing->next_stream_id = transport_global->next_stream_id; - transport_parsing->last_sent_max_table_size = - transport_global->settings[GRPC_SENT_SETTINGS] - [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]; - - /* update the parsing view of incoming window */ - while (grpc_chttp2_list_pop_unannounced_incoming_window_available( - transport_global, transport_parsing, &stream_global, &stream_parsing)) { - GRPC_CHTTP2_FLOW_MOVE_STREAM("parse", transport_parsing, stream_parsing, - incoming_window, stream_global, - unannounced_incoming_window_for_parse); - } - - GPR_TIMER_END("grpc_chttp2_prepare_to_read", 0); -} - -void grpc_chttp2_publish_reads( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_parsing *transport_parsing) { - grpc_chttp2_stream_global *stream_global; - grpc_chttp2_stream_parsing *stream_parsing; - int was_zero; - int is_zero; - - /* transport_parsing->last_incoming_stream_id is used as - last-grpc_chttp2_stream-id when - sending GOAWAY frame. - https://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-6.8 - says that last-grpc_chttp2_stream-id is peer-initiated grpc_chttp2_stream - ID. So, - since we don't have server pushed streams, client should send - GOAWAY last-grpc_chttp2_stream-id=0 in this case. */ - if (!transport_parsing->is_client) { - transport_global->last_incoming_stream_id = - transport_parsing->incoming_stream_id; - } - - /* update global settings */ - if (transport_parsing->settings_updated) { - memcpy(transport_global->settings[GRPC_PEER_SETTINGS], - transport_parsing->settings, sizeof(transport_parsing->settings)); - transport_parsing->settings_updated = 0; - } - - /* update settings based on ack if received */ - if (transport_parsing->settings_ack_received) { - memcpy(transport_global->settings[GRPC_ACKED_SETTINGS], - transport_global->settings[GRPC_SENT_SETTINGS], - GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); - transport_parsing->settings_ack_received = 0; - transport_global->sent_local_settings = 0; - } - - /* move goaway to the global state if we received one (it will be - published later */ - if (transport_parsing->goaway_received) { - grpc_chttp2_add_incoming_goaway(exec_ctx, transport_global, - (uint32_t)transport_parsing->goaway_error, - transport_parsing->goaway_text); - transport_parsing->goaway_text = gpr_empty_slice(); - transport_parsing->goaway_received = 0; - } - - /* propagate flow control tokens to global state */ - was_zero = transport_global->outgoing_window <= 0; - GRPC_CHTTP2_FLOW_MOVE_TRANSPORT("parsed", transport_global, outgoing_window, - transport_parsing, outgoing_window); - is_zero = transport_global->outgoing_window <= 0; - if (was_zero && !is_zero) { - while (grpc_chttp2_list_pop_stalled_by_transport(transport_global, - &stream_global)) { - grpc_chttp2_become_writable(transport_global, stream_global); - } - } - - if (transport_parsing->incoming_window < - transport_global->connection_window_target * 3 / 4) { - int64_t announce_bytes = transport_global->connection_window_target - - transport_parsing->incoming_window; - GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", transport_global, - announce_incoming_window, announce_bytes); - GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", transport_parsing, - incoming_window, announce_bytes); - } - - /* for each stream that saw an update, fixup global state */ - while (grpc_chttp2_list_pop_parsing_seen_stream( - transport_global, transport_parsing, &stream_global, &stream_parsing)) { - if (stream_parsing->seen_error) { - stream_global->seen_error = 1; - grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); - } - - /* update outgoing flow control window */ - was_zero = stream_global->outgoing_window <= 0; - GRPC_CHTTP2_FLOW_MOVE_STREAM("parsed", transport_global, stream_global, - outgoing_window, stream_parsing, - outgoing_window); - is_zero = stream_global->outgoing_window <= 0; - if (was_zero && !is_zero) { - grpc_chttp2_become_writable(transport_global, stream_global); - } - - stream_global->max_recv_bytes -= (uint32_t)GPR_MIN( - stream_global->max_recv_bytes, stream_parsing->received_bytes); - stream_parsing->received_bytes = 0; - - /* publish incoming stream ops */ - if (stream_global->incoming_frames.tail != NULL) { - stream_global->incoming_frames.tail->is_tail = 0; - } - if (stream_parsing->data_parser.incoming_frames.head != NULL) { - grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); - } - grpc_chttp2_incoming_frame_queue_merge( - &stream_global->incoming_frames, - &stream_parsing->data_parser.incoming_frames); - if (stream_global->incoming_frames.tail != NULL) { - stream_global->incoming_frames.tail->is_tail = 1; - } - - if (!stream_global->published_initial_metadata && - stream_parsing->got_metadata_on_parse[0]) { - stream_parsing->got_metadata_on_parse[0] = 0; - stream_global->published_initial_metadata = 1; - GPR_SWAP(grpc_chttp2_incoming_metadata_buffer, - stream_parsing->metadata_buffer[0], - stream_global->received_initial_metadata); - grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); - } - if (!stream_global->published_trailing_metadata && - stream_parsing->got_metadata_on_parse[1]) { - stream_parsing->got_metadata_on_parse[1] = 0; - stream_global->published_trailing_metadata = 1; - GPR_SWAP(grpc_chttp2_incoming_metadata_buffer, - stream_parsing->metadata_buffer[1], - stream_global->received_trailing_metadata); - grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); - } - - if (stream_parsing->saw_rst_stream) { - if (stream_parsing->rst_stream_reason != GRPC_CHTTP2_NO_ERROR) { - grpc_status_code status_code = grpc_chttp2_http2_error_to_grpc_status( - (grpc_chttp2_error_code)stream_parsing->rst_stream_reason); - char *status_details; - gpr_slice slice_details; - gpr_asprintf(&status_details, "Received RST_STREAM err=%d", - stream_parsing->rst_stream_reason); - slice_details = gpr_slice_from_copied_string(status_details); - gpr_free(status_details); - grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, - status_code, &slice_details); - } - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, - 1, 1); - } - - if (stream_parsing->received_close) { - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, - 1, 0); - } - } -} - -int grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *transport_parsing, - gpr_slice slice) { - uint8_t *beg = GPR_SLICE_START_PTR(slice); - uint8_t *end = GPR_SLICE_END_PTR(slice); - uint8_t *cur = beg; - - if (cur == end) return 1; - - switch (transport_parsing->deframe_state) { - case GRPC_DTS_CLIENT_PREFIX_0: - case GRPC_DTS_CLIENT_PREFIX_1: - case GRPC_DTS_CLIENT_PREFIX_2: - case GRPC_DTS_CLIENT_PREFIX_3: - case GRPC_DTS_CLIENT_PREFIX_4: - case GRPC_DTS_CLIENT_PREFIX_5: - case GRPC_DTS_CLIENT_PREFIX_6: - case GRPC_DTS_CLIENT_PREFIX_7: - case GRPC_DTS_CLIENT_PREFIX_8: - case GRPC_DTS_CLIENT_PREFIX_9: - case GRPC_DTS_CLIENT_PREFIX_10: - case GRPC_DTS_CLIENT_PREFIX_11: - case GRPC_DTS_CLIENT_PREFIX_12: - case GRPC_DTS_CLIENT_PREFIX_13: - case GRPC_DTS_CLIENT_PREFIX_14: - case GRPC_DTS_CLIENT_PREFIX_15: - case GRPC_DTS_CLIENT_PREFIX_16: - case GRPC_DTS_CLIENT_PREFIX_17: - case GRPC_DTS_CLIENT_PREFIX_18: - case GRPC_DTS_CLIENT_PREFIX_19: - case GRPC_DTS_CLIENT_PREFIX_20: - case GRPC_DTS_CLIENT_PREFIX_21: - case GRPC_DTS_CLIENT_PREFIX_22: - case GRPC_DTS_CLIENT_PREFIX_23: - while (cur != end && transport_parsing->deframe_state != GRPC_DTS_FH_0) { - if (*cur != GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing - ->deframe_state]) { - gpr_log(GPR_INFO, - "Connect string mismatch: expected '%c' (%d) got '%c' (%d) " - "at byte %d", - GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing - ->deframe_state], - (int)(uint8_t)GRPC_CHTTP2_CLIENT_CONNECT_STRING - [transport_parsing->deframe_state], - *cur, (int)*cur, transport_parsing->deframe_state); - return 0; - } - ++cur; - ++transport_parsing->deframe_state; - } - if (cur == end) { - return 1; - } - /* fallthrough */ - dts_fh_0: - case GRPC_DTS_FH_0: - GPR_ASSERT(cur < end); - transport_parsing->incoming_frame_size = ((uint32_t)*cur) << 16; - if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_1; - return 1; - } - /* fallthrough */ - case GRPC_DTS_FH_1: - GPR_ASSERT(cur < end); - transport_parsing->incoming_frame_size |= ((uint32_t)*cur) << 8; - if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_2; - return 1; - } - /* fallthrough */ - case GRPC_DTS_FH_2: - GPR_ASSERT(cur < end); - transport_parsing->incoming_frame_size |= *cur; - if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_3; - return 1; - } - /* fallthrough */ - case GRPC_DTS_FH_3: - GPR_ASSERT(cur < end); - transport_parsing->incoming_frame_type = *cur; - if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_4; - return 1; - } - /* fallthrough */ - case GRPC_DTS_FH_4: - GPR_ASSERT(cur < end); - transport_parsing->incoming_frame_flags = *cur; - if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_5; - return 1; - } - /* fallthrough */ - case GRPC_DTS_FH_5: - GPR_ASSERT(cur < end); - transport_parsing->incoming_stream_id = (((uint32_t)*cur) & 0x7f) << 24; - if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_6; - return 1; - } - /* fallthrough */ - case GRPC_DTS_FH_6: - GPR_ASSERT(cur < end); - transport_parsing->incoming_stream_id |= ((uint32_t)*cur) << 16; - if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_7; - return 1; - } - /* fallthrough */ - case GRPC_DTS_FH_7: - GPR_ASSERT(cur < end); - transport_parsing->incoming_stream_id |= ((uint32_t)*cur) << 8; - if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_8; - return 1; - } - /* fallthrough */ - case GRPC_DTS_FH_8: - GPR_ASSERT(cur < end); - transport_parsing->incoming_stream_id |= ((uint32_t)*cur); - transport_parsing->deframe_state = GRPC_DTS_FRAME; - if (!init_frame_parser(exec_ctx, transport_parsing)) { - return 0; - } - if (transport_parsing->incoming_stream_id) { - transport_parsing->last_incoming_stream_id = - transport_parsing->incoming_stream_id; - } - if (transport_parsing->incoming_frame_size == 0) { - if (!parse_frame_slice(exec_ctx, transport_parsing, gpr_empty_slice(), - 1)) { - return 0; - } - transport_parsing->incoming_stream = NULL; - if (++cur == end) { - transport_parsing->deframe_state = GRPC_DTS_FH_0; - return 1; - } - goto dts_fh_0; /* loop */ - } - if (++cur == end) { - return 1; - } - /* fallthrough */ - case GRPC_DTS_FRAME: - GPR_ASSERT(cur < end); - if ((uint32_t)(end - cur) == transport_parsing->incoming_frame_size) { - if (!parse_frame_slice(exec_ctx, transport_parsing, - gpr_slice_sub_no_ref(slice, (size_t)(cur - beg), - (size_t)(end - beg)), - 1)) { - return 0; - } - transport_parsing->deframe_state = GRPC_DTS_FH_0; - transport_parsing->incoming_stream = NULL; - return 1; - } else if ((uint32_t)(end - cur) > - transport_parsing->incoming_frame_size) { - size_t cur_offset = (size_t)(cur - beg); - if (!parse_frame_slice( - exec_ctx, transport_parsing, - gpr_slice_sub_no_ref( - slice, cur_offset, - cur_offset + transport_parsing->incoming_frame_size), - 1)) { - return 0; - } - cur += transport_parsing->incoming_frame_size; - transport_parsing->incoming_stream = NULL; - goto dts_fh_0; /* loop */ - } else { - if (!parse_frame_slice(exec_ctx, transport_parsing, - gpr_slice_sub_no_ref(slice, (size_t)(cur - beg), - (size_t)(end - beg)), - 0)) { - return 0; - } - transport_parsing->incoming_frame_size -= (uint32_t)(end - cur); - return 1; - } - GPR_UNREACHABLE_CODE(return 0); - } - - GPR_UNREACHABLE_CODE(return 0); -} - -static int init_frame_parser(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *transport_parsing) { - if (transport_parsing->expect_continuation_stream_id != 0) { - if (transport_parsing->incoming_frame_type != - GRPC_CHTTP2_FRAME_CONTINUATION) { - gpr_log(GPR_ERROR, "Expected CONTINUATION frame, got frame type %02x", - transport_parsing->incoming_frame_type); - return 0; - } - if (transport_parsing->expect_continuation_stream_id != - transport_parsing->incoming_stream_id) { - gpr_log(GPR_ERROR, - "Expected CONTINUATION frame for grpc_chttp2_stream %08x, got " - "grpc_chttp2_stream %08x", - transport_parsing->expect_continuation_stream_id, - transport_parsing->incoming_stream_id); - return 0; - } - return init_header_frame_parser(exec_ctx, transport_parsing, 1); - } - switch (transport_parsing->incoming_frame_type) { - case GRPC_CHTTP2_FRAME_DATA: - return init_data_frame_parser(exec_ctx, transport_parsing); - case GRPC_CHTTP2_FRAME_HEADER: - return init_header_frame_parser(exec_ctx, transport_parsing, 0); - case GRPC_CHTTP2_FRAME_CONTINUATION: - gpr_log(GPR_ERROR, "Unexpected CONTINUATION frame"); - return 0; - case GRPC_CHTTP2_FRAME_RST_STREAM: - return init_rst_stream_parser(exec_ctx, transport_parsing); - case GRPC_CHTTP2_FRAME_SETTINGS: - return init_settings_frame_parser(exec_ctx, transport_parsing); - case GRPC_CHTTP2_FRAME_WINDOW_UPDATE: - return init_window_update_frame_parser(exec_ctx, transport_parsing); - case GRPC_CHTTP2_FRAME_PING: - return init_ping_parser(exec_ctx, transport_parsing); - case GRPC_CHTTP2_FRAME_GOAWAY: - return init_goaway_parser(exec_ctx, transport_parsing); - default: - gpr_log(GPR_ERROR, "Unknown frame type %02x", - transport_parsing->incoming_frame_type); - return init_skip_frame_parser(exec_ctx, transport_parsing, 0); - } -} - -static grpc_chttp2_parse_error skip_parser( - grpc_exec_ctx *exec_ctx, void *parser, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) { - return GRPC_CHTTP2_PARSE_OK; -} - -static void skip_header(void *tp, grpc_mdelem *md) { GRPC_MDELEM_UNREF(md); } - -static int init_skip_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - int is_header) { - if (is_header) { - uint8_t is_eoh = transport_parsing->expect_continuation_stream_id != 0; - transport_parsing->parser = grpc_chttp2_header_parser_parse; - transport_parsing->parser_data = &transport_parsing->hpack_parser; - transport_parsing->hpack_parser.on_header = skip_header; - transport_parsing->hpack_parser.on_header_user_data = NULL; - transport_parsing->hpack_parser.is_boundary = is_eoh; - transport_parsing->hpack_parser.is_eof = - (uint8_t)(is_eoh ? transport_parsing->header_eof : 0); - } else { - transport_parsing->parser = skip_parser; - } - return 1; -} - -void grpc_chttp2_parsing_become_skip_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { - init_skip_frame_parser( - exec_ctx, transport_parsing, - transport_parsing->parser == grpc_chttp2_header_parser_parse); -} - -static grpc_chttp2_parse_error update_incoming_window( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing) { - uint32_t incoming_frame_size = transport_parsing->incoming_frame_size; - if (incoming_frame_size > transport_parsing->incoming_window) { - gpr_log(GPR_ERROR, "frame of size %d overflows incoming window of %d", - transport_parsing->incoming_frame_size, - transport_parsing->incoming_window); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - - if (incoming_frame_size > stream_parsing->incoming_window) { - gpr_log(GPR_ERROR, "frame of size %d overflows incoming window of %d", - transport_parsing->incoming_frame_size, - stream_parsing->incoming_window); - return GRPC_CHTTP2_CONNECTION_ERROR; - } - - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", transport_parsing, incoming_window, - incoming_frame_size); - GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", transport_parsing, stream_parsing, - incoming_window, incoming_frame_size); - stream_parsing->received_bytes += incoming_frame_size; - - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); - - return GRPC_CHTTP2_PARSE_OK; -} - -static int init_data_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { - grpc_chttp2_stream_parsing *stream_parsing = - grpc_chttp2_parsing_lookup_stream(transport_parsing, - transport_parsing->incoming_stream_id); - grpc_chttp2_parse_error err = GRPC_CHTTP2_PARSE_OK; - if (!stream_parsing || stream_parsing->received_close) - return init_skip_frame_parser(exec_ctx, transport_parsing, 0); - if (err == GRPC_CHTTP2_PARSE_OK) { - err = update_incoming_window(exec_ctx, transport_parsing, stream_parsing); - } - if (err == GRPC_CHTTP2_PARSE_OK) { - err = grpc_chttp2_data_parser_begin_frame( - &stream_parsing->data_parser, transport_parsing->incoming_frame_flags); - } - switch (err) { - case GRPC_CHTTP2_PARSE_OK: - transport_parsing->incoming_stream = stream_parsing; - transport_parsing->parser = grpc_chttp2_data_parser_parse; - transport_parsing->parser_data = &stream_parsing->data_parser; - return 1; - case GRPC_CHTTP2_STREAM_ERROR: - stream_parsing->received_close = 1; - stream_parsing->saw_rst_stream = 1; - stream_parsing->rst_stream_reason = GRPC_CHTTP2_PROTOCOL_ERROR; - gpr_slice_buffer_add( - &transport_parsing->qbuf, - grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id, - GRPC_CHTTP2_PROTOCOL_ERROR)); - return init_skip_frame_parser(exec_ctx, transport_parsing, 0); - case GRPC_CHTTP2_CONNECTION_ERROR: - return 0; - } - GPR_UNREACHABLE_CODE(return 0); -} - -static void free_timeout(void *p) { gpr_free(p); } - -static void on_initial_header(void *tp, grpc_mdelem *md) { - grpc_chttp2_transport_parsing *transport_parsing = tp; - grpc_chttp2_stream_parsing *stream_parsing = - transport_parsing->incoming_stream; - - GPR_TIMER_BEGIN("on_initial_header", 0); - - GPR_ASSERT(stream_parsing); - - GRPC_CHTTP2_IF_TRACING(gpr_log( - GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", stream_parsing->id, - transport_parsing->is_client ? "CLI" : "SVR", - grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value))); - - if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) { - /* TODO(ctiller): check for a status like " 0" */ - stream_parsing->seen_error = 1; - } - - if (md->key == GRPC_MDSTR_GRPC_TIMEOUT) { - gpr_timespec *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout); - if (!cached_timeout) { - /* not already parsed: parse it now, and store the result away */ - cached_timeout = gpr_malloc(sizeof(gpr_timespec)); - if (!grpc_chttp2_decode_timeout(grpc_mdstr_as_c_string(md->value), - cached_timeout)) { - gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", - grpc_mdstr_as_c_string(md->value)); - *cached_timeout = gpr_inf_future(GPR_TIMESPAN); - } - grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); - } - grpc_chttp2_incoming_metadata_buffer_set_deadline( - &stream_parsing->metadata_buffer[0], - gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout)); - GRPC_MDELEM_UNREF(md); - } else { - grpc_chttp2_incoming_metadata_buffer_add( - &stream_parsing->metadata_buffer[0], md); - } - - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); - - GPR_TIMER_END("on_initial_header", 0); -} - -static void on_trailing_header(void *tp, grpc_mdelem *md) { - grpc_chttp2_transport_parsing *transport_parsing = tp; - grpc_chttp2_stream_parsing *stream_parsing = - transport_parsing->incoming_stream; - - GPR_TIMER_BEGIN("on_trailing_header", 0); - - GPR_ASSERT(stream_parsing); - - GRPC_CHTTP2_IF_TRACING(gpr_log( - GPR_INFO, "HTTP:%d:TRL:%s: %s: %s", stream_parsing->id, - transport_parsing->is_client ? "CLI" : "SVR", - grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value))); - - if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) { - /* TODO(ctiller): check for a status like " 0" */ - stream_parsing->seen_error = 1; - } - - grpc_chttp2_incoming_metadata_buffer_add(&stream_parsing->metadata_buffer[1], - md); - - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); - - GPR_TIMER_END("on_trailing_header", 0); -} - -static int init_header_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - int is_continuation) { - uint8_t is_eoh = (transport_parsing->incoming_frame_flags & - GRPC_CHTTP2_DATA_FLAG_END_HEADERS) != 0; - int via_accept = 0; - grpc_chttp2_stream_parsing *stream_parsing; - - /* TODO(ctiller): when to increment header_frames_received? */ - - if (is_eoh) { - transport_parsing->expect_continuation_stream_id = 0; - } else { - transport_parsing->expect_continuation_stream_id = - transport_parsing->incoming_stream_id; - } - - if (!is_continuation) { - transport_parsing->header_eof = (transport_parsing->incoming_frame_flags & - GRPC_CHTTP2_DATA_FLAG_END_STREAM) != 0; - } - - /* could be a new grpc_chttp2_stream or an existing grpc_chttp2_stream */ - stream_parsing = grpc_chttp2_parsing_lookup_stream( - transport_parsing, transport_parsing->incoming_stream_id); - if (stream_parsing == NULL) { - if (is_continuation) { - gpr_log(GPR_ERROR, - "grpc_chttp2_stream disbanded before CONTINUATION received"); - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); - } - if (transport_parsing->is_client) { - if ((transport_parsing->incoming_stream_id & 1) && - transport_parsing->incoming_stream_id < - transport_parsing->next_stream_id) { - /* this is an old (probably cancelled) grpc_chttp2_stream */ - } else { - gpr_log(GPR_ERROR, - "ignoring new grpc_chttp2_stream creation on client"); - } - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); - } else if (transport_parsing->last_incoming_stream_id > - transport_parsing->incoming_stream_id) { - gpr_log(GPR_ERROR, - "ignoring out of order new grpc_chttp2_stream request on server; " - "last grpc_chttp2_stream " - "id=%d, new grpc_chttp2_stream id=%d", - transport_parsing->last_incoming_stream_id, - transport_parsing->incoming_stream_id); - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); - } else if ((transport_parsing->incoming_stream_id & 1) == 0) { - gpr_log(GPR_ERROR, - "ignoring grpc_chttp2_stream with non-client generated index %d", - transport_parsing->incoming_stream_id); - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); - } - stream_parsing = transport_parsing->incoming_stream = - grpc_chttp2_parsing_accept_stream( - exec_ctx, transport_parsing, transport_parsing->incoming_stream_id); - if (stream_parsing == NULL) { - gpr_log(GPR_ERROR, "grpc_chttp2_stream not accepted"); - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); - } - via_accept = 1; - } else { - transport_parsing->incoming_stream = stream_parsing; - } - GPR_ASSERT(stream_parsing != NULL && (via_accept == 0 || via_accept == 1)); - if (stream_parsing->received_close) { - gpr_log(GPR_ERROR, "skipping already closed grpc_chttp2_stream header"); - transport_parsing->incoming_stream = NULL; - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); - } - transport_parsing->parser = grpc_chttp2_header_parser_parse; - transport_parsing->parser_data = &transport_parsing->hpack_parser; - switch (stream_parsing->header_frames_received) { - case 0: - transport_parsing->hpack_parser.on_header = on_initial_header; - break; - case 1: - transport_parsing->hpack_parser.on_header = on_trailing_header; - break; - case 2: - gpr_log(GPR_ERROR, "too many header frames received"); - return init_skip_frame_parser(exec_ctx, transport_parsing, 1); - } - transport_parsing->hpack_parser.on_header_user_data = transport_parsing; - transport_parsing->hpack_parser.is_boundary = is_eoh; - transport_parsing->hpack_parser.is_eof = - (uint8_t)(is_eoh ? transport_parsing->header_eof : 0); - if (!is_continuation && (transport_parsing->incoming_frame_flags & - GRPC_CHTTP2_FLAG_HAS_PRIORITY)) { - grpc_chttp2_hpack_parser_set_has_priority(&transport_parsing->hpack_parser); - } - return 1; -} - -static int init_window_update_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { - int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_window_update_parser_begin_frame( - &transport_parsing->simple.window_update, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags); - if (transport_parsing->incoming_stream_id) { - transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream( - transport_parsing, transport_parsing->incoming_stream_id); - } - transport_parsing->parser = grpc_chttp2_window_update_parser_parse; - transport_parsing->parser_data = &transport_parsing->simple.window_update; - return ok; -} - -static int init_ping_parser(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *transport_parsing) { - int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_ping_parser_begin_frame( - &transport_parsing->simple.ping, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags); - transport_parsing->parser = grpc_chttp2_ping_parser_parse; - transport_parsing->parser_data = &transport_parsing->simple.ping; - return ok; -} - -static int init_rst_stream_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { - int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_rst_stream_parser_begin_frame( - &transport_parsing->simple.rst_stream, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags); - transport_parsing->incoming_stream = grpc_chttp2_parsing_lookup_stream( - transport_parsing, transport_parsing->incoming_stream_id); - if (!transport_parsing->incoming_stream) { - return init_skip_frame_parser(exec_ctx, transport_parsing, 0); - } - transport_parsing->parser = grpc_chttp2_rst_stream_parser_parse; - transport_parsing->parser_data = &transport_parsing->simple.rst_stream; - return ok; -} - -static int init_goaway_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { - int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_goaway_parser_begin_frame( - &transport_parsing->goaway_parser, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags); - transport_parsing->parser = grpc_chttp2_goaway_parser_parse; - transport_parsing->parser_data = &transport_parsing->goaway_parser; - return ok; -} - -static int init_settings_frame_parser( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing) { - int ok; - - if (transport_parsing->incoming_stream_id != 0) { - gpr_log(GPR_ERROR, "settings frame received for grpc_chttp2_stream %d", - transport_parsing->incoming_stream_id); - return 0; - } - - ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_settings_parser_begin_frame( - &transport_parsing->simple.settings, - transport_parsing->incoming_frame_size, - transport_parsing->incoming_frame_flags, - transport_parsing->settings); - if (!ok) { - return 0; - } - if (transport_parsing->incoming_frame_flags & GRPC_CHTTP2_FLAG_ACK) { - transport_parsing->settings_ack_received = 1; - grpc_chttp2_hptbl_set_max_bytes( - &transport_parsing->hpack_parser.table, - transport_parsing->last_sent_max_table_size); - } - transport_parsing->parser = grpc_chttp2_settings_parser_parse; - transport_parsing->parser_data = &transport_parsing->simple.settings; - return ok; -} - -/* -static int is_window_update_legal(int64_t window_update, int64_t window) { - return window + window_update < MAX_WINDOW; -} -*/ - -static int parse_frame_slice(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *transport_parsing, - gpr_slice slice, int is_last) { - grpc_chttp2_stream_parsing *stream_parsing = - transport_parsing->incoming_stream; - switch (transport_parsing->parser(exec_ctx, transport_parsing->parser_data, - transport_parsing, stream_parsing, slice, - is_last)) { - case GRPC_CHTTP2_PARSE_OK: - if (stream_parsing) { - grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, - stream_parsing); - } - return 1; - case GRPC_CHTTP2_STREAM_ERROR: - grpc_chttp2_parsing_become_skip_parser(exec_ctx, transport_parsing); - if (stream_parsing) { - stream_parsing->saw_rst_stream = 1; - stream_parsing->rst_stream_reason = GRPC_CHTTP2_PROTOCOL_ERROR; - gpr_slice_buffer_add( - &transport_parsing->qbuf, - grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id, - GRPC_CHTTP2_PROTOCOL_ERROR)); - } - return 1; - case GRPC_CHTTP2_CONNECTION_ERROR: - return 0; - } - GPR_UNREACHABLE_CODE(return 0); -} diff --git a/src/core/transport/chttp2/status_conversion.c b/src/core/transport/chttp2/status_conversion.c deleted file mode 100644 index bf214b017a..0000000000 --- a/src/core/transport/chttp2/status_conversion.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/chttp2/status_conversion.h" - -int grpc_chttp2_grpc_status_to_http2_error(grpc_status_code status) { - switch (status) { - case GRPC_STATUS_OK: - return GRPC_CHTTP2_NO_ERROR; - case GRPC_STATUS_CANCELLED: - return GRPC_CHTTP2_CANCEL; - case GRPC_STATUS_RESOURCE_EXHAUSTED: - return GRPC_CHTTP2_ENHANCE_YOUR_CALM; - case GRPC_STATUS_PERMISSION_DENIED: - return GRPC_CHTTP2_INADEQUATE_SECURITY; - case GRPC_STATUS_UNAVAILABLE: - return GRPC_CHTTP2_REFUSED_STREAM; - default: - return GRPC_CHTTP2_INTERNAL_ERROR; - } -} - -grpc_status_code grpc_chttp2_http2_error_to_grpc_status( - grpc_chttp2_error_code error) { - switch (error) { - case GRPC_CHTTP2_NO_ERROR: - /* should never be received */ - return GRPC_STATUS_INTERNAL; - case GRPC_CHTTP2_CANCEL: - return GRPC_STATUS_CANCELLED; - case GRPC_CHTTP2_ENHANCE_YOUR_CALM: - return GRPC_STATUS_RESOURCE_EXHAUSTED; - case GRPC_CHTTP2_INADEQUATE_SECURITY: - return GRPC_STATUS_PERMISSION_DENIED; - case GRPC_CHTTP2_REFUSED_STREAM: - return GRPC_STATUS_UNAVAILABLE; - default: - return GRPC_STATUS_INTERNAL; - } -} - -grpc_status_code grpc_chttp2_http2_status_to_grpc_status(int status) { - switch (status) { - /* these HTTP2 status codes are called out explicitly in status.proto */ - case 200: - return GRPC_STATUS_OK; - case 400: - return GRPC_STATUS_INVALID_ARGUMENT; - case 401: - return GRPC_STATUS_UNAUTHENTICATED; - case 403: - return GRPC_STATUS_PERMISSION_DENIED; - case 404: - return GRPC_STATUS_NOT_FOUND; - case 409: - return GRPC_STATUS_ABORTED; - case 412: - return GRPC_STATUS_FAILED_PRECONDITION; - case 429: - return GRPC_STATUS_RESOURCE_EXHAUSTED; - case 499: - return GRPC_STATUS_CANCELLED; - case 500: - return GRPC_STATUS_UNKNOWN; - case 501: - return GRPC_STATUS_UNIMPLEMENTED; - case 503: - return GRPC_STATUS_UNAVAILABLE; - case 504: - return GRPC_STATUS_DEADLINE_EXCEEDED; - /* everything else is unknown */ - default: - return GRPC_STATUS_UNKNOWN; - } -} - -int grpc_chttp2_grpc_status_to_http2_status(grpc_status_code status) { - return 200; -} diff --git a/src/core/transport/chttp2/status_conversion.h b/src/core/transport/chttp2/status_conversion.h deleted file mode 100644 index c6e066bb5d..0000000000 --- a/src/core/transport/chttp2/status_conversion.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_STATUS_CONVERSION_H -#define GRPC_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H - -#include -#include "src/core/transport/chttp2/http2_errors.h" - -/* Conversion of grpc status codes to http2 error codes (for RST_STREAM) */ -grpc_chttp2_error_code grpc_chttp2_grpc_status_to_http2_error( - grpc_status_code status); -grpc_status_code grpc_chttp2_http2_error_to_grpc_status( - grpc_chttp2_error_code error); - -/* Conversion of HTTP status codes (:status) to grpc status codes */ -grpc_status_code grpc_chttp2_http2_status_to_grpc_status(int status); -int grpc_chttp2_grpc_status_to_http2_status(grpc_status_code status); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H */ diff --git a/src/core/transport/chttp2/stream_lists.c b/src/core/transport/chttp2/stream_lists.c deleted file mode 100644 index 60fe735cfc..0000000000 --- a/src/core/transport/chttp2/stream_lists.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * - * Copyright 2015-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/transport/chttp2/internal.h" - -#include - -#define TRANSPORT_FROM_GLOBAL(tg) \ - ((grpc_chttp2_transport *)((char *)(tg)-offsetof(grpc_chttp2_transport, \ - global))) - -#define STREAM_FROM_GLOBAL(sg) \ - ((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, global))) - -#define TRANSPORT_FROM_WRITING(tw) \ - ((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \ - writing))) - -#define STREAM_FROM_WRITING(sw) \ - ((grpc_chttp2_stream *)((char *)(sw)-offsetof(grpc_chttp2_stream, writing))) - -#define TRANSPORT_FROM_PARSING(tp) \ - ((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \ - parsing))) - -#define STREAM_FROM_PARSING(sp) \ - ((grpc_chttp2_stream *)((char *)(sp)-offsetof(grpc_chttp2_stream, parsing))) - -/* core list management */ - -static int stream_list_empty(grpc_chttp2_transport *t, - grpc_chttp2_stream_list_id id) { - return t->lists[id].head == NULL; -} - -static int stream_list_pop(grpc_chttp2_transport *t, - grpc_chttp2_stream **stream, - grpc_chttp2_stream_list_id id) { - grpc_chttp2_stream *s = t->lists[id].head; - if (s) { - grpc_chttp2_stream *new_head = s->links[id].next; - GPR_ASSERT(s->included[id]); - if (new_head) { - t->lists[id].head = new_head; - new_head->links[id].prev = NULL; - } else { - t->lists[id].head = NULL; - t->lists[id].tail = NULL; - } - s->included[id] = 0; - } - *stream = s; - return s != 0; -} - -static void stream_list_remove(grpc_chttp2_transport *t, grpc_chttp2_stream *s, - grpc_chttp2_stream_list_id id) { - GPR_ASSERT(s->included[id]); - s->included[id] = 0; - if (s->links[id].prev) { - s->links[id].prev->links[id].next = s->links[id].next; - } else { - GPR_ASSERT(t->lists[id].head == s); - t->lists[id].head = s->links[id].next; - } - if (s->links[id].next) { - s->links[id].next->links[id].prev = s->links[id].prev; - } else { - t->lists[id].tail = s->links[id].prev; - } -} - -static bool stream_list_maybe_remove(grpc_chttp2_transport *t, - grpc_chttp2_stream *s, - grpc_chttp2_stream_list_id id) { - if (s->included[id]) { - stream_list_remove(t, s, id); - return true; - } else { - return false; - } -} - -static void stream_list_add_tail(grpc_chttp2_transport *t, - grpc_chttp2_stream *s, - grpc_chttp2_stream_list_id id) { - grpc_chttp2_stream *old_tail; - GPR_ASSERT(!s->included[id]); - old_tail = t->lists[id].tail; - s->links[id].next = NULL; - s->links[id].prev = old_tail; - if (old_tail) { - old_tail->links[id].next = s; - } else { - t->lists[id].head = s; - } - t->lists[id].tail = s; - s->included[id] = 1; -} - -static bool stream_list_add(grpc_chttp2_transport *t, grpc_chttp2_stream *s, - grpc_chttp2_stream_list_id id) { - if (s->included[id]) { - return false; - } - stream_list_add_tail(t, s, id); - return true; -} - -/* wrappers for specializations */ - -bool grpc_chttp2_list_add_writable_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - GPR_ASSERT(stream_global->id != 0); - return stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_WRITABLE); -} - -int grpc_chttp2_list_pop_writable_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_writing **stream_writing) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_WRITABLE); - if (r != 0) { - *stream_global = &stream->global; - *stream_writing = &stream->writing; - } - return r; -} - -bool grpc_chttp2_list_remove_writable_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - return stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_WRITABLE); -} - -void grpc_chttp2_list_add_writing_stream( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing) { - GPR_ASSERT(stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), - STREAM_FROM_WRITING(stream_writing), - GRPC_CHTTP2_LIST_WRITING)); -} - -int grpc_chttp2_list_have_writing_streams( - grpc_chttp2_transport_writing *transport_writing) { - return !stream_list_empty(TRANSPORT_FROM_WRITING(transport_writing), - GRPC_CHTTP2_LIST_WRITING); -} - -int grpc_chttp2_list_pop_writing_stream( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing **stream_writing) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_WRITING(transport_writing), &stream, - GRPC_CHTTP2_LIST_WRITING); - if (r != 0) { - *stream_writing = &stream->writing; - } - return r; -} - -void grpc_chttp2_list_add_written_stream( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing) { - stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), - STREAM_FROM_WRITING(stream_writing), - GRPC_CHTTP2_LIST_WRITTEN); -} - -int grpc_chttp2_list_pop_written_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_writing **stream_writing) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_WRITING(transport_writing), &stream, - GRPC_CHTTP2_LIST_WRITTEN); - if (r != 0) { - *stream_global = &stream->global; - *stream_writing = &stream->writing; - } - return r; -} - -void grpc_chttp2_list_add_unannounced_incoming_window_available( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - GPR_ASSERT(stream_global->id != 0); - stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE); -} - -void grpc_chttp2_list_remove_unannounced_incoming_window_available( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - stream_list_maybe_remove( - TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE); -} - -int grpc_chttp2_list_pop_unannounced_incoming_window_available( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_parsing **stream_parsing) { - grpc_chttp2_stream *stream; - int r = - stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE); - if (r != 0) { - *stream_global = &stream->global; - *stream_parsing = &stream->parsing; - } - return r; -} - -void grpc_chttp2_list_add_parsing_seen_stream( - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing) { - stream_list_add(TRANSPORT_FROM_PARSING(transport_parsing), - STREAM_FROM_PARSING(stream_parsing), - GRPC_CHTTP2_LIST_PARSING_SEEN); -} - -int grpc_chttp2_list_pop_parsing_seen_stream( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_global **stream_global, - grpc_chttp2_stream_parsing **stream_parsing) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_PARSING(transport_parsing), &stream, - GRPC_CHTTP2_LIST_PARSING_SEEN); - if (r != 0) { - *stream_global = &stream->global; - *stream_parsing = &stream->parsing; - } - return r; -} - -void grpc_chttp2_list_add_waiting_for_concurrency( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY); -} - -int grpc_chttp2_list_pop_waiting_for_concurrency( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY); - if (r != 0) { - *stream_global = &stream->global; - } - return r; -} - -void grpc_chttp2_list_add_check_read_ops( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_CHECK_READ_OPS); -} - -int grpc_chttp2_list_pop_check_read_ops( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_CHECK_READ_OPS); - if (r != 0) { - *stream_global = &stream->global; - } - return r; -} - -void grpc_chttp2_list_add_writing_stalled_by_transport( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing) { - grpc_chttp2_stream *stream = STREAM_FROM_WRITING(stream_writing); - if (!stream->included[GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT]) { - GRPC_CHTTP2_STREAM_REF(&stream->global, "chttp2_writing_stalled"); - } - stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), stream, - GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT); -} - -void grpc_chttp2_list_flush_writing_stalled_by_transport( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, - bool is_window_available) { - grpc_chttp2_stream *stream; - grpc_chttp2_transport *transport = TRANSPORT_FROM_WRITING(transport_writing); - while (stream_list_pop(transport, &stream, - GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT)) { - if (is_window_available) { - grpc_chttp2_become_writable(&transport->global, &stream->global); - } else { - grpc_chttp2_list_add_stalled_by_transport(transport_writing, - &stream->writing); - } - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &stream->global, - "chttp2_writing_stalled"); - } -} - -void grpc_chttp2_list_add_stalled_by_transport( - grpc_chttp2_transport_writing *transport_writing, - grpc_chttp2_stream_writing *stream_writing) { - stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), - STREAM_FROM_WRITING(stream_writing), - GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); -} - -int grpc_chttp2_list_pop_stalled_by_transport( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); - if (r != 0) { - *stream_global = &stream->global; - } - return r; -} - -void grpc_chttp2_list_remove_stalled_by_transport( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); -} - -void grpc_chttp2_list_add_closed_waiting_for_parsing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING); -} - -int grpc_chttp2_list_pop_closed_waiting_for_parsing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING); - if (r != 0) { - *stream_global = &stream->global; - } - return r; -} - -void grpc_chttp2_list_add_closed_waiting_for_writing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), - STREAM_FROM_GLOBAL(stream_global), - GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING); -} - -int grpc_chttp2_list_pop_closed_waiting_for_writing( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global **stream_global) { - grpc_chttp2_stream *stream; - int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, - GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING); - if (r != 0) { - *stream_global = &stream->global; - } - return r; -} - -void grpc_chttp2_register_stream(grpc_chttp2_transport *t, - grpc_chttp2_stream *s) { - stream_list_add_tail(t, s, GRPC_CHTTP2_LIST_ALL_STREAMS); -} - -int grpc_chttp2_unregister_stream(grpc_chttp2_transport *t, - grpc_chttp2_stream *s) { - stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_ALL_STREAMS); - return stream_list_empty(t, GRPC_CHTTP2_LIST_ALL_STREAMS); -} - -int grpc_chttp2_has_streams(grpc_chttp2_transport *t) { - return !stream_list_empty(t, GRPC_CHTTP2_LIST_ALL_STREAMS); -} - -void grpc_chttp2_for_all_streams( - grpc_chttp2_transport_global *transport_global, void *user_data, - void (*cb)(grpc_chttp2_transport_global *transport_global, void *user_data, - grpc_chttp2_stream_global *stream_global)) { - grpc_chttp2_stream *s; - grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); - for (s = t->lists[GRPC_CHTTP2_LIST_ALL_STREAMS].head; s != NULL; - s = s->links[GRPC_CHTTP2_LIST_ALL_STREAMS].next) { - cb(transport_global, user_data, &s->global); - } -} diff --git a/src/core/transport/chttp2/stream_map.c b/src/core/transport/chttp2/stream_map.c deleted file mode 100644 index 555a16fb72..0000000000 --- a/src/core/transport/chttp2/stream_map.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/chttp2/stream_map.h" - -#include - -#include -#include -#include - -void grpc_chttp2_stream_map_init(grpc_chttp2_stream_map *map, - size_t initial_capacity) { - GPR_ASSERT(initial_capacity > 1); - map->keys = gpr_malloc(sizeof(uint32_t) * initial_capacity); - map->values = gpr_malloc(sizeof(void *) * initial_capacity); - map->count = 0; - map->free = 0; - map->capacity = initial_capacity; -} - -void grpc_chttp2_stream_map_destroy(grpc_chttp2_stream_map *map) { - gpr_free(map->keys); - gpr_free(map->values); -} - -static size_t compact(uint32_t *keys, void **values, size_t count) { - size_t i, out; - - for (i = 0, out = 0; i < count; i++) { - if (values[i]) { - keys[out] = keys[i]; - values[out] = values[i]; - out++; - } - } - - return out; -} - -void grpc_chttp2_stream_map_add(grpc_chttp2_stream_map *map, uint32_t key, - void *value) { - size_t count = map->count; - size_t capacity = map->capacity; - uint32_t *keys = map->keys; - void **values = map->values; - - GPR_ASSERT(count == 0 || keys[count - 1] < key); - GPR_ASSERT(value); - - if (count == capacity) { - if (map->free > capacity / 4) { - count = compact(keys, values, count); - map->free = 0; - } else { - /* resize when less than 25% of the table is free, because compaction - won't help much */ - map->capacity = capacity = 3 * capacity / 2; - map->keys = keys = gpr_realloc(keys, capacity * sizeof(uint32_t)); - map->values = values = gpr_realloc(values, capacity * sizeof(void *)); - } - } - - keys[count] = key; - values[count] = value; - map->count = count + 1; -} - -void grpc_chttp2_stream_map_move_into(grpc_chttp2_stream_map *src, - grpc_chttp2_stream_map *dst) { - /* if src is empty we dont need to do anything */ - if (src->count == src->free) { - return; - } - /* if dst is empty we simply need to swap */ - if (dst->count == dst->free) { - GPR_SWAP(grpc_chttp2_stream_map, *src, *dst); - return; - } - /* the first element of src must be greater than the last of dst... - * however the maps may need compacting for this property to hold */ - if (src->keys[0] <= dst->keys[dst->count - 1]) { - src->count = compact(src->keys, src->values, src->count); - src->free = 0; - dst->count = compact(dst->keys, dst->values, dst->count); - dst->free = 0; - } - GPR_ASSERT(src->keys[0] > dst->keys[dst->count - 1]); - /* if dst doesn't have capacity, resize */ - if (dst->count + src->count > dst->capacity) { - dst->capacity = GPR_MAX(dst->capacity * 3 / 2, dst->count + src->count); - dst->keys = gpr_realloc(dst->keys, dst->capacity * sizeof(uint32_t)); - dst->values = gpr_realloc(dst->values, dst->capacity * sizeof(void *)); - } - memcpy(dst->keys + dst->count, src->keys, src->count * sizeof(uint32_t)); - memcpy(dst->values + dst->count, src->values, src->count * sizeof(void *)); - dst->count += src->count; - dst->free += src->free; - src->count = 0; - src->free = 0; -} - -static void **find(grpc_chttp2_stream_map *map, uint32_t key) { - size_t min_idx = 0; - size_t max_idx = map->count; - size_t mid_idx; - uint32_t *keys = map->keys; - void **values = map->values; - uint32_t mid_key; - - if (max_idx == 0) return NULL; - - while (min_idx < max_idx) { - /* find the midpoint, avoiding overflow */ - mid_idx = min_idx + ((max_idx - min_idx) / 2); - mid_key = keys[mid_idx]; - - if (mid_key < key) { - min_idx = mid_idx + 1; - } else if (mid_key > key) { - max_idx = mid_idx; - } else /* mid_key == key */ - { - return &values[mid_idx]; - } - } - - return NULL; -} - -void *grpc_chttp2_stream_map_delete(grpc_chttp2_stream_map *map, uint32_t key) { - void **pvalue = find(map, key); - void *out = NULL; - if (pvalue != NULL) { - out = *pvalue; - *pvalue = NULL; - map->free += (out != NULL); - /* recognize complete emptyness and ensure we can skip - * defragmentation later */ - if (map->free == map->count) { - map->free = map->count = 0; - } - } - return out; -} - -void *grpc_chttp2_stream_map_find(grpc_chttp2_stream_map *map, uint32_t key) { - void **pvalue = find(map, key); - return pvalue != NULL ? *pvalue : NULL; -} - -size_t grpc_chttp2_stream_map_size(grpc_chttp2_stream_map *map) { - return map->count - map->free; -} - -void grpc_chttp2_stream_map_for_each(grpc_chttp2_stream_map *map, - void (*f)(void *user_data, uint32_t key, - void *value), - void *user_data) { - size_t i; - - for (i = 0; i < map->count; i++) { - if (map->values[i]) { - f(user_data, map->keys[i], map->values[i]); - } - } -} diff --git a/src/core/transport/chttp2/stream_map.h b/src/core/transport/chttp2/stream_map.h deleted file mode 100644 index 957a58a4f2..0000000000 --- a/src/core/transport/chttp2/stream_map.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_STREAM_MAP_H -#define GRPC_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H - -#include - -#include - -/* Data structure to map a uint32_t to a data object (represented by a void*) - - Represented as a sorted array of keys, and a corresponding array of values. - Lookups are performed with binary search. - Adds are restricted to strictly higher keys than previously seen (this is - guaranteed by http2). */ -typedef struct { - uint32_t *keys; - void **values; - size_t count; - size_t free; - size_t capacity; -} grpc_chttp2_stream_map; - -void grpc_chttp2_stream_map_init(grpc_chttp2_stream_map *map, - size_t initial_capacity); -void grpc_chttp2_stream_map_destroy(grpc_chttp2_stream_map *map); - -/* Add a new key: given http2 semantics, new keys must always be greater than - existing keys - this is asserted */ -void grpc_chttp2_stream_map_add(grpc_chttp2_stream_map *map, uint32_t key, - void *value); - -/* Delete an existing key - returns the previous value of the key if it existed, - or NULL otherwise */ -void *grpc_chttp2_stream_map_delete(grpc_chttp2_stream_map *map, uint32_t key); - -/* Move all elements of src into dst */ -void grpc_chttp2_stream_map_move_into(grpc_chttp2_stream_map *src, - grpc_chttp2_stream_map *dst); - -/* Return an existing key, or NULL if it does not exist */ -void *grpc_chttp2_stream_map_find(grpc_chttp2_stream_map *map, uint32_t key); - -/* How many (populated) entries are in the stream map? */ -size_t grpc_chttp2_stream_map_size(grpc_chttp2_stream_map *map); - -/* Callback on each stream */ -void grpc_chttp2_stream_map_for_each(grpc_chttp2_stream_map *map, - void (*f)(void *user_data, uint32_t key, - void *value), - void *user_data); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H */ diff --git a/src/core/transport/chttp2/timeout_encoding.c b/src/core/transport/chttp2/timeout_encoding.c deleted file mode 100644 index c4802e050e..0000000000 --- a/src/core/transport/chttp2/timeout_encoding.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * - * Copyright 2015-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/transport/chttp2/timeout_encoding.h" - -#include -#include - -#include -#include "src/core/support/string.h" - -static int64_t round_up(int64_t x, int64_t divisor) { - return (x / divisor + (x % divisor != 0)) * divisor; -} - -/* round an integer up to the next value with three significant figures */ -static int64_t round_up_to_three_sig_figs(int64_t x) { - if (x < 1000) return x; - if (x < 10000) return round_up(x, 10); - if (x < 100000) return round_up(x, 100); - if (x < 1000000) return round_up(x, 1000); - if (x < 10000000) return round_up(x, 10000); - if (x < 100000000) return round_up(x, 100000); - if (x < 1000000000) return round_up(x, 1000000); - return round_up(x, 10000000); -} - -/* encode our minimum viable timeout value */ -static void enc_tiny(char *buffer) { memcpy(buffer, "1n", 3); } - -static void enc_ext(char *buffer, int64_t value, char ext) { - int n = int64_ttoa(value, buffer); - buffer[n] = ext; - buffer[n + 1] = 0; -} - -static void enc_seconds(char *buffer, int64_t sec) { - if (sec % 3600 == 0) { - enc_ext(buffer, sec / 3600, 'H'); - } else if (sec % 60 == 0) { - enc_ext(buffer, sec / 60, 'M'); - } else { - enc_ext(buffer, sec, 'S'); - } -} - -static void enc_nanos(char *buffer, int64_t x) { - x = round_up_to_three_sig_figs(x); - if (x < 100000) { - if (x % 1000 == 0) { - enc_ext(buffer, x / 1000, 'u'); - } else { - enc_ext(buffer, x, 'n'); - } - } else if (x < 100000000) { - if (x % 1000000 == 0) { - enc_ext(buffer, x / 1000000, 'm'); - } else { - enc_ext(buffer, x / 1000, 'u'); - } - } else if (x < 1000000000) { - enc_ext(buffer, x / 1000000, 'm'); - } else { - /* note that this is only ever called with times of less than one second, - so if we reach here the time must have been rounded up to a whole second - (and no more) */ - memcpy(buffer, "1S", 3); - } -} - -static void enc_micros(char *buffer, int64_t x) { - x = round_up_to_three_sig_figs(x); - if (x < 100000) { - if (x % 1000 == 0) { - enc_ext(buffer, x / 1000, 'm'); - } else { - enc_ext(buffer, x, 'u'); - } - } else if (x < 100000000) { - if (x % 1000000 == 0) { - enc_ext(buffer, x / 1000000, 'S'); - } else { - enc_ext(buffer, x / 1000, 'm'); - } - } else { - enc_ext(buffer, x / 1000000, 'S'); - } -} - -void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer) { - if (timeout.tv_sec < 0) { - enc_tiny(buffer); - } else if (timeout.tv_sec == 0) { - enc_nanos(buffer, timeout.tv_nsec); - } else if (timeout.tv_sec < 1000 && timeout.tv_nsec != 0) { - enc_micros(buffer, - (int64_t)(timeout.tv_sec * 1000000) + - (timeout.tv_nsec / 1000 + (timeout.tv_nsec % 1000 != 0))); - } else { - enc_seconds(buffer, timeout.tv_sec + (timeout.tv_nsec != 0)); - } -} - -static int is_all_whitespace(const char *p) { - while (*p == ' ') p++; - return *p == 0; -} - -int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout) { - int32_t x = 0; - const uint8_t *p = (const uint8_t *)buffer; - int have_digit = 0; - /* skip whitespace */ - for (; *p == ' '; p++) - ; - /* decode numeric part */ - for (; *p >= '0' && *p <= '9'; p++) { - int32_t digit = (int32_t)(*p - (uint8_t)'0'); - have_digit = 1; - /* spec allows max. 8 digits, but we allow values up to 1,000,000,000 */ - if (x >= (100 * 1000 * 1000)) { - if (x != (100 * 1000 * 1000) || digit != 0) { - *timeout = gpr_inf_future(GPR_TIMESPAN); - return 1; - } - } - x = x * 10 + digit; - } - if (!have_digit) return 0; - /* skip whitespace */ - for (; *p == ' '; p++) - ; - /* decode unit specifier */ - switch (*p) { - case 'n': - *timeout = gpr_time_from_nanos(x, GPR_TIMESPAN); - break; - case 'u': - *timeout = gpr_time_from_micros(x, GPR_TIMESPAN); - break; - case 'm': - *timeout = gpr_time_from_millis(x, GPR_TIMESPAN); - break; - case 'S': - *timeout = gpr_time_from_seconds(x, GPR_TIMESPAN); - break; - case 'M': - *timeout = gpr_time_from_minutes(x, GPR_TIMESPAN); - break; - case 'H': - *timeout = gpr_time_from_hours(x, GPR_TIMESPAN); - break; - default: - return 0; - } - p++; - return is_all_whitespace((const char *)p); -} diff --git a/src/core/transport/chttp2/timeout_encoding.h b/src/core/transport/chttp2/timeout_encoding.h deleted file mode 100644 index f8e25226eb..0000000000 --- a/src/core/transport/chttp2/timeout_encoding.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H -#define GRPC_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H - -#include -#include "src/core/support/string.h" - -#define GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1) - -/* Encode/decode timeouts to the GRPC over HTTP2 format; - encoding may round up arbitrarily */ -void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer); -int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H */ diff --git a/src/core/transport/chttp2/varint.c b/src/core/transport/chttp2/varint.c deleted file mode 100644 index 1cc235e989..0000000000 --- a/src/core/transport/chttp2/varint.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/chttp2/varint.h" - -uint32_t grpc_chttp2_hpack_varint_length(uint32_t tail_value) { - if (tail_value < (1 << 7)) { - return 2; - } else if (tail_value < (1 << 14)) { - return 3; - } else if (tail_value < (1 << 21)) { - return 4; - } else if (tail_value < (1 << 28)) { - return 5; - } else { - return 6; - } -} - -void grpc_chttp2_hpack_write_varint_tail(uint32_t tail_value, uint8_t* target, - uint32_t tail_length) { - switch (tail_length) { - case 5: - target[4] = (uint8_t)((tail_value >> 28) | 0x80); - case 4: - target[3] = (uint8_t)((tail_value >> 21) | 0x80); - case 3: - target[2] = (uint8_t)((tail_value >> 14) | 0x80); - case 2: - target[1] = (uint8_t)((tail_value >> 7) | 0x80); - case 1: - target[0] = (uint8_t)((tail_value) | 0x80); - } - target[tail_length - 1] &= 0x7f; -} diff --git a/src/core/transport/chttp2/varint.h b/src/core/transport/chttp2/varint.h deleted file mode 100644 index 7ab9d22ab5..0000000000 --- a/src/core/transport/chttp2/varint.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_VARINT_H -#define GRPC_CORE_TRANSPORT_CHTTP2_VARINT_H - -#include - -/* Helpers for hpack varint encoding */ - -/* length of a value that needs varint tail encoding (it's bigger than can be - bitpacked into the opcode byte) - returned value includes the length of the - opcode byte */ -uint32_t grpc_chttp2_hpack_varint_length(uint32_t tail_value); - -void grpc_chttp2_hpack_write_varint_tail(uint32_t tail_value, uint8_t* target, - uint32_t tail_length); - -/* maximum value that can be bitpacked with the opcode if the opcode has a - prefix - of length prefix_bits */ -#define GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits) \ - ((uint32_t)((1 << (8 - (prefix_bits))) - 1)) - -/* length required to bitpack a value */ -#define GRPC_CHTTP2_VARINT_LENGTH(n, prefix_bits) \ - ((n) < GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits) \ - ? 1u \ - : grpc_chttp2_hpack_varint_length( \ - (n)-GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits))) - -#define GRPC_CHTTP2_WRITE_VARINT(n, prefix_bits, prefix_or, target, length) \ - do { \ - uint8_t* tgt = target; \ - if ((length) == 1u) { \ - (tgt)[0] = (uint8_t)((prefix_or) | (n)); \ - } else { \ - (tgt)[0] = \ - (prefix_or) | (uint8_t)GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits); \ - grpc_chttp2_hpack_write_varint_tail( \ - (n)-GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits), (tgt) + 1, (length)-1); \ - } \ - } while (0) - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_VARINT_H */ diff --git a/src/core/transport/chttp2/writing.c b/src/core/transport/chttp2/writing.c deleted file mode 100644 index 107725cbc7..0000000000 --- a/src/core/transport/chttp2/writing.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * - * Copyright 2015-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/transport/chttp2/internal.h" - -#include - -#include - -#include "src/core/profiling/timers.h" -#include "src/core/transport/chttp2/http2_errors.h" - -static void finalize_outbuf(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_writing *transport_writing); - -int grpc_chttp2_unlocking_check_writes( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing, int is_parsing) { - grpc_chttp2_stream_global *stream_global; - grpc_chttp2_stream_writing *stream_writing; - - GPR_TIMER_BEGIN("grpc_chttp2_unlocking_check_writes", 0); - - /* simple writes are queued to qbuf, and flushed here */ - gpr_slice_buffer_swap(&transport_global->qbuf, &transport_writing->outbuf); - GPR_ASSERT(transport_global->qbuf.count == 0); - - grpc_chttp2_hpack_compressor_set_max_table_size( - &transport_writing->hpack_compressor, - transport_global->settings[GRPC_PEER_SETTINGS] - [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); - - if (transport_global->dirtied_local_settings && - !transport_global->sent_local_settings && !is_parsing) { - gpr_slice_buffer_add( - &transport_writing->outbuf, - grpc_chttp2_settings_create( - transport_global->settings[GRPC_SENT_SETTINGS], - transport_global->settings[GRPC_LOCAL_SETTINGS], - transport_global->force_send_settings, GRPC_CHTTP2_NUM_SETTINGS)); - transport_global->force_send_settings = 0; - transport_global->dirtied_local_settings = 0; - transport_global->sent_local_settings = 1; - } - - GRPC_CHTTP2_FLOW_MOVE_TRANSPORT("write", transport_writing, outgoing_window, - transport_global, outgoing_window); - bool is_window_available = transport_writing->outgoing_window > 0; - grpc_chttp2_list_flush_writing_stalled_by_transport( - exec_ctx, transport_writing, is_window_available); - - /* for each grpc_chttp2_stream that's become writable, frame it's data - (according to available window sizes) and add to the output buffer */ - while (grpc_chttp2_list_pop_writable_stream( - transport_global, transport_writing, &stream_global, &stream_writing)) { - bool sent_initial_metadata = stream_writing->sent_initial_metadata; - bool become_writable = false; - - stream_writing->id = stream_global->id; - stream_writing->read_closed = stream_global->read_closed; - - GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_writing, stream_writing, - outgoing_window, stream_global, - outgoing_window); - - if (!sent_initial_metadata && stream_global->send_initial_metadata) { - stream_writing->send_initial_metadata = - stream_global->send_initial_metadata; - stream_global->send_initial_metadata = NULL; - become_writable = true; - sent_initial_metadata = true; - } - if (sent_initial_metadata) { - if (stream_global->send_message != NULL) { - gpr_slice hdr = gpr_slice_malloc(5); - uint8_t *p = GPR_SLICE_START_PTR(hdr); - uint32_t len = stream_global->send_message->length; - GPR_ASSERT(stream_writing->send_message == NULL); - p[0] = (stream_global->send_message->flags & - GRPC_WRITE_INTERNAL_COMPRESS) != 0; - p[1] = (uint8_t)(len >> 24); - p[2] = (uint8_t)(len >> 16); - p[3] = (uint8_t)(len >> 8); - p[4] = (uint8_t)(len); - gpr_slice_buffer_add(&stream_writing->flow_controlled_buffer, hdr); - if (stream_global->send_message->length > 0) { - stream_writing->send_message = stream_global->send_message; - } else { - stream_writing->send_message = NULL; - } - stream_writing->stream_fetched = 0; - stream_global->send_message = NULL; - } - if ((stream_writing->send_message != NULL || - stream_writing->flow_controlled_buffer.length > 0) && - stream_writing->outgoing_window > 0) { - if (transport_writing->outgoing_window > 0) { - become_writable = true; - } else { - grpc_chttp2_list_add_stalled_by_transport(transport_writing, - stream_writing); - } - } - if (stream_global->send_trailing_metadata) { - stream_writing->send_trailing_metadata = - stream_global->send_trailing_metadata; - stream_global->send_trailing_metadata = NULL; - become_writable = true; - } - } - - if (!stream_global->read_closed && - stream_global->unannounced_incoming_window_for_writing > 1024) { - GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_global, stream_writing, - announce_window, stream_global, - unannounced_incoming_window_for_writing); - become_writable = true; - } - - if (become_writable) { - grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing); - } else { - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); - } - } - - /* if the grpc_chttp2_transport is ready to send a window update, do so here - also; 3/4 is a magic number that will likely get tuned soon */ - if (transport_global->announce_incoming_window > 0) { - uint32_t announced = (uint32_t)GPR_MIN( - transport_global->announce_incoming_window, UINT32_MAX); - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_global, - announce_incoming_window, announced); - gpr_slice_buffer_add(&transport_writing->outbuf, - grpc_chttp2_window_update_create(0, announced)); - } - - GPR_TIMER_END("grpc_chttp2_unlocking_check_writes", 0); - - return transport_writing->outbuf.count > 0 || - grpc_chttp2_list_have_writing_streams(transport_writing); -} - -void grpc_chttp2_perform_writes( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing, - grpc_endpoint *endpoint) { - GPR_ASSERT(transport_writing->outbuf.count > 0 || - grpc_chttp2_list_have_writing_streams(transport_writing)); - - finalize_outbuf(exec_ctx, transport_writing); - - GPR_ASSERT(endpoint); - - if (transport_writing->outbuf.count > 0) { - grpc_endpoint_write(exec_ctx, endpoint, &transport_writing->outbuf, - &transport_writing->done_cb); - } else { - grpc_exec_ctx_enqueue(exec_ctx, &transport_writing->done_cb, true, NULL); - } -} - -static void finalize_outbuf(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_writing *transport_writing) { - grpc_chttp2_stream_writing *stream_writing; - - GPR_TIMER_BEGIN("finalize_outbuf", 0); - - while ( - grpc_chttp2_list_pop_writing_stream(transport_writing, &stream_writing)) { - uint32_t max_outgoing = - (uint32_t)GPR_MIN(GRPC_CHTTP2_MAX_PAYLOAD_LENGTH, - GPR_MIN(stream_writing->outgoing_window, - transport_writing->outgoing_window)); - /* send initial metadata if it's available */ - if (stream_writing->send_initial_metadata != NULL) { - grpc_chttp2_encode_header( - &transport_writing->hpack_compressor, stream_writing->id, - stream_writing->send_initial_metadata, 0, &transport_writing->outbuf); - stream_writing->send_initial_metadata = NULL; - stream_writing->sent_initial_metadata = 1; - } - /* send any window updates */ - if (stream_writing->announce_window > 0 && - stream_writing->send_initial_metadata == NULL) { - uint32_t announce = stream_writing->announce_window; - gpr_slice_buffer_add( - &transport_writing->outbuf, - grpc_chttp2_window_update_create(stream_writing->id, - stream_writing->announce_window)); - GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing, stream_writing, - announce_window, announce); - stream_writing->announce_window = 0; - } - /* fetch any body bytes */ - while (!stream_writing->fetching && stream_writing->send_message && - stream_writing->flow_controlled_buffer.length < max_outgoing && - stream_writing->stream_fetched < - stream_writing->send_message->length) { - if (grpc_byte_stream_next(exec_ctx, stream_writing->send_message, - &stream_writing->fetching_slice, max_outgoing, - &stream_writing->finished_fetch)) { - stream_writing->stream_fetched += - GPR_SLICE_LENGTH(stream_writing->fetching_slice); - if (stream_writing->stream_fetched == - stream_writing->send_message->length) { - stream_writing->send_message = NULL; - } - gpr_slice_buffer_add(&stream_writing->flow_controlled_buffer, - stream_writing->fetching_slice); - } else { - stream_writing->fetching = 1; - } - } - /* send any body bytes */ - if (stream_writing->flow_controlled_buffer.length > 0) { - if (max_outgoing > 0) { - uint32_t send_bytes = (uint32_t)GPR_MIN( - max_outgoing, stream_writing->flow_controlled_buffer.length); - int is_last_data_frame = - stream_writing->send_message == NULL && - send_bytes == stream_writing->flow_controlled_buffer.length; - int is_last_frame = is_last_data_frame && - stream_writing->send_trailing_metadata != NULL && - grpc_metadata_batch_is_empty( - stream_writing->send_trailing_metadata); - grpc_chttp2_encode_data( - stream_writing->id, &stream_writing->flow_controlled_buffer, - send_bytes, is_last_frame, &transport_writing->outbuf); - GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing, - stream_writing, outgoing_window, - send_bytes); - GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", transport_writing, - outgoing_window, send_bytes); - if (is_last_frame) { - stream_writing->send_trailing_metadata = NULL; - stream_writing->sent_trailing_metadata = 1; - } - if (is_last_data_frame) { - GPR_ASSERT(stream_writing->send_message == NULL); - stream_writing->sent_message = 1; - } - } else if (transport_writing->outgoing_window == 0) { - grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, - stream_writing); - grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); - } - } - /* send trailing metadata if it's available and we're ready for it */ - if (stream_writing->send_message == NULL && - stream_writing->flow_controlled_buffer.length == 0 && - stream_writing->send_trailing_metadata != NULL) { - if (grpc_metadata_batch_is_empty( - stream_writing->send_trailing_metadata)) { - grpc_chttp2_encode_data(stream_writing->id, - &stream_writing->flow_controlled_buffer, 0, 1, - &transport_writing->outbuf); - } else { - grpc_chttp2_encode_header(&transport_writing->hpack_compressor, - stream_writing->id, - stream_writing->send_trailing_metadata, 1, - &transport_writing->outbuf); - } - if (!transport_writing->is_client && !stream_writing->read_closed) { - gpr_slice_buffer_add(&transport_writing->outbuf, - grpc_chttp2_rst_stream_create( - stream_writing->id, GRPC_CHTTP2_NO_ERROR)); - } - stream_writing->send_trailing_metadata = NULL; - stream_writing->sent_trailing_metadata = 1; - } - /* if there's more to write, then loop, otherwise prepare to finish the - * write */ - if ((stream_writing->flow_controlled_buffer.length > 0 || - (stream_writing->send_message && !stream_writing->fetching)) && - stream_writing->outgoing_window > 0) { - if (transport_writing->outgoing_window > 0) { - grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing); - } else { - grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing, - stream_writing); - grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); - } - } else { - grpc_chttp2_list_add_written_stream(transport_writing, stream_writing); - } - } - - GPR_TIMER_END("finalize_outbuf", 0); -} - -void grpc_chttp2_cleanup_writing( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_transport_writing *transport_writing) { - grpc_chttp2_stream_writing *stream_writing; - grpc_chttp2_stream_global *stream_global; - - while (grpc_chttp2_list_pop_written_stream( - transport_global, transport_writing, &stream_global, &stream_writing)) { - if (stream_writing->sent_initial_metadata) { - grpc_chttp2_complete_closure_step( - exec_ctx, &stream_global->send_initial_metadata_finished, 1); - } - if (stream_writing->sent_message) { - GPR_ASSERT(stream_writing->send_message == NULL); - grpc_chttp2_complete_closure_step( - exec_ctx, &stream_global->send_message_finished, 1); - stream_writing->sent_message = 0; - } - if (stream_writing->sent_trailing_metadata) { - grpc_chttp2_complete_closure_step( - exec_ctx, &stream_global->send_trailing_metadata_finished, 1); - } - if (stream_writing->sent_trailing_metadata) { - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, - !transport_global->is_client, 1); - } - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); - } - gpr_slice_buffer_reset_and_unref(&transport_writing->outbuf); -} diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c deleted file mode 100644 index b45bf31997..0000000000 --- a/src/core/transport/chttp2_transport.c +++ /dev/null @@ -1,1785 +0,0 @@ -/* - * - * Copyright 2015-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/transport/chttp2_transport.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/http2_errors.h" -#include "src/core/transport/chttp2/internal.h" -#include "src/core/transport/chttp2/status_conversion.h" -#include "src/core/transport/chttp2/timeout_encoding.h" -#include "src/core/transport/static_metadata.h" -#include "src/core/transport/transport_impl.h" - -#define DEFAULT_WINDOW 65535 -#define DEFAULT_CONNECTION_WINDOW_TARGET (1024 * 1024) -#define MAX_WINDOW 0x7fffffffu - -#define MAX_CLIENT_STREAM_ID 0x7fffffffu - -int grpc_http_trace = 0; -int grpc_flowctl_trace = 0; - -#define TRANSPORT_FROM_WRITING(tw) \ - ((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \ - writing))) - -#define TRANSPORT_FROM_PARSING(tw) \ - ((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \ - parsing))) - -#define TRANSPORT_FROM_GLOBAL(tg) \ - ((grpc_chttp2_transport *)((char *)(tg)-offsetof(grpc_chttp2_transport, \ - global))) - -#define STREAM_FROM_GLOBAL(sg) \ - ((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, global))) - -#define STREAM_FROM_PARSING(sg) \ - ((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, parsing))) - -static const grpc_transport_vtable vtable; - -static void lock(grpc_chttp2_transport *t); -static void unlock(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); - -/* forward declarations of various callbacks that we'll build closures around */ -static void writing_action(grpc_exec_ctx *exec_ctx, void *t, - bool iomgr_success_ignored); - -/** Set a transport level setting, and push it to our peer */ -static void push_setting(grpc_chttp2_transport *t, grpc_chttp2_setting_id id, - uint32_t value); - -/** Endpoint callback to process incoming data */ -static void recv_data(grpc_exec_ctx *exec_ctx, void *tp, bool success); - -/** Start disconnection chain */ -static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); - -/** Perform a transport_op */ -static void perform_stream_op_locked( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, grpc_transport_stream_op *op); - -/** Cancel a stream: coming from the transport API */ -static void cancel_from_api(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, - grpc_status_code status); - -static void close_from_api(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, - grpc_status_code status, - gpr_slice *optional_message); - -/** Add endpoint from this transport to pollset */ -static void add_to_pollset_locked(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, - grpc_pollset *pollset); -static void add_to_pollset_set_locked(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, - grpc_pollset_set *pollset_set); - -/** Start new streams that have been created if we can */ -static void maybe_start_some_streams( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global); - -static void connectivity_state_set( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_connectivity_state state, const char *reason); - -static void check_read_ops(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global); - -static void incoming_byte_stream_update_flow_control( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, size_t max_size_hint, - size_t have_already); - -static void fail_pending_writes(grpc_exec_ctx *exec_ctx, - grpc_chttp2_stream_global *stream_global); - -/******************************************************************************* - * CONSTRUCTION/DESTRUCTION/REFCOUNTING - */ - -static void destruct_transport(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t) { - size_t i; - - gpr_mu_lock(&t->mu); - - GPR_ASSERT(t->ep == NULL); - - gpr_slice_buffer_destroy(&t->global.qbuf); - - gpr_slice_buffer_destroy(&t->writing.outbuf); - grpc_chttp2_hpack_compressor_destroy(&t->writing.hpack_compressor); - - gpr_slice_buffer_destroy(&t->parsing.qbuf); - gpr_slice_buffer_destroy(&t->read_buffer); - grpc_chttp2_hpack_parser_destroy(&t->parsing.hpack_parser); - grpc_chttp2_goaway_parser_destroy(&t->parsing.goaway_parser); - - for (i = 0; i < STREAM_LIST_COUNT; i++) { - GPR_ASSERT(t->lists[i].head == NULL); - GPR_ASSERT(t->lists[i].tail == NULL); - } - - GPR_ASSERT(grpc_chttp2_stream_map_size(&t->parsing_stream_map) == 0); - GPR_ASSERT(grpc_chttp2_stream_map_size(&t->new_stream_map) == 0); - - grpc_chttp2_stream_map_destroy(&t->parsing_stream_map); - grpc_chttp2_stream_map_destroy(&t->new_stream_map); - grpc_connectivity_state_destroy(exec_ctx, &t->channel_callback.state_tracker); - - gpr_mu_unlock(&t->mu); - gpr_mu_destroy(&t->mu); - - /* callback remaining pings: they're not allowed to call into the transpot, - and maybe they hold resources that need to be freed */ - while (t->global.pings.next != &t->global.pings) { - grpc_chttp2_outstanding_ping *ping = t->global.pings.next; - grpc_exec_ctx_enqueue(exec_ctx, ping->on_recv, false, NULL); - ping->next->prev = ping->prev; - ping->prev->next = ping->next; - gpr_free(ping); - } - - gpr_free(t->peer_string); - gpr_free(t); -} - -#ifdef REFCOUNTING_DEBUG -#define REF_TRANSPORT(t, r) ref_transport(t, r, __FILE__, __LINE__) -#define UNREF_TRANSPORT(cl, t, r) unref_transport(cl, t, r, __FILE__, __LINE__) -static void unref_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, - const char *reason, const char *file, int line) { - gpr_log(GPR_DEBUG, "chttp2:unref:%p %d->%d %s [%s:%d]", t, t->refs.count, - t->refs.count - 1, reason, file, line); - if (!gpr_unref(&t->refs)) return; - destruct_transport(exec_ctx, t); -} - -static void ref_transport(grpc_chttp2_transport *t, const char *reason, - const char *file, int line) { - gpr_log(GPR_DEBUG, "chttp2: ref:%p %d->%d %s [%s:%d]", t, t->refs.count, - t->refs.count + 1, reason, file, line); - gpr_ref(&t->refs); -} -#else -#define REF_TRANSPORT(t, r) ref_transport(t) -#define UNREF_TRANSPORT(cl, t, r) unref_transport(cl, t) -static void unref_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { - if (!gpr_unref(&t->refs)) return; - destruct_transport(exec_ctx, t); -} - -static void ref_transport(grpc_chttp2_transport *t) { gpr_ref(&t->refs); } -#endif - -static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, - const grpc_channel_args *channel_args, - grpc_endpoint *ep, uint8_t is_client) { - size_t i; - int j; - - GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) == - GRPC_CHTTP2_CLIENT_CONNECT_STRLEN); - - memset(t, 0, sizeof(*t)); - - t->base.vtable = &vtable; - t->ep = ep; - /* one ref is for destroy, the other for when ep becomes NULL */ - gpr_ref_init(&t->refs, 2); - /* ref is dropped at transport close() */ - gpr_ref_init(&t->shutdown_ep_refs, 1); - gpr_mu_init(&t->mu); - t->peer_string = grpc_endpoint_get_peer(ep); - t->endpoint_reading = 1; - t->global.next_stream_id = is_client ? 1 : 2; - t->global.is_client = is_client; - t->writing.outgoing_window = DEFAULT_WINDOW; - t->parsing.incoming_window = DEFAULT_WINDOW; - t->global.stream_lookahead = DEFAULT_WINDOW; - t->global.connection_window_target = DEFAULT_CONNECTION_WINDOW_TARGET; - t->global.ping_counter = 1; - t->global.pings.next = t->global.pings.prev = &t->global.pings; - t->parsing.is_client = is_client; - t->parsing.deframe_state = - is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0; - t->writing.is_client = is_client; - grpc_connectivity_state_init( - &t->channel_callback.state_tracker, GRPC_CHANNEL_READY, - is_client ? "client_transport" : "server_transport"); - - gpr_slice_buffer_init(&t->global.qbuf); - - gpr_slice_buffer_init(&t->writing.outbuf); - grpc_chttp2_hpack_compressor_init(&t->writing.hpack_compressor); - grpc_closure_init(&t->writing_action, writing_action, t); - - gpr_slice_buffer_init(&t->parsing.qbuf); - grpc_chttp2_goaway_parser_init(&t->parsing.goaway_parser); - grpc_chttp2_hpack_parser_init(&t->parsing.hpack_parser); - - grpc_closure_init(&t->writing.done_cb, grpc_chttp2_terminate_writing, - &t->writing); - grpc_closure_init(&t->recv_data, recv_data, t); - gpr_slice_buffer_init(&t->read_buffer); - - if (is_client) { - gpr_slice_buffer_add( - &t->global.qbuf, - gpr_slice_from_copied_string(GRPC_CHTTP2_CLIENT_CONNECT_STRING)); - } - /* 8 is a random stab in the dark as to a good initial size: it's small enough - that it shouldn't waste memory for infrequently used connections, yet - large enough that the exponential growth should happen nicely when it's - needed. - TODO(ctiller): tune this */ - grpc_chttp2_stream_map_init(&t->parsing_stream_map, 8); - grpc_chttp2_stream_map_init(&t->new_stream_map, 8); - - /* copy in initial settings to all setting sets */ - for (i = 0; i < GRPC_CHTTP2_NUM_SETTINGS; i++) { - t->parsing.settings[i] = grpc_chttp2_settings_parameters[i].default_value; - for (j = 0; j < GRPC_NUM_SETTING_SETS; j++) { - t->global.settings[j][i] = - grpc_chttp2_settings_parameters[i].default_value; - } - } - t->global.dirtied_local_settings = 1; - /* Hack: it's common for implementations to assume 65536 bytes initial send - window -- this should by rights be 0 */ - t->global.force_send_settings = 1 << GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; - t->global.sent_local_settings = 0; - - /* configure http2 the way we like it */ - if (is_client) { - push_setting(t, GRPC_CHTTP2_SETTINGS_ENABLE_PUSH, 0); - push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0); - } - push_setting(t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, DEFAULT_WINDOW); - - if (channel_args) { - for (i = 0; i < channel_args->num_args; i++) { - if (0 == - strcmp(channel_args->args[i].key, GRPC_ARG_MAX_CONCURRENT_STREAMS)) { - if (is_client) { - gpr_log(GPR_ERROR, "%s: is ignored on the client", - GRPC_ARG_MAX_CONCURRENT_STREAMS); - } else if (channel_args->args[i].type != GRPC_ARG_INTEGER) { - gpr_log(GPR_ERROR, "%s: must be an integer", - GRPC_ARG_MAX_CONCURRENT_STREAMS); - } else { - push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, - (uint32_t)channel_args->args[i].value.integer); - } - } else if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER)) { - if (channel_args->args[i].type != GRPC_ARG_INTEGER) { - gpr_log(GPR_ERROR, "%s: must be an integer", - GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER); - } else if ((t->global.next_stream_id & 1) != - (channel_args->args[i].value.integer & 1)) { - gpr_log(GPR_ERROR, "%s: low bit must be %d on %s", - GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER, - t->global.next_stream_id & 1, - is_client ? "client" : "server"); - } else { - t->global.next_stream_id = - (uint32_t)channel_args->args[i].value.integer; - } - } else if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES)) { - if (channel_args->args[i].type != GRPC_ARG_INTEGER) { - gpr_log(GPR_ERROR, "%s: must be an integer", - GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES); - } else if (channel_args->args[i].value.integer <= 5) { - gpr_log(GPR_ERROR, "%s: must be at least 5", - GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES); - } else { - t->global.stream_lookahead = - (uint32_t)channel_args->args[i].value.integer; - } - } else if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER)) { - if (channel_args->args[i].type != GRPC_ARG_INTEGER) { - gpr_log(GPR_ERROR, "%s: must be an integer", - GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER); - } else if (channel_args->args[i].value.integer < 0) { - gpr_log(GPR_ERROR, "%s: must be non-negative", - GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER); - } else { - push_setting(t, GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE, - (uint32_t)channel_args->args[i].value.integer); - } - } else if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER)) { - if (channel_args->args[i].type != GRPC_ARG_INTEGER) { - gpr_log(GPR_ERROR, "%s: must be an integer", - GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER); - } else if (channel_args->args[i].value.integer < 0) { - gpr_log(GPR_ERROR, "%s: must be non-negative", - GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER); - } else { - grpc_chttp2_hpack_compressor_set_max_usable_size( - &t->writing.hpack_compressor, - (uint32_t)channel_args->args[i].value.integer); - } - } - } - } -} - -static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { - grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - - lock(t); - t->destroying = 1; - drop_connection(exec_ctx, t); - unlock(exec_ctx, t); - - UNREF_TRANSPORT(exec_ctx, t, "destroy"); -} - -/** block grpc_endpoint_shutdown being called until a paired - allow_endpoint_shutdown is made */ -static void prevent_endpoint_shutdown(grpc_chttp2_transport *t) { - GPR_ASSERT(t->ep); - gpr_ref(&t->shutdown_ep_refs); -} - -static void allow_endpoint_shutdown_locked(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t) { - if (gpr_unref(&t->shutdown_ep_refs)) { - if (t->ep) { - grpc_endpoint_shutdown(exec_ctx, t->ep); - } - } -} - -static void allow_endpoint_shutdown_unlocked(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t) { - if (gpr_unref(&t->shutdown_ep_refs)) { - gpr_mu_lock(&t->mu); - if (t->ep) { - grpc_endpoint_shutdown(exec_ctx, t->ep); - } - gpr_mu_unlock(&t->mu); - } -} - -static void destroy_endpoint(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t) { - grpc_endpoint_destroy(exec_ctx, t->ep); - t->ep = NULL; - /* safe because we'll still have the ref for write */ - UNREF_TRANSPORT(exec_ctx, t, "disconnect"); -} - -static void close_transport_locked(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t) { - if (!t->closed) { - t->closed = 1; - connectivity_state_set(exec_ctx, &t->global, GRPC_CHANNEL_FATAL_FAILURE, - "close_transport"); - if (t->ep) { - allow_endpoint_shutdown_locked(exec_ctx, t); - } - - /* flush writable stream list to avoid dangling references */ - grpc_chttp2_stream_global *stream_global; - grpc_chttp2_stream_writing *stream_writing; - while (grpc_chttp2_list_pop_writable_stream( - &t->global, &t->writing, &stream_global, &stream_writing)) { - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing"); - } - } -} - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global, - const char *reason) { - grpc_stream_ref(STREAM_FROM_GLOBAL(stream_global)->refcount, reason); -} -void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, - grpc_chttp2_stream_global *stream_global, - const char *reason) { - grpc_stream_unref(exec_ctx, STREAM_FROM_GLOBAL(stream_global)->refcount, - reason); -} -#else -void grpc_chttp2_stream_ref(grpc_chttp2_stream_global *stream_global) { - grpc_stream_ref(STREAM_FROM_GLOBAL(stream_global)->refcount); -} -void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, - grpc_chttp2_stream_global *stream_global) { - grpc_stream_unref(exec_ctx, STREAM_FROM_GLOBAL(stream_global)->refcount); -} -#endif - -static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_stream *gs, grpc_stream_refcount *refcount, - const void *server_data) { - grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; - - memset(s, 0, sizeof(*s)); - - s->refcount = refcount; - GRPC_CHTTP2_STREAM_REF(&s->global, "chttp2"); - - grpc_chttp2_incoming_metadata_buffer_init(&s->parsing.metadata_buffer[0]); - grpc_chttp2_incoming_metadata_buffer_init(&s->parsing.metadata_buffer[1]); - grpc_chttp2_incoming_metadata_buffer_init( - &s->global.received_initial_metadata); - grpc_chttp2_incoming_metadata_buffer_init( - &s->global.received_trailing_metadata); - grpc_chttp2_data_parser_init(&s->parsing.data_parser); - gpr_slice_buffer_init(&s->writing.flow_controlled_buffer); - - REF_TRANSPORT(t, "stream"); - - lock(t); - grpc_chttp2_register_stream(t, s); - if (server_data) { - GPR_ASSERT(t->parsing_active); - s->global.id = (uint32_t)(uintptr_t)server_data; - s->parsing.id = s->global.id; - s->global.outgoing_window = - t->global.settings[GRPC_PEER_SETTINGS] - [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; - s->parsing.incoming_window = s->global.max_recv_bytes = - t->global.settings[GRPC_SENT_SETTINGS] - [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; - *t->accepting_stream = s; - grpc_chttp2_stream_map_add(&t->parsing_stream_map, s->global.id, s); - s->global.in_stream_map = 1; - } - unlock(exec_ctx, t); - - return 0; -} - -static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_stream *gs) { - grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; - int i; - grpc_byte_stream *bs; - - GPR_TIMER_BEGIN("destroy_stream", 0); - - gpr_mu_lock(&t->mu); - - GPR_ASSERT((s->global.write_closed && s->global.read_closed) || - s->global.id == 0); - GPR_ASSERT(!s->global.in_stream_map); - if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) { - close_transport_locked(exec_ctx, t); - } - if (!t->parsing_active && s->global.id) { - GPR_ASSERT(grpc_chttp2_stream_map_find(&t->parsing_stream_map, - s->global.id) == NULL); - } - - grpc_chttp2_list_remove_unannounced_incoming_window_available(&t->global, - &s->global); - grpc_chttp2_list_remove_stalled_by_transport(&t->global, &s->global); - - gpr_mu_unlock(&t->mu); - - for (i = 0; i < STREAM_LIST_COUNT; i++) { - if (s->included[i]) { - gpr_log(GPR_ERROR, "%s stream %d still included in list %d", - t->global.is_client ? "client" : "server", s->global.id, i); - abort(); - } - } - - while ( - (bs = grpc_chttp2_incoming_frame_queue_pop(&s->global.incoming_frames))) { - grpc_byte_stream_destroy(exec_ctx, bs); - } - - GPR_ASSERT(s->global.send_initial_metadata_finished == NULL); - GPR_ASSERT(s->global.send_message_finished == NULL); - GPR_ASSERT(s->global.send_trailing_metadata_finished == NULL); - GPR_ASSERT(s->global.recv_initial_metadata_ready == NULL); - GPR_ASSERT(s->global.recv_message_ready == NULL); - GPR_ASSERT(s->global.recv_trailing_metadata_finished == NULL); - grpc_chttp2_data_parser_destroy(exec_ctx, &s->parsing.data_parser); - grpc_chttp2_incoming_metadata_buffer_destroy(&s->parsing.metadata_buffer[0]); - grpc_chttp2_incoming_metadata_buffer_destroy(&s->parsing.metadata_buffer[1]); - grpc_chttp2_incoming_metadata_buffer_destroy( - &s->global.received_initial_metadata); - grpc_chttp2_incoming_metadata_buffer_destroy( - &s->global.received_trailing_metadata); - gpr_slice_buffer_destroy(&s->writing.flow_controlled_buffer); - - UNREF_TRANSPORT(exec_ctx, t, "stream"); - - GPR_TIMER_END("destroy_stream", 0); -} - -grpc_chttp2_stream_parsing *grpc_chttp2_parsing_lookup_stream( - grpc_chttp2_transport_parsing *transport_parsing, uint32_t id) { - grpc_chttp2_transport *t = TRANSPORT_FROM_PARSING(transport_parsing); - grpc_chttp2_stream *s = - grpc_chttp2_stream_map_find(&t->parsing_stream_map, id); - return s ? &s->parsing : NULL; -} - -grpc_chttp2_stream_parsing *grpc_chttp2_parsing_accept_stream( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - uint32_t id) { - grpc_chttp2_stream *accepting; - grpc_chttp2_transport *t = TRANSPORT_FROM_PARSING(transport_parsing); - GPR_ASSERT(t->accepting_stream == NULL); - t->accepting_stream = &accepting; - t->channel_callback.accept_stream(exec_ctx, - t->channel_callback.accept_stream_user_data, - &t->base, (void *)(uintptr_t)id); - t->accepting_stream = NULL; - return &accepting->parsing; -} - -/******************************************************************************* - * LOCK MANAGEMENT - */ - -/* We take a grpc_chttp2_transport-global lock in response to calls coming in - from above, - and in response to data being received from below. New data to be written - is always queued, as are callbacks to process data. During unlock() we - check our todo lists and initiate callbacks and flush writes. */ - -static void lock(grpc_chttp2_transport *t) { gpr_mu_lock(&t->mu); } - -static void unlock(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { - GPR_TIMER_BEGIN("unlock", 0); - if (!t->writing_active && !t->closed && - grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing, - t->parsing_active)) { - t->writing_active = 1; - REF_TRANSPORT(t, "writing"); - grpc_exec_ctx_enqueue(exec_ctx, &t->writing_action, true, NULL); - prevent_endpoint_shutdown(t); - } - check_read_ops(exec_ctx, &t->global); - - gpr_mu_unlock(&t->mu); - GPR_TIMER_END("unlock", 0); -} - -/******************************************************************************* - * OUTPUT PROCESSING - */ - -void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global) { - if (!TRANSPORT_FROM_GLOBAL(transport_global)->closed && - grpc_chttp2_list_add_writable_stream(transport_global, stream_global)) { - GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing"); - } -} - -static void push_setting(grpc_chttp2_transport *t, grpc_chttp2_setting_id id, - uint32_t value) { - const grpc_chttp2_setting_parameters *sp = - &grpc_chttp2_settings_parameters[id]; - uint32_t use_value = GPR_CLAMP(value, sp->min_value, sp->max_value); - if (use_value != value) { - gpr_log(GPR_INFO, "Requested parameter %s clamped from %d to %d", sp->name, - value, use_value); - } - if (use_value != t->global.settings[GRPC_LOCAL_SETTINGS][id]) { - t->global.settings[GRPC_LOCAL_SETTINGS][id] = use_value; - t->global.dirtied_local_settings = 1; - } -} - -void grpc_chttp2_terminate_writing(grpc_exec_ctx *exec_ctx, - void *transport_writing_ptr, bool success) { - grpc_chttp2_transport_writing *transport_writing = transport_writing_ptr; - grpc_chttp2_transport *t = TRANSPORT_FROM_WRITING(transport_writing); - grpc_chttp2_stream_global *stream_global; - - GPR_TIMER_BEGIN("grpc_chttp2_terminate_writing", 0); - - lock(t); - - allow_endpoint_shutdown_locked(exec_ctx, t); - - if (!success) { - drop_connection(exec_ctx, t); - } - - grpc_chttp2_cleanup_writing(exec_ctx, &t->global, &t->writing); - - while (grpc_chttp2_list_pop_closed_waiting_for_writing(&t->global, - &stream_global)) { - fail_pending_writes(exec_ctx, stream_global); - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "finish_writes"); - } - - /* leave the writing flag up on shutdown to prevent further writes in unlock() - from starting */ - t->writing_active = 0; - if (t->ep && !t->endpoint_reading) { - destroy_endpoint(exec_ctx, t); - } - - unlock(exec_ctx, t); - - UNREF_TRANSPORT(exec_ctx, t, "writing"); - - GPR_TIMER_END("grpc_chttp2_terminate_writing", 0); -} - -static void writing_action(grpc_exec_ctx *exec_ctx, void *gt, - bool iomgr_success_ignored) { - grpc_chttp2_transport *t = gt; - GPR_TIMER_BEGIN("writing_action", 0); - grpc_chttp2_perform_writes(exec_ctx, &t->writing, t->ep); - GPR_TIMER_END("writing_action", 0); -} - -void grpc_chttp2_add_incoming_goaway( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - uint32_t goaway_error, gpr_slice goaway_text) { - char *msg = gpr_dump_slice(goaway_text, GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg); - gpr_free(msg); - gpr_slice_unref(goaway_text); - transport_global->seen_goaway = 1; - connectivity_state_set(exec_ctx, transport_global, GRPC_CHANNEL_FATAL_FAILURE, - "got_goaway"); -} - -static void maybe_start_some_streams( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global) { - grpc_chttp2_stream_global *stream_global; - uint32_t stream_incoming_window; - /* start streams where we have free grpc_chttp2_stream ids and free - * concurrency */ - while (transport_global->next_stream_id <= MAX_CLIENT_STREAM_ID && - transport_global->concurrent_stream_count < - transport_global - ->settings[GRPC_PEER_SETTINGS] - [GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS] && - grpc_chttp2_list_pop_waiting_for_concurrency(transport_global, - &stream_global)) { - /* safe since we can't (legally) be parsing this stream yet */ - grpc_chttp2_stream_parsing *stream_parsing = - &STREAM_FROM_GLOBAL(stream_global)->parsing; - GRPC_CHTTP2_IF_TRACING(gpr_log( - GPR_DEBUG, "HTTP:%s: Allocating new grpc_chttp2_stream %p to id %d", - transport_global->is_client ? "CLI" : "SVR", stream_global, - transport_global->next_stream_id)); - - GPR_ASSERT(stream_global->id == 0); - stream_global->id = stream_parsing->id = transport_global->next_stream_id; - transport_global->next_stream_id += 2; - - if (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID) { - connectivity_state_set(exec_ctx, transport_global, - GRPC_CHANNEL_TRANSIENT_FAILURE, - "no_more_stream_ids"); - } - - stream_global->outgoing_window = - transport_global->settings[GRPC_PEER_SETTINGS] - [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; - stream_parsing->incoming_window = stream_incoming_window = - transport_global->settings[GRPC_SENT_SETTINGS] - [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; - stream_global->max_recv_bytes = - GPR_MAX(stream_incoming_window, stream_global->max_recv_bytes); - grpc_chttp2_stream_map_add( - &TRANSPORT_FROM_GLOBAL(transport_global)->new_stream_map, - stream_global->id, STREAM_FROM_GLOBAL(stream_global)); - stream_global->in_stream_map = 1; - transport_global->concurrent_stream_count++; - grpc_chttp2_become_writable(transport_global, stream_global); - } - /* cancel out streams that will never be started */ - while (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID && - grpc_chttp2_list_pop_waiting_for_concurrency(transport_global, - &stream_global)) { - cancel_from_api(exec_ctx, transport_global, stream_global, - GRPC_STATUS_UNAVAILABLE); - } -} - -static grpc_closure *add_closure_barrier(grpc_closure *closure) { - closure->final_data += 2; - return closure; -} - -void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, - grpc_closure **pclosure, int success) { - grpc_closure *closure = *pclosure; - if (closure == NULL) { - return; - } - closure->final_data -= 2; - if (!success) { - closure->final_data |= 1; - } - if (closure->final_data < 2) { - grpc_exec_ctx_enqueue(exec_ctx, closure, closure->final_data == 0, NULL); - } - *pclosure = NULL; -} - -static int contains_non_ok_status( - grpc_chttp2_transport_global *transport_global, - grpc_metadata_batch *batch) { - grpc_linked_mdelem *l; - for (l = batch->list.head; l; l = l->next) { - if (l->md->key == GRPC_MDSTR_GRPC_STATUS && - l->md != GRPC_MDELEM_GRPC_STATUS_0) { - return 1; - } - } - return 0; -} - -static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, bool success) {} - -static void perform_stream_op_locked( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, grpc_transport_stream_op *op) { - grpc_closure *on_complete; - - GPR_TIMER_BEGIN("perform_stream_op_locked", 0); - - on_complete = op->on_complete; - if (on_complete == NULL) { - on_complete = grpc_closure_create(do_nothing, NULL); - } - /* use final_data as a barrier until enqueue time; the inital counter is - dropped at the end of this function */ - on_complete->final_data = 2; - - if (op->cancel_with_status != GRPC_STATUS_OK) { - cancel_from_api(exec_ctx, transport_global, stream_global, - op->cancel_with_status); - } - - if (op->close_with_status != GRPC_STATUS_OK) { - close_from_api(exec_ctx, transport_global, stream_global, - op->close_with_status, op->optional_close_message); - } - - if (op->send_initial_metadata != NULL) { - GPR_ASSERT(stream_global->send_initial_metadata_finished == NULL); - stream_global->send_initial_metadata_finished = - add_closure_barrier(on_complete); - stream_global->send_initial_metadata = op->send_initial_metadata; - if (contains_non_ok_status(transport_global, op->send_initial_metadata)) { - stream_global->seen_error = 1; - grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); - } - if (!stream_global->write_closed) { - if (transport_global->is_client) { - GPR_ASSERT(stream_global->id == 0); - grpc_chttp2_list_add_waiting_for_concurrency(transport_global, - stream_global); - maybe_start_some_streams(exec_ctx, transport_global); - } else { - GPR_ASSERT(stream_global->id != 0); - grpc_chttp2_become_writable(transport_global, stream_global); - } - } else { - grpc_chttp2_complete_closure_step( - exec_ctx, &stream_global->send_initial_metadata_finished, 0); - } - } - - if (op->send_message != NULL) { - GPR_ASSERT(stream_global->send_message_finished == NULL); - GPR_ASSERT(stream_global->send_message == NULL); - stream_global->send_message_finished = add_closure_barrier(on_complete); - if (stream_global->write_closed) { - grpc_chttp2_complete_closure_step( - exec_ctx, &stream_global->send_message_finished, 0); - } else { - stream_global->send_message = op->send_message; - if (stream_global->id != 0) { - grpc_chttp2_become_writable(transport_global, stream_global); - } - } - } - - if (op->send_trailing_metadata != NULL) { - GPR_ASSERT(stream_global->send_trailing_metadata_finished == NULL); - stream_global->send_trailing_metadata_finished = - add_closure_barrier(on_complete); - stream_global->send_trailing_metadata = op->send_trailing_metadata; - if (contains_non_ok_status(transport_global, op->send_trailing_metadata)) { - stream_global->seen_error = 1; - grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); - } - if (stream_global->write_closed) { - grpc_chttp2_complete_closure_step( - exec_ctx, &stream_global->send_trailing_metadata_finished, - grpc_metadata_batch_is_empty(op->send_trailing_metadata)); - } else if (stream_global->id != 0) { - /* TODO(ctiller): check if there's flow control for any outstanding - bytes before going writable */ - grpc_chttp2_become_writable(transport_global, stream_global); - } - } - - if (op->recv_initial_metadata != NULL) { - GPR_ASSERT(stream_global->recv_initial_metadata_ready == NULL); - stream_global->recv_initial_metadata_ready = - op->recv_initial_metadata_ready; - stream_global->recv_initial_metadata = op->recv_initial_metadata; - grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); - } - - if (op->recv_message != NULL) { - GPR_ASSERT(stream_global->recv_message_ready == NULL); - stream_global->recv_message_ready = op->recv_message_ready; - stream_global->recv_message = op->recv_message; - if (stream_global->id != 0 && - (stream_global->incoming_frames.head == NULL || - stream_global->incoming_frames.head->is_tail)) { - incoming_byte_stream_update_flow_control( - transport_global, stream_global, transport_global->stream_lookahead, - 0); - } - grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); - } - - if (op->recv_trailing_metadata != NULL) { - GPR_ASSERT(stream_global->recv_trailing_metadata_finished == NULL); - stream_global->recv_trailing_metadata_finished = - add_closure_barrier(on_complete); - stream_global->recv_trailing_metadata = op->recv_trailing_metadata; - grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); - } - - grpc_chttp2_complete_closure_step(exec_ctx, &on_complete, 1); - - GPR_TIMER_END("perform_stream_op_locked", 0); -} - -static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_stream *gs, grpc_transport_stream_op *op) { - grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; - - lock(t); - perform_stream_op_locked(exec_ctx, &t->global, &s->global, op); - unlock(exec_ctx, t); -} - -static void send_ping_locked(grpc_chttp2_transport *t, grpc_closure *on_recv) { - grpc_chttp2_outstanding_ping *p = gpr_malloc(sizeof(*p)); - p->next = &t->global.pings; - p->prev = p->next->prev; - p->prev->next = p->next->prev = p; - p->id[0] = (uint8_t)((t->global.ping_counter >> 56) & 0xff); - p->id[1] = (uint8_t)((t->global.ping_counter >> 48) & 0xff); - p->id[2] = (uint8_t)((t->global.ping_counter >> 40) & 0xff); - p->id[3] = (uint8_t)((t->global.ping_counter >> 32) & 0xff); - p->id[4] = (uint8_t)((t->global.ping_counter >> 24) & 0xff); - p->id[5] = (uint8_t)((t->global.ping_counter >> 16) & 0xff); - p->id[6] = (uint8_t)((t->global.ping_counter >> 8) & 0xff); - p->id[7] = (uint8_t)(t->global.ping_counter & 0xff); - p->on_recv = on_recv; - gpr_slice_buffer_add(&t->global.qbuf, grpc_chttp2_ping_create(0, p->id)); -} - -void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *transport_parsing, - const uint8_t *opaque_8bytes) { - grpc_chttp2_outstanding_ping *ping; - grpc_chttp2_transport *t = TRANSPORT_FROM_PARSING(transport_parsing); - grpc_chttp2_transport_global *transport_global = &t->global; - lock(t); - for (ping = transport_global->pings.next; ping != &transport_global->pings; - ping = ping->next) { - if (0 == memcmp(opaque_8bytes, ping->id, 8)) { - grpc_exec_ctx_enqueue(exec_ctx, ping->on_recv, true, NULL); - ping->next->prev = ping->prev; - ping->prev->next = ping->next; - gpr_free(ping); - break; - } - } - unlock(exec_ctx, t); -} - -static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, - grpc_transport_op *op) { - bool close_transport = false; - - grpc_exec_ctx_enqueue(exec_ctx, op->on_consumed, true, NULL); - - if (op->on_connectivity_state_change != NULL) { - grpc_connectivity_state_notify_on_state_change( - exec_ctx, &t->channel_callback.state_tracker, op->connectivity_state, - op->on_connectivity_state_change); - } - - if (op->send_goaway) { - t->global.sent_goaway = 1; - grpc_chttp2_goaway_append( - t->global.last_incoming_stream_id, - (uint32_t)grpc_chttp2_grpc_status_to_http2_error(op->goaway_status), - gpr_slice_ref(*op->goaway_message), &t->global.qbuf); - close_transport = !grpc_chttp2_has_streams(t); - } - - if (op->set_accept_stream) { - t->channel_callback.accept_stream = op->set_accept_stream_fn; - t->channel_callback.accept_stream_user_data = - op->set_accept_stream_user_data; - } - - if (op->bind_pollset) { - add_to_pollset_locked(exec_ctx, t, op->bind_pollset); - } - - if (op->bind_pollset_set) { - add_to_pollset_set_locked(exec_ctx, t, op->bind_pollset_set); - } - - if (op->send_ping) { - send_ping_locked(t, op->send_ping); - } - - if (op->disconnect) { - close_transport_locked(exec_ctx, t); - } - - if (close_transport) { - close_transport_locked(exec_ctx, t); - } -} - -static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_transport_op *op) { - grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - - lock(t); - - /* If there's a set_accept_stream ensure that we're not parsing - to avoid changing things out from underneath */ - if (t->parsing_active && op->set_accept_stream) { - GPR_ASSERT(t->post_parsing_op == NULL); - t->post_parsing_op = gpr_malloc(sizeof(*op)); - memcpy(t->post_parsing_op, op, sizeof(*op)); - } else { - perform_transport_op_locked(exec_ctx, t, op); - } - - unlock(exec_ctx, t); -} - -/******************************************************************************* - * INPUT PROCESSING - */ - -static void check_read_ops(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global) { - grpc_chttp2_stream_global *stream_global; - grpc_byte_stream *bs; - while ( - grpc_chttp2_list_pop_check_read_ops(transport_global, &stream_global)) { - if (stream_global->recv_initial_metadata_ready != NULL && - stream_global->published_initial_metadata) { - grpc_chttp2_incoming_metadata_buffer_publish( - &stream_global->received_initial_metadata, - stream_global->recv_initial_metadata); - grpc_exec_ctx_enqueue( - exec_ctx, stream_global->recv_initial_metadata_ready, true, NULL); - stream_global->recv_initial_metadata_ready = NULL; - } - if (stream_global->recv_message_ready != NULL) { - while (stream_global->seen_error && - (bs = grpc_chttp2_incoming_frame_queue_pop( - &stream_global->incoming_frames)) != NULL) { - grpc_byte_stream_destroy(exec_ctx, bs); - } - if (stream_global->incoming_frames.head != NULL) { - *stream_global->recv_message = grpc_chttp2_incoming_frame_queue_pop( - &stream_global->incoming_frames); - GPR_ASSERT(*stream_global->recv_message != NULL); - grpc_exec_ctx_enqueue(exec_ctx, stream_global->recv_message_ready, true, - NULL); - stream_global->recv_message_ready = NULL; - } else if (stream_global->published_trailing_metadata) { - *stream_global->recv_message = NULL; - grpc_exec_ctx_enqueue(exec_ctx, stream_global->recv_message_ready, true, - NULL); - stream_global->recv_message_ready = NULL; - } - } - if (stream_global->recv_trailing_metadata_finished != NULL && - stream_global->read_closed && stream_global->write_closed) { - while (stream_global->seen_error && - (bs = grpc_chttp2_incoming_frame_queue_pop( - &stream_global->incoming_frames)) != NULL) { - grpc_byte_stream_destroy(exec_ctx, bs); - } - if (stream_global->incoming_frames.head == NULL) { - grpc_chttp2_incoming_metadata_buffer_publish( - &stream_global->received_trailing_metadata, - stream_global->recv_trailing_metadata); - grpc_chttp2_complete_closure_step( - exec_ctx, &stream_global->recv_trailing_metadata_finished, 1); - } - } - } -} - -static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, - uint32_t id) { - size_t new_stream_count; - grpc_chttp2_stream *s = - grpc_chttp2_stream_map_delete(&t->parsing_stream_map, id); - if (!s) { - s = grpc_chttp2_stream_map_delete(&t->new_stream_map, id); - } - GPR_ASSERT(s); - s->global.in_stream_map = 0; - if (t->parsing.incoming_stream == &s->parsing) { - t->parsing.incoming_stream = NULL; - grpc_chttp2_parsing_become_skip_parser(exec_ctx, &t->parsing); - } - if (s->parsing.data_parser.parsing_frame != NULL) { - grpc_chttp2_incoming_byte_stream_finished( - exec_ctx, s->parsing.data_parser.parsing_frame, 0, 0); - s->parsing.data_parser.parsing_frame = NULL; - } - - if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) { - close_transport_locked(exec_ctx, t); - } - if (grpc_chttp2_list_remove_writable_stream(&t->global, &s->global)) { - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &s->global, "chttp2_writing"); - } - - new_stream_count = grpc_chttp2_stream_map_size(&t->parsing_stream_map) + - grpc_chttp2_stream_map_size(&t->new_stream_map); - GPR_ASSERT(new_stream_count <= UINT32_MAX); - if (new_stream_count != t->global.concurrent_stream_count) { - t->global.concurrent_stream_count = (uint32_t)new_stream_count; - maybe_start_some_streams(exec_ctx, &t->global); - } -} - -static void cancel_from_api(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, - grpc_status_code status) { - if (stream_global->id != 0) { - gpr_slice_buffer_add( - &transport_global->qbuf, - grpc_chttp2_rst_stream_create( - stream_global->id, - (uint32_t)grpc_chttp2_grpc_status_to_http2_error(status))); - } - grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status, - NULL); - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1, - 1); -} - -void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, - grpc_status_code status, gpr_slice *slice) { - if (status != GRPC_STATUS_OK) { - stream_global->seen_error = 1; - grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); - } - /* stream_global->recv_trailing_metadata_finished gives us a - last chance replacement: we've received trailing metadata, - but something more important has become available to signal - to the upper layers - drop what we've got, and then publish - what we want - which is safe because we haven't told anyone - about the metadata yet */ - if (!stream_global->published_trailing_metadata || - stream_global->recv_trailing_metadata_finished != NULL) { - char status_string[GPR_LTOA_MIN_BUFSIZE]; - gpr_ltoa(status, status_string); - grpc_chttp2_incoming_metadata_buffer_add( - &stream_global->received_trailing_metadata, - grpc_mdelem_from_metadata_strings( - GRPC_MDSTR_GRPC_STATUS, grpc_mdstr_from_string(status_string))); - if (slice) { - grpc_chttp2_incoming_metadata_buffer_add( - &stream_global->received_trailing_metadata, - grpc_mdelem_from_metadata_strings( - GRPC_MDSTR_GRPC_MESSAGE, - grpc_mdstr_from_slice(gpr_slice_ref(*slice)))); - } - stream_global->published_trailing_metadata = 1; - grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); - } - if (slice) { - gpr_slice_unref(*slice); - } -} - -static void fail_pending_writes(grpc_exec_ctx *exec_ctx, - grpc_chttp2_stream_global *stream_global) { - grpc_chttp2_complete_closure_step( - exec_ctx, &stream_global->send_initial_metadata_finished, 0); - grpc_chttp2_complete_closure_step( - exec_ctx, &stream_global->send_trailing_metadata_finished, 0); - grpc_chttp2_complete_closure_step(exec_ctx, - &stream_global->send_message_finished, 0); -} - -void grpc_chttp2_mark_stream_closed( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, int close_reads, - int close_writes) { - if (stream_global->read_closed && stream_global->write_closed) { - /* already closed */ - return; - } - grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); - if (close_reads && !stream_global->read_closed) { - stream_global->read_closed = 1; - stream_global->published_initial_metadata = 1; - stream_global->published_trailing_metadata = 1; - } - if (close_writes && !stream_global->write_closed) { - stream_global->write_closed = 1; - if (TRANSPORT_FROM_GLOBAL(transport_global)->writing_active) { - GRPC_CHTTP2_STREAM_REF(stream_global, "finish_writes"); - grpc_chttp2_list_add_closed_waiting_for_writing(transport_global, - stream_global); - } else { - fail_pending_writes(exec_ctx, stream_global); - } - } - if (stream_global->read_closed && stream_global->write_closed) { - if (stream_global->id != 0 && - TRANSPORT_FROM_GLOBAL(transport_global)->parsing_active) { - grpc_chttp2_list_add_closed_waiting_for_parsing(transport_global, - stream_global); - } else { - if (stream_global->id != 0) { - remove_stream(exec_ctx, TRANSPORT_FROM_GLOBAL(transport_global), - stream_global->id); - } - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); - } - } -} - -static void close_from_api(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, - grpc_status_code status, - gpr_slice *optional_message) { - gpr_slice hdr; - gpr_slice status_hdr; - gpr_slice message_pfx; - uint8_t *p; - uint32_t len = 0; - - GPR_ASSERT(status >= 0 && (int)status < 100); - - GPR_ASSERT(stream_global->id != 0); - - /* Hand roll a header block. - This is unnecessarily ugly - at some point we should find a more elegant - solution. - It's complicated by the fact that our send machinery would be dead by the - time we got around to sending this, so instead we ignore HPACK compression - and just write the uncompressed bytes onto the wire. */ - status_hdr = gpr_slice_malloc(15 + (status >= 10)); - p = GPR_SLICE_START_PTR(status_hdr); - *p++ = 0x40; /* literal header */ - *p++ = 11; /* len(grpc-status) */ - *p++ = 'g'; - *p++ = 'r'; - *p++ = 'p'; - *p++ = 'c'; - *p++ = '-'; - *p++ = 's'; - *p++ = 't'; - *p++ = 'a'; - *p++ = 't'; - *p++ = 'u'; - *p++ = 's'; - if (status < 10) { - *p++ = 1; - *p++ = (uint8_t)('0' + status); - } else { - *p++ = 2; - *p++ = (uint8_t)('0' + (status / 10)); - *p++ = (uint8_t)('0' + (status % 10)); - } - GPR_ASSERT(p == GPR_SLICE_END_PTR(status_hdr)); - len += (uint32_t)GPR_SLICE_LENGTH(status_hdr); - - if (optional_message) { - GPR_ASSERT(GPR_SLICE_LENGTH(*optional_message) < 127); - message_pfx = gpr_slice_malloc(15); - p = GPR_SLICE_START_PTR(message_pfx); - *p++ = 0x40; - *p++ = 12; /* len(grpc-message) */ - *p++ = 'g'; - *p++ = 'r'; - *p++ = 'p'; - *p++ = 'c'; - *p++ = '-'; - *p++ = 'm'; - *p++ = 'e'; - *p++ = 's'; - *p++ = 's'; - *p++ = 'a'; - *p++ = 'g'; - *p++ = 'e'; - *p++ = (uint8_t)GPR_SLICE_LENGTH(*optional_message); - GPR_ASSERT(p == GPR_SLICE_END_PTR(message_pfx)); - len += (uint32_t)GPR_SLICE_LENGTH(message_pfx); - len += (uint32_t)GPR_SLICE_LENGTH(*optional_message); - } - - hdr = gpr_slice_malloc(9); - p = GPR_SLICE_START_PTR(hdr); - *p++ = (uint8_t)(len >> 16); - *p++ = (uint8_t)(len >> 8); - *p++ = (uint8_t)(len); - *p++ = GRPC_CHTTP2_FRAME_HEADER; - *p++ = GRPC_CHTTP2_DATA_FLAG_END_STREAM | GRPC_CHTTP2_DATA_FLAG_END_HEADERS; - *p++ = (uint8_t)(stream_global->id >> 24); - *p++ = (uint8_t)(stream_global->id >> 16); - *p++ = (uint8_t)(stream_global->id >> 8); - *p++ = (uint8_t)(stream_global->id); - GPR_ASSERT(p == GPR_SLICE_END_PTR(hdr)); - - gpr_slice_buffer_add(&transport_global->qbuf, hdr); - gpr_slice_buffer_add(&transport_global->qbuf, status_hdr); - if (optional_message) { - gpr_slice_buffer_add(&transport_global->qbuf, message_pfx); - gpr_slice_buffer_add(&transport_global->qbuf, - gpr_slice_ref(*optional_message)); - } - - gpr_slice_buffer_add( - &transport_global->qbuf, - grpc_chttp2_rst_stream_create(stream_global->id, GRPC_CHTTP2_NO_ERROR)); - - if (optional_message) { - gpr_slice_ref(*optional_message); - } - grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status, - optional_message); - grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1, - 1); -} - -static void cancel_stream_cb(grpc_chttp2_transport_global *transport_global, - void *user_data, - grpc_chttp2_stream_global *stream_global) { - cancel_from_api(user_data, transport_global, stream_global, - GRPC_STATUS_UNAVAILABLE); -} - -static void end_all_the_calls(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t) { - grpc_chttp2_for_all_streams(&t->global, exec_ctx, cancel_stream_cb); -} - -static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { - close_transport_locked(exec_ctx, t); - end_all_the_calls(exec_ctx, t); -} - -/** update window from a settings change */ -static void update_global_window(void *args, uint32_t id, void *stream) { - grpc_chttp2_transport *t = args; - grpc_chttp2_stream *s = stream; - grpc_chttp2_transport_global *transport_global = &t->global; - grpc_chttp2_stream_global *stream_global = &s->global; - int was_zero; - int is_zero; - int64_t initial_window_update = t->parsing.initial_window_update; - - was_zero = stream_global->outgoing_window <= 0; - GRPC_CHTTP2_FLOW_CREDIT_STREAM("settings", transport_global, stream_global, - outgoing_window, initial_window_update); - is_zero = stream_global->outgoing_window <= 0; - - if (was_zero && !is_zero) { - grpc_chttp2_become_writable(transport_global, stream_global); - } -} - -static void read_error_locked(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t) { - t->endpoint_reading = 0; - if (!t->writing_active && t->ep) { - destroy_endpoint(exec_ctx, t); - } -} - -/* tcp read callback */ -static void recv_data(grpc_exec_ctx *exec_ctx, void *tp, bool success) { - size_t i; - int keep_reading = 0; - grpc_chttp2_transport *t = tp; - grpc_chttp2_transport_global *transport_global = &t->global; - grpc_chttp2_transport_parsing *transport_parsing = &t->parsing; - grpc_chttp2_stream_global *stream_global; - - GPR_TIMER_BEGIN("recv_data", 0); - - lock(t); - i = 0; - GPR_ASSERT(!t->parsing_active); - if (!t->closed) { - t->parsing_active = 1; - /* merge stream lists */ - grpc_chttp2_stream_map_move_into(&t->new_stream_map, - &t->parsing_stream_map); - grpc_chttp2_prepare_to_read(transport_global, transport_parsing); - gpr_mu_unlock(&t->mu); - GPR_TIMER_BEGIN("recv_data.parse", 0); - for (; i < t->read_buffer.count && - grpc_chttp2_perform_read(exec_ctx, transport_parsing, - t->read_buffer.slices[i]); - i++) - ; - GPR_TIMER_END("recv_data.parse", 0); - gpr_mu_lock(&t->mu); - /* copy parsing qbuf to global qbuf */ - gpr_slice_buffer_move_into(&t->parsing.qbuf, &t->global.qbuf); - if (i != t->read_buffer.count) { - unlock(exec_ctx, t); - lock(t); - drop_connection(exec_ctx, t); - } - /* merge stream lists */ - grpc_chttp2_stream_map_move_into(&t->new_stream_map, - &t->parsing_stream_map); - transport_global->concurrent_stream_count = - (uint32_t)grpc_chttp2_stream_map_size(&t->parsing_stream_map); - if (transport_parsing->initial_window_update != 0) { - grpc_chttp2_stream_map_for_each(&t->parsing_stream_map, - update_global_window, t); - transport_parsing->initial_window_update = 0; - } - /* handle higher level things */ - grpc_chttp2_publish_reads(exec_ctx, transport_global, transport_parsing); - t->parsing_active = 0; - /* handle delayed transport ops (if there is one) */ - if (t->post_parsing_op) { - grpc_transport_op *op = t->post_parsing_op; - t->post_parsing_op = NULL; - perform_transport_op_locked(exec_ctx, t, op); - gpr_free(op); - } - /* if a stream is in the stream map, and gets cancelled, we need to ensure - * we are not parsing before continuing the cancellation to keep things in - * a sane state */ - while (grpc_chttp2_list_pop_closed_waiting_for_parsing(transport_global, - &stream_global)) { - GPR_ASSERT(stream_global->in_stream_map); - GPR_ASSERT(stream_global->write_closed); - GPR_ASSERT(stream_global->read_closed); - remove_stream(exec_ctx, t, stream_global->id); - GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); - } - } - if (!success || i != t->read_buffer.count || t->closed) { - drop_connection(exec_ctx, t); - read_error_locked(exec_ctx, t); - } else if (!t->closed) { - keep_reading = 1; - REF_TRANSPORT(t, "keep_reading"); - prevent_endpoint_shutdown(t); - } - gpr_slice_buffer_reset_and_unref(&t->read_buffer); - unlock(exec_ctx, t); - - if (keep_reading) { - grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, &t->recv_data); - allow_endpoint_shutdown_unlocked(exec_ctx, t); - UNREF_TRANSPORT(exec_ctx, t, "keep_reading"); - } else { - UNREF_TRANSPORT(exec_ctx, t, "recv_data"); - } - - GPR_TIMER_END("recv_data", 0); -} - -/******************************************************************************* - * CALLBACK LOOP - */ - -static void connectivity_state_set( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, - grpc_connectivity_state state, const char *reason) { - GRPC_CHTTP2_IF_TRACING( - gpr_log(GPR_DEBUG, "set connectivity_state=%d", state)); - grpc_connectivity_state_set( - exec_ctx, - &TRANSPORT_FROM_GLOBAL(transport_global)->channel_callback.state_tracker, - state, reason); -} - -/******************************************************************************* - * POLLSET STUFF - */ - -static void add_to_pollset_locked(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, - grpc_pollset *pollset) { - if (t->ep) { - grpc_endpoint_add_to_pollset(exec_ctx, t->ep, pollset); - } -} - -static void add_to_pollset_set_locked(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, - grpc_pollset_set *pollset_set) { - if (t->ep) { - grpc_endpoint_add_to_pollset_set(exec_ctx, t->ep, pollset_set); - } -} - -static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_stream *gs, grpc_pollset *pollset) { - grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; - lock(t); - add_to_pollset_locked(exec_ctx, t, pollset); - unlock(exec_ctx, t); -} - -/******************************************************************************* - * BYTE STREAM - */ - -static void incoming_byte_stream_update_flow_control( - grpc_chttp2_transport_global *transport_global, - grpc_chttp2_stream_global *stream_global, size_t max_size_hint, - size_t have_already) { - uint32_t max_recv_bytes; - - /* clamp max recv hint to an allowable size */ - if (max_size_hint >= UINT32_MAX - transport_global->stream_lookahead) { - max_recv_bytes = UINT32_MAX - transport_global->stream_lookahead; - } else { - max_recv_bytes = (uint32_t)max_size_hint; - } - - /* account for bytes already received but unknown to higher layers */ - if (max_recv_bytes >= have_already) { - max_recv_bytes -= (uint32_t)have_already; - } else { - max_recv_bytes = 0; - } - - /* add some small lookahead to keep pipelines flowing */ - GPR_ASSERT(max_recv_bytes <= UINT32_MAX - transport_global->stream_lookahead); - max_recv_bytes += transport_global->stream_lookahead; - if (stream_global->max_recv_bytes < max_recv_bytes) { - uint32_t add_max_recv_bytes = - max_recv_bytes - stream_global->max_recv_bytes; - GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", transport_global, stream_global, - max_recv_bytes, add_max_recv_bytes); - GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", transport_global, stream_global, - unannounced_incoming_window_for_parse, - add_max_recv_bytes); - GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", transport_global, stream_global, - unannounced_incoming_window_for_writing, - add_max_recv_bytes); - grpc_chttp2_list_add_unannounced_incoming_window_available(transport_global, - stream_global); - grpc_chttp2_become_writable(transport_global, stream_global); - } -} - -static int incoming_byte_stream_next(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream, - gpr_slice *slice, size_t max_size_hint, - grpc_closure *on_complete) { - grpc_chttp2_incoming_byte_stream *bs = - (grpc_chttp2_incoming_byte_stream *)byte_stream; - grpc_chttp2_transport_global *transport_global = &bs->transport->global; - grpc_chttp2_stream_global *stream_global = &bs->stream->global; - - lock(bs->transport); - if (bs->is_tail) { - incoming_byte_stream_update_flow_control(transport_global, stream_global, - max_size_hint, bs->slices.length); - } - if (bs->slices.count > 0) { - *slice = gpr_slice_buffer_take_first(&bs->slices); - unlock(exec_ctx, bs->transport); - return 1; - } else if (bs->failed) { - grpc_exec_ctx_enqueue(exec_ctx, on_complete, false, NULL); - unlock(exec_ctx, bs->transport); - return 0; - } else { - bs->on_next = on_complete; - bs->next = slice; - unlock(exec_ctx, bs->transport); - return 0; - } -} - -static void incoming_byte_stream_unref(grpc_chttp2_incoming_byte_stream *bs) { - if (gpr_unref(&bs->refs)) { - gpr_slice_buffer_destroy(&bs->slices); - gpr_free(bs); - } -} - -static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx, - grpc_byte_stream *byte_stream) { - incoming_byte_stream_unref((grpc_chttp2_incoming_byte_stream *)byte_stream); -} - -void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, - grpc_chttp2_incoming_byte_stream *bs, - gpr_slice slice) { - gpr_mu_lock(&bs->transport->mu); - if (bs->on_next != NULL) { - *bs->next = slice; - grpc_exec_ctx_enqueue(exec_ctx, bs->on_next, true, NULL); - bs->on_next = NULL; - } else { - gpr_slice_buffer_add(&bs->slices, slice); - } - gpr_mu_unlock(&bs->transport->mu); -} - -void grpc_chttp2_incoming_byte_stream_finished( - grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, int success, - int from_parsing_thread) { - if (!success) { - if (from_parsing_thread) { - gpr_mu_lock(&bs->transport->mu); - } - grpc_exec_ctx_enqueue(exec_ctx, bs->on_next, false, NULL); - bs->on_next = NULL; - bs->failed = 1; - if (from_parsing_thread) { - gpr_mu_unlock(&bs->transport->mu); - } - } else { -#ifndef NDEBUG - if (from_parsing_thread) { - gpr_mu_lock(&bs->transport->mu); - } - GPR_ASSERT(bs->on_next == NULL); - if (from_parsing_thread) { - gpr_mu_unlock(&bs->transport->mu); - } -#endif - } - incoming_byte_stream_unref(bs); -} - -grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create( - grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, - grpc_chttp2_stream_parsing *stream_parsing, uint32_t frame_size, - uint32_t flags, grpc_chttp2_incoming_frame_queue *add_to_queue) { - grpc_chttp2_incoming_byte_stream *incoming_byte_stream = - gpr_malloc(sizeof(*incoming_byte_stream)); - incoming_byte_stream->base.length = frame_size; - incoming_byte_stream->base.flags = flags; - incoming_byte_stream->base.next = incoming_byte_stream_next; - incoming_byte_stream->base.destroy = incoming_byte_stream_destroy; - gpr_ref_init(&incoming_byte_stream->refs, 2); - incoming_byte_stream->next_message = NULL; - incoming_byte_stream->transport = TRANSPORT_FROM_PARSING(transport_parsing); - incoming_byte_stream->stream = STREAM_FROM_PARSING(stream_parsing); - gpr_slice_buffer_init(&incoming_byte_stream->slices); - incoming_byte_stream->on_next = NULL; - incoming_byte_stream->is_tail = 1; - incoming_byte_stream->failed = 0; - if (add_to_queue->head == NULL) { - add_to_queue->head = incoming_byte_stream; - } else { - add_to_queue->tail->is_tail = 0; - add_to_queue->tail->next_message = incoming_byte_stream; - } - add_to_queue->tail = incoming_byte_stream; - return incoming_byte_stream; -} - -/******************************************************************************* - * TRACING - */ - -static char *format_flowctl_context_var(const char *context, const char *var, - int64_t val, uint32_t id, - char **scope) { - char *underscore_pos; - char *result; - if (context == NULL) { - *scope = NULL; - gpr_asprintf(&result, "%s(%lld)", var, val); - return result; - } - underscore_pos = strchr(context, '_'); - *scope = gpr_strdup(context); - (*scope)[underscore_pos - context] = 0; - if (id != 0) { - char *tmp = *scope; - gpr_asprintf(scope, "%s[%d]", tmp, id); - gpr_free(tmp); - } - gpr_asprintf(&result, "%s.%s(%lld)", underscore_pos + 1, var, val); - return result; -} - -static int samestr(char *a, char *b) { - if (a == NULL) { - return b == NULL; - } - if (b == NULL) { - return 0; - } - return 0 == strcmp(a, b); -} - -void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase, - grpc_chttp2_flowctl_op op, const char *context1, - const char *var1, const char *context2, - const char *var2, int is_client, - uint32_t stream_id, int64_t val1, int64_t val2) { - char *scope1; - char *scope2; - char *label1 = - format_flowctl_context_var(context1, var1, val1, stream_id, &scope1); - char *label2 = - format_flowctl_context_var(context2, var2, val2, stream_id, &scope2); - char *clisvr = is_client ? "client" : "server"; - char *prefix; - - gpr_asprintf(&prefix, "FLOW % 8s: %s % 11s ", phase, clisvr, scope1); - - switch (op) { - case GRPC_CHTTP2_FLOWCTL_MOVE: - GPR_ASSERT(samestr(scope1, scope2)); - if (val2 != 0) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "%sMOVE % 40s <- % 40s giving %d", prefix, label1, label2, - val1 + val2); - } - break; - case GRPC_CHTTP2_FLOWCTL_CREDIT: - GPR_ASSERT(val2 >= 0); - if (val2 != 0) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "%sCREDIT % 40s by % 40s giving %d", prefix, label1, label2, - val1 + val2); - } - break; - case GRPC_CHTTP2_FLOWCTL_DEBIT: - GPR_ASSERT(val2 >= 0); - if (val2 != 0) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "%sDEBIT % 40s by % 40s giving %d", prefix, label1, label2, - val1 - val2); - } - break; - } - - gpr_free(scope1); - gpr_free(scope2); - gpr_free(label1); - gpr_free(label2); - gpr_free(prefix); -} - -/******************************************************************************* - * INTEGRATION GLUE - */ - -static char *chttp2_get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *t) { - return gpr_strdup(((grpc_chttp2_transport *)t)->peer_string); -} - -static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), - "chttp2", - init_stream, - set_pollset, - perform_stream_op, - perform_transport_op, - destroy_stream, - destroy_transport, - chttp2_get_peer}; - -grpc_transport *grpc_create_chttp2_transport( - grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args, - grpc_endpoint *ep, int is_client) { - grpc_chttp2_transport *t = gpr_malloc(sizeof(grpc_chttp2_transport)); - init_transport(exec_ctx, t, channel_args, ep, is_client != 0); - return &t->base; -} - -void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, - grpc_transport *transport, - gpr_slice *slices, size_t nslices) { - grpc_chttp2_transport *t = (grpc_chttp2_transport *)transport; - REF_TRANSPORT(t, "recv_data"); /* matches unref inside recv_data */ - gpr_slice_buffer_addn(&t->read_buffer, slices, nslices); - recv_data(exec_ctx, t, 1); -} diff --git a/src/core/transport/chttp2_transport.h b/src/core/transport/chttp2_transport.h deleted file mode 100644 index 9a6cf0ed35..0000000000 --- a/src/core/transport/chttp2_transport.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CHTTP2_TRANSPORT_H -#define GRPC_CORE_TRANSPORT_CHTTP2_TRANSPORT_H - -#include "src/core/iomgr/endpoint.h" -#include "src/core/transport/transport.h" - -extern int grpc_http_trace; -extern int grpc_flowctl_trace; - -grpc_transport *grpc_create_chttp2_transport( - grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args, - grpc_endpoint *ep, int is_client); - -void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, - grpc_transport *transport, - gpr_slice *slices, size_t nslices); - -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_TRANSPORT_H */ diff --git a/src/core/transport/connectivity_state.c b/src/core/transport/connectivity_state.c deleted file mode 100644 index 87765b9799..0000000000 --- a/src/core/transport/connectivity_state.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * - * Copyright 2015-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/transport/connectivity_state.h" - -#include - -#include -#include -#include - -int grpc_connectivity_state_trace = 0; - -const char *grpc_connectivity_state_name(grpc_connectivity_state state) { - switch (state) { - case GRPC_CHANNEL_IDLE: - return "IDLE"; - case GRPC_CHANNEL_CONNECTING: - return "CONNECTING"; - case GRPC_CHANNEL_READY: - return "READY"; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - return "TRANSIENT_FAILURE"; - case GRPC_CHANNEL_FATAL_FAILURE: - return "FATAL_FAILURE"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker, - grpc_connectivity_state init_state, - const char *name) { - tracker->current_state = init_state; - tracker->watchers = NULL; - tracker->name = gpr_strdup(name); -} - -void grpc_connectivity_state_destroy(grpc_exec_ctx *exec_ctx, - grpc_connectivity_state_tracker *tracker) { - int success; - grpc_connectivity_state_watcher *w; - while ((w = tracker->watchers)) { - tracker->watchers = w->next; - - if (GRPC_CHANNEL_FATAL_FAILURE != *w->current) { - *w->current = GRPC_CHANNEL_FATAL_FAILURE; - success = 1; - } else { - success = 0; - } - grpc_exec_ctx_enqueue(exec_ctx, w->notify, success, NULL); - gpr_free(w); - } - gpr_free(tracker->name); -} - -grpc_connectivity_state grpc_connectivity_state_check( - grpc_connectivity_state_tracker *tracker) { - if (grpc_connectivity_state_trace) { - gpr_log(GPR_DEBUG, "CONWATCH: %p %s: get %s", tracker, tracker->name, - grpc_connectivity_state_name(tracker->current_state)); - } - return tracker->current_state; -} - -int grpc_connectivity_state_notify_on_state_change( - grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker, - grpc_connectivity_state *current, grpc_closure *notify) { - if (grpc_connectivity_state_trace) { - if (current == NULL) { - gpr_log(GPR_DEBUG, "CONWATCH: %p %s: unsubscribe notify=%p", tracker, - tracker->name, notify); - } else { - gpr_log(GPR_DEBUG, "CONWATCH: %p %s: from %s [cur=%s] notify=%p", tracker, - tracker->name, grpc_connectivity_state_name(*current), - grpc_connectivity_state_name(tracker->current_state), notify); - } - } - if (current == NULL) { - grpc_connectivity_state_watcher *w = tracker->watchers; - if (w != NULL && w->notify == notify) { - grpc_exec_ctx_enqueue(exec_ctx, notify, false, NULL); - tracker->watchers = w->next; - gpr_free(w); - return 0; - } - while (w != NULL) { - grpc_connectivity_state_watcher *rm_candidate = w->next; - if (rm_candidate != NULL && rm_candidate->notify == notify) { - grpc_exec_ctx_enqueue(exec_ctx, notify, false, NULL); - w->next = w->next->next; - gpr_free(rm_candidate); - return 0; - } - w = w->next; - } - return 0; - } else { - if (tracker->current_state != *current) { - *current = tracker->current_state; - grpc_exec_ctx_enqueue(exec_ctx, notify, true, NULL); - } else { - grpc_connectivity_state_watcher *w = gpr_malloc(sizeof(*w)); - w->current = current; - w->notify = notify; - w->next = tracker->watchers; - tracker->watchers = w; - } - return tracker->current_state == GRPC_CHANNEL_IDLE; - } -} - -void grpc_connectivity_state_set(grpc_exec_ctx *exec_ctx, - grpc_connectivity_state_tracker *tracker, - grpc_connectivity_state state, - const char *reason) { - grpc_connectivity_state_watcher *w; - if (grpc_connectivity_state_trace) { - gpr_log(GPR_DEBUG, "SET: %p %s: %s --> %s [%s]", tracker, tracker->name, - grpc_connectivity_state_name(tracker->current_state), - grpc_connectivity_state_name(state), reason); - } - if (tracker->current_state == state) { - return; - } - GPR_ASSERT(tracker->current_state != GRPC_CHANNEL_FATAL_FAILURE); - tracker->current_state = state; - while ((w = tracker->watchers) != NULL) { - *w->current = tracker->current_state; - tracker->watchers = w->next; - grpc_exec_ctx_enqueue(exec_ctx, w->notify, true, NULL); - gpr_free(w); - } -} diff --git a/src/core/transport/connectivity_state.h b/src/core/transport/connectivity_state.h deleted file mode 100644 index b4a3ce924d..0000000000 --- a/src/core/transport/connectivity_state.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_CONNECTIVITY_STATE_H -#define GRPC_CORE_TRANSPORT_CONNECTIVITY_STATE_H - -#include -#include "src/core/iomgr/exec_ctx.h" - -typedef struct grpc_connectivity_state_watcher { - /** we keep watchers in a linked list */ - struct grpc_connectivity_state_watcher *next; - /** closure to notify on change */ - grpc_closure *notify; - /** the current state as believed by the watcher */ - grpc_connectivity_state *current; -} grpc_connectivity_state_watcher; - -typedef struct { - /** current connectivity state */ - grpc_connectivity_state current_state; - /** all our watchers */ - grpc_connectivity_state_watcher *watchers; - /** a name to help debugging */ - char *name; -} grpc_connectivity_state_tracker; - -extern int grpc_connectivity_state_trace; - -const char *grpc_connectivity_state_name(grpc_connectivity_state state); - -void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker, - grpc_connectivity_state init_state, - const char *name); -void grpc_connectivity_state_destroy(grpc_exec_ctx *exec_ctx, - grpc_connectivity_state_tracker *tracker); - -/** Set connectivity state; not thread safe; access must be serialized with an - * external lock */ -void grpc_connectivity_state_set(grpc_exec_ctx *exec_ctx, - grpc_connectivity_state_tracker *tracker, - grpc_connectivity_state state, - const char *reason); - -grpc_connectivity_state grpc_connectivity_state_check( - grpc_connectivity_state_tracker *tracker); - -/** Return 1 if the channel should start connecting, 0 otherwise. - If current==NULL cancel notify if it is already queued (success==0 in that - case) */ -int grpc_connectivity_state_notify_on_state_change( - grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker, - grpc_connectivity_state *current, grpc_closure *notify); - -#endif /* GRPC_CORE_TRANSPORT_CONNECTIVITY_STATE_H */ diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c deleted file mode 100644 index 7ed28feca8..0000000000 --- a/src/core/transport/metadata.c +++ /dev/null @@ -1,698 +0,0 @@ -/* - * - * Copyright 2015-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/transport/metadata.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/murmur_hash.h" -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/bin_encoder.h" -#include "src/core/transport/static_metadata.h" - -/* There are two kinds of mdelem and mdstr instances. - * Static instances are declared in static_metadata.{h,c} and - * are initialized by grpc_mdctx_global_init(). - * Dynamic instances are stored in hash tables on grpc_mdctx, and are backed - * by internal_string and internal_element structures. - * Internal helper functions here-in (is_mdstr_static, is_mdelem_static) are - * used to determine which kind of element a pointer refers to. - */ - -#define INITIAL_STRTAB_CAPACITY 4 -#define INITIAL_MDTAB_CAPACITY 4 - -#ifdef GRPC_METADATA_REFCOUNT_DEBUG -#define DEBUG_ARGS , const char *file, int line -#define FWD_DEBUG_ARGS , file, line -#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s), __FILE__, __LINE__) -#else -#define DEBUG_ARGS -#define FWD_DEBUG_ARGS -#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s)) -#endif - -#define TABLE_IDX(hash, log2_shards, capacity) \ - (((hash) >> (log2_shards)) % (capacity)) -#define SHARD_IDX(hash, log2_shards) ((hash) & ((1 << (log2_shards)) - 1)) - -typedef void (*destroy_user_data_func)(void *user_data); - -/* Shadow structure for grpc_mdstr for non-static values */ -typedef struct internal_string { - /* must be byte compatible with grpc_mdstr */ - gpr_slice slice; - uint32_t hash; - - /* private only data */ - gpr_atm refcnt; - - uint8_t has_base64_and_huffman_encoded; - gpr_slice_refcount refcount; - - gpr_slice base64_and_huffman; - - struct internal_string *bucket_next; -} internal_string; - -/* Shadow structure for grpc_mdelem for non-static elements */ -typedef struct internal_metadata { - /* must be byte compatible with grpc_mdelem */ - internal_string *key; - internal_string *value; - - /* private only data */ - gpr_atm refcnt; - - gpr_mu mu_user_data; - gpr_atm destroy_user_data; - gpr_atm user_data; - - struct internal_metadata *bucket_next; -} internal_metadata; - -typedef struct strtab_shard { - gpr_mu mu; - internal_string **strs; - size_t count; - size_t capacity; -} strtab_shard; - -typedef struct mdtab_shard { - gpr_mu mu; - internal_metadata **elems; - size_t count; - size_t capacity; - size_t free; -} mdtab_shard; - -#define LOG2_STRTAB_SHARD_COUNT 5 -#define LOG2_MDTAB_SHARD_COUNT 4 -#define STRTAB_SHARD_COUNT ((size_t)(1 << LOG2_STRTAB_SHARD_COUNT)) -#define MDTAB_SHARD_COUNT ((size_t)(1 << LOG2_MDTAB_SHARD_COUNT)) - -/* hash seed: decided at initialization time */ -static uint32_t g_hash_seed; -static int g_forced_hash_seed = 0; - -/* linearly probed hash tables for static element lookup */ -static grpc_mdstr *g_static_strtab[GRPC_STATIC_MDSTR_COUNT * 2]; -static grpc_mdelem *g_static_mdtab[GRPC_STATIC_MDELEM_COUNT * 2]; -static size_t g_static_strtab_maxprobe; -static size_t g_static_mdtab_maxprobe; - -static strtab_shard g_strtab_shard[STRTAB_SHARD_COUNT]; -static mdtab_shard g_mdtab_shard[MDTAB_SHARD_COUNT]; - -static void gc_mdtab(mdtab_shard *shard); - -void grpc_test_only_set_metadata_hash_seed(uint32_t seed) { - g_hash_seed = seed; - g_forced_hash_seed = 1; -} - -void grpc_mdctx_global_init(void) { - size_t i, j; - if (!g_forced_hash_seed) { - g_hash_seed = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec; - } - g_static_strtab_maxprobe = 0; - g_static_mdtab_maxprobe = 0; - /* build static tables */ - memset(g_static_mdtab, 0, sizeof(g_static_mdtab)); - memset(g_static_strtab, 0, sizeof(g_static_strtab)); - for (i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) { - grpc_mdstr *elem = &grpc_static_mdstr_table[i]; - const char *str = grpc_static_metadata_strings[i]; - uint32_t hash = gpr_murmur_hash3(str, strlen(str), g_hash_seed); - *(gpr_slice *)&elem->slice = gpr_slice_from_static_string(str); - *(uint32_t *)&elem->hash = hash; - for (j = 0;; j++) { - size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_strtab); - if (g_static_strtab[idx] == NULL) { - g_static_strtab[idx] = &grpc_static_mdstr_table[i]; - break; - } - } - if (j > g_static_strtab_maxprobe) { - g_static_strtab_maxprobe = j; - } - } - for (i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) { - grpc_mdelem *elem = &grpc_static_mdelem_table[i]; - grpc_mdstr *key = - &grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 0]]; - grpc_mdstr *value = - &grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 1]]; - uint32_t hash = GRPC_MDSTR_KV_HASH(key->hash, value->hash); - *(grpc_mdstr **)&elem->key = key; - *(grpc_mdstr **)&elem->value = value; - for (j = 0;; j++) { - size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_mdtab); - if (g_static_mdtab[idx] == NULL) { - g_static_mdtab[idx] = elem; - break; - } - } - if (j > g_static_mdtab_maxprobe) { - g_static_mdtab_maxprobe = j; - } - } - /* initialize shards */ - for (i = 0; i < STRTAB_SHARD_COUNT; i++) { - strtab_shard *shard = &g_strtab_shard[i]; - gpr_mu_init(&shard->mu); - shard->count = 0; - shard->capacity = INITIAL_STRTAB_CAPACITY; - shard->strs = gpr_malloc(sizeof(*shard->strs) * shard->capacity); - memset(shard->strs, 0, sizeof(*shard->strs) * shard->capacity); - } - for (i = 0; i < MDTAB_SHARD_COUNT; i++) { - mdtab_shard *shard = &g_mdtab_shard[i]; - gpr_mu_init(&shard->mu); - shard->count = 0; - shard->free = 0; - shard->capacity = INITIAL_MDTAB_CAPACITY; - shard->elems = gpr_malloc(sizeof(*shard->elems) * shard->capacity); - memset(shard->elems, 0, sizeof(*shard->elems) * shard->capacity); - } -} - -void grpc_mdctx_global_shutdown(void) { - size_t i; - for (i = 0; i < MDTAB_SHARD_COUNT; i++) { - mdtab_shard *shard = &g_mdtab_shard[i]; - gpr_mu_destroy(&shard->mu); - gc_mdtab(shard); - /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */ - if (shard->count != 0) { - gpr_log(GPR_DEBUG, "WARNING: %d metadata elements were leaked", - shard->count); - if (grpc_iomgr_abort_on_leaks()) { - abort(); - } - } - gpr_free(shard->elems); - } - for (i = 0; i < STRTAB_SHARD_COUNT; i++) { - strtab_shard *shard = &g_strtab_shard[i]; - gpr_mu_destroy(&shard->mu); - /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */ - if (shard->count != 0) { - gpr_log(GPR_DEBUG, "WARNING: %d metadata strings were leaked", - shard->count); - if (grpc_iomgr_abort_on_leaks()) { - abort(); - } - } - gpr_free(shard->strs); - } -} - -static int is_mdstr_static(grpc_mdstr *s) { - return s >= &grpc_static_mdstr_table[0] && - s < &grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; -} - -static int is_mdelem_static(grpc_mdelem *e) { - return e >= &grpc_static_mdelem_table[0] && - e < &grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; -} - -static void ref_md_locked(mdtab_shard *shard, - internal_metadata *md DEBUG_ARGS) { -#ifdef GRPC_METADATA_REFCOUNT_DEBUG - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM REF:%p:%d->%d: '%s' = '%s'", md, - gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) + 1, - grpc_mdstr_as_c_string((grpc_mdstr *)md->key), - grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); -#endif - if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 2)) { - shard->free--; - } else { - GPR_ASSERT(1 != gpr_atm_no_barrier_fetch_add(&md->refcnt, -1)); - } -} - -static void grow_strtab(strtab_shard *shard) { - size_t capacity = shard->capacity * 2; - size_t i; - internal_string **strtab; - internal_string *s, *next; - - GPR_TIMER_BEGIN("grow_strtab", 0); - - strtab = gpr_malloc(sizeof(internal_string *) * capacity); - memset(strtab, 0, sizeof(internal_string *) * capacity); - - for (i = 0; i < shard->capacity; i++) { - for (s = shard->strs[i]; s; s = next) { - size_t idx = TABLE_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT, capacity); - next = s->bucket_next; - s->bucket_next = strtab[idx]; - strtab[idx] = s; - } - } - - gpr_free(shard->strs); - shard->strs = strtab; - shard->capacity = capacity; - - GPR_TIMER_END("grow_strtab", 0); -} - -static void internal_destroy_string(strtab_shard *shard, internal_string *is) { - internal_string **prev_next; - internal_string *cur; - GPR_TIMER_BEGIN("internal_destroy_string", 0); - if (is->has_base64_and_huffman_encoded) { - gpr_slice_unref(is->base64_and_huffman); - } - for (prev_next = &shard->strs[TABLE_IDX(is->hash, LOG2_STRTAB_SHARD_COUNT, - shard->capacity)], - cur = *prev_next; - cur != is; prev_next = &cur->bucket_next, cur = cur->bucket_next) - ; - *prev_next = cur->bucket_next; - shard->count--; - gpr_free(is); - GPR_TIMER_END("internal_destroy_string", 0); -} - -static void slice_ref(void *p) { - internal_string *is = - (internal_string *)((char *)p - offsetof(internal_string, refcount)); - GRPC_MDSTR_REF((grpc_mdstr *)(is)); -} - -static void slice_unref(void *p) { - internal_string *is = - (internal_string *)((char *)p - offsetof(internal_string, refcount)); - GRPC_MDSTR_UNREF((grpc_mdstr *)(is)); -} - -grpc_mdstr *grpc_mdstr_from_string(const char *str) { - return grpc_mdstr_from_buffer((const uint8_t *)str, strlen(str)); -} - -grpc_mdstr *grpc_mdstr_from_slice(gpr_slice slice) { - grpc_mdstr *result = grpc_mdstr_from_buffer(GPR_SLICE_START_PTR(slice), - GPR_SLICE_LENGTH(slice)); - gpr_slice_unref(slice); - return result; -} - -grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) { - uint32_t hash = gpr_murmur_hash3(buf, length, g_hash_seed); - internal_string *s; - strtab_shard *shard = - &g_strtab_shard[SHARD_IDX(hash, LOG2_STRTAB_SHARD_COUNT)]; - size_t i; - size_t idx; - - GPR_TIMER_BEGIN("grpc_mdstr_from_buffer", 0); - - /* search for a static string */ - for (i = 0; i <= g_static_strtab_maxprobe; i++) { - grpc_mdstr *ss; - idx = (hash + i) % GPR_ARRAY_SIZE(g_static_strtab); - ss = g_static_strtab[idx]; - if (ss == NULL) break; - if (ss->hash == hash && GPR_SLICE_LENGTH(ss->slice) == length && - 0 == memcmp(buf, GPR_SLICE_START_PTR(ss->slice), length)) { - GPR_TIMER_END("grpc_mdstr_from_buffer", 0); - return ss; - } - } - - gpr_mu_lock(&shard->mu); - - /* search for an existing string */ - idx = TABLE_IDX(hash, LOG2_STRTAB_SHARD_COUNT, shard->capacity); - for (s = shard->strs[idx]; s; s = s->bucket_next) { - if (s->hash == hash && GPR_SLICE_LENGTH(s->slice) == length && - 0 == memcmp(buf, GPR_SLICE_START_PTR(s->slice), length)) { - GRPC_MDSTR_REF((grpc_mdstr *)s); - gpr_mu_unlock(&shard->mu); - GPR_TIMER_END("grpc_mdstr_from_buffer", 0); - return (grpc_mdstr *)s; - } - } - - /* not found: create a new string */ - if (length + 1 < GPR_SLICE_INLINED_SIZE) { - /* string data goes directly into the slice */ - s = gpr_malloc(sizeof(internal_string)); - gpr_atm_rel_store(&s->refcnt, 2); - s->slice.refcount = NULL; - memcpy(s->slice.data.inlined.bytes, buf, length); - s->slice.data.inlined.bytes[length] = 0; - s->slice.data.inlined.length = (uint8_t)length; - } else { - /* string data goes after the internal_string header, and we +1 for null - terminator */ - s = gpr_malloc(sizeof(internal_string) + length + 1); - gpr_atm_rel_store(&s->refcnt, 2); - s->refcount.ref = slice_ref; - s->refcount.unref = slice_unref; - s->slice.refcount = &s->refcount; - s->slice.data.refcounted.bytes = (uint8_t *)(s + 1); - s->slice.data.refcounted.length = length; - memcpy(s->slice.data.refcounted.bytes, buf, length); - /* add a null terminator for cheap c string conversion when desired */ - s->slice.data.refcounted.bytes[length] = 0; - } - s->has_base64_and_huffman_encoded = 0; - s->hash = hash; - s->bucket_next = shard->strs[idx]; - shard->strs[idx] = s; - - shard->count++; - - if (shard->count > shard->capacity * 2) { - grow_strtab(shard); - } - - gpr_mu_unlock(&shard->mu); - GPR_TIMER_END("grpc_mdstr_from_buffer", 0); - - return (grpc_mdstr *)s; -} - -static void gc_mdtab(mdtab_shard *shard) { - size_t i; - internal_metadata **prev_next; - internal_metadata *md, *next; - - GPR_TIMER_BEGIN("gc_mdtab", 0); - for (i = 0; i < shard->capacity; i++) { - prev_next = &shard->elems[i]; - for (md = shard->elems[i]; md; md = next) { - void *user_data = (void *)gpr_atm_no_barrier_load(&md->user_data); - next = md->bucket_next; - if (gpr_atm_acq_load(&md->refcnt) == 0) { - GRPC_MDSTR_UNREF((grpc_mdstr *)md->key); - GRPC_MDSTR_UNREF((grpc_mdstr *)md->value); - if (md->user_data) { - ((destroy_user_data_func)gpr_atm_no_barrier_load( - &md->destroy_user_data))(user_data); - } - gpr_free(md); - *prev_next = next; - shard->free--; - shard->count--; - } else { - prev_next = &md->bucket_next; - } - } - } - GPR_TIMER_END("gc_mdtab", 0); -} - -static void grow_mdtab(mdtab_shard *shard) { - size_t capacity = shard->capacity * 2; - size_t i; - internal_metadata **mdtab; - internal_metadata *md, *next; - uint32_t hash; - - GPR_TIMER_BEGIN("grow_mdtab", 0); - - mdtab = gpr_malloc(sizeof(internal_metadata *) * capacity); - memset(mdtab, 0, sizeof(internal_metadata *) * capacity); - - for (i = 0; i < shard->capacity; i++) { - for (md = shard->elems[i]; md; md = next) { - size_t idx; - hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash); - next = md->bucket_next; - idx = TABLE_IDX(hash, LOG2_MDTAB_SHARD_COUNT, capacity); - md->bucket_next = mdtab[idx]; - mdtab[idx] = md; - } - } - - gpr_free(shard->elems); - shard->elems = mdtab; - shard->capacity = capacity; - - GPR_TIMER_END("grow_mdtab", 0); -} - -static void rehash_mdtab(mdtab_shard *shard) { - if (shard->free > shard->capacity / 4) { - gc_mdtab(shard); - } else { - grow_mdtab(shard); - } -} - -grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *mkey, - grpc_mdstr *mvalue) { - internal_string *key = (internal_string *)mkey; - internal_string *value = (internal_string *)mvalue; - uint32_t hash = GRPC_MDSTR_KV_HASH(mkey->hash, mvalue->hash); - internal_metadata *md; - mdtab_shard *shard = &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)]; - size_t i; - size_t idx; - - GPR_TIMER_BEGIN("grpc_mdelem_from_metadata_strings", 0); - - if (is_mdstr_static(mkey) && is_mdstr_static(mvalue)) { - for (i = 0; i <= g_static_mdtab_maxprobe; i++) { - grpc_mdelem *smd; - idx = (hash + i) % GPR_ARRAY_SIZE(g_static_mdtab); - smd = g_static_mdtab[idx]; - if (smd == NULL) break; - if (smd->key == mkey && smd->value == mvalue) { - GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0); - return smd; - } - } - } - - gpr_mu_lock(&shard->mu); - - idx = TABLE_IDX(hash, LOG2_MDTAB_SHARD_COUNT, shard->capacity); - /* search for an existing pair */ - for (md = shard->elems[idx]; md; md = md->bucket_next) { - if (md->key == key && md->value == value) { - REF_MD_LOCKED(shard, md); - GRPC_MDSTR_UNREF((grpc_mdstr *)key); - GRPC_MDSTR_UNREF((grpc_mdstr *)value); - gpr_mu_unlock(&shard->mu); - GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0); - return (grpc_mdelem *)md; - } - } - - /* not found: create a new pair */ - md = gpr_malloc(sizeof(internal_metadata)); - gpr_atm_rel_store(&md->refcnt, 2); - md->key = key; - md->value = value; - md->user_data = 0; - md->destroy_user_data = 0; - md->bucket_next = shard->elems[idx]; - shard->elems[idx] = md; - gpr_mu_init(&md->mu_user_data); -#ifdef GRPC_METADATA_REFCOUNT_DEBUG - gpr_log(GPR_DEBUG, "ELM NEW:%p:%d: '%s' = '%s'", md, - gpr_atm_no_barrier_load(&md->refcnt), - grpc_mdstr_as_c_string((grpc_mdstr *)md->key), - grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); -#endif - shard->count++; - - if (shard->count > shard->capacity * 2) { - rehash_mdtab(shard); - } - - gpr_mu_unlock(&shard->mu); - - GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0); - - return (grpc_mdelem *)md; -} - -grpc_mdelem *grpc_mdelem_from_strings(const char *key, const char *value) { - return grpc_mdelem_from_metadata_strings(grpc_mdstr_from_string(key), - grpc_mdstr_from_string(value)); -} - -grpc_mdelem *grpc_mdelem_from_slices(gpr_slice key, gpr_slice value) { - return grpc_mdelem_from_metadata_strings(grpc_mdstr_from_slice(key), - grpc_mdstr_from_slice(value)); -} - -grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key, - const uint8_t *value, - size_t value_length) { - return grpc_mdelem_from_metadata_strings( - grpc_mdstr_from_string(key), grpc_mdstr_from_buffer(value, value_length)); -} - -grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) { - internal_metadata *md = (internal_metadata *)gmd; - if (is_mdelem_static(gmd)) return gmd; -#ifdef GRPC_METADATA_REFCOUNT_DEBUG - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM REF:%p:%d->%d: '%s' = '%s'", md, - gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) + 1, - grpc_mdstr_as_c_string((grpc_mdstr *)md->key), - grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); -#endif - /* we can assume the ref count is >= 1 as the application is calling - this function - meaning that no adjustment to mdtab_free is necessary, - simplifying the logic here to be just an atomic increment */ - /* use C assert to have this removed in opt builds */ - assert(gpr_atm_no_barrier_load(&md->refcnt) >= 2); - gpr_atm_no_barrier_fetch_add(&md->refcnt, 1); - return gmd; -} - -void grpc_mdelem_unref(grpc_mdelem *gmd DEBUG_ARGS) { - internal_metadata *md = (internal_metadata *)gmd; - if (!md) return; - if (is_mdelem_static(gmd)) return; -#ifdef GRPC_METADATA_REFCOUNT_DEBUG - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM UNREF:%p:%d->%d: '%s' = '%s'", md, - gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) - 1, - grpc_mdstr_as_c_string((grpc_mdstr *)md->key), - grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); -#endif - if (2 == gpr_atm_full_fetch_add(&md->refcnt, -1)) { - uint32_t hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash); - mdtab_shard *shard = - &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)]; - GPR_TIMER_BEGIN("grpc_mdelem_unref.to_zero", 0); - gpr_mu_lock(&shard->mu); - if (1 == gpr_atm_no_barrier_load(&md->refcnt)) { - shard->free++; - gpr_atm_no_barrier_store(&md->refcnt, 0); - } - gpr_mu_unlock(&shard->mu); - GPR_TIMER_END("grpc_mdelem_unref.to_zero", 0); - } -} - -const char *grpc_mdstr_as_c_string(grpc_mdstr *s) { - return (const char *)GPR_SLICE_START_PTR(s->slice); -} - -grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *gs DEBUG_ARGS) { - internal_string *s = (internal_string *)gs; - if (is_mdstr_static(gs)) return gs; - GPR_ASSERT(gpr_atm_full_fetch_add(&s->refcnt, 1) != 0); - return gs; -} - -void grpc_mdstr_unref(grpc_mdstr *gs DEBUG_ARGS) { - internal_string *s = (internal_string *)gs; - if (is_mdstr_static(gs)) return; - if (2 == gpr_atm_full_fetch_add(&s->refcnt, -1)) { - strtab_shard *shard = - &g_strtab_shard[SHARD_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT)]; - gpr_mu_lock(&shard->mu); - if (1 == gpr_atm_no_barrier_load(&s->refcnt)) { - internal_destroy_string(shard, s); - } - gpr_mu_unlock(&shard->mu); - } -} - -void *grpc_mdelem_get_user_data(grpc_mdelem *md, void (*destroy_func)(void *)) { - internal_metadata *im = (internal_metadata *)md; - void *result; - if (is_mdelem_static(md)) { - return (void *)grpc_static_mdelem_user_data[md - grpc_static_mdelem_table]; - } - if (gpr_atm_acq_load(&im->destroy_user_data) == (gpr_atm)destroy_func) { - return (void *)gpr_atm_no_barrier_load(&im->user_data); - } else { - return NULL; - } - return result; -} - -void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *), - void *user_data) { - internal_metadata *im = (internal_metadata *)md; - GPR_ASSERT(!is_mdelem_static(md)); - GPR_ASSERT((user_data == NULL) == (destroy_func == NULL)); - gpr_mu_lock(&im->mu_user_data); - if (gpr_atm_no_barrier_load(&im->destroy_user_data)) { - /* user data can only be set once */ - gpr_mu_unlock(&im->mu_user_data); - if (destroy_func != NULL) { - destroy_func(user_data); - } - return; - } - gpr_atm_no_barrier_store(&im->user_data, (gpr_atm)user_data); - gpr_atm_rel_store(&im->destroy_user_data, (gpr_atm)destroy_func); - gpr_mu_unlock(&im->mu_user_data); -} - -gpr_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *gs) { - internal_string *s = (internal_string *)gs; - gpr_slice slice; - strtab_shard *shard = - &g_strtab_shard[SHARD_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT)]; - gpr_mu_lock(&shard->mu); - if (!s->has_base64_and_huffman_encoded) { - s->base64_and_huffman = - grpc_chttp2_base64_encode_and_huffman_compress(s->slice); - s->has_base64_and_huffman_encoded = 1; - } - slice = s->base64_and_huffman; - gpr_mu_unlock(&shard->mu); - return slice; -} diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h deleted file mode 100644 index 5ab397848c..0000000000 --- a/src/core/transport/metadata.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_METADATA_H -#define GRPC_CORE_TRANSPORT_METADATA_H - -#include -#include - -/* This file provides a mechanism for tracking metadata through the grpc stack. - It's not intended for consumption outside of the library. - - Metadata is tracked in the context of a grpc_mdctx. For the time being there - is one of these per-channel, avoiding cross channel interference with memory - use and lock contention. - - The context tracks unique strings (grpc_mdstr) and pairs of strings - (grpc_mdelem). Any of these objects can be checked for equality by comparing - their pointers. These objects are reference counted. - - grpc_mdelem can additionally store a (non-NULL) user data pointer. This - pointer is intended to be used to cache semantic meaning of a metadata - element. For example, an OAuth token may cache the credentials it represents - and the time at which it expires in the mdelem user data. - - Combining this metadata cache and the hpack compression table allows us to - simply lookup complete preparsed objects quickly, incurring a few atomic - ops per metadata element on the fast path. - - grpc_mdelem instances MAY live longer than their refcount implies, and are - garbage collected periodically, meaning cached data can easily outlive a - single request. - - STATIC METADATA: in static_metadata.h we declare a set of static metadata. - These mdelems and mdstrs are available via pre-declared code generated macros - and are available to code anywhere between grpc_init() and grpc_shutdown(). - They are not refcounted, but can be passed to _ref and _unref functions - declared here - in which case those functions are effectively no-ops. */ - -/* Forward declarations */ -typedef struct grpc_mdstr grpc_mdstr; -typedef struct grpc_mdelem grpc_mdelem; - -/* if changing this, make identical changes in internal_string in metadata.c */ -struct grpc_mdstr { - const gpr_slice slice; - const uint32_t hash; - /* there is a private part to this in metadata.c */ -}; - -/* if changing this, make identical changes in internal_metadata in - metadata.c */ -struct grpc_mdelem { - grpc_mdstr *const key; - grpc_mdstr *const value; - /* there is a private part to this in metadata.c */ -}; - -void grpc_test_only_set_metadata_hash_seed(uint32_t seed); - -/* Constructors for grpc_mdstr instances; take a variety of data types that - clients may have handy */ -grpc_mdstr *grpc_mdstr_from_string(const char *str); -/* Unrefs the slice. */ -grpc_mdstr *grpc_mdstr_from_slice(gpr_slice slice); -grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *str, size_t length); - -/* Returns a borrowed slice from the mdstr with its contents base64 encoded - and huffman compressed */ -gpr_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *str); - -/* Constructors for grpc_mdelem instances; take a variety of data types that - clients may have handy */ -grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *key, - grpc_mdstr *value); -grpc_mdelem *grpc_mdelem_from_strings(const char *key, const char *value); -/* Unrefs the slices. */ -grpc_mdelem *grpc_mdelem_from_slices(gpr_slice key, gpr_slice value); -grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key, - const uint8_t *value, - size_t value_length); - -/* Mutator and accessor for grpc_mdelem user data. The destructor function - is used as a type tag and is checked during user_data fetch. */ -void *grpc_mdelem_get_user_data(grpc_mdelem *md, - void (*if_destroy_func)(void *)); -void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *), - void *user_data); - -/* Reference counting */ -#ifdef GRPC_METADATA_REFCOUNT_DEBUG -#define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s), __FILE__, __LINE__) -#define GRPC_MDSTR_UNREF(s) grpc_mdstr_unref((s), __FILE__, __LINE__) -#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__) -#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__) -grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s, const char *file, int line); -void grpc_mdstr_unref(grpc_mdstr *s, const char *file, int line); -grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md, const char *file, int line); -void grpc_mdelem_unref(grpc_mdelem *md, const char *file, int line); -#else -#define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s)) -#define GRPC_MDSTR_UNREF(s) grpc_mdstr_unref((s)) -#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s)) -#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s)) -grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s); -void grpc_mdstr_unref(grpc_mdstr *s); -grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md); -void grpc_mdelem_unref(grpc_mdelem *md); -#endif - -/* Recover a char* from a grpc_mdstr. The returned string is null terminated. - Does not promise that the returned string has no embedded nulls however. */ -const char *grpc_mdstr_as_c_string(grpc_mdstr *s); - -#define GRPC_MDSTR_LENGTH(s) (GPR_SLICE_LENGTH(s->slice)) - -int grpc_mdstr_is_legal_header(grpc_mdstr *s); -int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s); -int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s); - -#define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash)) - -void grpc_mdctx_global_init(void); -void grpc_mdctx_global_shutdown(void); - -#endif /* GRPC_CORE_TRANSPORT_METADATA_H */ diff --git a/src/core/transport/metadata_batch.c b/src/core/transport/metadata_batch.c deleted file mode 100644 index 1266862f82..0000000000 --- a/src/core/transport/metadata_batch.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * - * Copyright 2015, 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/transport/metadata_batch.h" - -#include - -#include -#include - -#include "src/core/profiling/timers.h" - -static void assert_valid_list(grpc_mdelem_list *list) { -#ifndef NDEBUG - grpc_linked_mdelem *l; - - GPR_ASSERT((list->head == NULL) == (list->tail == NULL)); - if (!list->head) return; - GPR_ASSERT(list->head->prev == NULL); - GPR_ASSERT(list->tail->next == NULL); - GPR_ASSERT((list->head == list->tail) == (list->head->next == NULL)); - - for (l = list->head; l; l = l->next) { - GPR_ASSERT(l->md); - GPR_ASSERT((l->prev == NULL) == (l == list->head)); - GPR_ASSERT((l->next == NULL) == (l == list->tail)); - if (l->next) GPR_ASSERT(l->next->prev == l); - if (l->prev) GPR_ASSERT(l->prev->next == l); - } -#endif /* NDEBUG */ -} - -#ifndef NDEBUG -void grpc_metadata_batch_assert_ok(grpc_metadata_batch *batch) { - assert_valid_list(&batch->list); -} -#endif /* NDEBUG */ - -void grpc_metadata_batch_init(grpc_metadata_batch *batch) { - batch->list.head = batch->list.tail = NULL; - batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME); -} - -void grpc_metadata_batch_destroy(grpc_metadata_batch *batch) { - grpc_linked_mdelem *l; - for (l = batch->list.head; l; l = l->next) { - GRPC_MDELEM_UNREF(l->md); - } -} - -void grpc_metadata_batch_add_head(grpc_metadata_batch *batch, - grpc_linked_mdelem *storage, - grpc_mdelem *elem_to_add) { - GPR_ASSERT(elem_to_add); - storage->md = elem_to_add; - grpc_metadata_batch_link_head(batch, storage); -} - -static void link_head(grpc_mdelem_list *list, grpc_linked_mdelem *storage) { - assert_valid_list(list); - GPR_ASSERT(storage->md); - storage->prev = NULL; - storage->next = list->head; - if (list->head != NULL) { - list->head->prev = storage; - } else { - list->tail = storage; - } - list->head = storage; - assert_valid_list(list); -} - -void grpc_metadata_batch_link_head(grpc_metadata_batch *batch, - grpc_linked_mdelem *storage) { - link_head(&batch->list, storage); -} - -void grpc_metadata_batch_add_tail(grpc_metadata_batch *batch, - grpc_linked_mdelem *storage, - grpc_mdelem *elem_to_add) { - GPR_ASSERT(elem_to_add); - storage->md = elem_to_add; - grpc_metadata_batch_link_tail(batch, storage); -} - -static void link_tail(grpc_mdelem_list *list, grpc_linked_mdelem *storage) { - assert_valid_list(list); - GPR_ASSERT(storage->md); - storage->prev = list->tail; - storage->next = NULL; - storage->reserved = NULL; - if (list->tail != NULL) { - list->tail->next = storage; - } else { - list->head = storage; - } - list->tail = storage; - assert_valid_list(list); -} - -void grpc_metadata_batch_link_tail(grpc_metadata_batch *batch, - grpc_linked_mdelem *storage) { - link_tail(&batch->list, storage); -} - -void grpc_metadata_batch_move(grpc_metadata_batch *dst, - grpc_metadata_batch *src) { - *dst = *src; - memset(src, 0, sizeof(grpc_metadata_batch)); -} - -void grpc_metadata_batch_filter(grpc_metadata_batch *batch, - grpc_mdelem *(*filter)(void *user_data, - grpc_mdelem *elem), - void *user_data) { - grpc_linked_mdelem *l; - grpc_linked_mdelem *next; - - GPR_TIMER_BEGIN("grpc_metadata_batch_filter", 0); - - assert_valid_list(&batch->list); - for (l = batch->list.head; l; l = next) { - grpc_mdelem *orig = l->md; - grpc_mdelem *filt = filter(user_data, orig); - next = l->next; - if (filt == NULL) { - if (l->prev) { - l->prev->next = l->next; - } - if (l->next) { - l->next->prev = l->prev; - } - if (batch->list.head == l) { - batch->list.head = l->next; - } - if (batch->list.tail == l) { - batch->list.tail = l->prev; - } - assert_valid_list(&batch->list); - GRPC_MDELEM_UNREF(l->md); - } else if (filt != orig) { - GRPC_MDELEM_UNREF(orig); - l->md = filt; - } - } - assert_valid_list(&batch->list); - - GPR_TIMER_END("grpc_metadata_batch_filter", 0); -} - -static grpc_mdelem *no_metadata_for_you(void *user_data, grpc_mdelem *elem) { - return NULL; -} - -void grpc_metadata_batch_clear(grpc_metadata_batch *batch) { - batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME); - grpc_metadata_batch_filter(batch, no_metadata_for_you, NULL); -} - -int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) { - return batch->list.head == NULL && - gpr_time_cmp(gpr_inf_future(batch->deadline.clock_type), - batch->deadline) == 0; -} diff --git a/src/core/transport/metadata_batch.h b/src/core/transport/metadata_batch.h deleted file mode 100644 index 9337b28328..0000000000 --- a/src/core/transport/metadata_batch.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_METADATA_BATCH_H -#define GRPC_CORE_TRANSPORT_METADATA_BATCH_H - -#include -#include -#include -#include -#include "src/core/transport/metadata.h" - -typedef struct grpc_linked_mdelem { - grpc_mdelem *md; - struct grpc_linked_mdelem *next; - struct grpc_linked_mdelem *prev; - void *reserved; -} grpc_linked_mdelem; - -typedef struct grpc_mdelem_list { - grpc_linked_mdelem *head; - grpc_linked_mdelem *tail; -} grpc_mdelem_list; - -typedef struct grpc_metadata_batch { - /** Metadata elements in this batch */ - grpc_mdelem_list list; - /** Used to calculate grpc-timeout at the point of sending, - or gpr_inf_future if this batch does not need to send a - grpc-timeout */ - gpr_timespec deadline; -} grpc_metadata_batch; - -void grpc_metadata_batch_init(grpc_metadata_batch *batch); -void grpc_metadata_batch_destroy(grpc_metadata_batch *batch); -void grpc_metadata_batch_clear(grpc_metadata_batch *batch); -int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch); - -/** Moves the metadata information from \a src to \a dst. Upon return, \a src is - * zeroed. */ -void grpc_metadata_batch_move(grpc_metadata_batch *dst, - grpc_metadata_batch *src); - -/** Add \a storage to the beginning of \a batch. storage->md is - assumed to be valid. - \a storage is owned by the caller and must survive for the - lifetime of batch. This usually means it should be around - for the lifetime of the call. */ -void grpc_metadata_batch_link_head(grpc_metadata_batch *batch, - grpc_linked_mdelem *storage); -/** Add \a storage to the end of \a batch. storage->md is - assumed to be valid. - \a storage is owned by the caller and must survive for the - lifetime of batch. This usually means it should be around - for the lifetime of the call. */ -void grpc_metadata_batch_link_tail(grpc_metadata_batch *batch, - grpc_linked_mdelem *storage); - -/** Add \a elem_to_add as the first element in \a batch, using - \a storage as backing storage for the linked list element. - \a storage is owned by the caller and must survive for the - lifetime of batch. This usually means it should be around - for the lifetime of the call. - Takes ownership of \a elem_to_add */ -void grpc_metadata_batch_add_head(grpc_metadata_batch *batch, - grpc_linked_mdelem *storage, - grpc_mdelem *elem_to_add); -/** Add \a elem_to_add as the last element in \a batch, using - \a storage as backing storage for the linked list element. - \a storage is owned by the caller and must survive for the - lifetime of batch. This usually means it should be around - for the lifetime of the call. - Takes ownership of \a elem_to_add */ -void grpc_metadata_batch_add_tail(grpc_metadata_batch *batch, - grpc_linked_mdelem *storage, - grpc_mdelem *elem_to_add); - -/** For each element in \a batch, execute \a filter. - The return value from \a filter will be substituted for the - grpc_mdelem passed to \a filter. If \a filter returns NULL, - the element will be moved to the garbage list. */ -void grpc_metadata_batch_filter(grpc_metadata_batch *batch, - grpc_mdelem *(*filter)(void *user_data, - grpc_mdelem *elem), - void *user_data); - -#ifndef NDEBUG -void grpc_metadata_batch_assert_ok(grpc_metadata_batch *comd); -#else -#define grpc_metadata_batch_assert_ok(comd) \ - do { \ - } while (0) -#endif - -#endif /* GRPC_CORE_TRANSPORT_METADATA_BATCH_H */ diff --git a/src/core/transport/static_metadata.c b/src/core/transport/static_metadata.c deleted file mode 100644 index 30bbb89880..0000000000 --- a/src/core/transport/static_metadata.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* - * WARNING: Auto-generated code. - * - * To make changes to this file, change - * tools/codegen/core/gen_static_metadata.py, - * and then re-run it. - * - * See metadata.h for an explanation of the interface here, and metadata.c for - * an - * explanation of what's going on. - */ - -#include "src/core/transport/static_metadata.h" - -grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; - -grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; -uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4, 8, 6, 2, 4, 8, 6, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] = - {11, 35, 10, 35, 12, 35, 12, 49, 13, 35, 14, 35, 15, 35, 16, 35, 17, 35, - 19, 35, 20, 35, 21, 35, 24, 35, 25, 35, 26, 35, 27, 35, 28, 35, 29, 35, - 30, 18, 30, 35, 31, 35, 32, 35, 36, 35, 37, 35, 38, 35, 39, 35, 42, 33, - 42, 34, 42, 48, 42, 53, 42, 54, 42, 55, 42, 56, 43, 33, 43, 48, 43, 53, - 46, 0, 46, 1, 46, 2, 50, 35, 57, 35, 58, 35, 59, 35, 60, 35, 61, 35, - 62, 35, 63, 35, 64, 35, 65, 35, 66, 40, 66, 68, 67, 78, 67, 79, 69, 35, - 70, 35, 71, 35, 72, 35, 73, 35, 74, 35, 75, 41, 75, 51, 75, 52, 76, 35, - 77, 35, 80, 3, 80, 4, 80, 5, 80, 6, 80, 7, 80, 8, 80, 9, 81, 35, - 82, 83, 84, 35, 85, 35, 86, 35, 87, 35, 88, 35}; - -const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = { - "0", - "1", - "2", - "200", - "204", - "206", - "304", - "400", - "404", - "500", - "accept", - "accept-charset", - "accept-encoding", - "accept-language", - "accept-ranges", - "access-control-allow-origin", - "age", - "allow", - "application/grpc", - ":authority", - "authorization", - "cache-control", - "census-bin", - "census-binary-bin", - "content-disposition", - "content-encoding", - "content-language", - "content-length", - "content-location", - "content-range", - "content-type", - "cookie", - "date", - "deflate", - "deflate,gzip", - "", - "etag", - "expect", - "expires", - "from", - "GET", - "grpc", - "grpc-accept-encoding", - "grpc-encoding", - "grpc-internal-encoding-request", - "grpc-message", - "grpc-status", - "grpc-timeout", - "gzip", - "gzip, deflate", - "host", - "http", - "https", - "identity", - "identity,deflate", - "identity,deflate,gzip", - "identity,gzip", - "if-match", - "if-modified-since", - "if-none-match", - "if-range", - "if-unmodified-since", - "last-modified", - "link", - "location", - "max-forwards", - ":method", - ":path", - "POST", - "proxy-authenticate", - "proxy-authorization", - "range", - "referer", - "refresh", - "retry-after", - ":scheme", - "server", - "set-cookie", - "/", - "/index.html", - ":status", - "strict-transport-security", - "te", - "trailers", - "transfer-encoding", - "user-agent", - "vary", - "via", - "www-authenticate"}; - -const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 29, 26, 30, - 28, 32, 27, 31}; diff --git a/src/core/transport/static_metadata.h b/src/core/transport/static_metadata.h deleted file mode 100644 index 85442f8107..0000000000 --- a/src/core/transport/static_metadata.h +++ /dev/null @@ -1,408 +0,0 @@ -/* - * - * Copyright 2015-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. - * - */ - -/* - * WARNING: Auto-generated code. - * - * To make changes to this file, change - * tools/codegen/core/gen_static_metadata.py, - * and then re-run it. - * - * See metadata.h for an explanation of the interface here, and metadata.c for - * an - * explanation of what's going on. - */ - -#ifndef GRPC_CORE_TRANSPORT_STATIC_METADATA_H -#define GRPC_CORE_TRANSPORT_STATIC_METADATA_H - -#include "src/core/transport/metadata.h" - -#define GRPC_STATIC_MDSTR_COUNT 89 -extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; -/* "0" */ -#define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0]) -/* "1" */ -#define GRPC_MDSTR_1 (&grpc_static_mdstr_table[1]) -/* "2" */ -#define GRPC_MDSTR_2 (&grpc_static_mdstr_table[2]) -/* "200" */ -#define GRPC_MDSTR_200 (&grpc_static_mdstr_table[3]) -/* "204" */ -#define GRPC_MDSTR_204 (&grpc_static_mdstr_table[4]) -/* "206" */ -#define GRPC_MDSTR_206 (&grpc_static_mdstr_table[5]) -/* "304" */ -#define GRPC_MDSTR_304 (&grpc_static_mdstr_table[6]) -/* "400" */ -#define GRPC_MDSTR_400 (&grpc_static_mdstr_table[7]) -/* "404" */ -#define GRPC_MDSTR_404 (&grpc_static_mdstr_table[8]) -/* "500" */ -#define GRPC_MDSTR_500 (&grpc_static_mdstr_table[9]) -/* "accept" */ -#define GRPC_MDSTR_ACCEPT (&grpc_static_mdstr_table[10]) -/* "accept-charset" */ -#define GRPC_MDSTR_ACCEPT_CHARSET (&grpc_static_mdstr_table[11]) -/* "accept-encoding" */ -#define GRPC_MDSTR_ACCEPT_ENCODING (&grpc_static_mdstr_table[12]) -/* "accept-language" */ -#define GRPC_MDSTR_ACCEPT_LANGUAGE (&grpc_static_mdstr_table[13]) -/* "accept-ranges" */ -#define GRPC_MDSTR_ACCEPT_RANGES (&grpc_static_mdstr_table[14]) -/* "access-control-allow-origin" */ -#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (&grpc_static_mdstr_table[15]) -/* "age" */ -#define GRPC_MDSTR_AGE (&grpc_static_mdstr_table[16]) -/* "allow" */ -#define GRPC_MDSTR_ALLOW (&grpc_static_mdstr_table[17]) -/* "application/grpc" */ -#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (&grpc_static_mdstr_table[18]) -/* ":authority" */ -#define GRPC_MDSTR_AUTHORITY (&grpc_static_mdstr_table[19]) -/* "authorization" */ -#define GRPC_MDSTR_AUTHORIZATION (&grpc_static_mdstr_table[20]) -/* "cache-control" */ -#define GRPC_MDSTR_CACHE_CONTROL (&grpc_static_mdstr_table[21]) -/* "census-bin" */ -#define GRPC_MDSTR_CENSUS_BIN (&grpc_static_mdstr_table[22]) -/* "census-binary-bin" */ -#define GRPC_MDSTR_CENSUS_BINARY_BIN (&grpc_static_mdstr_table[23]) -/* "content-disposition" */ -#define GRPC_MDSTR_CONTENT_DISPOSITION (&grpc_static_mdstr_table[24]) -/* "content-encoding" */ -#define GRPC_MDSTR_CONTENT_ENCODING (&grpc_static_mdstr_table[25]) -/* "content-language" */ -#define GRPC_MDSTR_CONTENT_LANGUAGE (&grpc_static_mdstr_table[26]) -/* "content-length" */ -#define GRPC_MDSTR_CONTENT_LENGTH (&grpc_static_mdstr_table[27]) -/* "content-location" */ -#define GRPC_MDSTR_CONTENT_LOCATION (&grpc_static_mdstr_table[28]) -/* "content-range" */ -#define GRPC_MDSTR_CONTENT_RANGE (&grpc_static_mdstr_table[29]) -/* "content-type" */ -#define GRPC_MDSTR_CONTENT_TYPE (&grpc_static_mdstr_table[30]) -/* "cookie" */ -#define GRPC_MDSTR_COOKIE (&grpc_static_mdstr_table[31]) -/* "date" */ -#define GRPC_MDSTR_DATE (&grpc_static_mdstr_table[32]) -/* "deflate" */ -#define GRPC_MDSTR_DEFLATE (&grpc_static_mdstr_table[33]) -/* "deflate,gzip" */ -#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (&grpc_static_mdstr_table[34]) -/* "" */ -#define GRPC_MDSTR_EMPTY (&grpc_static_mdstr_table[35]) -/* "etag" */ -#define GRPC_MDSTR_ETAG (&grpc_static_mdstr_table[36]) -/* "expect" */ -#define GRPC_MDSTR_EXPECT (&grpc_static_mdstr_table[37]) -/* "expires" */ -#define GRPC_MDSTR_EXPIRES (&grpc_static_mdstr_table[38]) -/* "from" */ -#define GRPC_MDSTR_FROM (&grpc_static_mdstr_table[39]) -/* "GET" */ -#define GRPC_MDSTR_GET (&grpc_static_mdstr_table[40]) -/* "grpc" */ -#define GRPC_MDSTR_GRPC (&grpc_static_mdstr_table[41]) -/* "grpc-accept-encoding" */ -#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (&grpc_static_mdstr_table[42]) -/* "grpc-encoding" */ -#define GRPC_MDSTR_GRPC_ENCODING (&grpc_static_mdstr_table[43]) -/* "grpc-internal-encoding-request" */ -#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[44]) -/* "grpc-message" */ -#define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[45]) -/* "grpc-status" */ -#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[46]) -/* "grpc-timeout" */ -#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[47]) -/* "gzip" */ -#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[48]) -/* "gzip, deflate" */ -#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[49]) -/* "host" */ -#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[50]) -/* "http" */ -#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[51]) -/* "https" */ -#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[52]) -/* "identity" */ -#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[53]) -/* "identity,deflate" */ -#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (&grpc_static_mdstr_table[54]) -/* "identity,deflate,gzip" */ -#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (&grpc_static_mdstr_table[55]) -/* "identity,gzip" */ -#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (&grpc_static_mdstr_table[56]) -/* "if-match" */ -#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[57]) -/* "if-modified-since" */ -#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[58]) -/* "if-none-match" */ -#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[59]) -/* "if-range" */ -#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[60]) -/* "if-unmodified-since" */ -#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[61]) -/* "last-modified" */ -#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[62]) -/* "link" */ -#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[63]) -/* "location" */ -#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[64]) -/* "max-forwards" */ -#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[65]) -/* ":method" */ -#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[66]) -/* ":path" */ -#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[67]) -/* "POST" */ -#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[68]) -/* "proxy-authenticate" */ -#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[69]) -/* "proxy-authorization" */ -#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[70]) -/* "range" */ -#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[71]) -/* "referer" */ -#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[72]) -/* "refresh" */ -#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[73]) -/* "retry-after" */ -#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[74]) -/* ":scheme" */ -#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[75]) -/* "server" */ -#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[76]) -/* "set-cookie" */ -#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[77]) -/* "/" */ -#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[78]) -/* "/index.html" */ -#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[79]) -/* ":status" */ -#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[80]) -/* "strict-transport-security" */ -#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[81]) -/* "te" */ -#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[82]) -/* "trailers" */ -#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[83]) -/* "transfer-encoding" */ -#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[84]) -/* "user-agent" */ -#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[85]) -/* "vary" */ -#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[86]) -/* "via" */ -#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[87]) -/* "www-authenticate" */ -#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[88]) - -#define GRPC_STATIC_MDELEM_COUNT 78 -extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; -extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; -/* "accept-charset": "" */ -#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY (&grpc_static_mdelem_table[0]) -/* "accept": "" */ -#define GRPC_MDELEM_ACCEPT_EMPTY (&grpc_static_mdelem_table[1]) -/* "accept-encoding": "" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY (&grpc_static_mdelem_table[2]) -/* "accept-encoding": "gzip, deflate" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ - (&grpc_static_mdelem_table[3]) -/* "accept-language": "" */ -#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY (&grpc_static_mdelem_table[4]) -/* "accept-ranges": "" */ -#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY (&grpc_static_mdelem_table[5]) -/* "access-control-allow-origin": "" */ -#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ - (&grpc_static_mdelem_table[6]) -/* "age": "" */ -#define GRPC_MDELEM_AGE_EMPTY (&grpc_static_mdelem_table[7]) -/* "allow": "" */ -#define GRPC_MDELEM_ALLOW_EMPTY (&grpc_static_mdelem_table[8]) -/* ":authority": "" */ -#define GRPC_MDELEM_AUTHORITY_EMPTY (&grpc_static_mdelem_table[9]) -/* "authorization": "" */ -#define GRPC_MDELEM_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[10]) -/* "cache-control": "" */ -#define GRPC_MDELEM_CACHE_CONTROL_EMPTY (&grpc_static_mdelem_table[11]) -/* "content-disposition": "" */ -#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY (&grpc_static_mdelem_table[12]) -/* "content-encoding": "" */ -#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY (&grpc_static_mdelem_table[13]) -/* "content-language": "" */ -#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY (&grpc_static_mdelem_table[14]) -/* "content-length": "" */ -#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY (&grpc_static_mdelem_table[15]) -/* "content-location": "" */ -#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY (&grpc_static_mdelem_table[16]) -/* "content-range": "" */ -#define GRPC_MDELEM_CONTENT_RANGE_EMPTY (&grpc_static_mdelem_table[17]) -/* "content-type": "application/grpc" */ -#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ - (&grpc_static_mdelem_table[18]) -/* "content-type": "" */ -#define GRPC_MDELEM_CONTENT_TYPE_EMPTY (&grpc_static_mdelem_table[19]) -/* "cookie": "" */ -#define GRPC_MDELEM_COOKIE_EMPTY (&grpc_static_mdelem_table[20]) -/* "date": "" */ -#define GRPC_MDELEM_DATE_EMPTY (&grpc_static_mdelem_table[21]) -/* "etag": "" */ -#define GRPC_MDELEM_ETAG_EMPTY (&grpc_static_mdelem_table[22]) -/* "expect": "" */ -#define GRPC_MDELEM_EXPECT_EMPTY (&grpc_static_mdelem_table[23]) -/* "expires": "" */ -#define GRPC_MDELEM_EXPIRES_EMPTY (&grpc_static_mdelem_table[24]) -/* "from": "" */ -#define GRPC_MDELEM_FROM_EMPTY (&grpc_static_mdelem_table[25]) -/* "grpc-accept-encoding": "deflate" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE (&grpc_static_mdelem_table[26]) -/* "grpc-accept-encoding": "deflate,gzip" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \ - (&grpc_static_mdelem_table[27]) -/* "grpc-accept-encoding": "gzip" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP (&grpc_static_mdelem_table[28]) -/* "grpc-accept-encoding": "identity" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ - (&grpc_static_mdelem_table[29]) -/* "grpc-accept-encoding": "identity,deflate" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \ - (&grpc_static_mdelem_table[30]) -/* "grpc-accept-encoding": "identity,deflate,gzip" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (&grpc_static_mdelem_table[31]) -/* "grpc-accept-encoding": "identity,gzip" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ - (&grpc_static_mdelem_table[32]) -/* "grpc-encoding": "deflate" */ -#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE (&grpc_static_mdelem_table[33]) -/* "grpc-encoding": "gzip" */ -#define GRPC_MDELEM_GRPC_ENCODING_GZIP (&grpc_static_mdelem_table[34]) -/* "grpc-encoding": "identity" */ -#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY (&grpc_static_mdelem_table[35]) -/* "grpc-status": "0" */ -#define GRPC_MDELEM_GRPC_STATUS_0 (&grpc_static_mdelem_table[36]) -/* "grpc-status": "1" */ -#define GRPC_MDELEM_GRPC_STATUS_1 (&grpc_static_mdelem_table[37]) -/* "grpc-status": "2" */ -#define GRPC_MDELEM_GRPC_STATUS_2 (&grpc_static_mdelem_table[38]) -/* "host": "" */ -#define GRPC_MDELEM_HOST_EMPTY (&grpc_static_mdelem_table[39]) -/* "if-match": "" */ -#define GRPC_MDELEM_IF_MATCH_EMPTY (&grpc_static_mdelem_table[40]) -/* "if-modified-since": "" */ -#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[41]) -/* "if-none-match": "" */ -#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY (&grpc_static_mdelem_table[42]) -/* "if-range": "" */ -#define GRPC_MDELEM_IF_RANGE_EMPTY (&grpc_static_mdelem_table[43]) -/* "if-unmodified-since": "" */ -#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[44]) -/* "last-modified": "" */ -#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (&grpc_static_mdelem_table[45]) -/* "link": "" */ -#define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[46]) -/* "location": "" */ -#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[47]) -/* "max-forwards": "" */ -#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (&grpc_static_mdelem_table[48]) -/* ":method": "GET" */ -#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[49]) -/* ":method": "POST" */ -#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[50]) -/* ":path": "/" */ -#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[51]) -/* ":path": "/index.html" */ -#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[52]) -/* "proxy-authenticate": "" */ -#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[53]) -/* "proxy-authorization": "" */ -#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[54]) -/* "range": "" */ -#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[55]) -/* "referer": "" */ -#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[56]) -/* "refresh": "" */ -#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[57]) -/* "retry-after": "" */ -#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[58]) -/* ":scheme": "grpc" */ -#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[59]) -/* ":scheme": "http" */ -#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[60]) -/* ":scheme": "https" */ -#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[61]) -/* "server": "" */ -#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[62]) -/* "set-cookie": "" */ -#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[63]) -/* ":status": "200" */ -#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[64]) -/* ":status": "204" */ -#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[65]) -/* ":status": "206" */ -#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[66]) -/* ":status": "304" */ -#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[67]) -/* ":status": "400" */ -#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[68]) -/* ":status": "404" */ -#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[69]) -/* ":status": "500" */ -#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[70]) -/* "strict-transport-security": "" */ -#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ - (&grpc_static_mdelem_table[71]) -/* "te": "trailers" */ -#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[72]) -/* "transfer-encoding": "" */ -#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[73]) -/* "user-agent": "" */ -#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[74]) -/* "vary": "" */ -#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[75]) -/* "via": "" */ -#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[76]) -/* "www-authenticate": "" */ -#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[77]) - -extern const uint8_t - grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2]; -extern const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT]; -extern const uint8_t grpc_static_accept_encoding_metadata[8]; -#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \ - (&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]]) -#endif /* GRPC_CORE_TRANSPORT_STATIC_METADATA_H */ diff --git a/src/core/transport/transport.c b/src/core/transport/transport.c deleted file mode 100644 index 3b555fa933..0000000000 --- a/src/core/transport/transport.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * - * Copyright 2015-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/transport/transport.h" -#include -#include -#include -#include "src/core/transport/transport_impl.h" - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -void grpc_stream_ref(grpc_stream_refcount *refcount, const char *reason) { - gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count); - gpr_log(GPR_DEBUG, "%s %p:%p REF %d->%d %s", refcount->object_type, - refcount, refcount->destroy.cb_arg, val, val + 1, reason); -#else -void grpc_stream_ref(grpc_stream_refcount *refcount) { -#endif - gpr_ref_non_zero(&refcount->refs); -} - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount, - const char *reason) { - gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count); - gpr_log(GPR_DEBUG, "%s %p:%p UNREF %d->%d %s", refcount->object_type, - refcount, refcount->destroy.cb_arg, val, val - 1, reason); -#else -void grpc_stream_unref(grpc_exec_ctx *exec_ctx, - grpc_stream_refcount *refcount) { -#endif - if (gpr_unref(&refcount->refs)) { - grpc_exec_ctx_enqueue(exec_ctx, &refcount->destroy, true, NULL); - } -} - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, - grpc_iomgr_cb_func cb, void *cb_arg, - const char *object_type) { - refcount->object_type = object_type; -#else -void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, - grpc_iomgr_cb_func cb, void *cb_arg) { -#endif - gpr_ref_init(&refcount->refs, initial_refs); - grpc_closure_init(&refcount->destroy, cb, cb_arg); -} - -size_t grpc_transport_stream_size(grpc_transport *transport) { - return transport->vtable->sizeof_stream; -} - -void grpc_transport_destroy(grpc_exec_ctx *exec_ctx, - grpc_transport *transport) { - transport->vtable->destroy(exec_ctx, transport); -} - -int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx, - grpc_transport *transport, grpc_stream *stream, - grpc_stream_refcount *refcount, - const void *server_data) { - return transport->vtable->init_stream(exec_ctx, transport, stream, refcount, - server_data); -} - -void grpc_transport_perform_stream_op(grpc_exec_ctx *exec_ctx, - grpc_transport *transport, - grpc_stream *stream, - grpc_transport_stream_op *op) { - transport->vtable->perform_stream_op(exec_ctx, transport, stream, op); -} - -void grpc_transport_perform_op(grpc_exec_ctx *exec_ctx, - grpc_transport *transport, - grpc_transport_op *op) { - transport->vtable->perform_op(exec_ctx, transport, op); -} - -void grpc_transport_set_pollset(grpc_exec_ctx *exec_ctx, - grpc_transport *transport, grpc_stream *stream, - grpc_pollset *pollset) { - transport->vtable->set_pollset(exec_ctx, transport, stream, pollset); -} - -void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx, - grpc_transport *transport, - grpc_stream *stream) { - transport->vtable->destroy_stream(exec_ctx, transport, stream); -} - -char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx, - grpc_transport *transport) { - return transport->vtable->get_peer(exec_ctx, transport); -} - -void grpc_transport_stream_op_finish_with_failure( - grpc_exec_ctx *exec_ctx, grpc_transport_stream_op *op) { - grpc_exec_ctx_enqueue(exec_ctx, op->recv_message_ready, false, NULL); - grpc_exec_ctx_enqueue(exec_ctx, op->recv_initial_metadata_ready, false, NULL); - grpc_exec_ctx_enqueue(exec_ctx, op->on_complete, false, NULL); -} - -void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op, - grpc_status_code status) { - GPR_ASSERT(status != GRPC_STATUS_OK); - if (op->cancel_with_status == GRPC_STATUS_OK) { - op->cancel_with_status = status; - } - if (op->close_with_status != GRPC_STATUS_OK) { - op->close_with_status = GRPC_STATUS_OK; - if (op->optional_close_message != NULL) { - gpr_slice_unref(*op->optional_close_message); - op->optional_close_message = NULL; - } - } -} - -typedef struct { - gpr_slice message; - grpc_closure *then_call; - grpc_closure closure; -} close_message_data; - -static void free_message(grpc_exec_ctx *exec_ctx, void *p, bool iomgr_success) { - close_message_data *cmd = p; - gpr_slice_unref(cmd->message); - if (cmd->then_call != NULL) { - cmd->then_call->cb(exec_ctx, cmd->then_call->cb_arg, iomgr_success); - } - gpr_free(cmd); -} - -void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op, - grpc_status_code status, - gpr_slice *optional_message) { - close_message_data *cmd; - GPR_ASSERT(status != GRPC_STATUS_OK); - if (op->cancel_with_status != GRPC_STATUS_OK || - op->close_with_status != GRPC_STATUS_OK) { - if (optional_message) { - gpr_slice_unref(*optional_message); - } - return; - } - if (optional_message) { - cmd = gpr_malloc(sizeof(*cmd)); - cmd->message = *optional_message; - cmd->then_call = op->on_complete; - grpc_closure_init(&cmd->closure, free_message, cmd); - op->on_complete = &cmd->closure; - op->optional_close_message = &cmd->message; - } - op->close_with_status = status; -} diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h deleted file mode 100644 index f43e56f23c..0000000000 --- a/src/core/transport/transport.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_TRANSPORT_H -#define GRPC_CORE_TRANSPORT_TRANSPORT_H - -#include - -#include "src/core/channel/context.h" -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/pollset_set.h" -#include "src/core/transport/byte_stream.h" -#include "src/core/transport/metadata_batch.h" - -/* forward declarations */ -typedef struct grpc_transport grpc_transport; - -/* grpc_stream doesn't actually exist. It's used as a typesafe - opaque pointer for whatever data the transport wants to track - for a stream. */ -typedef struct grpc_stream grpc_stream; - -/*#define GRPC_STREAM_REFCOUNT_DEBUG*/ - -typedef struct grpc_stream_refcount { - gpr_refcount refs; - grpc_closure destroy; -#ifdef GRPC_STREAM_REFCOUNT_DEBUG - const char *object_type; -#endif -} grpc_stream_refcount; - -#ifdef GRPC_STREAM_REFCOUNT_DEBUG -void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, - grpc_iomgr_cb_func cb, void *cb_arg, - const char *object_type); -void grpc_stream_ref(grpc_stream_refcount *refcount, const char *reason); -void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount, - const char *reason); -#define GRPC_STREAM_REF_INIT(rc, ir, cb, cb_arg, objtype) \ - grpc_stream_ref_init(rc, ir, cb, cb_arg, objtype) -#else -void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, - grpc_iomgr_cb_func cb, void *cb_arg); -void grpc_stream_ref(grpc_stream_refcount *refcount); -void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount); -#define GRPC_STREAM_REF_INIT(rc, ir, cb, cb_arg, objtype) \ - grpc_stream_ref_init(rc, ir, cb, cb_arg) -#endif - -/* Transport stream op: a set of operations to perform on a transport - against a single stream */ -typedef struct grpc_transport_stream_op { - /** Send initial metadata to the peer, from the provided metadata batch. */ - grpc_metadata_batch *send_initial_metadata; - - /** Send trailing metadata to the peer, from the provided metadata batch. */ - grpc_metadata_batch *send_trailing_metadata; - - /** Send message data to the peer, from the provided byte stream. */ - grpc_byte_stream *send_message; - - /** Receive initial metadata from the stream, into provided metadata batch. */ - grpc_metadata_batch *recv_initial_metadata; - /** Should be enqueued when initial metadata is ready to be processed. */ - grpc_closure *recv_initial_metadata_ready; - - /** Receive message data from the stream, into provided byte stream. */ - grpc_byte_stream **recv_message; - /** Should be enqueued when one message is ready to be processed. */ - grpc_closure *recv_message_ready; - - /** Receive trailing metadata from the stream, into provided metadata batch. - */ - grpc_metadata_batch *recv_trailing_metadata; - - /** Should be enqueued when all requested operations (excluding recv_message - and recv_initial_metadata which have their own closures) in a given batch - have been completed. */ - grpc_closure *on_complete; - - /** If != GRPC_STATUS_OK, cancel this stream */ - grpc_status_code cancel_with_status; - - /** If != GRPC_STATUS_OK, send grpc-status, grpc-message, and close this - stream for both reading and writing */ - grpc_status_code close_with_status; - gpr_slice *optional_close_message; - - /* Indexes correspond to grpc_context_index enum values */ - grpc_call_context_element *context; -} grpc_transport_stream_op; - -/** Transport op: a set of operations to perform on a transport as a whole */ -typedef struct grpc_transport_op { - /** Called when processing of this op is done. */ - grpc_closure *on_consumed; - /** connectivity monitoring - set connectivity_state to NULL to unsubscribe */ - grpc_closure *on_connectivity_state_change; - grpc_connectivity_state *connectivity_state; - /** should the transport be disconnected */ - int disconnect; - /** should we send a goaway? - after a goaway is sent, once there are no more active calls on - the transport, the transport should disconnect */ - int send_goaway; - /** what should the goaway contain? */ - grpc_status_code goaway_status; - gpr_slice *goaway_message; - /** set the callback for accepting new streams; - this is a permanent callback, unlike the other one-shot closures. - If true, the callback is set to set_accept_stream_fn, with its - user_data argument set to set_accept_stream_user_data */ - bool set_accept_stream; - void (*set_accept_stream_fn)(grpc_exec_ctx *exec_ctx, void *user_data, - grpc_transport *transport, - const void *server_data); - void *set_accept_stream_user_data; - /** add this transport to a pollset */ - grpc_pollset *bind_pollset; - /** add this transport to a pollset_set */ - grpc_pollset_set *bind_pollset_set; - /** send a ping, call this back if not NULL */ - grpc_closure *send_ping; -} grpc_transport_op; - -/* Returns the amount of memory required to store a grpc_stream for this - transport */ -size_t grpc_transport_stream_size(grpc_transport *transport); - -/* Initialize transport data for a stream. - - Returns 0 on success, any other (transport-defined) value for failure. - - Arguments: - transport - the transport on which to create this stream - stream - a pointer to uninitialized memory to initialize - server_data - either NULL for a client initiated stream, or a pointer - supplied from the accept_stream callback function */ -int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx, - grpc_transport *transport, grpc_stream *stream, - grpc_stream_refcount *refcount, - const void *server_data); - -void grpc_transport_set_pollset(grpc_exec_ctx *exec_ctx, - grpc_transport *transport, grpc_stream *stream, - grpc_pollset *pollset); - -/* Destroy transport data for a stream. - - Requires: a recv_batch with final_state == GRPC_STREAM_CLOSED has been - received by the up-layer. Must not be called in the same call stack as - recv_frame. - - Arguments: - transport - the transport on which to create this stream - stream - the grpc_stream to destroy (memory is still owned by the - caller, but any child memory must be cleaned up) */ -void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx, - grpc_transport *transport, - grpc_stream *stream); - -void grpc_transport_stream_op_finish_with_failure(grpc_exec_ctx *exec_ctx, - grpc_transport_stream_op *op); - -void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op, - grpc_status_code status); - -void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op, - grpc_status_code status, - gpr_slice *optional_message); - -char *grpc_transport_stream_op_string(grpc_transport_stream_op *op); - -/* Send a batch of operations on a transport - - Takes ownership of any objects contained in ops. - - Arguments: - transport - the transport on which to initiate the stream - stream - the stream on which to send the operations. This must be - non-NULL and previously initialized by the same transport. - op - a grpc_transport_stream_op specifying the op to perform */ -void grpc_transport_perform_stream_op(grpc_exec_ctx *exec_ctx, - grpc_transport *transport, - grpc_stream *stream, - grpc_transport_stream_op *op); - -void grpc_transport_perform_op(grpc_exec_ctx *exec_ctx, - grpc_transport *transport, - grpc_transport_op *op); - -/* Send a ping on a transport - - Calls cb with user data when a response is received. */ -void grpc_transport_ping(grpc_transport *transport, grpc_closure *cb); - -/* Advise peer of pending connection termination. */ -void grpc_transport_goaway(grpc_transport *transport, grpc_status_code status, - gpr_slice debug_data); - -/* Close a transport. Aborts all open streams. */ -void grpc_transport_close(grpc_transport *transport); - -/* Destroy the transport */ -void grpc_transport_destroy(grpc_exec_ctx *exec_ctx, grpc_transport *transport); - -/* Get the transports peer */ -char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx, - grpc_transport *transport); - -#endif /* GRPC_CORE_TRANSPORT_TRANSPORT_H */ diff --git a/src/core/transport/transport_impl.h b/src/core/transport/transport_impl.h deleted file mode 100644 index d9ecc4d2ba..0000000000 --- a/src/core/transport/transport_impl.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * Copyright 2015-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_TRANSPORT_TRANSPORT_IMPL_H -#define GRPC_CORE_TRANSPORT_TRANSPORT_IMPL_H - -#include "src/core/transport/transport.h" - -typedef struct grpc_transport_vtable { - /* Memory required for a single stream element - this is allocated by upper - layers and initialized by the transport */ - size_t sizeof_stream; /* = sizeof(transport stream) */ - - /* name of this transport implementation */ - const char *name; - - /* implementation of grpc_transport_init_stream */ - int (*init_stream)(grpc_exec_ctx *exec_ctx, grpc_transport *self, - grpc_stream *stream, grpc_stream_refcount *refcount, - const void *server_data); - - /* implementation of grpc_transport_set_pollset */ - void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_transport *self, - grpc_stream *stream, grpc_pollset *pollset); - - /* implementation of grpc_transport_perform_stream_op */ - void (*perform_stream_op)(grpc_exec_ctx *exec_ctx, grpc_transport *self, - grpc_stream *stream, grpc_transport_stream_op *op); - - /* implementation of grpc_transport_perform_op */ - void (*perform_op)(grpc_exec_ctx *exec_ctx, grpc_transport *self, - grpc_transport_op *op); - - /* implementation of grpc_transport_destroy_stream */ - void (*destroy_stream)(grpc_exec_ctx *exec_ctx, grpc_transport *self, - grpc_stream *stream); - - /* implementation of grpc_transport_destroy */ - void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_transport *self); - - /* implementation of grpc_transport_get_peer */ - char *(*get_peer)(grpc_exec_ctx *exec_ctx, grpc_transport *self); -} grpc_transport_vtable; - -/* an instance of a grpc transport */ -struct grpc_transport { - /* pointer to a vtable defining operations on this transport */ - const grpc_transport_vtable *vtable; -}; - -#endif /* GRPC_CORE_TRANSPORT_TRANSPORT_IMPL_H */ diff --git a/src/core/transport/transport_op_string.c b/src/core/transport/transport_op_string.c deleted file mode 100644 index 8453412480..0000000000 --- a/src/core/transport/transport_op_string.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * - * Copyright 2015-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/channel/channel_stack.h" - -#include -#include -#include - -#include -#include -#include -#include "src/core/support/string.h" - -/* These routines are here to facilitate debugging - they produce string - representations of various transport data structures */ - -static void put_metadata(gpr_strvec *b, grpc_mdelem *md) { - gpr_strvec_add(b, gpr_strdup("key=")); - gpr_strvec_add(b, - gpr_dump_slice(md->key->slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)); - - gpr_strvec_add(b, gpr_strdup(" value=")); - gpr_strvec_add( - b, gpr_dump_slice(md->value->slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)); -} - -static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) { - grpc_linked_mdelem *m; - for (m = md.list.head; m != NULL; m = m->next) { - if (m != md.list.head) gpr_strvec_add(b, gpr_strdup(", ")); - put_metadata(b, m->md); - } - if (gpr_time_cmp(md.deadline, gpr_inf_future(md.deadline.clock_type)) != 0) { - char *tmp; - gpr_asprintf(&tmp, " deadline=%lld.%09d", (long long)md.deadline.tv_sec, - (int)md.deadline.tv_nsec); - gpr_strvec_add(b, tmp); - } -} - -char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { - char *tmp; - char *out; - int first = 1; - - gpr_strvec b; - gpr_strvec_init(&b); - - if (op->send_initial_metadata != NULL) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; - gpr_strvec_add(&b, gpr_strdup("SEND_INITIAL_METADATA{")); - put_metadata_list(&b, *op->send_initial_metadata); - gpr_strvec_add(&b, gpr_strdup("}")); - } - - if (op->send_message != NULL) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; - gpr_asprintf(&tmp, "SEND_MESSAGE:flags=0x%08x:len=%d", - op->send_message->flags, op->send_message->length); - gpr_strvec_add(&b, tmp); - } - - if (op->send_trailing_metadata != NULL) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; - gpr_strvec_add(&b, gpr_strdup("SEND_TRAILING_METADATA{")); - put_metadata_list(&b, *op->send_trailing_metadata); - gpr_strvec_add(&b, gpr_strdup("}")); - } - - if (op->recv_initial_metadata != NULL) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; - gpr_strvec_add(&b, gpr_strdup("RECV_INITIAL_METADATA")); - } - - if (op->recv_message != NULL) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; - gpr_strvec_add(&b, gpr_strdup("RECV_MESSAGE")); - } - - if (op->recv_trailing_metadata != NULL) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; - gpr_strvec_add(&b, gpr_strdup("RECV_TRAILING_METADATA")); - } - - if (op->cancel_with_status != GRPC_STATUS_OK) { - if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); - first = 0; - gpr_asprintf(&tmp, "CANCEL:%d", op->cancel_with_status); - gpr_strvec_add(&b, tmp); - } - - out = gpr_strvec_flatten(&b, NULL); - gpr_strvec_destroy(&b); - - return out; -} - -void grpc_call_log_op(char *file, int line, gpr_log_severity severity, - grpc_call_element *elem, grpc_transport_stream_op *op) { - char *str = grpc_transport_stream_op_string(op); - gpr_log(file, line, severity, "OP[%s:%p]: %s", elem->filter->name, elem, str); - gpr_free(str); -} diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c deleted file mode 100644 index c0106f7a33..0000000000 --- a/src/core/tsi/fake_transport_security.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * - * Copyright 2015-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/tsi/fake_transport_security.h" - -#include -#include - -#include -#include -#include -#include "src/core/tsi/transport_security.h" - -/* --- Constants. ---*/ -#define TSI_FAKE_FRAME_HEADER_SIZE 4 -#define TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE 64 -#define TSI_FAKE_DEFAULT_FRAME_SIZE 16384 - -/* --- Structure definitions. ---*/ - -/* a frame is encoded like this: - | size | data | - where the size field value is the size of the size field plus the size of - the data encoded in little endian on 4 bytes. */ -typedef struct { - unsigned char *data; - size_t size; - size_t allocated_size; - size_t offset; - int needs_draining; -} tsi_fake_frame; - -typedef enum { - TSI_FAKE_CLIENT_INIT = 0, - TSI_FAKE_SERVER_INIT = 1, - TSI_FAKE_CLIENT_FINISHED = 2, - TSI_FAKE_SERVER_FINISHED = 3, - TSI_FAKE_HANDSHAKE_MESSAGE_MAX = 4 -} tsi_fake_handshake_message; - -typedef struct { - tsi_handshaker base; - int is_client; - tsi_fake_handshake_message next_message_to_send; - int needs_incoming_message; - tsi_fake_frame incoming; - tsi_fake_frame outgoing; - tsi_result result; -} tsi_fake_handshaker; - -typedef struct { - tsi_frame_protector base; - tsi_fake_frame protect_frame; - tsi_fake_frame unprotect_frame; - size_t max_frame_size; -} tsi_fake_frame_protector; - -/* --- Utils. ---*/ - -static const char *tsi_fake_handshake_message_strings[] = { - "CLIENT_INIT", "SERVER_INIT", "CLIENT_FINISHED", "SERVER_FINISHED"}; - -static const char *tsi_fake_handshake_message_to_string(int msg) { - if (msg < 0 || msg >= TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { - gpr_log(GPR_ERROR, "Invalid message %d", msg); - return "UNKNOWN"; - } - return tsi_fake_handshake_message_strings[msg]; -} - -static tsi_result tsi_fake_handshake_message_from_string( - const char *msg_string, tsi_fake_handshake_message *msg) { - tsi_fake_handshake_message i; - for (i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) { - if (strncmp(msg_string, tsi_fake_handshake_message_strings[i], - strlen(tsi_fake_handshake_message_strings[i])) == 0) { - *msg = i; - return TSI_OK; - } - } - gpr_log(GPR_ERROR, "Invalid handshake message."); - return TSI_DATA_CORRUPTED; -} - -static uint32_t load32_little_endian(const unsigned char *buf) { - return ((uint32_t)(buf[0]) | (uint32_t)(buf[1] << 8) | - (uint32_t)(buf[2] << 16) | (uint32_t)(buf[3] << 24)); -} - -static void store32_little_endian(uint32_t value, unsigned char *buf) { - buf[3] = (unsigned char)((value >> 24) & 0xFF); - buf[2] = (unsigned char)((value >> 16) & 0xFF); - buf[1] = (unsigned char)((value >> 8) & 0xFF); - buf[0] = (unsigned char)((value)&0xFF); -} - -static void tsi_fake_frame_reset(tsi_fake_frame *frame, int needs_draining) { - frame->offset = 0; - frame->needs_draining = needs_draining; - if (!needs_draining) frame->size = 0; -} - -/* Returns 1 if successful, 0 otherwise. */ -static int tsi_fake_frame_ensure_size(tsi_fake_frame *frame) { - if (frame->data == NULL) { - frame->allocated_size = frame->size; - frame->data = malloc(frame->allocated_size); - if (frame->data == NULL) return 0; - } else if (frame->size > frame->allocated_size) { - unsigned char *new_data = realloc(frame->data, frame->size); - if (new_data == NULL) { - free(frame->data); - frame->data = NULL; - return 0; - } - frame->data = new_data; - frame->allocated_size = frame->size; - } - return 1; -} - -/* This method should not be called if frame->needs_framing is not 0. */ -static tsi_result fill_frame_from_bytes(const unsigned char *incoming_bytes, - size_t *incoming_bytes_size, - tsi_fake_frame *frame) { - size_t available_size = *incoming_bytes_size; - size_t to_read_size = 0; - const unsigned char *bytes_cursor = incoming_bytes; - - if (frame->needs_draining) return TSI_INTERNAL_ERROR; - if (frame->data == NULL) { - frame->allocated_size = TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE; - frame->data = malloc(frame->allocated_size); - if (frame->data == NULL) return TSI_OUT_OF_RESOURCES; - } - - if (frame->offset < TSI_FAKE_FRAME_HEADER_SIZE) { - to_read_size = TSI_FAKE_FRAME_HEADER_SIZE - frame->offset; - if (to_read_size > available_size) { - /* Just fill what we can and exit. */ - memcpy(frame->data + frame->offset, bytes_cursor, available_size); - bytes_cursor += available_size; - frame->offset += available_size; - *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes); - return TSI_INCOMPLETE_DATA; - } - memcpy(frame->data + frame->offset, bytes_cursor, to_read_size); - bytes_cursor += to_read_size; - frame->offset += to_read_size; - available_size -= to_read_size; - frame->size = load32_little_endian(frame->data); - if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES; - } - - to_read_size = frame->size - frame->offset; - if (to_read_size > available_size) { - memcpy(frame->data + frame->offset, bytes_cursor, available_size); - frame->offset += available_size; - bytes_cursor += available_size; - *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes); - return TSI_INCOMPLETE_DATA; - } - memcpy(frame->data + frame->offset, bytes_cursor, to_read_size); - bytes_cursor += to_read_size; - *incoming_bytes_size = (size_t)(bytes_cursor - incoming_bytes); - tsi_fake_frame_reset(frame, 1 /* needs_draining */); - return TSI_OK; -} - -/* This method should not be called if frame->needs_framing is 0. */ -static tsi_result drain_frame_to_bytes(unsigned char *outgoing_bytes, - size_t *outgoing_bytes_size, - tsi_fake_frame *frame) { - size_t to_write_size = frame->size - frame->offset; - if (!frame->needs_draining) return TSI_INTERNAL_ERROR; - if (*outgoing_bytes_size < to_write_size) { - memcpy(outgoing_bytes, frame->data + frame->offset, *outgoing_bytes_size); - frame->offset += *outgoing_bytes_size; - return TSI_INCOMPLETE_DATA; - } - memcpy(outgoing_bytes, frame->data + frame->offset, to_write_size); - *outgoing_bytes_size = to_write_size; - tsi_fake_frame_reset(frame, 0 /* needs_draining */); - return TSI_OK; -} - -static tsi_result bytes_to_frame(unsigned char *bytes, size_t bytes_size, - tsi_fake_frame *frame) { - frame->offset = 0; - frame->size = bytes_size + TSI_FAKE_FRAME_HEADER_SIZE; - if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES; - store32_little_endian((uint32_t)frame->size, frame->data); - memcpy(frame->data + TSI_FAKE_FRAME_HEADER_SIZE, bytes, bytes_size); - tsi_fake_frame_reset(frame, 1 /* needs draining */); - return TSI_OK; -} - -static void tsi_fake_frame_destruct(tsi_fake_frame *frame) { - if (frame->data != NULL) free(frame->data); -} - -/* --- tsi_frame_protector methods implementation. ---*/ - -static tsi_result fake_protector_protect(tsi_frame_protector *self, - const unsigned char *unprotected_bytes, - size_t *unprotected_bytes_size, - unsigned char *protected_output_frames, - size_t *protected_output_frames_size) { - tsi_result result = TSI_OK; - tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; - unsigned char frame_header[TSI_FAKE_FRAME_HEADER_SIZE]; - tsi_fake_frame *frame = &impl->protect_frame; - size_t saved_output_size = *protected_output_frames_size; - size_t drained_size = 0; - size_t *num_bytes_written = protected_output_frames_size; - *num_bytes_written = 0; - - /* Try to drain first. */ - if (frame->needs_draining) { - drained_size = saved_output_size - *num_bytes_written; - result = - drain_frame_to_bytes(protected_output_frames, &drained_size, frame); - *num_bytes_written += drained_size; - protected_output_frames += drained_size; - if (result != TSI_OK) { - if (result == TSI_INCOMPLETE_DATA) { - *unprotected_bytes_size = 0; - result = TSI_OK; - } - return result; - } - } - - /* Now process the unprotected_bytes. */ - if (frame->needs_draining) return TSI_INTERNAL_ERROR; - if (frame->size == 0) { - /* New frame, create a header. */ - size_t written_in_frame_size = 0; - store32_little_endian((uint32_t)impl->max_frame_size, frame_header); - written_in_frame_size = TSI_FAKE_FRAME_HEADER_SIZE; - result = fill_frame_from_bytes(frame_header, &written_in_frame_size, frame); - if (result != TSI_INCOMPLETE_DATA) { - gpr_log(GPR_ERROR, "fill_frame_from_bytes returned %s", - tsi_result_to_string(result)); - return result; - } - } - result = - fill_frame_from_bytes(unprotected_bytes, unprotected_bytes_size, frame); - if (result != TSI_OK) { - if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; - return result; - } - - /* Try to drain again. */ - if (!frame->needs_draining) return TSI_INTERNAL_ERROR; - if (frame->offset != 0) return TSI_INTERNAL_ERROR; - drained_size = saved_output_size - *num_bytes_written; - result = drain_frame_to_bytes(protected_output_frames, &drained_size, frame); - *num_bytes_written += drained_size; - if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; - return result; -} - -static tsi_result fake_protector_protect_flush( - tsi_frame_protector *self, unsigned char *protected_output_frames, - size_t *protected_output_frames_size, size_t *still_pending_size) { - tsi_result result = TSI_OK; - tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; - tsi_fake_frame *frame = &impl->protect_frame; - if (!frame->needs_draining) { - /* Create a short frame. */ - frame->size = frame->offset; - frame->offset = 0; - frame->needs_draining = 1; - store32_little_endian((uint32_t)frame->size, - frame->data); /* Overwrite header. */ - } - result = drain_frame_to_bytes(protected_output_frames, - protected_output_frames_size, frame); - if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; - *still_pending_size = frame->size - frame->offset; - return result; -} - -static tsi_result fake_protector_unprotect( - tsi_frame_protector *self, const unsigned char *protected_frames_bytes, - size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes, - size_t *unprotected_bytes_size) { - tsi_result result = TSI_OK; - tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; - tsi_fake_frame *frame = &impl->unprotect_frame; - size_t saved_output_size = *unprotected_bytes_size; - size_t drained_size = 0; - size_t *num_bytes_written = unprotected_bytes_size; - *num_bytes_written = 0; - - /* Try to drain first. */ - if (frame->needs_draining) { - /* Go past the header if needed. */ - if (frame->offset == 0) frame->offset = TSI_FAKE_FRAME_HEADER_SIZE; - drained_size = saved_output_size - *num_bytes_written; - result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame); - unprotected_bytes += drained_size; - *num_bytes_written += drained_size; - if (result != TSI_OK) { - if (result == TSI_INCOMPLETE_DATA) { - *protected_frames_bytes_size = 0; - result = TSI_OK; - } - return result; - } - } - - /* Now process the protected_bytes. */ - if (frame->needs_draining) return TSI_INTERNAL_ERROR; - result = fill_frame_from_bytes(protected_frames_bytes, - protected_frames_bytes_size, frame); - if (result != TSI_OK) { - if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; - return result; - } - - /* Try to drain again. */ - if (!frame->needs_draining) return TSI_INTERNAL_ERROR; - if (frame->offset != 0) return TSI_INTERNAL_ERROR; - frame->offset = TSI_FAKE_FRAME_HEADER_SIZE; /* Go past the header. */ - drained_size = saved_output_size - *num_bytes_written; - result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame); - *num_bytes_written += drained_size; - if (result == TSI_INCOMPLETE_DATA) result = TSI_OK; - return result; -} - -static void fake_protector_destroy(tsi_frame_protector *self) { - tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; - tsi_fake_frame_destruct(&impl->protect_frame); - tsi_fake_frame_destruct(&impl->unprotect_frame); - free(self); -} - -static const tsi_frame_protector_vtable frame_protector_vtable = { - fake_protector_protect, fake_protector_protect_flush, - fake_protector_unprotect, fake_protector_destroy, -}; - -/* --- tsi_handshaker methods implementation. ---*/ - -static tsi_result fake_handshaker_get_bytes_to_send_to_peer( - tsi_handshaker *self, unsigned char *bytes, size_t *bytes_size) { - tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; - tsi_result result = TSI_OK; - if (impl->needs_incoming_message || impl->result == TSI_OK) { - *bytes_size = 0; - return TSI_OK; - } - if (!impl->outgoing.needs_draining) { - tsi_fake_handshake_message next_message_to_send = - impl->next_message_to_send + 2; - const char *msg_string = - tsi_fake_handshake_message_to_string(impl->next_message_to_send); - result = bytes_to_frame((unsigned char *)msg_string, strlen(msg_string), - &impl->outgoing); - if (result != TSI_OK) return result; - if (next_message_to_send > TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { - next_message_to_send = TSI_FAKE_HANDSHAKE_MESSAGE_MAX; - } - if (tsi_tracing_enabled) { - gpr_log(GPR_INFO, "%s prepared %s.", - impl->is_client ? "Client" : "Server", - tsi_fake_handshake_message_to_string(impl->next_message_to_send)); - } - impl->next_message_to_send = next_message_to_send; - } - result = drain_frame_to_bytes(bytes, bytes_size, &impl->outgoing); - if (result != TSI_OK) return result; - if (!impl->is_client && - impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { - /* We're done. */ - if (tsi_tracing_enabled) { - gpr_log(GPR_INFO, "Server is done."); - } - impl->result = TSI_OK; - } else { - impl->needs_incoming_message = 1; - } - return TSI_OK; -} - -static tsi_result fake_handshaker_process_bytes_from_peer( - tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size) { - tsi_result result = TSI_OK; - tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; - tsi_fake_handshake_message expected_msg = impl->next_message_to_send - 1; - tsi_fake_handshake_message received_msg; - - if (!impl->needs_incoming_message || impl->result == TSI_OK) { - *bytes_size = 0; - return TSI_OK; - } - result = fill_frame_from_bytes(bytes, bytes_size, &impl->incoming); - if (result != TSI_OK) return result; - - /* We now have a complete frame. */ - result = tsi_fake_handshake_message_from_string( - (const char *)impl->incoming.data + TSI_FAKE_FRAME_HEADER_SIZE, - &received_msg); - if (result != TSI_OK) { - impl->result = result; - return result; - } - if (received_msg != expected_msg) { - gpr_log(GPR_ERROR, "Invalid received message (%s instead of %s)", - tsi_fake_handshake_message_to_string(received_msg), - tsi_fake_handshake_message_to_string(expected_msg)); - } - if (tsi_tracing_enabled) { - gpr_log(GPR_INFO, "%s received %s.", impl->is_client ? "Client" : "Server", - tsi_fake_handshake_message_to_string(received_msg)); - } - tsi_fake_frame_reset(&impl->incoming, 0 /* needs_draining */); - impl->needs_incoming_message = 0; - if (impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { - /* We're done. */ - if (tsi_tracing_enabled) { - gpr_log(GPR_INFO, "%s is done.", impl->is_client ? "Client" : "Server"); - } - impl->result = TSI_OK; - } - return TSI_OK; -} - -static tsi_result fake_handshaker_get_result(tsi_handshaker *self) { - tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; - return impl->result; -} - -static tsi_result fake_handshaker_extract_peer(tsi_handshaker *self, - tsi_peer *peer) { - tsi_result result = tsi_construct_peer(1, peer); - if (result != TSI_OK) return result; - result = tsi_construct_string_peer_property_from_cstring( - TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_FAKE_CERTIFICATE_TYPE, - &peer->properties[0]); - if (result != TSI_OK) tsi_peer_destruct(peer); - return result; -} - -static tsi_result fake_handshaker_create_frame_protector( - tsi_handshaker *self, size_t *max_protected_frame_size, - tsi_frame_protector **protector) { - *protector = tsi_create_fake_protector(max_protected_frame_size); - if (*protector == NULL) return TSI_OUT_OF_RESOURCES; - return TSI_OK; -} - -static void fake_handshaker_destroy(tsi_handshaker *self) { - tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; - tsi_fake_frame_destruct(&impl->incoming); - tsi_fake_frame_destruct(&impl->outgoing); - free(self); -} - -static const tsi_handshaker_vtable handshaker_vtable = { - fake_handshaker_get_bytes_to_send_to_peer, - fake_handshaker_process_bytes_from_peer, - fake_handshaker_get_result, - fake_handshaker_extract_peer, - fake_handshaker_create_frame_protector, - fake_handshaker_destroy, -}; - -tsi_handshaker *tsi_create_fake_handshaker(int is_client) { - tsi_fake_handshaker *impl = calloc(1, sizeof(tsi_fake_handshaker)); - impl->base.vtable = &handshaker_vtable; - impl->is_client = is_client; - impl->result = TSI_HANDSHAKE_IN_PROGRESS; - if (is_client) { - impl->needs_incoming_message = 0; - impl->next_message_to_send = TSI_FAKE_CLIENT_INIT; - } else { - impl->needs_incoming_message = 1; - impl->next_message_to_send = TSI_FAKE_SERVER_INIT; - } - return &impl->base; -} - -tsi_frame_protector *tsi_create_fake_protector( - size_t *max_protected_frame_size) { - tsi_fake_frame_protector *impl = calloc(1, sizeof(tsi_fake_frame_protector)); - if (impl == NULL) return NULL; - impl->max_frame_size = (max_protected_frame_size == NULL) - ? TSI_FAKE_DEFAULT_FRAME_SIZE - : *max_protected_frame_size; - impl->base.vtable = &frame_protector_vtable; - return &impl->base; -} diff --git a/src/core/tsi/fake_transport_security.h b/src/core/tsi/fake_transport_security.h deleted file mode 100644 index 6b8e596290..0000000000 --- a/src/core/tsi/fake_transport_security.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Copyright 2015-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_TSI_FAKE_TRANSPORT_SECURITY_H -#define GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H - -#include "src/core/tsi/transport_security_interface.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for FAKE certs. */ -#define TSI_FAKE_CERTIFICATE_TYPE "FAKE" - -/* Creates a fake handshaker that will create a fake frame protector. - - No cryptography is performed in these objects. They just simulate handshake - messages going back and forth for the handshaker and do some framing on - cleartext data for the protector. */ -tsi_handshaker *tsi_create_fake_handshaker(int is_client); - -/* Creates a protector directly without going through the handshake phase. */ -tsi_frame_protector *tsi_create_fake_protector( - size_t *max_protected_frame_size); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H */ diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c deleted file mode 100644 index 8df582609b..0000000000 --- a/src/core/tsi/ssl_transport_security.c +++ /dev/null @@ -1,1536 +0,0 @@ -/* - * - * Copyright 2015-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/tsi/ssl_transport_security.h" - -#include - -#include -#include - -/* TODO(jboeuf): refactor inet_ntop into a portability header. */ -#ifdef GPR_WINSOCK_SOCKET -#include -#else -#include -#endif - -#include -#include -#include -#include - -#include -#include /* For OPENSSL_free */ -#include -#include -#include -#include - -#include "src/core/tsi/ssl_types.h" -#include "src/core/tsi/transport_security.h" - -/* --- Constants. ---*/ - -#define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND 16384 -#define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND 1024 - -/* Putting a macro like this and littering the source file with #if is really - bad practice. - TODO(jboeuf): refactor all the #if / #endif in a separate module. */ -#ifndef TSI_OPENSSL_ALPN_SUPPORT -#define TSI_OPENSSL_ALPN_SUPPORT 1 -#endif - -/* TODO(jboeuf): I have not found a way to get this number dynamically from the - SSL structure. This is what we would ultimately want though... */ -#define TSI_SSL_MAX_PROTECTION_OVERHEAD 100 - -/* --- Structure definitions. ---*/ - -struct tsi_ssl_handshaker_factory { - tsi_result (*create_handshaker)(tsi_ssl_handshaker_factory *self, - const char *server_name_indication, - tsi_handshaker **handshaker); - void (*destroy)(tsi_ssl_handshaker_factory *self); -}; - -typedef struct { - tsi_ssl_handshaker_factory base; - SSL_CTX *ssl_context; - unsigned char *alpn_protocol_list; - size_t alpn_protocol_list_length; -} tsi_ssl_client_handshaker_factory; - -typedef struct { - tsi_ssl_handshaker_factory base; - - /* Several contexts to support SNI. - The tsi_peer array contains the subject names of the server certificates - associated with the contexts at the same index. */ - SSL_CTX **ssl_contexts; - tsi_peer *ssl_context_x509_subject_names; - size_t ssl_context_count; - unsigned char *alpn_protocol_list; - size_t alpn_protocol_list_length; -} tsi_ssl_server_handshaker_factory; - -typedef struct { - tsi_handshaker base; - SSL *ssl; - BIO *into_ssl; - BIO *from_ssl; - tsi_result result; -} tsi_ssl_handshaker; - -typedef struct { - tsi_frame_protector base; - SSL *ssl; - BIO *into_ssl; - BIO *from_ssl; - unsigned char *buffer; - size_t buffer_size; - size_t buffer_offset; -} tsi_ssl_frame_protector; - -/* --- Library Initialization. ---*/ - -static gpr_once init_openssl_once = GPR_ONCE_INIT; -static gpr_mu *openssl_mutexes = NULL; - -static void openssl_locking_cb(int mode, int type, const char *file, int line) { - if (mode & CRYPTO_LOCK) { - gpr_mu_lock(&openssl_mutexes[type]); - } else { - gpr_mu_unlock(&openssl_mutexes[type]); - } -} - -static unsigned long openssl_thread_id_cb(void) { - return (unsigned long)gpr_thd_currentid(); -} - -static void init_openssl(void) { - int i; - int num_locks; - SSL_library_init(); - SSL_load_error_strings(); - OpenSSL_add_all_algorithms(); - num_locks = CRYPTO_num_locks(); - GPR_ASSERT(num_locks > 0); - openssl_mutexes = malloc((size_t)num_locks * sizeof(gpr_mu)); - GPR_ASSERT(openssl_mutexes != NULL); - for (i = 0; i < CRYPTO_num_locks(); i++) { - gpr_mu_init(&openssl_mutexes[i]); - } - CRYPTO_set_locking_callback(openssl_locking_cb); - CRYPTO_set_id_callback(openssl_thread_id_cb); -} - -/* --- Ssl utils. ---*/ - -static const char *ssl_error_string(int error) { - switch (error) { - case SSL_ERROR_NONE: - return "SSL_ERROR_NONE"; - case SSL_ERROR_ZERO_RETURN: - return "SSL_ERROR_ZERO_RETURN"; - case SSL_ERROR_WANT_READ: - return "SSL_ERROR_WANT_READ"; - case SSL_ERROR_WANT_WRITE: - return "SSL_ERROR_WANT_WRITE"; - case SSL_ERROR_WANT_CONNECT: - return "SSL_ERROR_WANT_CONNECT"; - case SSL_ERROR_WANT_ACCEPT: - return "SSL_ERROR_WANT_ACCEPT"; - case SSL_ERROR_WANT_X509_LOOKUP: - return "SSL_ERROR_WANT_X509_LOOKUP"; - case SSL_ERROR_SYSCALL: - return "SSL_ERROR_SYSCALL"; - case SSL_ERROR_SSL: - return "SSL_ERROR_SSL"; - default: - return "Unknown error"; - } -} - -/* TODO(jboeuf): Remove when we are past the debugging phase with this code. */ -static void ssl_log_where_info(const SSL *ssl, int where, int flag, - const char *msg) { - if ((where & flag) && tsi_tracing_enabled) { - gpr_log(GPR_INFO, "%20.20s - %30.30s - %5.10s", msg, - SSL_state_string_long(ssl), SSL_state_string(ssl)); - } -} - -/* Used for debugging. TODO(jboeuf): Remove when code is mature enough. */ -static void ssl_info_callback(const SSL *ssl, int where, int ret) { - if (ret == 0) { - gpr_log(GPR_ERROR, "ssl_info_callback: error occured.\n"); - return; - } - - ssl_log_where_info(ssl, where, SSL_CB_LOOP, "LOOP"); - ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_START, "HANDSHAKE START"); - ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_DONE, "HANDSHAKE DONE"); -} - -/* Returns 1 if name looks like an IP address, 0 otherwise. - This is a very rough heuristic, and only handles IPv6 in hexadecimal form. */ -static int looks_like_ip_address(const char *name) { - size_t i; - size_t dot_count = 0; - size_t num_size = 0; - for (i = 0; i < strlen(name); i++) { - if (name[i] == ':') { - /* IPv6 Address in hexadecimal form, : is not allowed in DNS names. */ - return 1; - } - if (name[i] >= '0' && name[i] <= '9') { - if (num_size > 3) return 0; - num_size++; - } else if (name[i] == '.') { - if (dot_count > 3 || num_size == 0) return 0; - dot_count++; - num_size = 0; - } else { - return 0; - } - } - if (dot_count < 3 || num_size == 0) return 0; - return 1; -} - -/* Gets the subject CN from an X509 cert. */ -static tsi_result ssl_get_x509_common_name(X509 *cert, unsigned char **utf8, - size_t *utf8_size) { - int common_name_index = -1; - X509_NAME_ENTRY *common_name_entry = NULL; - ASN1_STRING *common_name_asn1 = NULL; - X509_NAME *subject_name = X509_get_subject_name(cert); - int utf8_returned_size = 0; - if (subject_name == NULL) { - gpr_log(GPR_ERROR, "Could not get subject name from certificate."); - return TSI_NOT_FOUND; - } - common_name_index = - X509_NAME_get_index_by_NID(subject_name, NID_commonName, -1); - if (common_name_index == -1) { - gpr_log(GPR_ERROR, - "Could not get common name of subject from certificate."); - return TSI_NOT_FOUND; - } - common_name_entry = X509_NAME_get_entry(subject_name, common_name_index); - if (common_name_entry == NULL) { - gpr_log(GPR_ERROR, "Could not get common name entry from certificate."); - return TSI_INTERNAL_ERROR; - } - common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry); - if (common_name_asn1 == NULL) { - gpr_log(GPR_ERROR, - "Could not get common name entry asn1 from certificate."); - return TSI_INTERNAL_ERROR; - } - utf8_returned_size = ASN1_STRING_to_UTF8(utf8, common_name_asn1); - if (utf8_returned_size < 0) { - gpr_log(GPR_ERROR, "Could not extract utf8 from asn1 string."); - return TSI_OUT_OF_RESOURCES; - } - *utf8_size = (size_t)utf8_returned_size; - return TSI_OK; -} - -/* Gets the subject CN of an X509 cert as a tsi_peer_property. */ -static tsi_result peer_property_from_x509_common_name( - X509 *cert, tsi_peer_property *property) { - unsigned char *common_name; - size_t common_name_size; - tsi_result result = - ssl_get_x509_common_name(cert, &common_name, &common_name_size); - if (result != TSI_OK) { - if (result == TSI_NOT_FOUND) { - common_name = NULL; - common_name_size = 0; - } else { - return result; - } - } - result = tsi_construct_string_peer_property( - TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, - common_name == NULL ? "" : (const char *)common_name, common_name_size, - property); - OPENSSL_free(common_name); - return result; -} - -/* Gets the X509 cert in PEM format as a tsi_peer_property. */ -static tsi_result add_pem_certificate(X509 *cert, tsi_peer_property *property) { - BIO *bio = BIO_new(BIO_s_mem()); - if (!PEM_write_bio_X509(bio, cert)) { - BIO_free(bio); - return TSI_INTERNAL_ERROR; - } - char *contents; - long len = BIO_get_mem_data(bio, &contents); - if (len <= 0) { - BIO_free(bio); - return TSI_INTERNAL_ERROR; - } - tsi_result result = tsi_construct_string_peer_property( - TSI_X509_PEM_CERT_PROPERTY, (const char *)contents, (size_t)len, - property); - BIO_free(bio); - return result; -} - -/* Gets the subject SANs from an X509 cert as a tsi_peer_property. */ -static tsi_result add_subject_alt_names_properties_to_peer( - tsi_peer *peer, GENERAL_NAMES *subject_alt_names, - size_t subject_alt_name_count) { - size_t i; - tsi_result result = TSI_OK; - - /* Reset for DNS entries filtering. */ - peer->property_count -= subject_alt_name_count; - - for (i = 0; i < subject_alt_name_count; i++) { - GENERAL_NAME *subject_alt_name = - sk_GENERAL_NAME_value(subject_alt_names, TSI_SIZE_AS_SIZE(i)); - /* Filter out the non-dns entries names. */ - if (subject_alt_name->type == GEN_DNS) { - unsigned char *name = NULL; - int name_size; - name_size = ASN1_STRING_to_UTF8(&name, subject_alt_name->d.dNSName); - if (name_size < 0) { - gpr_log(GPR_ERROR, "Could not get utf8 from asn1 string."); - result = TSI_INTERNAL_ERROR; - break; - } - result = tsi_construct_string_peer_property( - TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, (const char *)name, - (size_t)name_size, &peer->properties[peer->property_count++]); - OPENSSL_free(name); - } else if (subject_alt_name->type == GEN_IPADD) { - char ntop_buf[INET6_ADDRSTRLEN]; - int af; - - if (subject_alt_name->d.iPAddress->length == 4) { - af = AF_INET; - } else if (subject_alt_name->d.iPAddress->length == 16) { - af = AF_INET6; - } else { - gpr_log(GPR_ERROR, "SAN IP Address contained invalid IP"); - result = TSI_INTERNAL_ERROR; - break; - } - const char *name = inet_ntop(af, subject_alt_name->d.iPAddress->data, - ntop_buf, INET6_ADDRSTRLEN); - if (name == NULL) { - gpr_log(GPR_ERROR, "Could not get IP string from asn1 octet."); - result = TSI_INTERNAL_ERROR; - break; - } - - result = tsi_construct_string_peer_property_from_cstring( - TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, name, - &peer->properties[peer->property_count++]); - } - if (result != TSI_OK) break; - } - return result; -} - -/* Gets information about the peer's X509 cert as a tsi_peer object. */ -static tsi_result peer_from_x509(X509 *cert, int include_certificate_type, - tsi_peer *peer) { - /* TODO(jboeuf): Maybe add more properties. */ - GENERAL_NAMES *subject_alt_names = - X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0); - int subject_alt_name_count = (subject_alt_names != NULL) - ? (int)sk_GENERAL_NAME_num(subject_alt_names) - : 0; - size_t property_count; - tsi_result result; - GPR_ASSERT(subject_alt_name_count >= 0); - property_count = (include_certificate_type ? (size_t)1 : 0) + - 2 /* common name, certificate */ + - (size_t)subject_alt_name_count; - result = tsi_construct_peer(property_count, peer); - if (result != TSI_OK) return result; - do { - if (include_certificate_type) { - result = tsi_construct_string_peer_property_from_cstring( - TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, - &peer->properties[0]); - if (result != TSI_OK) break; - } - result = peer_property_from_x509_common_name( - cert, &peer->properties[include_certificate_type ? 1 : 0]); - if (result != TSI_OK) break; - - result = add_pem_certificate( - cert, &peer->properties[include_certificate_type ? 2 : 1]); - if (result != TSI_OK) break; - - if (subject_alt_name_count != 0) { - result = add_subject_alt_names_properties_to_peer( - peer, subject_alt_names, (size_t)subject_alt_name_count); - if (result != TSI_OK) break; - } - } while (0); - - if (subject_alt_names != NULL) { - sk_GENERAL_NAME_pop_free(subject_alt_names, GENERAL_NAME_free); - } - if (result != TSI_OK) tsi_peer_destruct(peer); - return result; -} - -/* Logs the SSL error stack. */ -static void log_ssl_error_stack(void) { - unsigned long err; - while ((err = ERR_get_error()) != 0) { - char details[256]; - ERR_error_string_n((uint32_t)err, details, sizeof(details)); - gpr_log(GPR_ERROR, "%s", details); - } -} - -/* Performs an SSL_read and handle errors. */ -static tsi_result do_ssl_read(SSL *ssl, unsigned char *unprotected_bytes, - size_t *unprotected_bytes_size) { - int read_from_ssl; - GPR_ASSERT(*unprotected_bytes_size <= INT_MAX); - read_from_ssl = - SSL_read(ssl, unprotected_bytes, (int)*unprotected_bytes_size); - if (read_from_ssl == 0) { - gpr_log(GPR_ERROR, "SSL_read returned 0 unexpectedly."); - return TSI_INTERNAL_ERROR; - } - if (read_from_ssl < 0) { - read_from_ssl = SSL_get_error(ssl, read_from_ssl); - switch (read_from_ssl) { - case SSL_ERROR_WANT_READ: - /* We need more data to finish the frame. */ - *unprotected_bytes_size = 0; - return TSI_OK; - case SSL_ERROR_WANT_WRITE: - gpr_log( - GPR_ERROR, - "Peer tried to renegotiate SSL connection. This is unsupported."); - return TSI_UNIMPLEMENTED; - case SSL_ERROR_SSL: - gpr_log(GPR_ERROR, "Corruption detected."); - log_ssl_error_stack(); - return TSI_DATA_CORRUPTED; - default: - gpr_log(GPR_ERROR, "SSL_read failed with error %s.", - ssl_error_string(read_from_ssl)); - return TSI_PROTOCOL_FAILURE; - } - } - *unprotected_bytes_size = (size_t)read_from_ssl; - return TSI_OK; -} - -/* Performs an SSL_write and handle errors. */ -static tsi_result do_ssl_write(SSL *ssl, unsigned char *unprotected_bytes, - size_t unprotected_bytes_size) { - int ssl_write_result; - GPR_ASSERT(unprotected_bytes_size <= INT_MAX); - ssl_write_result = - SSL_write(ssl, unprotected_bytes, (int)unprotected_bytes_size); - if (ssl_write_result < 0) { - ssl_write_result = SSL_get_error(ssl, ssl_write_result); - if (ssl_write_result == SSL_ERROR_WANT_READ) { - gpr_log(GPR_ERROR, - "Peer tried to renegotiate SSL connection. This is unsupported."); - return TSI_UNIMPLEMENTED; - } else { - gpr_log(GPR_ERROR, "SSL_write failed with error %s.", - ssl_error_string(ssl_write_result)); - return TSI_INTERNAL_ERROR; - } - } - return TSI_OK; -} - -/* Loads an in-memory PEM certificate chain into the SSL context. */ -static tsi_result ssl_ctx_use_certificate_chain( - SSL_CTX *context, const unsigned char *pem_cert_chain, - size_t pem_cert_chain_size) { - tsi_result result = TSI_OK; - X509 *certificate = NULL; - BIO *pem; - GPR_ASSERT(pem_cert_chain_size <= INT_MAX); - pem = BIO_new_mem_buf((void *)pem_cert_chain, (int)pem_cert_chain_size); - if (pem == NULL) return TSI_OUT_OF_RESOURCES; - - do { - certificate = PEM_read_bio_X509_AUX(pem, NULL, NULL, ""); - if (certificate == NULL) { - result = TSI_INVALID_ARGUMENT; - break; - } - if (!SSL_CTX_use_certificate(context, certificate)) { - result = TSI_INVALID_ARGUMENT; - break; - } - while (1) { - X509 *certificate_authority = PEM_read_bio_X509(pem, NULL, NULL, ""); - if (certificate_authority == NULL) { - ERR_clear_error(); - break; /* Done reading. */ - } - if (!SSL_CTX_add_extra_chain_cert(context, certificate_authority)) { - X509_free(certificate_authority); - result = TSI_INVALID_ARGUMENT; - break; - } - /* We don't need to free certificate_authority as its ownership has been - transfered to the context. That is not the case for certificate though. - */ - } - } while (0); - - if (certificate != NULL) X509_free(certificate); - BIO_free(pem); - return result; -} - -/* Loads an in-memory PEM private key into the SSL context. */ -static tsi_result ssl_ctx_use_private_key(SSL_CTX *context, - const unsigned char *pem_key, - size_t pem_key_size) { - tsi_result result = TSI_OK; - EVP_PKEY *private_key = NULL; - BIO *pem; - GPR_ASSERT(pem_key_size <= INT_MAX); - pem = BIO_new_mem_buf((void *)pem_key, (int)pem_key_size); - if (pem == NULL) return TSI_OUT_OF_RESOURCES; - do { - private_key = PEM_read_bio_PrivateKey(pem, NULL, NULL, ""); - if (private_key == NULL) { - result = TSI_INVALID_ARGUMENT; - break; - } - if (!SSL_CTX_use_PrivateKey(context, private_key)) { - result = TSI_INVALID_ARGUMENT; - break; - } - } while (0); - if (private_key != NULL) EVP_PKEY_free(private_key); - BIO_free(pem); - return result; -} - -/* Loads in-memory PEM verification certs into the SSL context and optionally - returns the verification cert names (root_names can be NULL). */ -static tsi_result ssl_ctx_load_verification_certs( - SSL_CTX *context, const unsigned char *pem_roots, size_t pem_roots_size, - STACK_OF(X509_NAME) * *root_names) { - tsi_result result = TSI_OK; - size_t num_roots = 0; - X509 *root = NULL; - X509_NAME *root_name = NULL; - BIO *pem; - X509_STORE *root_store; - GPR_ASSERT(pem_roots_size <= INT_MAX); - pem = BIO_new_mem_buf((void *)pem_roots, (int)pem_roots_size); - root_store = SSL_CTX_get_cert_store(context); - if (root_store == NULL) return TSI_INVALID_ARGUMENT; - if (pem == NULL) return TSI_OUT_OF_RESOURCES; - if (root_names != NULL) { - *root_names = sk_X509_NAME_new_null(); - if (*root_names == NULL) return TSI_OUT_OF_RESOURCES; - } - - while (1) { - root = PEM_read_bio_X509_AUX(pem, NULL, NULL, ""); - if (root == NULL) { - ERR_clear_error(); - break; /* We're at the end of stream. */ - } - if (root_names != NULL) { - root_name = X509_get_subject_name(root); - if (root_name == NULL) { - gpr_log(GPR_ERROR, "Could not get name from root certificate."); - result = TSI_INVALID_ARGUMENT; - break; - } - root_name = X509_NAME_dup(root_name); - if (root_name == NULL) { - result = TSI_OUT_OF_RESOURCES; - break; - } - sk_X509_NAME_push(*root_names, root_name); - root_name = NULL; - } - if (!X509_STORE_add_cert(root_store, root)) { - gpr_log(GPR_ERROR, "Could not add root certificate to ssl context."); - result = TSI_INTERNAL_ERROR; - break; - } - X509_free(root); - num_roots++; - } - - if (num_roots == 0) { - gpr_log(GPR_ERROR, "Could not load any root certificate."); - result = TSI_INVALID_ARGUMENT; - } - - if (result != TSI_OK) { - if (root != NULL) X509_free(root); - if (root_names != NULL) { - sk_X509_NAME_pop_free(*root_names, X509_NAME_free); - *root_names = NULL; - if (root_name != NULL) X509_NAME_free(root_name); - } - } - BIO_free(pem); - return result; -} - -/* Populates the SSL context with a private key and a cert chain, and sets the - cipher list and the ephemeral ECDH key. */ -static tsi_result populate_ssl_context( - SSL_CTX *context, const unsigned char *pem_private_key, - size_t pem_private_key_size, const unsigned char *pem_certificate_chain, - size_t pem_certificate_chain_size, const char *cipher_list) { - tsi_result result = TSI_OK; - if (pem_certificate_chain != NULL) { - result = ssl_ctx_use_certificate_chain(context, pem_certificate_chain, - pem_certificate_chain_size); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Invalid cert chain file."); - return result; - } - } - if (pem_private_key != NULL) { - result = - ssl_ctx_use_private_key(context, pem_private_key, pem_private_key_size); - if (result != TSI_OK || !SSL_CTX_check_private_key(context)) { - gpr_log(GPR_ERROR, "Invalid private key."); - return result != TSI_OK ? result : TSI_INVALID_ARGUMENT; - } - } - if ((cipher_list != NULL) && !SSL_CTX_set_cipher_list(context, cipher_list)) { - gpr_log(GPR_ERROR, "Invalid cipher list: %s.", cipher_list); - return TSI_INVALID_ARGUMENT; - } - { - EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - if (!SSL_CTX_set_tmp_ecdh(context, ecdh)) { - gpr_log(GPR_ERROR, "Could not set ephemeral ECDH key."); - EC_KEY_free(ecdh); - return TSI_INTERNAL_ERROR; - } - SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE); - EC_KEY_free(ecdh); - } - return TSI_OK; -} - -/* Extracts the CN and the SANs from an X509 cert as a peer object. */ -static tsi_result extract_x509_subject_names_from_pem_cert( - const unsigned char *pem_cert, size_t pem_cert_size, tsi_peer *peer) { - tsi_result result = TSI_OK; - X509 *cert = NULL; - BIO *pem; - GPR_ASSERT(pem_cert_size <= INT_MAX); - pem = BIO_new_mem_buf((void *)pem_cert, (int)pem_cert_size); - if (pem == NULL) return TSI_OUT_OF_RESOURCES; - - cert = PEM_read_bio_X509(pem, NULL, NULL, ""); - if (cert == NULL) { - gpr_log(GPR_ERROR, "Invalid certificate"); - result = TSI_INVALID_ARGUMENT; - } else { - result = peer_from_x509(cert, 0, peer); - } - if (cert != NULL) X509_free(cert); - BIO_free(pem); - return result; -} - -/* Builds the alpn protocol name list according to rfc 7301. */ -static tsi_result build_alpn_protocol_name_list( - const unsigned char **alpn_protocols, - const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, - unsigned char **protocol_name_list, size_t *protocol_name_list_length) { - uint16_t i; - unsigned char *current; - *protocol_name_list = NULL; - *protocol_name_list_length = 0; - if (num_alpn_protocols == 0) return TSI_INVALID_ARGUMENT; - for (i = 0; i < num_alpn_protocols; i++) { - if (alpn_protocols_lengths[i] == 0) { - gpr_log(GPR_ERROR, "Invalid 0-length protocol name."); - return TSI_INVALID_ARGUMENT; - } - *protocol_name_list_length += (size_t)alpn_protocols_lengths[i] + 1; - } - *protocol_name_list = malloc(*protocol_name_list_length); - if (*protocol_name_list == NULL) return TSI_OUT_OF_RESOURCES; - current = *protocol_name_list; - for (i = 0; i < num_alpn_protocols; i++) { - *(current++) = alpn_protocols_lengths[i]; - memcpy(current, alpn_protocols[i], alpn_protocols_lengths[i]); - current += alpn_protocols_lengths[i]; - } - /* Safety check. */ - if ((current < *protocol_name_list) || - ((uintptr_t)(current - *protocol_name_list) != - *protocol_name_list_length)) { - return TSI_INTERNAL_ERROR; - } - return TSI_OK; -} - -/* --- tsi_frame_protector methods implementation. ---*/ - -static tsi_result ssl_protector_protect(tsi_frame_protector *self, - const unsigned char *unprotected_bytes, - size_t *unprotected_bytes_size, - unsigned char *protected_output_frames, - size_t *protected_output_frames_size) { - tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; - int read_from_ssl; - size_t available; - tsi_result result = TSI_OK; - - /* First see if we have some pending data in the SSL BIO. */ - int pending_in_ssl = (int)BIO_pending(impl->from_ssl); - if (pending_in_ssl > 0) { - *unprotected_bytes_size = 0; - GPR_ASSERT(*protected_output_frames_size <= INT_MAX); - read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames, - (int)*protected_output_frames_size); - if (read_from_ssl < 0) { - gpr_log(GPR_ERROR, - "Could not read from BIO even though some data is pending"); - return TSI_INTERNAL_ERROR; - } - *protected_output_frames_size = (size_t)read_from_ssl; - return TSI_OK; - } - - /* Now see if we can send a complete frame. */ - available = impl->buffer_size - impl->buffer_offset; - if (available > *unprotected_bytes_size) { - /* If we cannot, just copy the data in our internal buffer. */ - memcpy(impl->buffer + impl->buffer_offset, unprotected_bytes, - *unprotected_bytes_size); - impl->buffer_offset += *unprotected_bytes_size; - *protected_output_frames_size = 0; - return TSI_OK; - } - - /* If we can, prepare the buffer, send it to SSL_write and read. */ - memcpy(impl->buffer + impl->buffer_offset, unprotected_bytes, available); - result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_size); - if (result != TSI_OK) return result; - - GPR_ASSERT(*protected_output_frames_size <= INT_MAX); - read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames, - (int)*protected_output_frames_size); - if (read_from_ssl < 0) { - gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write."); - return TSI_INTERNAL_ERROR; - } - *protected_output_frames_size = (size_t)read_from_ssl; - *unprotected_bytes_size = available; - impl->buffer_offset = 0; - return TSI_OK; -} - -static tsi_result ssl_protector_protect_flush( - tsi_frame_protector *self, unsigned char *protected_output_frames, - size_t *protected_output_frames_size, size_t *still_pending_size) { - tsi_result result = TSI_OK; - tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; - int read_from_ssl = 0; - int pending; - - if (impl->buffer_offset != 0) { - result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_offset); - if (result != TSI_OK) return result; - impl->buffer_offset = 0; - } - - pending = (int)BIO_pending(impl->from_ssl); - GPR_ASSERT(pending >= 0); - *still_pending_size = (size_t)pending; - if (*still_pending_size == 0) return TSI_OK; - - GPR_ASSERT(*protected_output_frames_size <= INT_MAX); - read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames, - (int)*protected_output_frames_size); - if (read_from_ssl <= 0) { - gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write."); - return TSI_INTERNAL_ERROR; - } - *protected_output_frames_size = (size_t)read_from_ssl; - pending = (int)BIO_pending(impl->from_ssl); - GPR_ASSERT(pending >= 0); - *still_pending_size = (size_t)pending; - return TSI_OK; -} - -static tsi_result ssl_protector_unprotect( - tsi_frame_protector *self, const unsigned char *protected_frames_bytes, - size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes, - size_t *unprotected_bytes_size) { - tsi_result result = TSI_OK; - int written_into_ssl = 0; - size_t output_bytes_size = *unprotected_bytes_size; - size_t output_bytes_offset = 0; - tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; - - /* First, try to read remaining data from ssl. */ - result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size); - if (result != TSI_OK) return result; - if (*unprotected_bytes_size == output_bytes_size) { - /* We have read everything we could and cannot process any more input. */ - *protected_frames_bytes_size = 0; - return TSI_OK; - } - output_bytes_offset = *unprotected_bytes_size; - unprotected_bytes += output_bytes_offset; - *unprotected_bytes_size = output_bytes_size - output_bytes_offset; - - /* Then, try to write some data to ssl. */ - GPR_ASSERT(*protected_frames_bytes_size <= INT_MAX); - written_into_ssl = BIO_write(impl->into_ssl, protected_frames_bytes, - (int)*protected_frames_bytes_size); - if (written_into_ssl < 0) { - gpr_log(GPR_ERROR, "Sending protected frame to ssl failed with %d", - written_into_ssl); - return TSI_INTERNAL_ERROR; - } - *protected_frames_bytes_size = (size_t)written_into_ssl; - - /* Now try to read some data again. */ - result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size); - if (result == TSI_OK) { - /* Don't forget to output the total number of bytes read. */ - *unprotected_bytes_size += output_bytes_offset; - } - return result; -} - -static void ssl_protector_destroy(tsi_frame_protector *self) { - tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; - if (impl->buffer != NULL) free(impl->buffer); - if (impl->ssl != NULL) SSL_free(impl->ssl); - free(self); -} - -static const tsi_frame_protector_vtable frame_protector_vtable = { - ssl_protector_protect, ssl_protector_protect_flush, ssl_protector_unprotect, - ssl_protector_destroy, -}; - -/* --- tsi_handshaker methods implementation. ---*/ - -static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, - unsigned char *bytes, - size_t *bytes_size) { - tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - int bytes_read_from_ssl = 0; - if (bytes == NULL || bytes_size == NULL || *bytes_size == 0 || - *bytes_size > INT_MAX) { - return TSI_INVALID_ARGUMENT; - } - GPR_ASSERT(*bytes_size <= INT_MAX); - bytes_read_from_ssl = BIO_read(impl->from_ssl, bytes, (int)*bytes_size); - if (bytes_read_from_ssl < 0) { - *bytes_size = 0; - if (!BIO_should_retry(impl->from_ssl)) { - impl->result = TSI_INTERNAL_ERROR; - return impl->result; - } else { - return TSI_OK; - } - } - *bytes_size = (size_t)bytes_read_from_ssl; - return BIO_pending(impl->from_ssl) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA; -} - -static tsi_result ssl_handshaker_get_result(tsi_handshaker *self) { - tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - if ((impl->result == TSI_HANDSHAKE_IN_PROGRESS) && - SSL_is_init_finished(impl->ssl)) { - impl->result = TSI_OK; - } - return impl->result; -} - -static tsi_result ssl_handshaker_process_bytes_from_peer( - tsi_handshaker *self, const unsigned char *bytes, size_t *bytes_size) { - tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - int bytes_written_into_ssl_size = 0; - if (bytes == NULL || bytes_size == 0 || *bytes_size > INT_MAX) { - return TSI_INVALID_ARGUMENT; - } - GPR_ASSERT(*bytes_size <= INT_MAX); - bytes_written_into_ssl_size = - BIO_write(impl->into_ssl, bytes, (int)*bytes_size); - if (bytes_written_into_ssl_size < 0) { - gpr_log(GPR_ERROR, "Could not write to memory BIO."); - impl->result = TSI_INTERNAL_ERROR; - return impl->result; - } - *bytes_size = (size_t)bytes_written_into_ssl_size; - - if (!tsi_handshaker_is_in_progress(self)) { - impl->result = TSI_OK; - return impl->result; - } else { - /* Get ready to get some bytes from SSL. */ - int ssl_result = SSL_do_handshake(impl->ssl); - ssl_result = SSL_get_error(impl->ssl, ssl_result); - switch (ssl_result) { - case SSL_ERROR_WANT_READ: - if (BIO_pending(impl->from_ssl) == 0) { - /* We need more data. */ - return TSI_INCOMPLETE_DATA; - } else { - return TSI_OK; - } - case SSL_ERROR_NONE: - return TSI_OK; - default: { - char err_str[256]; - ERR_error_string_n(ERR_get_error(), err_str, sizeof(err_str)); - gpr_log(GPR_ERROR, "Handshake failed with fatal error %s: %s.", - ssl_error_string(ssl_result), err_str); - impl->result = TSI_PROTOCOL_FAILURE; - return impl->result; - } - } - } -} - -static tsi_result ssl_handshaker_extract_peer(tsi_handshaker *self, - tsi_peer *peer) { - tsi_result result = TSI_OK; - const unsigned char *alpn_selected = NULL; - unsigned int alpn_selected_len; - tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - X509 *peer_cert = SSL_get_peer_certificate(impl->ssl); - if (peer_cert != NULL) { - result = peer_from_x509(peer_cert, 1, peer); - X509_free(peer_cert); - if (result != TSI_OK) return result; - } -#if TSI_OPENSSL_ALPN_SUPPORT - SSL_get0_alpn_selected(impl->ssl, &alpn_selected, &alpn_selected_len); -#endif /* TSI_OPENSSL_ALPN_SUPPORT */ - if (alpn_selected == NULL) { - /* Try npn. */ - SSL_get0_next_proto_negotiated(impl->ssl, &alpn_selected, - &alpn_selected_len); - } - if (alpn_selected != NULL) { - size_t i; - tsi_peer_property *new_properties = - calloc(1, sizeof(tsi_peer_property) * (peer->property_count + 1)); - if (new_properties == NULL) return TSI_OUT_OF_RESOURCES; - for (i = 0; i < peer->property_count; i++) { - new_properties[i] = peer->properties[i]; - } - result = tsi_construct_string_peer_property( - TSI_SSL_ALPN_SELECTED_PROTOCOL, (const char *)alpn_selected, - alpn_selected_len, &new_properties[peer->property_count]); - if (result != TSI_OK) { - free(new_properties); - return result; - } - if (peer->properties != NULL) free(peer->properties); - peer->property_count++; - peer->properties = new_properties; - } - return result; -} - -static tsi_result ssl_handshaker_create_frame_protector( - tsi_handshaker *self, size_t *max_output_protected_frame_size, - tsi_frame_protector **protector) { - size_t actual_max_output_protected_frame_size = - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND; - tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - tsi_ssl_frame_protector *protector_impl = - calloc(1, sizeof(tsi_ssl_frame_protector)); - if (protector_impl == NULL) { - return TSI_OUT_OF_RESOURCES; - } - - if (max_output_protected_frame_size != NULL) { - if (*max_output_protected_frame_size > - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND) { - *max_output_protected_frame_size = - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND; - } else if (*max_output_protected_frame_size < - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND) { - *max_output_protected_frame_size = - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND; - } - actual_max_output_protected_frame_size = *max_output_protected_frame_size; - } - protector_impl->buffer_size = - actual_max_output_protected_frame_size - TSI_SSL_MAX_PROTECTION_OVERHEAD; - protector_impl->buffer = malloc(protector_impl->buffer_size); - if (protector_impl->buffer == NULL) { - gpr_log(GPR_ERROR, - "Could not allocated buffer for tsi_ssl_frame_protector."); - free(protector_impl); - return TSI_INTERNAL_ERROR; - } - - /* Transfer ownership of ssl to the frame protector. It is OK as the caller - * cannot call anything else but destroy on the handshaker after this call. */ - protector_impl->ssl = impl->ssl; - impl->ssl = NULL; - protector_impl->into_ssl = impl->into_ssl; - protector_impl->from_ssl = impl->from_ssl; - - protector_impl->base.vtable = &frame_protector_vtable; - *protector = &protector_impl->base; - return TSI_OK; -} - -static void ssl_handshaker_destroy(tsi_handshaker *self) { - tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - SSL_free(impl->ssl); /* The BIO objects are owned by ssl */ - free(impl); -} - -static const tsi_handshaker_vtable handshaker_vtable = { - ssl_handshaker_get_bytes_to_send_to_peer, - ssl_handshaker_process_bytes_from_peer, - ssl_handshaker_get_result, - ssl_handshaker_extract_peer, - ssl_handshaker_create_frame_protector, - ssl_handshaker_destroy, -}; - -/* --- tsi_ssl_handshaker_factory common methods. --- */ - -tsi_result tsi_ssl_handshaker_factory_create_handshaker( - tsi_ssl_handshaker_factory *self, const char *server_name_indication, - tsi_handshaker **handshaker) { - if (self == NULL || handshaker == NULL) return TSI_INVALID_ARGUMENT; - return self->create_handshaker(self, server_name_indication, handshaker); -} - -void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory *self) { - if (self == NULL) return; - self->destroy(self); -} - -static tsi_result create_tsi_ssl_handshaker(SSL_CTX *ctx, int is_client, - const char *server_name_indication, - tsi_handshaker **handshaker) { - SSL *ssl = SSL_new(ctx); - BIO *into_ssl = NULL; - BIO *from_ssl = NULL; - tsi_ssl_handshaker *impl = NULL; - *handshaker = NULL; - if (ctx == NULL) { - gpr_log(GPR_ERROR, "SSL Context is null. Should never happen."); - return TSI_INTERNAL_ERROR; - } - if (ssl == NULL) { - return TSI_OUT_OF_RESOURCES; - } - SSL_set_info_callback(ssl, ssl_info_callback); - - into_ssl = BIO_new(BIO_s_mem()); - from_ssl = BIO_new(BIO_s_mem()); - if (into_ssl == NULL || from_ssl == NULL) { - gpr_log(GPR_ERROR, "BIO_new failed."); - SSL_free(ssl); - if (into_ssl != NULL) BIO_free(into_ssl); - if (from_ssl != NULL) BIO_free(into_ssl); - return TSI_OUT_OF_RESOURCES; - } - SSL_set_bio(ssl, into_ssl, from_ssl); - if (is_client) { - int ssl_result; - SSL_set_connect_state(ssl); - if (server_name_indication != NULL) { - if (!SSL_set_tlsext_host_name(ssl, server_name_indication)) { - gpr_log(GPR_ERROR, "Invalid server name indication %s.", - server_name_indication); - SSL_free(ssl); - return TSI_INTERNAL_ERROR; - } - } - ssl_result = SSL_do_handshake(ssl); - ssl_result = SSL_get_error(ssl, ssl_result); - if (ssl_result != SSL_ERROR_WANT_READ) { - gpr_log(GPR_ERROR, - "Unexpected error received from first SSL_do_handshake call: %s", - ssl_error_string(ssl_result)); - SSL_free(ssl); - return TSI_INTERNAL_ERROR; - } - } else { - SSL_set_accept_state(ssl); - } - - impl = calloc(1, sizeof(tsi_ssl_handshaker)); - if (impl == NULL) { - SSL_free(ssl); - return TSI_OUT_OF_RESOURCES; - } - impl->ssl = ssl; - impl->into_ssl = into_ssl; - impl->from_ssl = from_ssl; - impl->result = TSI_HANDSHAKE_IN_PROGRESS; - impl->base.vtable = &handshaker_vtable; - *handshaker = &impl->base; - return TSI_OK; -} - -static int select_protocol_list(const unsigned char **out, - unsigned char *outlen, - const unsigned char *client_list, - size_t client_list_len, - const unsigned char *server_list, - size_t server_list_len) { - const unsigned char *client_current = client_list; - while ((unsigned int)(client_current - client_list) < client_list_len) { - unsigned char client_current_len = *(client_current++); - const unsigned char *server_current = server_list; - while ((server_current >= server_list) && - (uintptr_t)(server_current - server_list) < server_list_len) { - unsigned char server_current_len = *(server_current++); - if ((client_current_len == server_current_len) && - !memcmp(client_current, server_current, server_current_len)) { - *out = server_current; - *outlen = server_current_len; - return SSL_TLSEXT_ERR_OK; - } - server_current += server_current_len; - } - client_current += client_current_len; - } - return SSL_TLSEXT_ERR_NOACK; -} - -/* --- tsi_ssl__client_handshaker_factory methods implementation. --- */ - -static tsi_result ssl_client_handshaker_factory_create_handshaker( - tsi_ssl_handshaker_factory *self, const char *server_name_indication, - tsi_handshaker **handshaker) { - tsi_ssl_client_handshaker_factory *impl = - (tsi_ssl_client_handshaker_factory *)self; - return create_tsi_ssl_handshaker(impl->ssl_context, 1, server_name_indication, - handshaker); -} - -static void ssl_client_handshaker_factory_destroy( - tsi_ssl_handshaker_factory *self) { - tsi_ssl_client_handshaker_factory *impl = - (tsi_ssl_client_handshaker_factory *)self; - if (impl->ssl_context != NULL) SSL_CTX_free(impl->ssl_context); - if (impl->alpn_protocol_list != NULL) free(impl->alpn_protocol_list); - free(impl); -} - -static int client_handshaker_factory_npn_callback(SSL *ssl, unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg) { - tsi_ssl_client_handshaker_factory *factory = - (tsi_ssl_client_handshaker_factory *)arg; - return select_protocol_list((const unsigned char **)out, outlen, - factory->alpn_protocol_list, - factory->alpn_protocol_list_length, in, inlen); -} - -/* --- tsi_ssl_server_handshaker_factory methods implementation. --- */ - -static tsi_result ssl_server_handshaker_factory_create_handshaker( - tsi_ssl_handshaker_factory *self, const char *server_name_indication, - tsi_handshaker **handshaker) { - tsi_ssl_server_handshaker_factory *impl = - (tsi_ssl_server_handshaker_factory *)self; - if (impl->ssl_context_count == 0 || server_name_indication != NULL) { - return TSI_INVALID_ARGUMENT; - } - /* Create the handshaker with the first context. We will switch if needed - because of SNI in ssl_server_handshaker_factory_servername_callback. */ - return create_tsi_ssl_handshaker(impl->ssl_contexts[0], 0, NULL, handshaker); -} - -static void ssl_server_handshaker_factory_destroy( - tsi_ssl_handshaker_factory *self) { - tsi_ssl_server_handshaker_factory *impl = - (tsi_ssl_server_handshaker_factory *)self; - size_t i; - for (i = 0; i < impl->ssl_context_count; i++) { - if (impl->ssl_contexts[i] != NULL) { - SSL_CTX_free(impl->ssl_contexts[i]); - tsi_peer_destruct(&impl->ssl_context_x509_subject_names[i]); - } - } - if (impl->ssl_contexts != NULL) free(impl->ssl_contexts); - if (impl->ssl_context_x509_subject_names != NULL) { - free(impl->ssl_context_x509_subject_names); - } - if (impl->alpn_protocol_list != NULL) free(impl->alpn_protocol_list); - free(impl); -} - -static int does_entry_match_name(const char *entry, size_t entry_length, - const char *name) { - const char *dot; - const char *name_subdomain = NULL; - size_t name_length = strlen(name); - size_t name_subdomain_length; - if (entry_length == 0) return 0; - - /* Take care of '.' terminations. */ - if (name[name_length - 1] == '.') { - name_length--; - } - if (entry[entry_length - 1] == '.') { - entry_length--; - if (entry_length == 0) return 0; - } - - if ((name_length == entry_length) && - strncmp(name, entry, entry_length) == 0) { - return 1; /* Perfect match. */ - } - if (entry[0] != '*') return 0; - - /* Wildchar subdomain matching. */ - if (entry_length < 3 || entry[1] != '.') { /* At least *.x */ - gpr_log(GPR_ERROR, "Invalid wildchar entry."); - return 0; - } - name_subdomain = strchr(name, '.'); - if (name_subdomain == NULL) return 0; - name_subdomain_length = strlen(name_subdomain); - if (name_subdomain_length < 2) return 0; - name_subdomain++; /* Starts after the dot. */ - name_subdomain_length--; - entry += 2; /* Remove *. */ - entry_length -= 2; - dot = strchr(name_subdomain, '.'); - if ((dot == NULL) || (dot == &name_subdomain[name_subdomain_length - 1])) { - gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", name_subdomain); - return 0; - } - if (name_subdomain[name_subdomain_length - 1] == '.') { - name_subdomain_length--; - } - return ((entry_length > 0) && (name_subdomain_length == entry_length) && - strncmp(entry, name_subdomain, entry_length) == 0); -} - -static int ssl_server_handshaker_factory_servername_callback(SSL *ssl, int *ap, - void *arg) { - tsi_ssl_server_handshaker_factory *impl = - (tsi_ssl_server_handshaker_factory *)arg; - size_t i = 0; - const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); - if (servername == NULL || strlen(servername) == 0) { - return SSL_TLSEXT_ERR_NOACK; - } - - for (i = 0; i < impl->ssl_context_count; i++) { - if (tsi_ssl_peer_matches_name(&impl->ssl_context_x509_subject_names[i], - servername)) { - SSL_set_SSL_CTX(ssl, impl->ssl_contexts[i]); - return SSL_TLSEXT_ERR_OK; - } - } - gpr_log(GPR_ERROR, "No match found for server name: %s.", servername); - return SSL_TLSEXT_ERR_ALERT_WARNING; -} - -#if TSI_OPENSSL_ALPN_SUPPORT -static int server_handshaker_factory_alpn_callback( - SSL *ssl, const unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, void *arg) { - tsi_ssl_server_handshaker_factory *factory = - (tsi_ssl_server_handshaker_factory *)arg; - return select_protocol_list(out, outlen, in, inlen, - factory->alpn_protocol_list, - factory->alpn_protocol_list_length); -} -#endif /* TSI_OPENSSL_ALPN_SUPPORT */ - -static int server_handshaker_factory_npn_advertised_callback( - SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg) { - tsi_ssl_server_handshaker_factory *factory = - (tsi_ssl_server_handshaker_factory *)arg; - *out = factory->alpn_protocol_list; - GPR_ASSERT(factory->alpn_protocol_list_length <= UINT_MAX); - *outlen = (unsigned int)factory->alpn_protocol_list_length; - return SSL_TLSEXT_ERR_OK; -} - -/* --- tsi_ssl_handshaker_factory constructors. --- */ - -tsi_result tsi_create_ssl_client_handshaker_factory( - const unsigned char *pem_private_key, size_t pem_private_key_size, - const unsigned char *pem_cert_chain, size_t pem_cert_chain_size, - const unsigned char *pem_root_certs, size_t pem_root_certs_size, - const char *cipher_list, const unsigned char **alpn_protocols, - const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, - tsi_ssl_handshaker_factory **factory) { - SSL_CTX *ssl_context = NULL; - tsi_ssl_client_handshaker_factory *impl = NULL; - tsi_result result = TSI_OK; - - gpr_once_init(&init_openssl_once, init_openssl); - - if (factory == NULL) return TSI_INVALID_ARGUMENT; - *factory = NULL; - if (pem_root_certs == NULL) return TSI_INVALID_ARGUMENT; - - ssl_context = SSL_CTX_new(TLSv1_2_method()); - if (ssl_context == NULL) { - gpr_log(GPR_ERROR, "Could not create ssl context."); - return TSI_INVALID_ARGUMENT; - } - - impl = calloc(1, sizeof(tsi_ssl_client_handshaker_factory)); - if (impl == NULL) { - SSL_CTX_free(ssl_context); - return TSI_OUT_OF_RESOURCES; - } - impl->ssl_context = ssl_context; - - do { - result = - populate_ssl_context(ssl_context, pem_private_key, pem_private_key_size, - pem_cert_chain, pem_cert_chain_size, cipher_list); - if (result != TSI_OK) break; - result = ssl_ctx_load_verification_certs(ssl_context, pem_root_certs, - pem_root_certs_size, NULL); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Cannot load server root certificates."); - break; - } - - if (num_alpn_protocols != 0) { - result = build_alpn_protocol_name_list( - alpn_protocols, alpn_protocols_lengths, num_alpn_protocols, - &impl->alpn_protocol_list, &impl->alpn_protocol_list_length); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Building alpn list failed with error %s.", - tsi_result_to_string(result)); - break; - } -#if TSI_OPENSSL_ALPN_SUPPORT - GPR_ASSERT(impl->alpn_protocol_list_length < UINT_MAX); - if (SSL_CTX_set_alpn_protos( - ssl_context, impl->alpn_protocol_list, - (unsigned int)impl->alpn_protocol_list_length)) { - gpr_log(GPR_ERROR, "Could not set alpn protocol list to context."); - result = TSI_INVALID_ARGUMENT; - break; - } -#endif /* TSI_OPENSSL_ALPN_SUPPORT */ - SSL_CTX_set_next_proto_select_cb( - ssl_context, client_handshaker_factory_npn_callback, impl); - } - } while (0); - if (result != TSI_OK) { - ssl_client_handshaker_factory_destroy(&impl->base); - return result; - } - SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NULL); - /* TODO(jboeuf): Add revocation verification. */ - - impl->base.create_handshaker = - ssl_client_handshaker_factory_create_handshaker; - impl->base.destroy = ssl_client_handshaker_factory_destroy; - *factory = &impl->base; - return TSI_OK; -} - -tsi_result tsi_create_ssl_server_handshaker_factory( - const unsigned char **pem_private_keys, - const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains, - const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count, - const unsigned char *pem_client_root_certs, - size_t pem_client_root_certs_size, int force_client_auth, - const char *cipher_list, const unsigned char **alpn_protocols, - const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, - tsi_ssl_handshaker_factory **factory) { - tsi_ssl_server_handshaker_factory *impl = NULL; - tsi_result result = TSI_OK; - size_t i = 0; - - gpr_once_init(&init_openssl_once, init_openssl); - - if (factory == NULL) return TSI_INVALID_ARGUMENT; - *factory = NULL; - if (key_cert_pair_count == 0 || pem_private_keys == NULL || - pem_cert_chains == NULL) { - return TSI_INVALID_ARGUMENT; - } - - impl = calloc(1, sizeof(tsi_ssl_server_handshaker_factory)); - if (impl == NULL) return TSI_OUT_OF_RESOURCES; - impl->base.create_handshaker = - ssl_server_handshaker_factory_create_handshaker; - impl->base.destroy = ssl_server_handshaker_factory_destroy; - impl->ssl_contexts = calloc(key_cert_pair_count, sizeof(SSL_CTX *)); - impl->ssl_context_x509_subject_names = - calloc(key_cert_pair_count, sizeof(tsi_peer)); - if (impl->ssl_contexts == NULL || - impl->ssl_context_x509_subject_names == NULL) { - tsi_ssl_handshaker_factory_destroy(&impl->base); - return TSI_OUT_OF_RESOURCES; - } - impl->ssl_context_count = key_cert_pair_count; - - if (num_alpn_protocols > 0) { - result = build_alpn_protocol_name_list( - alpn_protocols, alpn_protocols_lengths, num_alpn_protocols, - &impl->alpn_protocol_list, &impl->alpn_protocol_list_length); - if (result != TSI_OK) { - tsi_ssl_handshaker_factory_destroy(&impl->base); - return result; - } - } - - for (i = 0; i < key_cert_pair_count; i++) { - do { - impl->ssl_contexts[i] = SSL_CTX_new(TLSv1_2_method()); - if (impl->ssl_contexts[i] == NULL) { - gpr_log(GPR_ERROR, "Could not create ssl context."); - result = TSI_OUT_OF_RESOURCES; - break; - } - result = populate_ssl_context( - impl->ssl_contexts[i], pem_private_keys[i], pem_private_keys_sizes[i], - pem_cert_chains[i], pem_cert_chains_sizes[i], cipher_list); - if (result != TSI_OK) break; - - if (pem_client_root_certs != NULL) { - int flags = SSL_VERIFY_PEER; - STACK_OF(X509_NAME) *root_names = NULL; - result = ssl_ctx_load_verification_certs( - impl->ssl_contexts[i], pem_client_root_certs, - pem_client_root_certs_size, &root_names); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Invalid verification certs."); - break; - } - SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names); - if (force_client_auth) flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; - SSL_CTX_set_verify(impl->ssl_contexts[i], flags, NULL); - /* TODO(jboeuf): Add revocation verification. */ - } - - result = extract_x509_subject_names_from_pem_cert( - pem_cert_chains[i], pem_cert_chains_sizes[i], - &impl->ssl_context_x509_subject_names[i]); - if (result != TSI_OK) break; - - SSL_CTX_set_tlsext_servername_callback( - impl->ssl_contexts[i], - ssl_server_handshaker_factory_servername_callback); - SSL_CTX_set_tlsext_servername_arg(impl->ssl_contexts[i], impl); -#if TSI_OPENSSL_ALPN_SUPPORT - SSL_CTX_set_alpn_select_cb(impl->ssl_contexts[i], - server_handshaker_factory_alpn_callback, impl); -#endif /* TSI_OPENSSL_ALPN_SUPPORT */ - SSL_CTX_set_next_protos_advertised_cb( - impl->ssl_contexts[i], - server_handshaker_factory_npn_advertised_callback, impl); - } while (0); - - if (result != TSI_OK) { - tsi_ssl_handshaker_factory_destroy(&impl->base); - return result; - } - } - *factory = &impl->base; - return TSI_OK; -} - -/* --- tsi_ssl utils. --- */ - -int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name) { - size_t i = 0; - size_t san_count = 0; - const tsi_peer_property *cn_property = NULL; - int like_ip = looks_like_ip_address(name); - - /* Check the SAN first. */ - for (i = 0; i < peer->property_count; i++) { - const tsi_peer_property *property = &peer->properties[i]; - if (property->name == NULL) continue; - if (strcmp(property->name, - TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { - san_count++; - - if (!like_ip && does_entry_match_name(property->value.data, - property->value.length, name)) { - return 1; - } else if (like_ip && - strncmp(name, property->value.data, property->value.length) == - 0 && - strlen(name) == property->value.length) { - /* IP Addresses are exact matches only. */ - return 1; - } - } else if (strcmp(property->name, - TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) { - cn_property = property; - } - } - - /* If there's no SAN, try the CN, but only if its not like an IP Address */ - if (san_count == 0 && cn_property != NULL && !like_ip) { - if (does_entry_match_name(cn_property->value.data, - cn_property->value.length, name)) { - return 1; - } - } - - return 0; /* Not found. */ -} diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h deleted file mode 100644 index 612f5c64cc..0000000000 --- a/src/core/tsi/ssl_transport_security.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * - * Copyright 2015-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_TSI_SSL_TRANSPORT_SECURITY_H -#define GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H - -#include "src/core/tsi/transport_security_interface.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */ -#define TSI_X509_CERTIFICATE_TYPE "X509" - -/* This property is of type TSI_PEER_PROPERTY_STRING. */ -#define TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY "x509_subject_common_name" -#define TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY \ - "x509_subject_alternative_name" - -#define TSI_X509_PEM_CERT_PROPERTY "x509_pem_cert" - -#define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol" - -/* --- tsi_ssl_handshaker_factory object --- - - This object creates tsi_handshaker objects implemented in terms of the - TLS 1.2 specificiation. */ - -typedef struct tsi_ssl_handshaker_factory tsi_ssl_handshaker_factory; - -/* Creates a client handshaker factory. - - pem_private_key is the buffer containing the PEM encoding of the client's - private key. This parameter can be NULL if the client does not have a - private key. - - pem_private_key_size is the size of the associated buffer. - - pem_cert_chain is the buffer containing the PEM encoding of the client's - certificate chain. This parameter can be NULL if the client does not have - a certificate chain. - - pem_cert_chain_size is the size of the associated buffer. - - pem_roots_cert is the buffer containing the PEM encoding of the server - root certificates. This parameter cannot be NULL. - - pem_roots_cert_size is the size of the associated buffer. - - cipher_suites contains an optional list of the ciphers that the client - supports. The format of this string is described in: - https://www.openssl.org/docs/apps/ciphers.html. - This parameter can be set to NULL to use the default set of ciphers. - TODO(jboeuf): Revisit the format of this parameter. - - alpn_protocols is an array containing the protocol names that the - handshakers created with this factory support. This parameter can be NULL. - - alpn_protocols_lengths is an array containing the lengths of the alpn - protocols specified in alpn_protocols. This parameter can be NULL. - - num_alpn_protocols is the number of alpn protocols and associated lengths - specified. If this parameter is 0, the other alpn parameters must be NULL. - - factory is the address of the factory pointer to be created. - - - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case - where a parameter is invalid. */ -tsi_result tsi_create_ssl_client_handshaker_factory( - const unsigned char *pem_private_key, size_t pem_private_key_size, - const unsigned char *pem_cert_chain, size_t pem_cert_chain_size, - const unsigned char *pem_root_certs, size_t pem_root_certs_size, - const char *cipher_suites, const unsigned char **alpn_protocols, - const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, - tsi_ssl_handshaker_factory **factory); - -/* Creates a server handshaker factory. - - version indicates which version of the specification to use. - - pem_private_keys is an array containing the PEM encoding of the server's - private keys. This parameter cannot be NULL. The size of the array is - given by the key_cert_pair_count parameter. - - pem_private_keys_sizes is the array containing the sizes of the associated - buffers. - - pem_cert_chains is an array containing the PEM encoding of the server's - cert chains. This parameter cannot be NULL. The size of the array is - given by the key_cert_pair_count parameter. - - pem_cert_chains_sizes is the array containing the sizes of the associated - buffers. - - key_cert_pair_count indicates the number of items in the private_key_files - and cert_chain_files parameters. - - pem_client_roots is the buffer containing the PEM encoding of the client - root certificates. This parameter may be NULL in which case the server will - not authenticate the client. If not NULL, the force_client_auth parameter - specifies if the server will accept only authenticated clients or both - authenticated and non-authenticated clients. - - pem_client_root_certs_size is the size of the associated buffer. - - force_client_auth, if set to non-zero will force the client to authenticate - with an SSL cert. Note that this option is ignored if pem_client_root_certs - is NULL or pem_client_roots_certs_size is 0 - - cipher_suites contains an optional list of the ciphers that the server - supports. The format of this string is described in: - https://www.openssl.org/docs/apps/ciphers.html. - This parameter can be set to NULL to use the default set of ciphers. - TODO(jboeuf): Revisit the format of this parameter. - - alpn_protocols is an array containing the protocol names that the - handshakers created with this factory support. This parameter can be NULL. - - alpn_protocols_lengths is an array containing the lengths of the alpn - protocols specified in alpn_protocols. This parameter can be NULL. - - num_alpn_protocols is the number of alpn protocols and associated lengths - specified. If this parameter is 0, the other alpn parameters must be NULL. - - factory is the address of the factory pointer to be created. - - - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case - where a parameter is invalid. */ -tsi_result tsi_create_ssl_server_handshaker_factory( - const unsigned char **pem_private_keys, - const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains, - const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count, - const unsigned char *pem_client_root_certs, - size_t pem_client_root_certs_size, int force_client_auth, - const char *cipher_suites, const unsigned char **alpn_protocols, - const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, - tsi_ssl_handshaker_factory **factory); - -/* Creates a handshaker. - - self is the factory from which the handshaker will be created. - - server_name_indication indicates the name of the server the client is - trying to connect to which will be relayed to the server using the SNI - extension. - This parameter must be NULL for a server handshaker factory. - - handhshaker is the address of the handshaker pointer to be created. - - - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case - where a parameter is invalid. */ -tsi_result tsi_ssl_handshaker_factory_create_handshaker( - tsi_ssl_handshaker_factory *self, const char *server_name_indication, - tsi_handshaker **handshaker); - -/* Destroys the handshaker factory. WARNING: it is unsafe to destroy a factory - while handshakers created with this factory are still in use. */ -void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory *self); - -/* Util that checks that an ssl peer matches a specific name. - Still TODO(jboeuf): - - handle mixed case. - - handle %encoded chars. - - handle public suffix wildchar more strictly (e.g. *.co.uk) */ -int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H */ diff --git a/src/core/tsi/ssl_types.h b/src/core/tsi/ssl_types.h deleted file mode 100644 index 6ea85fe6d4..0000000000 --- a/src/core/tsi/ssl_types.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright 2015-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_TSI_SSL_TYPES_H -#define GRPC_CORE_TSI_SSL_TYPES_H - -/* A collection of macros to cast between various integer types that are - * used differently between BoringSSL and OpenSSL: - * TSI_INT_AS_SIZE(x): convert 'int x' to a length parameter for an OpenSSL - * function - * TSI_SIZE_AS_SIZE(x): convert 'size_t x' to a length parameter for an OpenSSL - * function - */ - -#include - -#ifdef OPENSSL_IS_BORINGSSL -#define TSI_INT_AS_SIZE(x) ((size_t)(x)) -#define TSI_SIZE_AS_SIZE(x) (x) -#else -#define TSI_INT_AS_SIZE(x) (x) -#define TSI_SIZE_AS_SIZE(x) ((int)(x)) -#endif - -#endif /* GRPC_CORE_TSI_SSL_TYPES_H */ diff --git a/src/core/tsi/test_creds/README b/src/core/tsi/test_creds/README deleted file mode 100644 index eb8482d648..0000000000 --- a/src/core/tsi/test_creds/README +++ /dev/null @@ -1,62 +0,0 @@ -The test credentials (CONFIRMEDTESTKEY) have been generated with the following -commands: - -Bad credentials (badclient.* / badserver.*): -============================================ - -These are self-signed certificates: - -$ openssl req -x509 -newkey rsa:1024 -keyout badserver.key -out badserver.pem \ - -days 3650 -nodes - -When prompted for certificate information, everything is default except the -common name which is set to badserver.test.google.com. - - -Valid test credentials: -======================= - -The ca is self-signed: ----------------------- - -$ openssl req -x509 -new -newkey rsa:1024 -nodes -out ca.pem -config ca-openssl.cnf -days 3650 -extensions v3_req -When prompted for certificate information, everything is default. - -client is issued by CA: ------------------------ - -$ openssl genrsa -out client.key.rsa 1024 -$ openssl pkcs8 -topk8 -in client.key.rsa -out client.key -nocrypt -$ rm client.key.rsa -$ openssl req -new -key client.key -out client.csr - -When prompted for certificate information, everything is default except the -common name which is set to testclient. - -$ openssl ca -in client.csr -out client.pem - -server0 is issued by CA: ------------------------- - -$ openssl genrsa -out server0.key.rsa 1024 -$ openssl pkcs8 -topk8 -in server0.key.rsa -out server0.key -nocrypt -$ rm server0.key.rsa -$ openssl req -new -key server0.key -out server0.csr - -When prompted for certificate information, everything is default except the -common name which is set to *.test.google.com.au. - -$ openssl ca -in server0.csr -out server0.pem - -server1 is issued by CA with a special config for subject alternative names: ----------------------------------------------------------------------------- - -$ openssl genrsa -out server1.key.rsa 1024 -$ openssl pkcs8 -topk8 -in server1.key.rsa -out server1.key -nocrypt -$ rm server1.key.rsa -$ openssl req -new -key server1.key -out server1.csr -config server1-openssl.cnf - -When prompted for certificate information, everything is default except the -common name which is set to *.test.google.com. - -$ openssl ca -in server1.csr -out server1.pem diff --git a/src/core/tsi/test_creds/badclient.key b/src/core/tsi/test_creds/badclient.key deleted file mode 100644 index 5832685122..0000000000 --- a/src/core/tsi/test_creds/badclient.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALJfYnFn4nkj52WF -E5W2qUxCfjsEFyuXYYKS/07UPWsv3gpZhtjXgdeGL+dpwEBC0IRDBfGnkMp6YY5S -O7rnEz0X3r/fvgYy+dEl2jnaA6zgc7RzMGl9U11d56gP9FiDC2190mvP/hpq2xLZ -CTbIximpmaoQyxuuH1bbYunesIG/AgMBAAECgYAdqJCEzMIyZE7oaW0tOpcB0BiP -FYoIvH4BKRH8eHvR476mt+YdDhBP1scGUmYeCT4Ej+RgHv2LPTgVYwT9eciP2+E/ -CBCNRel0Sw9JepwW0r+jWJtDY1pp6YXAgNRGX2UflvUsT+o9lZvagf9moLTMyGvU -uLFnsyfLim1B4vXvWQJBANouZllXGZoSrZLtR3VgV4tzRQvJxu84kLeIk64Ov47X -pHVBMTRBfzPEhbBodjr1m5OLaVLqkFcXftzRCrbWoKsCQQDRSoLLXOiLrtJ3DLJC -rX7Y8wrHZrqk5bMdZLGa/UX8RanhVw3+Xp+urd1711umeNJfzu/MCk4a1KkG/CU0 -rqs9AkA4cSx1DD1JSG+yxMNpsAS1xJomFIrsM9vsPt7FdndDwrF+y+CovhDkGYDk -RAHh+svGfZg/pQK2JRPimAmHhzqFAkEAu6Ya70s2FUeB3Mu9aJs2CD6hg3dQEVkB -53DI7TX48d9kGW58VX1xnqS02LyWqAPcW5qm1kLHFLdndaPNmBaj4QJBAJugl367 -9d9t/QLTSuULLaoYv2vJT3s1y9HN89EoaDDEkPVfQu6GVEXgIBtim1sI/VPSzI8H -aXvaTUwblFWSM70= ------END PRIVATE KEY----- diff --git a/src/core/tsi/test_creds/badclient.pem b/src/core/tsi/test_creds/badclient.pem deleted file mode 100644 index 1785970221..0000000000 --- a/src/core/tsi/test_creds/badclient.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICoDCCAgmgAwIBAgIJANIz2/zoRiapMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGWJhZGNsaWVudC50ZXN0Lmdvb2dsZS5j -b20wHhcNMTQwNzI4MjAwODI1WhcNMjQwNzI1MjAwODI1WjBpMQswCQYDVQQGEwJB -VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 -cyBQdHkgTHRkMSIwIAYDVQQDDBliYWRjbGllbnQudGVzdC5nb29nbGUuY29tMIGf -MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyX2JxZ+J5I+dlhROVtqlMQn47BBcr -l2GCkv9O1D1rL94KWYbY14HXhi/nacBAQtCEQwXxp5DKemGOUju65xM9F96/374G -MvnRJdo52gOs4HO0czBpfVNdXeeoD/RYgwttfdJrz/4aatsS2Qk2yMYpqZmqEMsb -rh9W22Lp3rCBvwIDAQABo1AwTjAdBgNVHQ4EFgQU523AJMR8Ds9V8fhf7gu1i0MM -UqAwHwYDVR0jBBgwFoAU523AJMR8Ds9V8fhf7gu1i0MMUqAwDAYDVR0TBAUwAwEB -/zANBgkqhkiG9w0BAQUFAAOBgQCI/tvSBYH1iyfLaCTBKwpdj36+MkR9EeJJmImx -X+bjhKWXwsBX4PDMWvdusr++QGUYtyoya+hfYMXRhXua39mD54xgloQNuu9REDwX -Ffto+aOw3BcYducz6ofxicFK/Y2VeXDurSMpRv5TfGf2Qr6eOOdaRhj6ed7BibHk -X1VGZA== ------END CERTIFICATE----- diff --git a/src/core/tsi/test_creds/badserver.key b/src/core/tsi/test_creds/badserver.key deleted file mode 100644 index abfbde10ff..0000000000 --- a/src/core/tsi/test_creds/badserver.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKeZ1e1y29cmBKaW -oIUwJ5neOJUjx+eD/3nRPe+dvLXEd9+db0fG5RYRR0S3mF1Ywuj4PIxlTW2YprUS -oGSw+tcqWNIzxv94HjwYFkkvER3AblXcDBh0P2zAkzg+nf9AcAsMh0QpDTyrXtMl -gqryjq1/vkhFofKMMbY+aXJdG6OBAgMBAAECgYAAgaB51S0A22aMMkxN2rVj6530 -JWWHN4jgD1fGj41wZyWNkWYyq1Ep3ed/N6bIMWp1VbqpGe0/9YQba/D8HOTFHGRt -72YXnP1e/ds8cxU4x4j1vvqSPtXpMmkiXfXijOvCl9mrMH2xjghFAt6/1Nb9xo1m -VdcOB8OdSuOIw6CI+QJBAN5FZUbS+bRXDWII/FaAih1DBpwCxhYEN+TXPJBxSen6 -kOzGt5g+mB6YqRMZ/qshshwPq7bsgFGfJ2lIdS2t3GsCQQDBCKifV5AAkOdOUrkK -HvoX3qnVmyIA8CyvWLcIWpfZ76QAYh0q0StedKdOMXaB1jTeSJ2KU1nlss7UD1Yw -VbrDAkAwjMHpbW3jiVw//Kx5jIwehiRscWKpLnSzBJyTBFvbwsJjJai2lX2OuVO8 -+2GYKb0Iyhd81j3VFkl6grwtpRtPAkB7+n+yt555fpfRKjhGU9b09cHGu7h/OcK5 -bBVCfE0DYHLI/DsXgPiF1g6Onh4rDdUu3xyv9xDKAqnscV099hHZAkEAvcFBfXZs -tk18N+bUcvXTdZjzZbfLCHlJmwPIspZ8G/6Pn63deg4GVYoCvTwGruah+8y734Ph -7PskfPgUQlB7Ag== ------END PRIVATE KEY----- diff --git a/src/core/tsi/test_creds/badserver.pem b/src/core/tsi/test_creds/badserver.pem deleted file mode 100644 index 983c979f31..0000000000 --- a/src/core/tsi/test_creds/badserver.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICoDCCAgmgAwIBAgIJAPdqwqsKNy81MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGWJhZHNlcnZlci50ZXN0Lmdvb2dsZS5j -b20wHhcNMTQwNzI4MjAwODU0WhcNMjQwNzI1MjAwODU0WjBpMQswCQYDVQQGEwJB -VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 -cyBQdHkgTHRkMSIwIAYDVQQDDBliYWRzZXJ2ZXIudGVzdC5nb29nbGUuY29tMIGf -MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnmdXtctvXJgSmlqCFMCeZ3jiVI8fn -g/950T3vnby1xHffnW9HxuUWEUdEt5hdWMLo+DyMZU1tmKa1EqBksPrXKljSM8b/ -eB48GBZJLxEdwG5V3AwYdD9swJM4Pp3/QHALDIdEKQ08q17TJYKq8o6tf75IRaHy -jDG2PmlyXRujgQIDAQABo1AwTjAdBgNVHQ4EFgQU3u/qvHr9knMBeZyAD7mAA/ec -8cUwHwYDVR0jBBgwFoAU3u/qvHr9knMBeZyAD7mAA/ec8cUwDAYDVR0TBAUwAwEB -/zANBgkqhkiG9w0BAQUFAAOBgQA/FmR1SGLguxCCfhp4CYCbrAePSyPWDi48gTwj -vVZf/OMxdVu/H8sBYFf27BjbrEugAw16DElFtgTZ83pLb2BvkUgb6vBUK5sEkgmh -z88zBsgDp8aCf4STDOLFZMBh/E9ZKkm1zogbEmlTjFp/ceSpa2gNv7OuN4WiorOh -Wvw40g== ------END CERTIFICATE----- diff --git a/src/core/tsi/test_creds/ca-openssl.cnf b/src/core/tsi/test_creds/ca-openssl.cnf deleted file mode 100644 index e97b945e4b..0000000000 --- a/src/core/tsi/test_creds/ca-openssl.cnf +++ /dev/null @@ -1,17 +0,0 @@ -[req] -distinguished_name = req_distinguished_name -req_extensions = v3_req - -[req_distinguished_name] -countryName = Country Name (2 letter code) -countryName_default = AU -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = Some-State -organizationName = Organization Name (eg, company) -organizationName_default = Internet Widgits Pty Ltd -commonName = Common Name (eg, YOUR name) -commonName_default = testca - -[v3_req] -basicConstraints = CA:true -keyUsage = critical, keyCertSign diff --git a/src/core/tsi/test_creds/ca.key b/src/core/tsi/test_creds/ca.key deleted file mode 100644 index 03c4f950e3..0000000000 --- a/src/core/tsi/test_creds/ca.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMBA3wVeTGHZR1Ry -e/i+J8a2cu5gXwFV6TnObzGM7bLFCO5i9v4mLo4iFzPsHmWDUxKS3Y8iXbu0eYBl -LoNY0lSvxDx33O+DuwMmVN+DzSD+Eod9zfvwOWHsazYCZT2PhNxnVWIuJXViY4JA -HUGodjx+QAi6yCAurUZGvYXGgZSBAgMBAAECgYAxRi8i9BlFlufGSBVoGmydbJOm -bwLKl9dP3o33ODSP9hok5y6A0w5plWk3AJSF1hPLleK9VcSKYGYnt0clmPVHF35g -bx2rVK8dOT0mn7rz9Zr70jcSz1ETA2QonHZ+Y+niLmcic9At6hRtWiewblUmyFQm -GwggIzi7LOyEUHrEcQJBAOXxyQvnLvtKzXiqcsW/K6rExqVJVk+KF0fzzVyMzTJx -HRBxUVgvGdEJT7j+7P2kcTyafve0BBzDSPIaDyiJ+Y0CQQDWCb7jASFSbu5M3Zcd -Gkr4ZKN1XO3VLQX10b22bQYdF45hrTN2tnzRvVUR4q86VVnXmiGiTqmLkXcA2WWf -pHfFAkAhv9olUBo6MeF0i3frBEMRfm41hk0PwZHnMqZ6pgPcGnQMnMU2rzsXzkkQ -OwJnvAIOxhJKovZTjmofdqmw5odlAkBYVUdRWjsNUTjJwj3GRf6gyq/nFMYWz3EB -RWFdM1ttkDYzu45ctO2IhfHg4sPceDMO1s6AtKQmNI9/azkUjITdAkApNa9yFRzc -TBaDNPd5KVd58LVIzoPQ6i7uMHteLXJUWqSroji6S3s4gKMFJ/dO+ZXIlgQgfJJJ -ZDL4cdrdkeoM ------END PRIVATE KEY----- diff --git a/src/core/tsi/test_creds/ca.pem b/src/core/tsi/test_creds/ca.pem deleted file mode 100644 index 6c8511a73c..0000000000 --- a/src/core/tsi/test_creds/ca.pem +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla -Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT -BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 -+L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu -g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd -Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau -sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m -oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG -Dfcog5wrJytaQ6UA0wE= ------END CERTIFICATE----- diff --git a/src/core/tsi/test_creds/client.key b/src/core/tsi/test_creds/client.key deleted file mode 100644 index f48d0735d9..0000000000 --- a/src/core/tsi/test_creds/client.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAOxUR9uhvhbeVUIM -s5WbH0px0mehl2+6sZpNjzvE2KimZpHzMJHukVH0Ffkvhs0b8+S5Ut9VNUAqd3IM -JCCAEGtRNoQhM1t9Yr2zAckSvbRacp+FL/Cj9eDmyo00KsVGaeefA4Dh4OW+ZhkT -NKcldXqkSuj1sEf244JZYuqZp6/tAgMBAAECgYEAi2NSVqpZMafE5YYUTcMGe6QS -k2jtpsqYgggI2RnLJ/2tNZwYI5pwP8QVSbnMaiF4gokD5hGdrNDfTnb2v+yIwYEH -0w8+oG7Z81KodsiZSIDJfTGsAZhVNwOz9y0VD8BBZZ1/274Zh52AUKLjZS/ZwIbS -W2ywya855dPnH/wj+0ECQQD9X8D920kByTNHhBG18biAEZ4pxs9f0OAG8333eVcI -w2lJDLsYDZrCB2ocgA3lUdozlzPC7YDYw8reg0tkiRY5AkEA7sdNzOeQsQRn7++5 -0bP9DtT/iON1gbfxRzCfCfXdoOtfQWIzTePWtURt9X/5D9NofI0Rg5W2oGy/MLe5 -/sXHVQJBAIup5XrJDkQywNZyAUU2ecn2bCWBFjwtqd+LBmuMciI9fOKsZtEKZrz/ -U0lkeMRoSwvXE8wmGLjjrAbdfohrXFkCQQDZEx/LtIl6JINJQiswVe0tWr6k+ASP -1WXoTm+HYpoF/XUvv9LccNF1IazFj34hwRQwhx7w/V52Ieb+p0jUMYGxAkEAjDhd -9pBO1fKXWiXzi9ZKfoyTNcUq3eBSVKwPG2nItg5ycXengjT5sgcWDnciIzW7BIVI -JiqOszq9GWESErAatg== ------END PRIVATE KEY----- diff --git a/src/core/tsi/test_creds/client.pem b/src/core/tsi/test_creds/client.pem deleted file mode 100644 index e332091019..0000000000 --- a/src/core/tsi/test_creds/client.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICHzCCAYgCAQEwDQYJKoZIhvcNAQEFBQAwVjELMAkGA1UEBhMCQVUxEzARBgNV -BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 -ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTE0MDcxNzIzNTYwMloXDTI0MDcxNDIzNTYw -MlowWjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM -GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKdGVzdGNsaWVudDCB -nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA7FRH26G+Ft5VQgyzlZsfSnHSZ6GX -b7qxmk2PO8TYqKZmkfMwke6RUfQV+S+GzRvz5LlS31U1QCp3cgwkIIAQa1E2hCEz -W31ivbMByRK9tFpyn4Uv8KP14ObKjTQqxUZp558DgOHg5b5mGRM0pyV1eqRK6PWw -R/bjglli6pmnr+0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAStSm5PM7ubROiKK6/ -T2FkKlhiTOx+Ryenm3Eio59emq+jXl+1nhPySX5G2PQzSR5vd1dIhwgZSR4Gyttk -tRZ57k/NI1brUW8joiEOMJA/Mr7H7asx7wIRYDE91Fs8GkKWd5LhoPAQj+qdG35C -OO+svdkmqH0KZo320ZUqdl2ooQ== ------END CERTIFICATE----- diff --git a/src/core/tsi/test_creds/server0.key b/src/core/tsi/test_creds/server0.key deleted file mode 100644 index add153c9ae..0000000000 --- a/src/core/tsi/test_creds/server0.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANOmffupIGC8YDau -rOF4eKnHwPszgpkkhWzKsVxhNDBxCVYx4TEjG0XWIO0iyRXupZbUC+7N/8HnEVNa -8F1jYhng14Iiq99cNQbbnuHHhIztmpocrJTxmnhGzoAnRa1Tb+GnAuRoIHRA/V2c -VUE9tbikQugFx/SPgXAw6tfWB+YvAgMBAAECgYEAoEq9qzUBgoHoVEGiSPiWWe8g -5p6yUA1qx2QTQyWTAwT4z0DjjfVKmG99bFsl8+hTnJFnoCp/gnjflEOROwkjp5kG -m0drqOPx1jeipJjpXYTBu49h+WpZ1PF+KhVtxsIm3OOCvh67iWaKyyOVb5Og8aiR -jl6dn/TdG/dlGD8AfUECQQDuNMle6p0oU8amC6O9wIMBroxx2nFstzE6O35PLEzG -/tj0kxxn9Jp2TS9mGaLCzSuXmpjlF4+NOWiBPkrLC2TfAkEA43Xg7uEUkaJAz2/W -m1lIBTLt+4rIQY/2emh33bDcA+rv8rwwrMMIv17/xPx7bs49YqGG5xufD+Rwl6TL -qFXYsQJAPrOwagax1aKvwJeBw3oAQhoTKAkLIEXcdGqipe6QSzVcIIz0xjxxyEAr -AOIwoLxnBCISqwMXq2H4K0UdZPMb2wJAdhdYLY1L6YRMk6XjzImg25oidisKZweA -FvMv8DgHMj2CUAqmVrt3SivfLH1M9C09L3zfFhOAFHcsgX58gav4MQJBANSBnrHj -tIq4l8z79CPUIuu3QyeEh+XwY8s5qE5CNTck0U59lzp9NvENHbkx3KO896TTerko -+8bXHMLkJkHPXms= ------END PRIVATE KEY----- diff --git a/src/core/tsi/test_creds/server0.pem b/src/core/tsi/test_creds/server0.pem deleted file mode 100644 index ade75d8563..0000000000 --- a/src/core/tsi/test_creds/server0.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICHDCCAYUCAQQwDQYJKoZIhvcNAQEFBQAwVjELMAkGA1UEBhMCQVUxEzARBgNV -BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 -ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTE0MDcyMjE3NTk0OVoXDTI0MDcxOTE3NTk0 -OVowVzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxFDASBgNVBAoM -C0dvb2dsZSBJbmMuMR0wGwYDVQQDDBQqLnRlc3QuZ29vZ2xlLmNvbS5hdTCBnzAN -BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA06Z9+6kgYLxgNq6s4Xh4qcfA+zOCmSSF -bMqxXGE0MHEJVjHhMSMbRdYg7SLJFe6lltQL7s3/wecRU1rwXWNiGeDXgiKr31w1 -Btue4ceEjO2amhyslPGaeEbOgCdFrVNv4acC5GggdED9XZxVQT21uKRC6AXH9I+B -cDDq19YH5i8CAwEAATANBgkqhkiG9w0BAQUFAAOBgQBtfR5qXG9TTI8YcYh7sA4V -GeNoplp0x6p7OG0NLvbJqAkUnkvjIkk1m1R2AUHhbkxzx6G75JIOoNJcWrCzywBA -BIsaTdmnNysf/s1hQJuD3IHiVb+7Ji0jhttnJlYcMid4o0tJO/a2E9YUxR+9cg0i -obb+Ql3qsvKdWBC1dDLDLw== ------END CERTIFICATE----- diff --git a/src/core/tsi/test_creds/server1-openssl.cnf b/src/core/tsi/test_creds/server1-openssl.cnf deleted file mode 100644 index 8a02108289..0000000000 --- a/src/core/tsi/test_creds/server1-openssl.cnf +++ /dev/null @@ -1,26 +0,0 @@ -[req] -distinguished_name = req_distinguished_name -req_extensions = v3_req - -[req_distinguished_name] -countryName = Country Name (2 letter code) -countryName_default = US -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = Illinois -localityName = Locality Name (eg, city) -localityName_default = Chicago -organizationName = Organization Name (eg, company) -organizationName_default = Example, Co. -commonName = Common Name (eg, YOUR name) -commonName_max = 64 - -[v3_req] -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment -subjectAltName = @alt_names - -[alt_names] -DNS.1 = *.test.google.fr -DNS.2 = waterzooi.test.google.be -DNS.3 = *.test.youtube.com -IP.1 = "192.168.1.3" diff --git a/src/core/tsi/test_creds/server1.key b/src/core/tsi/test_creds/server1.key deleted file mode 100644 index 143a5b8765..0000000000 --- a/src/core/tsi/test_creds/server1.key +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD -M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf -3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY -AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm -V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY -tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p -dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q -K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR -81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff -DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd -aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 -ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 -XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe -F98XJ7tIFfJq ------END PRIVATE KEY----- diff --git a/src/core/tsi/test_creds/server1.pem b/src/core/tsi/test_creds/server1.pem deleted file mode 100644 index f3d43fcc5b..0000000000 --- a/src/core/tsi/test_creds/server1.pem +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET -MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ -dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx -MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV -BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 -ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco -LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg -zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd -9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw -CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy -em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G -CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 -hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh -y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 ------END CERTIFICATE----- diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c deleted file mode 100644 index db219a50a6..0000000000 --- a/src/core/tsi/transport_security.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * - * Copyright 2015, 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/tsi/transport_security.h" - -#include -#include - -/* --- Tracing. --- */ - -int tsi_tracing_enabled = 0; - -/* --- Utils. --- */ - -char *tsi_strdup(const char *src) { - char *dst; - size_t len; - if (!src) return NULL; - len = strlen(src) + 1; - dst = malloc(len); - if (!dst) return NULL; - memcpy(dst, src, len); - return dst; -} - -/* --- tsi_result common implementation. --- */ - -const char *tsi_result_to_string(tsi_result result) { - switch (result) { - case TSI_OK: - return "TSI_OK"; - case TSI_UNKNOWN_ERROR: - return "TSI_UNKNOWN_ERROR"; - case TSI_INVALID_ARGUMENT: - return "TSI_INVALID_ARGUMENT"; - case TSI_PERMISSION_DENIED: - return "TSI_PERMISSION_DENIED"; - case TSI_INCOMPLETE_DATA: - return "TSI_INCOMPLETE_DATA"; - case TSI_FAILED_PRECONDITION: - return "TSI_FAILED_PRECONDITION"; - case TSI_UNIMPLEMENTED: - return "TSI_UNIMPLEMENTED"; - case TSI_INTERNAL_ERROR: - return "TSI_INTERNAL_ERROR"; - case TSI_DATA_CORRUPTED: - return "TSI_DATA_CORRUPTED"; - case TSI_NOT_FOUND: - return "TSI_NOT_FOUND"; - case TSI_PROTOCOL_FAILURE: - return "TSI_PROTOCOL_FAILURE"; - case TSI_HANDSHAKE_IN_PROGRESS: - return "TSI_HANDSHAKE_IN_PROGRESS"; - case TSI_OUT_OF_RESOURCES: - return "TSI_OUT_OF_RESOURCES"; - default: - return "UNKNOWN"; - } -} - -/* --- tsi_frame_protector common implementation. --- - - Calls specific implementation after state/input validation. */ - -tsi_result tsi_frame_protector_protect(tsi_frame_protector *self, - const unsigned char *unprotected_bytes, - size_t *unprotected_bytes_size, - unsigned char *protected_output_frames, - size_t *protected_output_frames_size) { - if (self == NULL || unprotected_bytes == NULL || - unprotected_bytes_size == NULL || protected_output_frames == NULL || - protected_output_frames_size == NULL) { - return TSI_INVALID_ARGUMENT; - } - return self->vtable->protect(self, unprotected_bytes, unprotected_bytes_size, - protected_output_frames, - protected_output_frames_size); -} - -tsi_result tsi_frame_protector_protect_flush( - tsi_frame_protector *self, unsigned char *protected_output_frames, - size_t *protected_output_frames_size, size_t *still_pending_size) { - if (self == NULL || protected_output_frames == NULL || - protected_output_frames == NULL || still_pending_size == NULL) { - return TSI_INVALID_ARGUMENT; - } - return self->vtable->protect_flush(self, protected_output_frames, - protected_output_frames_size, - still_pending_size); -} - -tsi_result tsi_frame_protector_unprotect( - tsi_frame_protector *self, const unsigned char *protected_frames_bytes, - size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes, - size_t *unprotected_bytes_size) { - if (self == NULL || protected_frames_bytes == NULL || - protected_frames_bytes_size == NULL || unprotected_bytes == NULL || - unprotected_bytes_size == NULL) { - return TSI_INVALID_ARGUMENT; - } - return self->vtable->unprotect(self, protected_frames_bytes, - protected_frames_bytes_size, unprotected_bytes, - unprotected_bytes_size); -} - -void tsi_frame_protector_destroy(tsi_frame_protector *self) { - if (self == NULL) return; - self->vtable->destroy(self); -} - -/* --- tsi_handshaker common implementation. --- - - Calls specific implementation after state/input validation. */ - -tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, - unsigned char *bytes, - size_t *bytes_size) { - if (self == NULL || bytes == NULL || bytes_size == NULL) { - return TSI_INVALID_ARGUMENT; - } - if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; - return self->vtable->get_bytes_to_send_to_peer(self, bytes, bytes_size); -} - -tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self, - const unsigned char *bytes, - size_t *bytes_size) { - if (self == NULL || bytes == NULL || bytes_size == NULL) { - return TSI_INVALID_ARGUMENT; - } - if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; - return self->vtable->process_bytes_from_peer(self, bytes, bytes_size); -} - -tsi_result tsi_handshaker_get_result(tsi_handshaker *self) { - if (self == NULL) return TSI_INVALID_ARGUMENT; - if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; - return self->vtable->get_result(self); -} - -tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer) { - if (self == NULL || peer == NULL) return TSI_INVALID_ARGUMENT; - memset(peer, 0, sizeof(tsi_peer)); - if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; - if (tsi_handshaker_get_result(self) != TSI_OK) { - return TSI_FAILED_PRECONDITION; - } - return self->vtable->extract_peer(self, peer); -} - -tsi_result tsi_handshaker_create_frame_protector( - tsi_handshaker *self, size_t *max_protected_frame_size, - tsi_frame_protector **protector) { - tsi_result result; - if (self == NULL || protector == NULL) return TSI_INVALID_ARGUMENT; - if (self->frame_protector_created) return TSI_FAILED_PRECONDITION; - if (tsi_handshaker_get_result(self) != TSI_OK) { - return TSI_FAILED_PRECONDITION; - } - result = self->vtable->create_frame_protector(self, max_protected_frame_size, - protector); - if (result == TSI_OK) { - self->frame_protector_created = 1; - } - return result; -} - -void tsi_handshaker_destroy(tsi_handshaker *self) { - if (self == NULL) return; - self->vtable->destroy(self); -} - -/* --- tsi_peer implementation. --- */ - -tsi_peer_property tsi_init_peer_property(void) { - tsi_peer_property property; - memset(&property, 0, sizeof(tsi_peer_property)); - return property; -} - -static void tsi_peer_destroy_list_property(tsi_peer_property *children, - size_t child_count) { - size_t i; - for (i = 0; i < child_count; i++) { - tsi_peer_property_destruct(&children[i]); - } - free(children); -} - -void tsi_peer_property_destruct(tsi_peer_property *property) { - if (property->name != NULL) { - free(property->name); - } - if (property->value.data != NULL) { - free(property->value.data); - } - *property = tsi_init_peer_property(); /* Reset everything to 0. */ -} - -void tsi_peer_destruct(tsi_peer *self) { - if (self == NULL) return; - if (self->properties != NULL) { - tsi_peer_destroy_list_property(self->properties, self->property_count); - self->properties = NULL; - } - self->property_count = 0; -} - -tsi_result tsi_construct_allocated_string_peer_property( - const char *name, size_t value_length, tsi_peer_property *property) { - *property = tsi_init_peer_property(); - if (name != NULL) { - property->name = tsi_strdup(name); - if (property->name == NULL) return TSI_OUT_OF_RESOURCES; - } - if (value_length > 0) { - property->value.data = calloc(1, value_length); - if (property->value.data == NULL) { - tsi_peer_property_destruct(property); - return TSI_OUT_OF_RESOURCES; - } - property->value.length = value_length; - } - return TSI_OK; -} - -tsi_result tsi_construct_string_peer_property_from_cstring( - const char *name, const char *value, tsi_peer_property *property) { - return tsi_construct_string_peer_property(name, value, strlen(value), - property); -} - -tsi_result tsi_construct_string_peer_property(const char *name, - const char *value, - size_t value_length, - tsi_peer_property *property) { - tsi_result result = tsi_construct_allocated_string_peer_property( - name, value_length, property); - if (result != TSI_OK) return result; - if (value_length > 0) { - memcpy(property->value.data, value, value_length); - } - return TSI_OK; -} - -tsi_result tsi_construct_peer(size_t property_count, tsi_peer *peer) { - memset(peer, 0, sizeof(tsi_peer)); - if (property_count > 0) { - peer->properties = calloc(property_count, sizeof(tsi_peer_property)); - if (peer->properties == NULL) return TSI_OUT_OF_RESOURCES; - peer->property_count = property_count; - } - return TSI_OK; -} diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h deleted file mode 100644 index ecc037193b..0000000000 --- a/src/core/tsi/transport_security.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * - * Copyright 2015-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_TSI_TRANSPORT_SECURITY_H -#define GRPC_CORE_TSI_TRANSPORT_SECURITY_H - -#include "src/core/tsi/transport_security_interface.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern int tsi_tracing_enabled; - -/* Base for tsi_frame_protector implementations. - See transport_security_interface.h for documentation. */ -typedef struct { - tsi_result (*protect)(tsi_frame_protector *self, - const unsigned char *unprotected_bytes, - size_t *unprotected_bytes_size, - unsigned char *protected_output_frames, - size_t *protected_output_frames_size); - tsi_result (*protect_flush)(tsi_frame_protector *self, - unsigned char *protected_output_frames, - size_t *protected_output_frames_size, - size_t *still_pending_size); - tsi_result (*unprotect)(tsi_frame_protector *self, - const unsigned char *protected_frames_bytes, - size_t *protected_frames_bytes_size, - unsigned char *unprotected_bytes, - size_t *unprotected_bytes_size); - void (*destroy)(tsi_frame_protector *self); -} tsi_frame_protector_vtable; - -struct tsi_frame_protector { - const tsi_frame_protector_vtable *vtable; -}; - -/* Base for tsi_handshaker implementations. - See transport_security_interface.h for documentation. */ -typedef struct { - tsi_result (*get_bytes_to_send_to_peer)(tsi_handshaker *self, - unsigned char *bytes, - size_t *bytes_size); - tsi_result (*process_bytes_from_peer)(tsi_handshaker *self, - const unsigned char *bytes, - size_t *bytes_size); - tsi_result (*get_result)(tsi_handshaker *self); - tsi_result (*extract_peer)(tsi_handshaker *self, tsi_peer *peer); - tsi_result (*create_frame_protector)(tsi_handshaker *self, - size_t *max_protected_frame_size, - tsi_frame_protector **protector); - void (*destroy)(tsi_handshaker *self); -} tsi_handshaker_vtable; - -struct tsi_handshaker { - const tsi_handshaker_vtable *vtable; - int frame_protector_created; -}; - -/* Peer and property construction/destruction functions. */ -tsi_result tsi_construct_peer(size_t property_count, tsi_peer *peer); -tsi_peer_property tsi_init_peer_property(void); -void tsi_peer_property_destruct(tsi_peer_property *property); -tsi_result tsi_construct_string_peer_property(const char *name, - const char *value, - size_t value_length, - tsi_peer_property *property); -tsi_result tsi_construct_allocated_string_peer_property( - const char *name, size_t value_length, tsi_peer_property *property); -tsi_result tsi_construct_string_peer_property_from_cstring( - const char *name, const char *value, tsi_peer_property *property); - -/* Utils. */ -char *tsi_strdup(const char *src); /* Sadly, no strdup in C89. */ - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_H */ diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h deleted file mode 100644 index 08501802f5..0000000000 --- a/src/core/tsi/transport_security_interface.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * - * Copyright 2015-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_TSI_TRANSPORT_SECURITY_INTERFACE_H -#define GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* --- tsi result --- */ - -typedef enum { - TSI_OK = 0, - TSI_UNKNOWN_ERROR = 1, - TSI_INVALID_ARGUMENT = 2, - TSI_PERMISSION_DENIED = 3, - TSI_INCOMPLETE_DATA = 4, - TSI_FAILED_PRECONDITION = 5, - TSI_UNIMPLEMENTED = 6, - TSI_INTERNAL_ERROR = 7, - TSI_DATA_CORRUPTED = 8, - TSI_NOT_FOUND = 9, - TSI_PROTOCOL_FAILURE = 10, - TSI_HANDSHAKE_IN_PROGRESS = 11, - TSI_OUT_OF_RESOURCES = 12 -} tsi_result; - -const char *tsi_result_to_string(tsi_result result); - -/* --- tsi tracing --- */ - -/* Set this early to avoid races */ -extern int tsi_tracing_enabled; - -/* --- tsi_frame_protector object --- - - This object protects and unprotects buffers once the handshake is done. - Implementations of this object must be thread compatible. */ - -typedef struct tsi_frame_protector tsi_frame_protector; - -/* Outputs protected frames. - - unprotected_bytes is an input only parameter and points to the data - to be protected. - - unprotected_bytes_size is an input/output parameter used by the caller to - specify how many bytes are available in unprotected_bytes. The output - value is the number of bytes consumed during the call. - - protected_output_frames points to a buffer allocated by the caller that - will be written. - - protected_output_frames_size is an input/output parameter used by the - caller to specify how many bytes are available in protected_output_frames. - As an output, this value indicates the number of bytes written. - - This method returns TSI_OK in case of success or a specific error code in - case of failure. Note that even if all the input unprotected bytes are - consumed, they may not have been processed into the returned protected - output frames. The caller should call the protect_flush method - to make sure that there are no more protected bytes buffered in the - protector. - - A typical way to call this method would be: - - ------------------------------------------------------------------------ - unsigned char protected_buffer[4096]; - size_t protected_buffer_size = sizeof(protected_buffer); - tsi_result result = TSI_OK; - while (message_size > 0) { - size_t protected_buffer_size_to_send = protected_buffer_size; - size_t processed_message_size = message_size; - result = tsi_frame_protector_protect(protector, - message_bytes, - &processed_message_size, - protected_buffer, - &protected_buffer_size_to_send); - if (result != TSI_OK) break; - send_bytes_to_peer(protected_buffer, protected_buffer_size_to_send); - message_bytes += processed_message_size; - message_size -= processed_message_size; - - // Don't forget to flush. - if (message_size == 0) { - size_t still_pending_size; - do { - protected_buffer_size_to_send = protected_buffer_size; - result = tsi_frame_protector_protect_flush( - protector, protected_buffer, - &protected_buffer_size_to_send, &still_pending_size); - if (result != TSI_OK) break; - send_bytes_to_peer(protected_buffer, protected_buffer_size_to_send); - } while (still_pending_size > 0); - } - } - - if (result != TSI_OK) HandleError(result); - ------------------------------------------------------------------------ */ -tsi_result tsi_frame_protector_protect(tsi_frame_protector *self, - const unsigned char *unprotected_bytes, - size_t *unprotected_bytes_size, - unsigned char *protected_output_frames, - size_t *protected_output_frames_size); - -/* Indicates that we need to flush the bytes buffered in the protector and get - the resulting frame. - - protected_output_frames points to a buffer allocated by the caller that - will be written. - - protected_output_frames_size is an input/output parameter used by the - caller to specify how many bytes are available in protected_output_frames. - - still_pending_bytes is an output parameter indicating the number of bytes - that still need to be flushed from the protector.*/ -tsi_result tsi_frame_protector_protect_flush( - tsi_frame_protector *self, unsigned char *protected_output_frames, - size_t *protected_output_frames_size, size_t *still_pending_size); - -/* Outputs unprotected bytes. - - protected_frames_bytes is an input only parameter and points to the - protected frames to be unprotected. - - protected_frames_bytes_size is an input/output only parameter used by the - caller to specify how many bytes are available in protected_bytes. The - output value is the number of bytes consumed during the call. - Implementations will buffer up to a frame of protected data. - - unprotected_bytes points to a buffer allocated by the caller that will be - written. - - unprotected_bytes_size is an input/output parameter used by the caller to - specify how many bytes are available in unprotected_bytes. This - value is expected to be at most max_protected_frame_size minus overhead - which means that max_protected_frame_size is a safe bet. The output value - is the number of bytes actually written. - If *unprotected_bytes_size is unchanged, there may be more data remaining - to unprotect, and the caller should call this function again. - - - This method returns TSI_OK in case of success. Success includes cases where - there is not enough data to output a frame in which case - unprotected_bytes_size will be set to 0 and cases where the internal buffer - needs to be read before new protected data can be processed in which case - protected_frames_size will be set to 0. */ -tsi_result tsi_frame_protector_unprotect( - tsi_frame_protector *self, const unsigned char *protected_frames_bytes, - size_t *protected_frames_bytes_size, unsigned char *unprotected_bytes, - size_t *unprotected_bytes_size); - -/* Destroys the tsi_frame_protector object. */ -void tsi_frame_protector_destroy(tsi_frame_protector *self); - -/* --- tsi_peer objects --- - - tsi_peer objects are a set of properties. The peer owns the properties. */ - -/* This property is of type TSI_PEER_PROPERTY_STRING. */ -#define TSI_CERTIFICATE_TYPE_PEER_PROPERTY "certificate_type" - -/* Property values may contain NULL characters just like C++ strings. - The length field gives the length of the string. */ -typedef struct tsi_peer_property { - char *name; - struct { - char *data; - size_t length; - } value; -} tsi_peer_property; - -typedef struct { - tsi_peer_property *properties; - size_t property_count; -} tsi_peer; - -/* Destructs the tsi_peer object. */ -void tsi_peer_destruct(tsi_peer *self); - -/* --- tsi_handshaker objects ---- - - Implementations of this object must be thread compatible. - - A typical usage of this object would be: - - ------------------------------------------------------------------------ - tsi_result result = TSI_OK; - unsigned char buf[4096]; - size_t buf_offset; - size_t buf_size; - while (1) { - // See if we need to send some bytes to the peer. - do { - size_t buf_size_to_send = sizeof(buf); - result = tsi_handshaker_get_bytes_to_send_to_peer(handshaker, buf, - &buf_size_to_send); - if (buf_size_to_send > 0) send_bytes_to_peer(buf, buf_size_to_send); - } while (result == TSI_INCOMPLETE_DATA); - if (result != TSI_OK) return result; - if (!tsi_handshaker_is_in_progress(handshaker)) break; - - do { - // Read bytes from the peer. - buf_size = sizeof(buf); - buf_offset = 0; - read_bytes_from_peer(buf, &buf_size); - if (buf_size == 0) break; - - // Process the bytes from the peer. We have to be careful as these bytes - // may contain non-handshake data (protected data). If this is the case, - // we will exit from the loop with buf_size > 0. - size_t consumed_by_handshaker = buf_size; - result = tsi_handshaker_process_bytes_from_peer( - handshaker, buf, &consumed_by_handshaker); - buf_size -= consumed_by_handshaker; - buf_offset += consumed_by_handshaker; - } while (result == TSI_INCOMPLETE_DATA); - - if (result != TSI_OK) return result; - if (!tsi_handshaker_is_in_progress(handshaker)) break; - } - - // Check the Peer. - tsi_peer peer; - do { - result = tsi_handshaker_extract_peer(handshaker, &peer); - if (result != TSI_OK) break; - result = check_peer(&peer); - } while (0); - tsi_peer_destruct(&peer); - if (result != TSI_OK) return result; - - // Create the protector. - tsi_frame_protector* protector = NULL; - result = tsi_handshaker_create_frame_protector(handshaker, NULL, - &protector); - if (result != TSI_OK) return result; - - // Do not forget to unprotect outstanding data if any. - if (buf_size > 0) { - result = tsi_frame_protector_unprotect(protector, buf + buf_offset, - buf_size, ..., ...); - .... - } - ... - ------------------------------------------------------------------------ */ -typedef struct tsi_handshaker tsi_handshaker; - -/* Gets bytes that need to be sent to the peer. - - bytes is the buffer that will be written with the data to be sent to the - peer. - - bytes_size is an input/output parameter specifying the capacity of the - bytes parameter as input and the number of bytes written as output. - Returns TSI_OK if all the data to send to the peer has been written or if - nothing has to be sent to the peer (in which base bytes_size outputs to 0), - otherwise returns TSI_INCOMPLETE_DATA which indicates that this method - needs to be called again to get all the bytes to send to the peer (there - was more data to write than the specified bytes_size). In case of a fatal - error in the handshake, another specific error code is returned. */ -tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self, - unsigned char *bytes, - size_t *bytes_size); - -/* Processes bytes received from the peer. - - bytes is the buffer containing the data. - - bytes_size is an input/output parameter specifying the size of the data as - input and the number of bytes consumed as output. - Return TSI_OK if the handshake has all the data it needs to process, - otherwise return TSI_INCOMPLETE_DATA which indicates that this method - needs to be called again to complete the data needed for processing. In - case of a fatal error in the handshake, another specific error code is - returned. */ -tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker *self, - const unsigned char *bytes, - size_t *bytes_size); - -/* Gets the result of the handshaker. - Returns TSI_OK if the hanshake completed successfully and there has been no - errors. Returns TSI_HANDSHAKE_IN_PROGRESS if the handshaker is not done yet - but no error has been encountered so far. Otherwise the handshaker failed - with the returned error. */ -tsi_result tsi_handshaker_get_result(tsi_handshaker *self); - -/* Returns 1 if the handshake is in progress, 0 otherwise. */ -#define tsi_handshaker_is_in_progress(h) \ - (tsi_handshaker_get_result((h)) == TSI_HANDSHAKE_IN_PROGRESS) - -/* This method may return TSI_FAILED_PRECONDITION if - tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise - assuming the handshaker is not in a fatal error state. - The caller is responsible for destructing the peer. */ -tsi_result tsi_handshaker_extract_peer(tsi_handshaker *self, tsi_peer *peer); - -/* This method creates a tsi_frame_protector object after the handshake phase - is done. After this method has been called successfully, the only method - that can be called on this object is Destroy. - - max_output_protected_frame_size is an input/output parameter specifying the - desired max output protected frame size as input and outputing the actual - max output frame size as the output. Passing NULL is OK and will result in - the implementation choosing the default maximum protected frame size. Note - that this size only applies to outgoing frames (generated with - tsi_frame_protector_protect) and not incoming frames (input of - tsi_frame_protector_unprotect). - - protector is an output parameter pointing to the newly created - tsi_frame_protector object. - This method may return TSI_FAILED_PRECONDITION if - tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise assuming - the handshaker is not in a fatal error state. - The caller is responsible for destroying the protector. */ -tsi_result tsi_handshaker_create_frame_protector( - tsi_handshaker *self, size_t *max_output_protected_frame_size, - tsi_frame_protector **protector); - -/* This method releases the tsi_handshaker object. After this method is called, - no other method can be called on the object. */ -void tsi_handshaker_destroy(tsi_handshaker *self); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 27cd8d60bc..a5bc18af5e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -30,211 +30,211 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_core_dependencies.py.template`!!! CORE_SOURCE_FILES = [ - 'src/core/profiling/basic_timers.c', - 'src/core/profiling/stap_timers.c', - 'src/core/support/alloc.c', - 'src/core/support/avl.c', - 'src/core/support/backoff.c', - 'src/core/support/cmdline.c', - 'src/core/support/cpu_iphone.c', - 'src/core/support/cpu_linux.c', - 'src/core/support/cpu_posix.c', - 'src/core/support/cpu_windows.c', - 'src/core/support/env_linux.c', - 'src/core/support/env_posix.c', - 'src/core/support/env_win32.c', - 'src/core/support/histogram.c', - 'src/core/support/host_port.c', - 'src/core/support/load_file.c', - 'src/core/support/log.c', - 'src/core/support/log_android.c', - 'src/core/support/log_linux.c', - 'src/core/support/log_posix.c', - 'src/core/support/log_win32.c', - 'src/core/support/murmur_hash.c', - 'src/core/support/slice.c', - 'src/core/support/slice_buffer.c', - 'src/core/support/stack_lockfree.c', - 'src/core/support/string.c', - 'src/core/support/string_posix.c', - 'src/core/support/string_win32.c', - 'src/core/support/subprocess_posix.c', - 'src/core/support/subprocess_windows.c', - 'src/core/support/sync.c', - 'src/core/support/sync_posix.c', - 'src/core/support/sync_win32.c', - 'src/core/support/thd.c', - 'src/core/support/thd_posix.c', - 'src/core/support/thd_win32.c', - 'src/core/support/time.c', - 'src/core/support/time_posix.c', - 'src/core/support/time_precise.c', - 'src/core/support/time_win32.c', - 'src/core/support/tls_pthread.c', - 'src/core/support/tmpfile_posix.c', - 'src/core/support/tmpfile_win32.c', - 'src/core/support/wrap_memcpy.c', - 'src/core/census/grpc_context.c', - 'src/core/census/grpc_filter.c', - 'src/core/census/grpc_plugin.c', - 'src/core/channel/channel_args.c', - 'src/core/channel/channel_stack.c', - 'src/core/channel/channel_stack_builder.c', - 'src/core/channel/client_channel.c', - 'src/core/channel/compress_filter.c', - 'src/core/channel/connected_channel.c', - 'src/core/channel/http_client_filter.c', - 'src/core/channel/http_server_filter.c', - 'src/core/channel/subchannel_call_holder.c', - 'src/core/client_config/client_config.c', - 'src/core/client_config/connector.c', - 'src/core/client_config/default_initial_connect_string.c', - 'src/core/client_config/initial_connect_string.c', - 'src/core/client_config/lb_policies/load_balancer_api.c', - 'src/core/client_config/lb_policies/pick_first.c', - 'src/core/client_config/lb_policies/round_robin.c', - 'src/core/client_config/lb_policy.c', - 'src/core/client_config/lb_policy_factory.c', - 'src/core/client_config/lb_policy_registry.c', - 'src/core/client_config/resolver.c', - 'src/core/client_config/resolver_factory.c', - 'src/core/client_config/resolver_registry.c', - 'src/core/client_config/resolvers/dns_resolver.c', - 'src/core/client_config/resolvers/sockaddr_resolver.c', - 'src/core/client_config/subchannel.c', - 'src/core/client_config/subchannel_factory.c', - 'src/core/client_config/subchannel_index.c', - 'src/core/client_config/uri_parser.c', - 'src/core/compression/compression_algorithm.c', - 'src/core/compression/message_compress.c', - 'src/core/debug/trace.c', - 'src/core/http/format_request.c', - 'src/core/http/httpcli.c', - 'src/core/http/parser.c', - 'src/core/iomgr/closure.c', - 'src/core/iomgr/endpoint.c', - 'src/core/iomgr/endpoint_pair_posix.c', - 'src/core/iomgr/endpoint_pair_windows.c', - 'src/core/iomgr/exec_ctx.c', - 'src/core/iomgr/executor.c', - 'src/core/iomgr/fd_posix.c', - 'src/core/iomgr/iocp_windows.c', - 'src/core/iomgr/iomgr.c', - 'src/core/iomgr/iomgr_posix.c', - 'src/core/iomgr/iomgr_windows.c', - 'src/core/iomgr/pollset_multipoller_with_epoll.c', - 'src/core/iomgr/pollset_multipoller_with_poll_posix.c', - 'src/core/iomgr/pollset_posix.c', - 'src/core/iomgr/pollset_set_posix.c', - 'src/core/iomgr/pollset_set_windows.c', - 'src/core/iomgr/pollset_windows.c', - 'src/core/iomgr/resolve_address_posix.c', - 'src/core/iomgr/resolve_address_windows.c', - 'src/core/iomgr/sockaddr_utils.c', - 'src/core/iomgr/socket_utils_common_posix.c', - 'src/core/iomgr/socket_utils_linux.c', - 'src/core/iomgr/socket_utils_posix.c', - 'src/core/iomgr/socket_windows.c', - 'src/core/iomgr/tcp_client_posix.c', - 'src/core/iomgr/tcp_client_windows.c', - 'src/core/iomgr/tcp_posix.c', - 'src/core/iomgr/tcp_server_posix.c', - 'src/core/iomgr/tcp_server_windows.c', - 'src/core/iomgr/tcp_windows.c', - 'src/core/iomgr/time_averaged_stats.c', - 'src/core/iomgr/timer.c', - 'src/core/iomgr/timer_heap.c', - 'src/core/iomgr/udp_server.c', - 'src/core/iomgr/unix_sockets_posix.c', - 'src/core/iomgr/unix_sockets_posix_noop.c', - 'src/core/iomgr/wakeup_fd_eventfd.c', - 'src/core/iomgr/wakeup_fd_nospecial.c', - 'src/core/iomgr/wakeup_fd_pipe.c', - 'src/core/iomgr/wakeup_fd_posix.c', - 'src/core/iomgr/workqueue_posix.c', - 'src/core/iomgr/workqueue_windows.c', - 'src/core/json/json.c', - 'src/core/json/json_reader.c', - 'src/core/json/json_string.c', - 'src/core/json/json_writer.c', - 'src/core/proto/grpc/lb/v0/load_balancer.pb.c', - 'src/core/surface/alarm.c', - 'src/core/surface/api_trace.c', - 'src/core/surface/byte_buffer.c', - 'src/core/surface/byte_buffer_reader.c', - 'src/core/surface/call.c', - 'src/core/surface/call_details.c', - 'src/core/surface/call_log_batch.c', - 'src/core/surface/channel.c', - 'src/core/surface/channel_connectivity.c', - 'src/core/surface/channel_create.c', - 'src/core/surface/channel_init.c', - 'src/core/surface/channel_ping.c', - 'src/core/surface/channel_stack_type.c', - 'src/core/surface/completion_queue.c', - 'src/core/surface/event_string.c', - 'src/core/surface/init.c', - 'src/core/surface/lame_client.c', - 'src/core/surface/metadata_array.c', - 'src/core/surface/server.c', - 'src/core/surface/server_chttp2.c', - 'src/core/surface/validate_metadata.c', - 'src/core/surface/version.c', - 'src/core/transport/byte_stream.c', - 'src/core/transport/chttp2/alpn.c', - 'src/core/transport/chttp2/bin_encoder.c', - 'src/core/transport/chttp2/frame_data.c', - 'src/core/transport/chttp2/frame_goaway.c', - 'src/core/transport/chttp2/frame_ping.c', - 'src/core/transport/chttp2/frame_rst_stream.c', - 'src/core/transport/chttp2/frame_settings.c', - 'src/core/transport/chttp2/frame_window_update.c', - 'src/core/transport/chttp2/hpack_encoder.c', - 'src/core/transport/chttp2/hpack_parser.c', - 'src/core/transport/chttp2/hpack_table.c', - 'src/core/transport/chttp2/huffsyms.c', - 'src/core/transport/chttp2/incoming_metadata.c', - 'src/core/transport/chttp2/parsing.c', - 'src/core/transport/chttp2/status_conversion.c', - 'src/core/transport/chttp2/stream_lists.c', - 'src/core/transport/chttp2/stream_map.c', - 'src/core/transport/chttp2/timeout_encoding.c', - 'src/core/transport/chttp2/varint.c', - 'src/core/transport/chttp2/writing.c', - 'src/core/transport/chttp2_transport.c', - 'src/core/transport/connectivity_state.c', - 'src/core/transport/metadata.c', - 'src/core/transport/metadata_batch.c', - 'src/core/transport/static_metadata.c', - 'src/core/transport/transport.c', - 'src/core/transport/transport_op_string.c', - 'src/core/http/httpcli_security_connector.c', - 'src/core/security/b64.c', - 'src/core/security/client_auth_filter.c', - 'src/core/security/credentials.c', - 'src/core/security/credentials_metadata.c', - 'src/core/security/credentials_posix.c', - 'src/core/security/credentials_win32.c', - 'src/core/security/google_default_credentials.c', - 'src/core/security/handshake.c', - 'src/core/security/json_token.c', - 'src/core/security/jwt_verifier.c', - 'src/core/security/secure_endpoint.c', - 'src/core/security/security_connector.c', - 'src/core/security/security_context.c', - 'src/core/security/server_auth_filter.c', - 'src/core/security/server_secure_chttp2.c', - 'src/core/surface/init_secure.c', - 'src/core/surface/secure_channel_create.c', - 'src/core/tsi/fake_transport_security.c', - 'src/core/tsi/ssl_transport_security.c', - 'src/core/tsi/transport_security.c', - 'src/core/census/context.c', - 'src/core/census/initialize.c', - 'src/core/census/mlog.c', - 'src/core/census/operation.c', - 'src/core/census/placeholders.c', - 'src/core/census/tracing.c', + 'src/core/lib/profiling/basic_timers.c', + 'src/core/lib/profiling/stap_timers.c', + 'src/core/lib/support/alloc.c', + 'src/core/lib/support/avl.c', + 'src/core/lib/support/backoff.c', + 'src/core/lib/support/cmdline.c', + 'src/core/lib/support/cpu_iphone.c', + 'src/core/lib/support/cpu_linux.c', + 'src/core/lib/support/cpu_posix.c', + 'src/core/lib/support/cpu_windows.c', + 'src/core/lib/support/env_linux.c', + 'src/core/lib/support/env_posix.c', + 'src/core/lib/support/env_win32.c', + 'src/core/lib/support/histogram.c', + 'src/core/lib/support/host_port.c', + 'src/core/lib/support/load_file.c', + 'src/core/lib/support/log.c', + 'src/core/lib/support/log_android.c', + 'src/core/lib/support/log_linux.c', + 'src/core/lib/support/log_posix.c', + 'src/core/lib/support/log_win32.c', + 'src/core/lib/support/murmur_hash.c', + 'src/core/lib/support/slice.c', + 'src/core/lib/support/slice_buffer.c', + 'src/core/lib/support/stack_lockfree.c', + 'src/core/lib/support/string.c', + 'src/core/lib/support/string_posix.c', + 'src/core/lib/support/string_win32.c', + 'src/core/lib/support/subprocess_posix.c', + 'src/core/lib/support/subprocess_windows.c', + 'src/core/lib/support/sync.c', + 'src/core/lib/support/sync_posix.c', + 'src/core/lib/support/sync_win32.c', + 'src/core/lib/support/thd.c', + 'src/core/lib/support/thd_posix.c', + 'src/core/lib/support/thd_win32.c', + 'src/core/lib/support/time.c', + 'src/core/lib/support/time_posix.c', + 'src/core/lib/support/time_precise.c', + 'src/core/lib/support/time_win32.c', + 'src/core/lib/support/tls_pthread.c', + 'src/core/lib/support/tmpfile_posix.c', + 'src/core/lib/support/tmpfile_win32.c', + 'src/core/lib/support/wrap_memcpy.c', + 'src/core/lib/census/grpc_context.c', + 'src/core/lib/census/grpc_filter.c', + 'src/core/lib/census/grpc_plugin.c', + 'src/core/lib/channel/channel_args.c', + 'src/core/lib/channel/channel_stack.c', + 'src/core/lib/channel/channel_stack_builder.c', + 'src/core/lib/channel/client_channel.c', + 'src/core/lib/channel/compress_filter.c', + 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/http_client_filter.c', + 'src/core/lib/channel/http_server_filter.c', + 'src/core/lib/channel/subchannel_call_holder.c', + 'src/core/lib/client_config/client_config.c', + 'src/core/lib/client_config/connector.c', + 'src/core/lib/client_config/default_initial_connect_string.c', + 'src/core/lib/client_config/initial_connect_string.c', + 'src/core/lib/client_config/lb_policies/load_balancer_api.c', + 'src/core/lib/client_config/lb_policies/pick_first.c', + 'src/core/lib/client_config/lb_policies/round_robin.c', + 'src/core/lib/client_config/lb_policy.c', + 'src/core/lib/client_config/lb_policy_factory.c', + 'src/core/lib/client_config/lb_policy_registry.c', + 'src/core/lib/client_config/resolver.c', + 'src/core/lib/client_config/resolver_factory.c', + 'src/core/lib/client_config/resolver_registry.c', + 'src/core/lib/client_config/resolvers/dns_resolver.c', + 'src/core/lib/client_config/resolvers/sockaddr_resolver.c', + 'src/core/lib/client_config/subchannel.c', + 'src/core/lib/client_config/subchannel_factory.c', + 'src/core/lib/client_config/subchannel_index.c', + 'src/core/lib/client_config/uri_parser.c', + 'src/core/lib/compression/compression_algorithm.c', + 'src/core/lib/compression/message_compress.c', + 'src/core/lib/debug/trace.c', + 'src/core/lib/http/format_request.c', + 'src/core/lib/http/httpcli.c', + 'src/core/lib/http/parser.c', + 'src/core/lib/iomgr/closure.c', + 'src/core/lib/iomgr/endpoint.c', + 'src/core/lib/iomgr/endpoint_pair_posix.c', + 'src/core/lib/iomgr/endpoint_pair_windows.c', + 'src/core/lib/iomgr/exec_ctx.c', + 'src/core/lib/iomgr/executor.c', + 'src/core/lib/iomgr/fd_posix.c', + 'src/core/lib/iomgr/iocp_windows.c', + 'src/core/lib/iomgr/iomgr.c', + 'src/core/lib/iomgr/iomgr_posix.c', + 'src/core/lib/iomgr/iomgr_windows.c', + 'src/core/lib/iomgr/pollset_multipoller_with_epoll.c', + 'src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c', + 'src/core/lib/iomgr/pollset_posix.c', + 'src/core/lib/iomgr/pollset_set_posix.c', + 'src/core/lib/iomgr/pollset_set_windows.c', + 'src/core/lib/iomgr/pollset_windows.c', + 'src/core/lib/iomgr/resolve_address_posix.c', + 'src/core/lib/iomgr/resolve_address_windows.c', + 'src/core/lib/iomgr/sockaddr_utils.c', + 'src/core/lib/iomgr/socket_utils_common_posix.c', + 'src/core/lib/iomgr/socket_utils_linux.c', + 'src/core/lib/iomgr/socket_utils_posix.c', + 'src/core/lib/iomgr/socket_windows.c', + 'src/core/lib/iomgr/tcp_client_posix.c', + 'src/core/lib/iomgr/tcp_client_windows.c', + 'src/core/lib/iomgr/tcp_posix.c', + 'src/core/lib/iomgr/tcp_server_posix.c', + 'src/core/lib/iomgr/tcp_server_windows.c', + 'src/core/lib/iomgr/tcp_windows.c', + 'src/core/lib/iomgr/time_averaged_stats.c', + 'src/core/lib/iomgr/timer.c', + 'src/core/lib/iomgr/timer_heap.c', + 'src/core/lib/iomgr/udp_server.c', + 'src/core/lib/iomgr/unix_sockets_posix.c', + 'src/core/lib/iomgr/unix_sockets_posix_noop.c', + 'src/core/lib/iomgr/wakeup_fd_eventfd.c', + 'src/core/lib/iomgr/wakeup_fd_nospecial.c', + 'src/core/lib/iomgr/wakeup_fd_pipe.c', + 'src/core/lib/iomgr/wakeup_fd_posix.c', + 'src/core/lib/iomgr/workqueue_posix.c', + 'src/core/lib/iomgr/workqueue_windows.c', + 'src/core/lib/json/json.c', + 'src/core/lib/json/json_reader.c', + 'src/core/lib/json/json_string.c', + 'src/core/lib/json/json_writer.c', + 'src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c', + 'src/core/lib/surface/alarm.c', + 'src/core/lib/surface/api_trace.c', + 'src/core/lib/surface/byte_buffer.c', + 'src/core/lib/surface/byte_buffer_reader.c', + 'src/core/lib/surface/call.c', + 'src/core/lib/surface/call_details.c', + 'src/core/lib/surface/call_log_batch.c', + 'src/core/lib/surface/channel.c', + 'src/core/lib/surface/channel_connectivity.c', + 'src/core/lib/surface/channel_create.c', + 'src/core/lib/surface/channel_init.c', + 'src/core/lib/surface/channel_ping.c', + 'src/core/lib/surface/channel_stack_type.c', + 'src/core/lib/surface/completion_queue.c', + 'src/core/lib/surface/event_string.c', + 'src/core/lib/surface/init.c', + 'src/core/lib/surface/lame_client.c', + 'src/core/lib/surface/metadata_array.c', + 'src/core/lib/surface/server.c', + 'src/core/lib/surface/server_chttp2.c', + 'src/core/lib/surface/validate_metadata.c', + 'src/core/lib/surface/version.c', + 'src/core/lib/transport/byte_stream.c', + 'src/core/lib/transport/chttp2/alpn.c', + 'src/core/lib/transport/chttp2/bin_encoder.c', + 'src/core/lib/transport/chttp2/frame_data.c', + 'src/core/lib/transport/chttp2/frame_goaway.c', + 'src/core/lib/transport/chttp2/frame_ping.c', + 'src/core/lib/transport/chttp2/frame_rst_stream.c', + 'src/core/lib/transport/chttp2/frame_settings.c', + 'src/core/lib/transport/chttp2/frame_window_update.c', + 'src/core/lib/transport/chttp2/hpack_encoder.c', + 'src/core/lib/transport/chttp2/hpack_parser.c', + 'src/core/lib/transport/chttp2/hpack_table.c', + 'src/core/lib/transport/chttp2/huffsyms.c', + 'src/core/lib/transport/chttp2/incoming_metadata.c', + 'src/core/lib/transport/chttp2/parsing.c', + 'src/core/lib/transport/chttp2/status_conversion.c', + 'src/core/lib/transport/chttp2/stream_lists.c', + 'src/core/lib/transport/chttp2/stream_map.c', + 'src/core/lib/transport/chttp2/timeout_encoding.c', + 'src/core/lib/transport/chttp2/varint.c', + 'src/core/lib/transport/chttp2/writing.c', + 'src/core/lib/transport/chttp2_transport.c', + 'src/core/lib/transport/connectivity_state.c', + 'src/core/lib/transport/metadata.c', + 'src/core/lib/transport/metadata_batch.c', + 'src/core/lib/transport/static_metadata.c', + 'src/core/lib/transport/transport.c', + 'src/core/lib/transport/transport_op_string.c', + 'src/core/lib/http/httpcli_security_connector.c', + 'src/core/lib/security/b64.c', + 'src/core/lib/security/client_auth_filter.c', + 'src/core/lib/security/credentials.c', + 'src/core/lib/security/credentials_metadata.c', + 'src/core/lib/security/credentials_posix.c', + 'src/core/lib/security/credentials_win32.c', + 'src/core/lib/security/google_default_credentials.c', + 'src/core/lib/security/handshake.c', + 'src/core/lib/security/json_token.c', + 'src/core/lib/security/jwt_verifier.c', + 'src/core/lib/security/secure_endpoint.c', + 'src/core/lib/security/security_connector.c', + 'src/core/lib/security/security_context.c', + 'src/core/lib/security/server_auth_filter.c', + 'src/core/lib/security/server_secure_chttp2.c', + 'src/core/lib/surface/init_secure.c', + 'src/core/lib/surface/secure_channel_create.c', + 'src/core/lib/tsi/fake_transport_security.c', + 'src/core/lib/tsi/ssl_transport_security.c', + 'src/core/lib/tsi/transport_security.c', + 'src/core/lib/census/context.c', + 'src/core/lib/census/initialize.c', + 'src/core/lib/census/mlog.c', + 'src/core/lib/census/operation.c', + 'src/core/lib/census/placeholders.c', + 'src/core/lib/census/tracing.c', 'third_party/nanopb/pb_common.c', 'third_party/nanopb/pb_decode.c', 'third_party/nanopb/pb_encode.c', diff --git a/templates/src/core/lib/surface/version.c.template b/templates/src/core/lib/surface/version.c.template new file mode 100644 index 0000000000..f2b3cfdc58 --- /dev/null +++ b/templates/src/core/lib/surface/version.c.template @@ -0,0 +1,41 @@ +%YAML 1.2 +--- | + /* + * + * Copyright 2015-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. + * + */ + + /* This file is autogenerated from: + templates/src/core/surface/version.c.template */ + + #include + + const char *grpc_version_string(void) { return "${settings.core_version}"; } diff --git a/templates/src/core/surface/version.c.template b/templates/src/core/surface/version.c.template deleted file mode 100644 index f2b3cfdc58..0000000000 --- a/templates/src/core/surface/version.c.template +++ /dev/null @@ -1,41 +0,0 @@ -%YAML 1.2 ---- | - /* - * - * Copyright 2015-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. - * - */ - - /* This file is autogenerated from: - templates/src/core/surface/version.c.template */ - - #include - - const char *grpc_version_string(void) { return "${settings.core_version}"; } diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 5044ed2c93..7f91115cec 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -773,308 +773,308 @@ include/grpc/impl/codegen/grpc_types.h \ include/grpc/impl/codegen/propagation_bits.h \ include/grpc/impl/codegen/status.h \ include/grpc/census.h \ -src/core/census/grpc_filter.h \ -src/core/census/grpc_plugin.h \ -src/core/channel/channel_args.h \ -src/core/channel/channel_stack.h \ -src/core/channel/channel_stack_builder.h \ -src/core/channel/client_channel.h \ -src/core/channel/compress_filter.h \ -src/core/channel/connected_channel.h \ -src/core/channel/context.h \ -src/core/channel/http_client_filter.h \ -src/core/channel/http_server_filter.h \ -src/core/channel/subchannel_call_holder.h \ -src/core/client_config/client_config.h \ -src/core/client_config/connector.h \ -src/core/client_config/initial_connect_string.h \ -src/core/client_config/lb_policies/load_balancer_api.h \ -src/core/client_config/lb_policies/pick_first.h \ -src/core/client_config/lb_policies/round_robin.h \ -src/core/client_config/lb_policy.h \ -src/core/client_config/lb_policy_factory.h \ -src/core/client_config/lb_policy_registry.h \ -src/core/client_config/resolver.h \ -src/core/client_config/resolver_factory.h \ -src/core/client_config/resolver_registry.h \ -src/core/client_config/resolvers/dns_resolver.h \ -src/core/client_config/resolvers/sockaddr_resolver.h \ -src/core/client_config/subchannel.h \ -src/core/client_config/subchannel_factory.h \ -src/core/client_config/subchannel_index.h \ -src/core/client_config/uri_parser.h \ -src/core/compression/algorithm_metadata.h \ -src/core/compression/message_compress.h \ -src/core/debug/trace.h \ -src/core/http/format_request.h \ -src/core/http/httpcli.h \ -src/core/http/parser.h \ -src/core/iomgr/closure.h \ -src/core/iomgr/endpoint.h \ -src/core/iomgr/endpoint_pair.h \ -src/core/iomgr/exec_ctx.h \ -src/core/iomgr/executor.h \ -src/core/iomgr/fd_posix.h \ -src/core/iomgr/iocp_windows.h \ -src/core/iomgr/iomgr.h \ -src/core/iomgr/iomgr_internal.h \ -src/core/iomgr/iomgr_posix.h \ -src/core/iomgr/pollset.h \ -src/core/iomgr/pollset_posix.h \ -src/core/iomgr/pollset_set.h \ -src/core/iomgr/pollset_set_posix.h \ -src/core/iomgr/pollset_set_windows.h \ -src/core/iomgr/pollset_windows.h \ -src/core/iomgr/resolve_address.h \ -src/core/iomgr/sockaddr.h \ -src/core/iomgr/sockaddr_posix.h \ -src/core/iomgr/sockaddr_utils.h \ -src/core/iomgr/sockaddr_win32.h \ -src/core/iomgr/socket_utils_posix.h \ -src/core/iomgr/socket_windows.h \ -src/core/iomgr/tcp_client.h \ -src/core/iomgr/tcp_posix.h \ -src/core/iomgr/tcp_server.h \ -src/core/iomgr/tcp_windows.h \ -src/core/iomgr/time_averaged_stats.h \ -src/core/iomgr/timer.h \ -src/core/iomgr/timer_heap.h \ -src/core/iomgr/udp_server.h \ -src/core/iomgr/unix_sockets_posix.h \ -src/core/iomgr/wakeup_fd_pipe.h \ -src/core/iomgr/wakeup_fd_posix.h \ -src/core/iomgr/workqueue.h \ -src/core/iomgr/workqueue_posix.h \ -src/core/iomgr/workqueue_windows.h \ -src/core/json/json.h \ -src/core/json/json_common.h \ -src/core/json/json_reader.h \ -src/core/json/json_writer.h \ -src/core/proto/grpc/lb/v0/load_balancer.pb.h \ -src/core/statistics/census_interface.h \ -src/core/statistics/census_rpc_stats.h \ -src/core/surface/api_trace.h \ -src/core/surface/call.h \ -src/core/surface/call_test_only.h \ -src/core/surface/channel.h \ -src/core/surface/channel_init.h \ -src/core/surface/channel_stack_type.h \ -src/core/surface/completion_queue.h \ -src/core/surface/event_string.h \ -src/core/surface/init.h \ -src/core/surface/lame_client.h \ -src/core/surface/server.h \ -src/core/surface/surface_trace.h \ -src/core/transport/byte_stream.h \ -src/core/transport/chttp2/alpn.h \ -src/core/transport/chttp2/bin_encoder.h \ -src/core/transport/chttp2/frame.h \ -src/core/transport/chttp2/frame_data.h \ -src/core/transport/chttp2/frame_goaway.h \ -src/core/transport/chttp2/frame_ping.h \ -src/core/transport/chttp2/frame_rst_stream.h \ -src/core/transport/chttp2/frame_settings.h \ -src/core/transport/chttp2/frame_window_update.h \ -src/core/transport/chttp2/hpack_encoder.h \ -src/core/transport/chttp2/hpack_parser.h \ -src/core/transport/chttp2/hpack_table.h \ -src/core/transport/chttp2/http2_errors.h \ -src/core/transport/chttp2/huffsyms.h \ -src/core/transport/chttp2/incoming_metadata.h \ -src/core/transport/chttp2/internal.h \ -src/core/transport/chttp2/status_conversion.h \ -src/core/transport/chttp2/stream_map.h \ -src/core/transport/chttp2/timeout_encoding.h \ -src/core/transport/chttp2/varint.h \ -src/core/transport/chttp2_transport.h \ -src/core/transport/connectivity_state.h \ -src/core/transport/metadata.h \ -src/core/transport/metadata_batch.h \ -src/core/transport/static_metadata.h \ -src/core/transport/transport.h \ -src/core/transport/transport_impl.h \ -src/core/security/auth_filters.h \ -src/core/security/b64.h \ -src/core/security/credentials.h \ -src/core/security/handshake.h \ -src/core/security/json_token.h \ -src/core/security/jwt_verifier.h \ -src/core/security/secure_endpoint.h \ -src/core/security/security_connector.h \ -src/core/security/security_context.h \ -src/core/tsi/fake_transport_security.h \ -src/core/tsi/ssl_transport_security.h \ -src/core/tsi/ssl_types.h \ -src/core/tsi/transport_security.h \ -src/core/tsi/transport_security_interface.h \ -src/core/census/aggregation.h \ -src/core/census/mlog.h \ -src/core/census/rpc_metric_id.h \ +src/core/lib/census/grpc_filter.h \ +src/core/lib/census/grpc_plugin.h \ +src/core/lib/channel/channel_args.h \ +src/core/lib/channel/channel_stack.h \ +src/core/lib/channel/channel_stack_builder.h \ +src/core/lib/channel/client_channel.h \ +src/core/lib/channel/compress_filter.h \ +src/core/lib/channel/connected_channel.h \ +src/core/lib/channel/context.h \ +src/core/lib/channel/http_client_filter.h \ +src/core/lib/channel/http_server_filter.h \ +src/core/lib/channel/subchannel_call_holder.h \ +src/core/lib/client_config/client_config.h \ +src/core/lib/client_config/connector.h \ +src/core/lib/client_config/initial_connect_string.h \ +src/core/lib/client_config/lb_policies/load_balancer_api.h \ +src/core/lib/client_config/lb_policies/pick_first.h \ +src/core/lib/client_config/lb_policies/round_robin.h \ +src/core/lib/client_config/lb_policy.h \ +src/core/lib/client_config/lb_policy_factory.h \ +src/core/lib/client_config/lb_policy_registry.h \ +src/core/lib/client_config/resolver.h \ +src/core/lib/client_config/resolver_factory.h \ +src/core/lib/client_config/resolver_registry.h \ +src/core/lib/client_config/resolvers/dns_resolver.h \ +src/core/lib/client_config/resolvers/sockaddr_resolver.h \ +src/core/lib/client_config/subchannel.h \ +src/core/lib/client_config/subchannel_factory.h \ +src/core/lib/client_config/subchannel_index.h \ +src/core/lib/client_config/uri_parser.h \ +src/core/lib/compression/algorithm_metadata.h \ +src/core/lib/compression/message_compress.h \ +src/core/lib/debug/trace.h \ +src/core/lib/http/format_request.h \ +src/core/lib/http/httpcli.h \ +src/core/lib/http/parser.h \ +src/core/lib/iomgr/closure.h \ +src/core/lib/iomgr/endpoint.h \ +src/core/lib/iomgr/endpoint_pair.h \ +src/core/lib/iomgr/exec_ctx.h \ +src/core/lib/iomgr/executor.h \ +src/core/lib/iomgr/fd_posix.h \ +src/core/lib/iomgr/iocp_windows.h \ +src/core/lib/iomgr/iomgr.h \ +src/core/lib/iomgr/iomgr_internal.h \ +src/core/lib/iomgr/iomgr_posix.h \ +src/core/lib/iomgr/pollset.h \ +src/core/lib/iomgr/pollset_posix.h \ +src/core/lib/iomgr/pollset_set.h \ +src/core/lib/iomgr/pollset_set_posix.h \ +src/core/lib/iomgr/pollset_set_windows.h \ +src/core/lib/iomgr/pollset_windows.h \ +src/core/lib/iomgr/resolve_address.h \ +src/core/lib/iomgr/sockaddr.h \ +src/core/lib/iomgr/sockaddr_posix.h \ +src/core/lib/iomgr/sockaddr_utils.h \ +src/core/lib/iomgr/sockaddr_win32.h \ +src/core/lib/iomgr/socket_utils_posix.h \ +src/core/lib/iomgr/socket_windows.h \ +src/core/lib/iomgr/tcp_client.h \ +src/core/lib/iomgr/tcp_posix.h \ +src/core/lib/iomgr/tcp_server.h \ +src/core/lib/iomgr/tcp_windows.h \ +src/core/lib/iomgr/time_averaged_stats.h \ +src/core/lib/iomgr/timer.h \ +src/core/lib/iomgr/timer_heap.h \ +src/core/lib/iomgr/udp_server.h \ +src/core/lib/iomgr/unix_sockets_posix.h \ +src/core/lib/iomgr/wakeup_fd_pipe.h \ +src/core/lib/iomgr/wakeup_fd_posix.h \ +src/core/lib/iomgr/workqueue.h \ +src/core/lib/iomgr/workqueue_posix.h \ +src/core/lib/iomgr/workqueue_windows.h \ +src/core/lib/json/json.h \ +src/core/lib/json/json_common.h \ +src/core/lib/json/json_reader.h \ +src/core/lib/json/json_writer.h \ +src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h \ +src/core/lib/statistics/census_interface.h \ +src/core/lib/statistics/census_rpc_stats.h \ +src/core/lib/surface/api_trace.h \ +src/core/lib/surface/call.h \ +src/core/lib/surface/call_test_only.h \ +src/core/lib/surface/channel.h \ +src/core/lib/surface/channel_init.h \ +src/core/lib/surface/channel_stack_type.h \ +src/core/lib/surface/completion_queue.h \ +src/core/lib/surface/event_string.h \ +src/core/lib/surface/init.h \ +src/core/lib/surface/lame_client.h \ +src/core/lib/surface/server.h \ +src/core/lib/surface/surface_trace.h \ +src/core/lib/transport/byte_stream.h \ +src/core/lib/transport/chttp2/alpn.h \ +src/core/lib/transport/chttp2/bin_encoder.h \ +src/core/lib/transport/chttp2/frame.h \ +src/core/lib/transport/chttp2/frame_data.h \ +src/core/lib/transport/chttp2/frame_goaway.h \ +src/core/lib/transport/chttp2/frame_ping.h \ +src/core/lib/transport/chttp2/frame_rst_stream.h \ +src/core/lib/transport/chttp2/frame_settings.h \ +src/core/lib/transport/chttp2/frame_window_update.h \ +src/core/lib/transport/chttp2/hpack_encoder.h \ +src/core/lib/transport/chttp2/hpack_parser.h \ +src/core/lib/transport/chttp2/hpack_table.h \ +src/core/lib/transport/chttp2/http2_errors.h \ +src/core/lib/transport/chttp2/huffsyms.h \ +src/core/lib/transport/chttp2/incoming_metadata.h \ +src/core/lib/transport/chttp2/internal.h \ +src/core/lib/transport/chttp2/status_conversion.h \ +src/core/lib/transport/chttp2/stream_map.h \ +src/core/lib/transport/chttp2/timeout_encoding.h \ +src/core/lib/transport/chttp2/varint.h \ +src/core/lib/transport/chttp2_transport.h \ +src/core/lib/transport/connectivity_state.h \ +src/core/lib/transport/metadata.h \ +src/core/lib/transport/metadata_batch.h \ +src/core/lib/transport/static_metadata.h \ +src/core/lib/transport/transport.h \ +src/core/lib/transport/transport_impl.h \ +src/core/lib/security/auth_filters.h \ +src/core/lib/security/b64.h \ +src/core/lib/security/credentials.h \ +src/core/lib/security/handshake.h \ +src/core/lib/security/json_token.h \ +src/core/lib/security/jwt_verifier.h \ +src/core/lib/security/secure_endpoint.h \ +src/core/lib/security/security_connector.h \ +src/core/lib/security/security_context.h \ +src/core/lib/tsi/fake_transport_security.h \ +src/core/lib/tsi/ssl_transport_security.h \ +src/core/lib/tsi/ssl_types.h \ +src/core/lib/tsi/transport_security.h \ +src/core/lib/tsi/transport_security_interface.h \ +src/core/lib/census/aggregation.h \ +src/core/lib/census/mlog.h \ +src/core/lib/census/rpc_metric_id.h \ third_party/nanopb/pb.h \ third_party/nanopb/pb_common.h \ third_party/nanopb/pb_decode.h \ third_party/nanopb/pb_encode.h \ -src/core/census/grpc_context.c \ -src/core/census/grpc_filter.c \ -src/core/census/grpc_plugin.c \ -src/core/channel/channel_args.c \ -src/core/channel/channel_stack.c \ -src/core/channel/channel_stack_builder.c \ -src/core/channel/client_channel.c \ -src/core/channel/compress_filter.c \ -src/core/channel/connected_channel.c \ -src/core/channel/http_client_filter.c \ -src/core/channel/http_server_filter.c \ -src/core/channel/subchannel_call_holder.c \ -src/core/client_config/client_config.c \ -src/core/client_config/connector.c \ -src/core/client_config/default_initial_connect_string.c \ -src/core/client_config/initial_connect_string.c \ -src/core/client_config/lb_policies/load_balancer_api.c \ -src/core/client_config/lb_policies/pick_first.c \ -src/core/client_config/lb_policies/round_robin.c \ -src/core/client_config/lb_policy.c \ -src/core/client_config/lb_policy_factory.c \ -src/core/client_config/lb_policy_registry.c \ -src/core/client_config/resolver.c \ -src/core/client_config/resolver_factory.c \ -src/core/client_config/resolver_registry.c \ -src/core/client_config/resolvers/dns_resolver.c \ -src/core/client_config/resolvers/sockaddr_resolver.c \ -src/core/client_config/subchannel.c \ -src/core/client_config/subchannel_factory.c \ -src/core/client_config/subchannel_index.c \ -src/core/client_config/uri_parser.c \ -src/core/compression/compression_algorithm.c \ -src/core/compression/message_compress.c \ -src/core/debug/trace.c \ -src/core/http/format_request.c \ -src/core/http/httpcli.c \ -src/core/http/parser.c \ -src/core/iomgr/closure.c \ -src/core/iomgr/endpoint.c \ -src/core/iomgr/endpoint_pair_posix.c \ -src/core/iomgr/endpoint_pair_windows.c \ -src/core/iomgr/exec_ctx.c \ -src/core/iomgr/executor.c \ -src/core/iomgr/fd_posix.c \ -src/core/iomgr/iocp_windows.c \ -src/core/iomgr/iomgr.c \ -src/core/iomgr/iomgr_posix.c \ -src/core/iomgr/iomgr_windows.c \ -src/core/iomgr/pollset_multipoller_with_epoll.c \ -src/core/iomgr/pollset_multipoller_with_poll_posix.c \ -src/core/iomgr/pollset_posix.c \ -src/core/iomgr/pollset_set_posix.c \ -src/core/iomgr/pollset_set_windows.c \ -src/core/iomgr/pollset_windows.c \ -src/core/iomgr/resolve_address_posix.c \ -src/core/iomgr/resolve_address_windows.c \ -src/core/iomgr/sockaddr_utils.c \ -src/core/iomgr/socket_utils_common_posix.c \ -src/core/iomgr/socket_utils_linux.c \ -src/core/iomgr/socket_utils_posix.c \ -src/core/iomgr/socket_windows.c \ -src/core/iomgr/tcp_client_posix.c \ -src/core/iomgr/tcp_client_windows.c \ -src/core/iomgr/tcp_posix.c \ -src/core/iomgr/tcp_server_posix.c \ -src/core/iomgr/tcp_server_windows.c \ -src/core/iomgr/tcp_windows.c \ -src/core/iomgr/time_averaged_stats.c \ -src/core/iomgr/timer.c \ -src/core/iomgr/timer_heap.c \ -src/core/iomgr/udp_server.c \ -src/core/iomgr/unix_sockets_posix.c \ -src/core/iomgr/unix_sockets_posix_noop.c \ -src/core/iomgr/wakeup_fd_eventfd.c \ -src/core/iomgr/wakeup_fd_nospecial.c \ -src/core/iomgr/wakeup_fd_pipe.c \ -src/core/iomgr/wakeup_fd_posix.c \ -src/core/iomgr/workqueue_posix.c \ -src/core/iomgr/workqueue_windows.c \ -src/core/json/json.c \ -src/core/json/json_reader.c \ -src/core/json/json_string.c \ -src/core/json/json_writer.c \ -src/core/proto/grpc/lb/v0/load_balancer.pb.c \ -src/core/surface/alarm.c \ -src/core/surface/api_trace.c \ -src/core/surface/byte_buffer.c \ -src/core/surface/byte_buffer_reader.c \ -src/core/surface/call.c \ -src/core/surface/call_details.c \ -src/core/surface/call_log_batch.c \ -src/core/surface/channel.c \ -src/core/surface/channel_connectivity.c \ -src/core/surface/channel_create.c \ -src/core/surface/channel_init.c \ -src/core/surface/channel_ping.c \ -src/core/surface/channel_stack_type.c \ -src/core/surface/completion_queue.c \ -src/core/surface/event_string.c \ -src/core/surface/init.c \ -src/core/surface/lame_client.c \ -src/core/surface/metadata_array.c \ -src/core/surface/server.c \ -src/core/surface/server_chttp2.c \ -src/core/surface/validate_metadata.c \ -src/core/surface/version.c \ -src/core/transport/byte_stream.c \ -src/core/transport/chttp2/alpn.c \ -src/core/transport/chttp2/bin_encoder.c \ -src/core/transport/chttp2/frame_data.c \ -src/core/transport/chttp2/frame_goaway.c \ -src/core/transport/chttp2/frame_ping.c \ -src/core/transport/chttp2/frame_rst_stream.c \ -src/core/transport/chttp2/frame_settings.c \ -src/core/transport/chttp2/frame_window_update.c \ -src/core/transport/chttp2/hpack_encoder.c \ -src/core/transport/chttp2/hpack_parser.c \ -src/core/transport/chttp2/hpack_table.c \ -src/core/transport/chttp2/huffsyms.c \ -src/core/transport/chttp2/incoming_metadata.c \ -src/core/transport/chttp2/parsing.c \ -src/core/transport/chttp2/status_conversion.c \ -src/core/transport/chttp2/stream_lists.c \ -src/core/transport/chttp2/stream_map.c \ -src/core/transport/chttp2/timeout_encoding.c \ -src/core/transport/chttp2/varint.c \ -src/core/transport/chttp2/writing.c \ -src/core/transport/chttp2_transport.c \ -src/core/transport/connectivity_state.c \ -src/core/transport/metadata.c \ -src/core/transport/metadata_batch.c \ -src/core/transport/static_metadata.c \ -src/core/transport/transport.c \ -src/core/transport/transport_op_string.c \ -src/core/http/httpcli_security_connector.c \ -src/core/security/b64.c \ -src/core/security/client_auth_filter.c \ -src/core/security/credentials.c \ -src/core/security/credentials_metadata.c \ -src/core/security/credentials_posix.c \ -src/core/security/credentials_win32.c \ -src/core/security/google_default_credentials.c \ -src/core/security/handshake.c \ -src/core/security/json_token.c \ -src/core/security/jwt_verifier.c \ -src/core/security/secure_endpoint.c \ -src/core/security/security_connector.c \ -src/core/security/security_context.c \ -src/core/security/server_auth_filter.c \ -src/core/security/server_secure_chttp2.c \ -src/core/surface/init_secure.c \ -src/core/surface/secure_channel_create.c \ -src/core/tsi/fake_transport_security.c \ -src/core/tsi/ssl_transport_security.c \ -src/core/tsi/transport_security.c \ -src/core/census/context.c \ -src/core/census/initialize.c \ -src/core/census/mlog.c \ -src/core/census/operation.c \ -src/core/census/placeholders.c \ -src/core/census/tracing.c \ +src/core/lib/census/grpc_context.c \ +src/core/lib/census/grpc_filter.c \ +src/core/lib/census/grpc_plugin.c \ +src/core/lib/channel/channel_args.c \ +src/core/lib/channel/channel_stack.c \ +src/core/lib/channel/channel_stack_builder.c \ +src/core/lib/channel/client_channel.c \ +src/core/lib/channel/compress_filter.c \ +src/core/lib/channel/connected_channel.c \ +src/core/lib/channel/http_client_filter.c \ +src/core/lib/channel/http_server_filter.c \ +src/core/lib/channel/subchannel_call_holder.c \ +src/core/lib/client_config/client_config.c \ +src/core/lib/client_config/connector.c \ +src/core/lib/client_config/default_initial_connect_string.c \ +src/core/lib/client_config/initial_connect_string.c \ +src/core/lib/client_config/lb_policies/load_balancer_api.c \ +src/core/lib/client_config/lb_policies/pick_first.c \ +src/core/lib/client_config/lb_policies/round_robin.c \ +src/core/lib/client_config/lb_policy.c \ +src/core/lib/client_config/lb_policy_factory.c \ +src/core/lib/client_config/lb_policy_registry.c \ +src/core/lib/client_config/resolver.c \ +src/core/lib/client_config/resolver_factory.c \ +src/core/lib/client_config/resolver_registry.c \ +src/core/lib/client_config/resolvers/dns_resolver.c \ +src/core/lib/client_config/resolvers/sockaddr_resolver.c \ +src/core/lib/client_config/subchannel.c \ +src/core/lib/client_config/subchannel_factory.c \ +src/core/lib/client_config/subchannel_index.c \ +src/core/lib/client_config/uri_parser.c \ +src/core/lib/compression/compression_algorithm.c \ +src/core/lib/compression/message_compress.c \ +src/core/lib/debug/trace.c \ +src/core/lib/http/format_request.c \ +src/core/lib/http/httpcli.c \ +src/core/lib/http/parser.c \ +src/core/lib/iomgr/closure.c \ +src/core/lib/iomgr/endpoint.c \ +src/core/lib/iomgr/endpoint_pair_posix.c \ +src/core/lib/iomgr/endpoint_pair_windows.c \ +src/core/lib/iomgr/exec_ctx.c \ +src/core/lib/iomgr/executor.c \ +src/core/lib/iomgr/fd_posix.c \ +src/core/lib/iomgr/iocp_windows.c \ +src/core/lib/iomgr/iomgr.c \ +src/core/lib/iomgr/iomgr_posix.c \ +src/core/lib/iomgr/iomgr_windows.c \ +src/core/lib/iomgr/pollset_multipoller_with_epoll.c \ +src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c \ +src/core/lib/iomgr/pollset_posix.c \ +src/core/lib/iomgr/pollset_set_posix.c \ +src/core/lib/iomgr/pollset_set_windows.c \ +src/core/lib/iomgr/pollset_windows.c \ +src/core/lib/iomgr/resolve_address_posix.c \ +src/core/lib/iomgr/resolve_address_windows.c \ +src/core/lib/iomgr/sockaddr_utils.c \ +src/core/lib/iomgr/socket_utils_common_posix.c \ +src/core/lib/iomgr/socket_utils_linux.c \ +src/core/lib/iomgr/socket_utils_posix.c \ +src/core/lib/iomgr/socket_windows.c \ +src/core/lib/iomgr/tcp_client_posix.c \ +src/core/lib/iomgr/tcp_client_windows.c \ +src/core/lib/iomgr/tcp_posix.c \ +src/core/lib/iomgr/tcp_server_posix.c \ +src/core/lib/iomgr/tcp_server_windows.c \ +src/core/lib/iomgr/tcp_windows.c \ +src/core/lib/iomgr/time_averaged_stats.c \ +src/core/lib/iomgr/timer.c \ +src/core/lib/iomgr/timer_heap.c \ +src/core/lib/iomgr/udp_server.c \ +src/core/lib/iomgr/unix_sockets_posix.c \ +src/core/lib/iomgr/unix_sockets_posix_noop.c \ +src/core/lib/iomgr/wakeup_fd_eventfd.c \ +src/core/lib/iomgr/wakeup_fd_nospecial.c \ +src/core/lib/iomgr/wakeup_fd_pipe.c \ +src/core/lib/iomgr/wakeup_fd_posix.c \ +src/core/lib/iomgr/workqueue_posix.c \ +src/core/lib/iomgr/workqueue_windows.c \ +src/core/lib/json/json.c \ +src/core/lib/json/json_reader.c \ +src/core/lib/json/json_string.c \ +src/core/lib/json/json_writer.c \ +src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c \ +src/core/lib/surface/alarm.c \ +src/core/lib/surface/api_trace.c \ +src/core/lib/surface/byte_buffer.c \ +src/core/lib/surface/byte_buffer_reader.c \ +src/core/lib/surface/call.c \ +src/core/lib/surface/call_details.c \ +src/core/lib/surface/call_log_batch.c \ +src/core/lib/surface/channel.c \ +src/core/lib/surface/channel_connectivity.c \ +src/core/lib/surface/channel_create.c \ +src/core/lib/surface/channel_init.c \ +src/core/lib/surface/channel_ping.c \ +src/core/lib/surface/channel_stack_type.c \ +src/core/lib/surface/completion_queue.c \ +src/core/lib/surface/event_string.c \ +src/core/lib/surface/init.c \ +src/core/lib/surface/lame_client.c \ +src/core/lib/surface/metadata_array.c \ +src/core/lib/surface/server.c \ +src/core/lib/surface/server_chttp2.c \ +src/core/lib/surface/validate_metadata.c \ +src/core/lib/surface/version.c \ +src/core/lib/transport/byte_stream.c \ +src/core/lib/transport/chttp2/alpn.c \ +src/core/lib/transport/chttp2/bin_encoder.c \ +src/core/lib/transport/chttp2/frame_data.c \ +src/core/lib/transport/chttp2/frame_goaway.c \ +src/core/lib/transport/chttp2/frame_ping.c \ +src/core/lib/transport/chttp2/frame_rst_stream.c \ +src/core/lib/transport/chttp2/frame_settings.c \ +src/core/lib/transport/chttp2/frame_window_update.c \ +src/core/lib/transport/chttp2/hpack_encoder.c \ +src/core/lib/transport/chttp2/hpack_parser.c \ +src/core/lib/transport/chttp2/hpack_table.c \ +src/core/lib/transport/chttp2/huffsyms.c \ +src/core/lib/transport/chttp2/incoming_metadata.c \ +src/core/lib/transport/chttp2/parsing.c \ +src/core/lib/transport/chttp2/status_conversion.c \ +src/core/lib/transport/chttp2/stream_lists.c \ +src/core/lib/transport/chttp2/stream_map.c \ +src/core/lib/transport/chttp2/timeout_encoding.c \ +src/core/lib/transport/chttp2/varint.c \ +src/core/lib/transport/chttp2/writing.c \ +src/core/lib/transport/chttp2_transport.c \ +src/core/lib/transport/connectivity_state.c \ +src/core/lib/transport/metadata.c \ +src/core/lib/transport/metadata_batch.c \ +src/core/lib/transport/static_metadata.c \ +src/core/lib/transport/transport.c \ +src/core/lib/transport/transport_op_string.c \ +src/core/lib/http/httpcli_security_connector.c \ +src/core/lib/security/b64.c \ +src/core/lib/security/client_auth_filter.c \ +src/core/lib/security/credentials.c \ +src/core/lib/security/credentials_metadata.c \ +src/core/lib/security/credentials_posix.c \ +src/core/lib/security/credentials_win32.c \ +src/core/lib/security/google_default_credentials.c \ +src/core/lib/security/handshake.c \ +src/core/lib/security/json_token.c \ +src/core/lib/security/jwt_verifier.c \ +src/core/lib/security/secure_endpoint.c \ +src/core/lib/security/security_connector.c \ +src/core/lib/security/security_context.c \ +src/core/lib/security/server_auth_filter.c \ +src/core/lib/security/server_secure_chttp2.c \ +src/core/lib/surface/init_secure.c \ +src/core/lib/surface/secure_channel_create.c \ +src/core/lib/tsi/fake_transport_security.c \ +src/core/lib/tsi/ssl_transport_security.c \ +src/core/lib/tsi/transport_security.c \ +src/core/lib/census/context.c \ +src/core/lib/census/initialize.c \ +src/core/lib/census/mlog.c \ +src/core/lib/census/operation.c \ +src/core/lib/census/placeholders.c \ +src/core/lib/census/tracing.c \ third_party/nanopb/pb_common.c \ third_party/nanopb/pb_decode.c \ third_party/nanopb/pb_encode.c \ @@ -1120,62 +1120,62 @@ include/grpc/impl/codegen/sync_generic.h \ include/grpc/impl/codegen/sync_posix.h \ include/grpc/impl/codegen/sync_win32.h \ include/grpc/impl/codegen/time.h \ -src/core/profiling/timers.h \ -src/core/support/backoff.h \ -src/core/support/block_annotate.h \ -src/core/support/env.h \ -src/core/support/load_file.h \ -src/core/support/murmur_hash.h \ -src/core/support/stack_lockfree.h \ -src/core/support/string.h \ -src/core/support/string_win32.h \ -src/core/support/thd_internal.h \ -src/core/support/time_precise.h \ -src/core/support/tmpfile.h \ -src/core/profiling/basic_timers.c \ -src/core/profiling/stap_timers.c \ -src/core/support/alloc.c \ -src/core/support/avl.c \ -src/core/support/backoff.c \ -src/core/support/cmdline.c \ -src/core/support/cpu_iphone.c \ -src/core/support/cpu_linux.c \ -src/core/support/cpu_posix.c \ -src/core/support/cpu_windows.c \ -src/core/support/env_linux.c \ -src/core/support/env_posix.c \ -src/core/support/env_win32.c \ -src/core/support/histogram.c \ -src/core/support/host_port.c \ -src/core/support/load_file.c \ -src/core/support/log.c \ -src/core/support/log_android.c \ -src/core/support/log_linux.c \ -src/core/support/log_posix.c \ -src/core/support/log_win32.c \ -src/core/support/murmur_hash.c \ -src/core/support/slice.c \ -src/core/support/slice_buffer.c \ -src/core/support/stack_lockfree.c \ -src/core/support/string.c \ -src/core/support/string_posix.c \ -src/core/support/string_win32.c \ -src/core/support/subprocess_posix.c \ -src/core/support/subprocess_windows.c \ -src/core/support/sync.c \ -src/core/support/sync_posix.c \ -src/core/support/sync_win32.c \ -src/core/support/thd.c \ -src/core/support/thd_posix.c \ -src/core/support/thd_win32.c \ -src/core/support/time.c \ -src/core/support/time_posix.c \ -src/core/support/time_precise.c \ -src/core/support/time_win32.c \ -src/core/support/tls_pthread.c \ -src/core/support/tmpfile_posix.c \ -src/core/support/tmpfile_win32.c \ -src/core/support/wrap_memcpy.c +src/core/lib/profiling/timers.h \ +src/core/lib/support/backoff.h \ +src/core/lib/support/block_annotate.h \ +src/core/lib/support/env.h \ +src/core/lib/support/load_file.h \ +src/core/lib/support/murmur_hash.h \ +src/core/lib/support/stack_lockfree.h \ +src/core/lib/support/string.h \ +src/core/lib/support/string_win32.h \ +src/core/lib/support/thd_internal.h \ +src/core/lib/support/time_precise.h \ +src/core/lib/support/tmpfile.h \ +src/core/lib/profiling/basic_timers.c \ +src/core/lib/profiling/stap_timers.c \ +src/core/lib/support/alloc.c \ +src/core/lib/support/avl.c \ +src/core/lib/support/backoff.c \ +src/core/lib/support/cmdline.c \ +src/core/lib/support/cpu_iphone.c \ +src/core/lib/support/cpu_linux.c \ +src/core/lib/support/cpu_posix.c \ +src/core/lib/support/cpu_windows.c \ +src/core/lib/support/env_linux.c \ +src/core/lib/support/env_posix.c \ +src/core/lib/support/env_win32.c \ +src/core/lib/support/histogram.c \ +src/core/lib/support/host_port.c \ +src/core/lib/support/load_file.c \ +src/core/lib/support/log.c \ +src/core/lib/support/log_android.c \ +src/core/lib/support/log_linux.c \ +src/core/lib/support/log_posix.c \ +src/core/lib/support/log_win32.c \ +src/core/lib/support/murmur_hash.c \ +src/core/lib/support/slice.c \ +src/core/lib/support/slice_buffer.c \ +src/core/lib/support/stack_lockfree.c \ +src/core/lib/support/string.c \ +src/core/lib/support/string_posix.c \ +src/core/lib/support/string_win32.c \ +src/core/lib/support/subprocess_posix.c \ +src/core/lib/support/subprocess_windows.c \ +src/core/lib/support/sync.c \ +src/core/lib/support/sync_posix.c \ +src/core/lib/support/sync_win32.c \ +src/core/lib/support/thd.c \ +src/core/lib/support/thd_posix.c \ +src/core/lib/support/thd_win32.c \ +src/core/lib/support/time.c \ +src/core/lib/support/time_posix.c \ +src/core/lib/support/time_precise.c \ +src/core/lib/support/time_win32.c \ +src/core/lib/support/tls_pthread.c \ +src/core/lib/support/tmpfile_posix.c \ +src/core/lib/support/tmpfile_win32.c \ +src/core/lib/support/wrap_memcpy.c # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 06dc6d0ff8..8653cf7017 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -3772,18 +3772,18 @@ "include/grpc/support/tls_msvc.h", "include/grpc/support/tls_pthread.h", "include/grpc/support/useful.h", - "src/core/profiling/timers.h", - "src/core/support/backoff.h", - "src/core/support/block_annotate.h", - "src/core/support/env.h", - "src/core/support/load_file.h", - "src/core/support/murmur_hash.h", - "src/core/support/stack_lockfree.h", - "src/core/support/string.h", - "src/core/support/string_win32.h", - "src/core/support/thd_internal.h", - "src/core/support/time_precise.h", - "src/core/support/tmpfile.h" + "src/core/lib/profiling/timers.h", + "src/core/lib/support/backoff.h", + "src/core/lib/support/block_annotate.h", + "src/core/lib/support/env.h", + "src/core/lib/support/load_file.h", + "src/core/lib/support/murmur_hash.h", + "src/core/lib/support/stack_lockfree.h", + "src/core/lib/support/string.h", + "src/core/lib/support/string_win32.h", + "src/core/lib/support/thd_internal.h", + "src/core/lib/support/time_precise.h", + "src/core/lib/support/tmpfile.h" ], "language": "c", "name": "gpr", @@ -3830,62 +3830,62 @@ "include/grpc/support/tls_msvc.h", "include/grpc/support/tls_pthread.h", "include/grpc/support/useful.h", - "src/core/profiling/basic_timers.c", - "src/core/profiling/stap_timers.c", - "src/core/profiling/timers.h", - "src/core/support/alloc.c", - "src/core/support/avl.c", - "src/core/support/backoff.c", - "src/core/support/backoff.h", - "src/core/support/block_annotate.h", - "src/core/support/cmdline.c", - "src/core/support/cpu_iphone.c", - "src/core/support/cpu_linux.c", - "src/core/support/cpu_posix.c", - "src/core/support/cpu_windows.c", - "src/core/support/env.h", - "src/core/support/env_linux.c", - "src/core/support/env_posix.c", - "src/core/support/env_win32.c", - "src/core/support/histogram.c", - "src/core/support/host_port.c", - "src/core/support/load_file.c", - "src/core/support/load_file.h", - "src/core/support/log.c", - "src/core/support/log_android.c", - "src/core/support/log_linux.c", - "src/core/support/log_posix.c", - "src/core/support/log_win32.c", - "src/core/support/murmur_hash.c", - "src/core/support/murmur_hash.h", - "src/core/support/slice.c", - "src/core/support/slice_buffer.c", - "src/core/support/stack_lockfree.c", - "src/core/support/stack_lockfree.h", - "src/core/support/string.c", - "src/core/support/string.h", - "src/core/support/string_posix.c", - "src/core/support/string_win32.c", - "src/core/support/string_win32.h", - "src/core/support/subprocess_posix.c", - "src/core/support/subprocess_windows.c", - "src/core/support/sync.c", - "src/core/support/sync_posix.c", - "src/core/support/sync_win32.c", - "src/core/support/thd.c", - "src/core/support/thd_internal.h", - "src/core/support/thd_posix.c", - "src/core/support/thd_win32.c", - "src/core/support/time.c", - "src/core/support/time_posix.c", - "src/core/support/time_precise.c", - "src/core/support/time_precise.h", - "src/core/support/time_win32.c", - "src/core/support/tls_pthread.c", - "src/core/support/tmpfile.h", - "src/core/support/tmpfile_posix.c", - "src/core/support/tmpfile_win32.c", - "src/core/support/wrap_memcpy.c" + "src/core/lib/profiling/basic_timers.c", + "src/core/lib/profiling/stap_timers.c", + "src/core/lib/profiling/timers.h", + "src/core/lib/support/alloc.c", + "src/core/lib/support/avl.c", + "src/core/lib/support/backoff.c", + "src/core/lib/support/backoff.h", + "src/core/lib/support/block_annotate.h", + "src/core/lib/support/cmdline.c", + "src/core/lib/support/cpu_iphone.c", + "src/core/lib/support/cpu_linux.c", + "src/core/lib/support/cpu_posix.c", + "src/core/lib/support/cpu_windows.c", + "src/core/lib/support/env.h", + "src/core/lib/support/env_linux.c", + "src/core/lib/support/env_posix.c", + "src/core/lib/support/env_win32.c", + "src/core/lib/support/histogram.c", + "src/core/lib/support/host_port.c", + "src/core/lib/support/load_file.c", + "src/core/lib/support/load_file.h", + "src/core/lib/support/log.c", + "src/core/lib/support/log_android.c", + "src/core/lib/support/log_linux.c", + "src/core/lib/support/log_posix.c", + "src/core/lib/support/log_win32.c", + "src/core/lib/support/murmur_hash.c", + "src/core/lib/support/murmur_hash.h", + "src/core/lib/support/slice.c", + "src/core/lib/support/slice_buffer.c", + "src/core/lib/support/stack_lockfree.c", + "src/core/lib/support/stack_lockfree.h", + "src/core/lib/support/string.c", + "src/core/lib/support/string.h", + "src/core/lib/support/string_posix.c", + "src/core/lib/support/string_win32.c", + "src/core/lib/support/string_win32.h", + "src/core/lib/support/subprocess_posix.c", + "src/core/lib/support/subprocess_windows.c", + "src/core/lib/support/sync.c", + "src/core/lib/support/sync_posix.c", + "src/core/lib/support/sync_win32.c", + "src/core/lib/support/thd.c", + "src/core/lib/support/thd_internal.h", + "src/core/lib/support/thd_posix.c", + "src/core/lib/support/thd_win32.c", + "src/core/lib/support/time.c", + "src/core/lib/support/time_posix.c", + "src/core/lib/support/time_precise.c", + "src/core/lib/support/time_precise.h", + "src/core/lib/support/time_win32.c", + "src/core/lib/support/tls_pthread.c", + "src/core/lib/support/tmpfile.h", + "src/core/lib/support/tmpfile_posix.c", + "src/core/lib/support/tmpfile_win32.c", + "src/core/lib/support/wrap_memcpy.c" ], "third_party": false, "type": "lib" @@ -3924,143 +3924,143 @@ "include/grpc/impl/codegen/propagation_bits.h", "include/grpc/impl/codegen/status.h", "include/grpc/status.h", - "src/core/census/aggregation.h", - "src/core/census/grpc_filter.h", - "src/core/census/grpc_plugin.h", - "src/core/census/mlog.h", - "src/core/census/rpc_metric_id.h", - "src/core/channel/channel_args.h", - "src/core/channel/channel_stack.h", - "src/core/channel/channel_stack_builder.h", - "src/core/channel/client_channel.h", - "src/core/channel/compress_filter.h", - "src/core/channel/connected_channel.h", - "src/core/channel/context.h", - "src/core/channel/http_client_filter.h", - "src/core/channel/http_server_filter.h", - "src/core/channel/subchannel_call_holder.h", - "src/core/client_config/client_config.h", - "src/core/client_config/connector.h", - "src/core/client_config/initial_connect_string.h", - "src/core/client_config/lb_policies/load_balancer_api.h", - "src/core/client_config/lb_policies/pick_first.h", - "src/core/client_config/lb_policies/round_robin.h", - "src/core/client_config/lb_policy.h", - "src/core/client_config/lb_policy_factory.h", - "src/core/client_config/lb_policy_registry.h", - "src/core/client_config/resolver.h", - "src/core/client_config/resolver_factory.h", - "src/core/client_config/resolver_registry.h", - "src/core/client_config/resolvers/dns_resolver.h", - "src/core/client_config/resolvers/sockaddr_resolver.h", - "src/core/client_config/subchannel.h", - "src/core/client_config/subchannel_factory.h", - "src/core/client_config/subchannel_index.h", - "src/core/client_config/uri_parser.h", - "src/core/compression/algorithm_metadata.h", - "src/core/compression/message_compress.h", - "src/core/debug/trace.h", - "src/core/http/format_request.h", - "src/core/http/httpcli.h", - "src/core/http/parser.h", - "src/core/iomgr/closure.h", - "src/core/iomgr/endpoint.h", - "src/core/iomgr/endpoint_pair.h", - "src/core/iomgr/exec_ctx.h", - "src/core/iomgr/executor.h", - "src/core/iomgr/fd_posix.h", - "src/core/iomgr/iocp_windows.h", - "src/core/iomgr/iomgr.h", - "src/core/iomgr/iomgr_internal.h", - "src/core/iomgr/iomgr_posix.h", - "src/core/iomgr/pollset.h", - "src/core/iomgr/pollset_posix.h", - "src/core/iomgr/pollset_set.h", - "src/core/iomgr/pollset_set_posix.h", - "src/core/iomgr/pollset_set_windows.h", - "src/core/iomgr/pollset_windows.h", - "src/core/iomgr/resolve_address.h", - "src/core/iomgr/sockaddr.h", - "src/core/iomgr/sockaddr_posix.h", - "src/core/iomgr/sockaddr_utils.h", - "src/core/iomgr/sockaddr_win32.h", - "src/core/iomgr/socket_utils_posix.h", - "src/core/iomgr/socket_windows.h", - "src/core/iomgr/tcp_client.h", - "src/core/iomgr/tcp_posix.h", - "src/core/iomgr/tcp_server.h", - "src/core/iomgr/tcp_windows.h", - "src/core/iomgr/time_averaged_stats.h", - "src/core/iomgr/timer.h", - "src/core/iomgr/timer_heap.h", - "src/core/iomgr/udp_server.h", - "src/core/iomgr/unix_sockets_posix.h", - "src/core/iomgr/wakeup_fd_pipe.h", - "src/core/iomgr/wakeup_fd_posix.h", - "src/core/iomgr/workqueue.h", - "src/core/iomgr/workqueue_posix.h", - "src/core/iomgr/workqueue_windows.h", - "src/core/json/json.h", - "src/core/json/json_common.h", - "src/core/json/json_reader.h", - "src/core/json/json_writer.h", - "src/core/proto/grpc/lb/v0/load_balancer.pb.h", - "src/core/security/auth_filters.h", - "src/core/security/b64.h", - "src/core/security/credentials.h", - "src/core/security/handshake.h", - "src/core/security/json_token.h", - "src/core/security/jwt_verifier.h", - "src/core/security/secure_endpoint.h", - "src/core/security/security_connector.h", - "src/core/security/security_context.h", - "src/core/statistics/census_interface.h", - "src/core/statistics/census_rpc_stats.h", - "src/core/surface/api_trace.h", - "src/core/surface/call.h", - "src/core/surface/call_test_only.h", - "src/core/surface/channel.h", - "src/core/surface/channel_init.h", - "src/core/surface/channel_stack_type.h", - "src/core/surface/completion_queue.h", - "src/core/surface/event_string.h", - "src/core/surface/init.h", - "src/core/surface/lame_client.h", - "src/core/surface/server.h", - "src/core/surface/surface_trace.h", - "src/core/transport/byte_stream.h", - "src/core/transport/chttp2/alpn.h", - "src/core/transport/chttp2/bin_encoder.h", - "src/core/transport/chttp2/frame.h", - "src/core/transport/chttp2/frame_data.h", - "src/core/transport/chttp2/frame_goaway.h", - "src/core/transport/chttp2/frame_ping.h", - "src/core/transport/chttp2/frame_rst_stream.h", - "src/core/transport/chttp2/frame_settings.h", - "src/core/transport/chttp2/frame_window_update.h", - "src/core/transport/chttp2/hpack_encoder.h", - "src/core/transport/chttp2/hpack_parser.h", - "src/core/transport/chttp2/hpack_table.h", - "src/core/transport/chttp2/http2_errors.h", - "src/core/transport/chttp2/huffsyms.h", - "src/core/transport/chttp2/incoming_metadata.h", - "src/core/transport/chttp2/internal.h", - "src/core/transport/chttp2/status_conversion.h", - "src/core/transport/chttp2/stream_map.h", - "src/core/transport/chttp2/timeout_encoding.h", - "src/core/transport/chttp2/varint.h", - "src/core/transport/chttp2_transport.h", - "src/core/transport/connectivity_state.h", - "src/core/transport/metadata.h", - "src/core/transport/metadata_batch.h", - "src/core/transport/static_metadata.h", - "src/core/transport/transport.h", - "src/core/transport/transport_impl.h", - "src/core/tsi/fake_transport_security.h", - "src/core/tsi/ssl_transport_security.h", - "src/core/tsi/ssl_types.h", - "src/core/tsi/transport_security.h", - "src/core/tsi/transport_security_interface.h", + "src/core/lib/census/aggregation.h", + "src/core/lib/census/grpc_filter.h", + "src/core/lib/census/grpc_plugin.h", + "src/core/lib/census/mlog.h", + "src/core/lib/census/rpc_metric_id.h", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/client_channel.h", + "src/core/lib/channel/compress_filter.h", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/http_client_filter.h", + "src/core/lib/channel/http_server_filter.h", + "src/core/lib/channel/subchannel_call_holder.h", + "src/core/lib/client_config/client_config.h", + "src/core/lib/client_config/connector.h", + "src/core/lib/client_config/initial_connect_string.h", + "src/core/lib/client_config/lb_policies/load_balancer_api.h", + "src/core/lib/client_config/lb_policies/pick_first.h", + "src/core/lib/client_config/lb_policies/round_robin.h", + "src/core/lib/client_config/lb_policy.h", + "src/core/lib/client_config/lb_policy_factory.h", + "src/core/lib/client_config/lb_policy_registry.h", + "src/core/lib/client_config/resolver.h", + "src/core/lib/client_config/resolver_factory.h", + "src/core/lib/client_config/resolver_registry.h", + "src/core/lib/client_config/resolvers/dns_resolver.h", + "src/core/lib/client_config/resolvers/sockaddr_resolver.h", + "src/core/lib/client_config/subchannel.h", + "src/core/lib/client_config/subchannel_factory.h", + "src/core/lib/client_config/subchannel_index.h", + "src/core/lib/client_config/uri_parser.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/message_compress.h", + "src/core/lib/debug/trace.h", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/fd_posix.h", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_posix.h", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_posix.h", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_win32.h", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/iomgr/workqueue.h", + "src/core/lib/iomgr/workqueue_posix.h", + "src/core/lib/iomgr/workqueue_windows.h", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_writer.h", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h", + "src/core/lib/security/auth_filters.h", + "src/core/lib/security/b64.h", + "src/core/lib/security/credentials.h", + "src/core/lib/security/handshake.h", + "src/core/lib/security/json_token.h", + "src/core/lib/security/jwt_verifier.h", + "src/core/lib/security/secure_endpoint.h", + "src/core/lib/security/security_connector.h", + "src/core/lib/security/security_context.h", + "src/core/lib/statistics/census_interface.h", + "src/core/lib/statistics/census_rpc_stats.h", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.h", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/server.h", + "src/core/lib/surface/surface_trace.h", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/chttp2/alpn.h", + "src/core/lib/transport/chttp2/bin_encoder.h", + "src/core/lib/transport/chttp2/frame.h", + "src/core/lib/transport/chttp2/frame_data.h", + "src/core/lib/transport/chttp2/frame_goaway.h", + "src/core/lib/transport/chttp2/frame_ping.h", + "src/core/lib/transport/chttp2/frame_rst_stream.h", + "src/core/lib/transport/chttp2/frame_settings.h", + "src/core/lib/transport/chttp2/frame_window_update.h", + "src/core/lib/transport/chttp2/hpack_encoder.h", + "src/core/lib/transport/chttp2/hpack_parser.h", + "src/core/lib/transport/chttp2/hpack_table.h", + "src/core/lib/transport/chttp2/http2_errors.h", + "src/core/lib/transport/chttp2/huffsyms.h", + "src/core/lib/transport/chttp2/incoming_metadata.h", + "src/core/lib/transport/chttp2/internal.h", + "src/core/lib/transport/chttp2/status_conversion.h", + "src/core/lib/transport/chttp2/stream_map.h", + "src/core/lib/transport/chttp2/timeout_encoding.h", + "src/core/lib/transport/chttp2/varint.h", + "src/core/lib/transport/chttp2_transport.h", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", + "src/core/lib/tsi/fake_transport_security.h", + "src/core/lib/tsi/ssl_transport_security.h", + "src/core/lib/tsi/ssl_types.h", + "src/core/lib/tsi/transport_security.h", + "src/core/lib/tsi/transport_security_interface.h", "third_party/nanopb/pb.h", "third_party/nanopb/pb_common.h", "third_party/nanopb/pb_decode.h", @@ -4082,304 +4082,304 @@ "include/grpc/impl/codegen/propagation_bits.h", "include/grpc/impl/codegen/status.h", "include/grpc/status.h", - "src/core/census/aggregation.h", - "src/core/census/context.c", - "src/core/census/grpc_context.c", - "src/core/census/grpc_filter.c", - "src/core/census/grpc_filter.h", - "src/core/census/grpc_plugin.c", - "src/core/census/grpc_plugin.h", - "src/core/census/initialize.c", - "src/core/census/mlog.c", - "src/core/census/mlog.h", - "src/core/census/operation.c", - "src/core/census/placeholders.c", - "src/core/census/rpc_metric_id.h", - "src/core/census/tracing.c", - "src/core/channel/channel_args.c", - "src/core/channel/channel_args.h", - "src/core/channel/channel_stack.c", - "src/core/channel/channel_stack.h", - "src/core/channel/channel_stack_builder.c", - "src/core/channel/channel_stack_builder.h", - "src/core/channel/client_channel.c", - "src/core/channel/client_channel.h", - "src/core/channel/compress_filter.c", - "src/core/channel/compress_filter.h", - "src/core/channel/connected_channel.c", - "src/core/channel/connected_channel.h", - "src/core/channel/context.h", - "src/core/channel/http_client_filter.c", - "src/core/channel/http_client_filter.h", - "src/core/channel/http_server_filter.c", - "src/core/channel/http_server_filter.h", - "src/core/channel/subchannel_call_holder.c", - "src/core/channel/subchannel_call_holder.h", - "src/core/client_config/client_config.c", - "src/core/client_config/client_config.h", - "src/core/client_config/connector.c", - "src/core/client_config/connector.h", - "src/core/client_config/default_initial_connect_string.c", - "src/core/client_config/initial_connect_string.c", - "src/core/client_config/initial_connect_string.h", - "src/core/client_config/lb_policies/load_balancer_api.c", - "src/core/client_config/lb_policies/load_balancer_api.h", - "src/core/client_config/lb_policies/pick_first.c", - "src/core/client_config/lb_policies/pick_first.h", - "src/core/client_config/lb_policies/round_robin.c", - "src/core/client_config/lb_policies/round_robin.h", - "src/core/client_config/lb_policy.c", - "src/core/client_config/lb_policy.h", - "src/core/client_config/lb_policy_factory.c", - "src/core/client_config/lb_policy_factory.h", - "src/core/client_config/lb_policy_registry.c", - "src/core/client_config/lb_policy_registry.h", - "src/core/client_config/resolver.c", - "src/core/client_config/resolver.h", - "src/core/client_config/resolver_factory.c", - "src/core/client_config/resolver_factory.h", - "src/core/client_config/resolver_registry.c", - "src/core/client_config/resolver_registry.h", - "src/core/client_config/resolvers/dns_resolver.c", - "src/core/client_config/resolvers/dns_resolver.h", - "src/core/client_config/resolvers/sockaddr_resolver.c", - "src/core/client_config/resolvers/sockaddr_resolver.h", - "src/core/client_config/subchannel.c", - "src/core/client_config/subchannel.h", - "src/core/client_config/subchannel_factory.c", - "src/core/client_config/subchannel_factory.h", - "src/core/client_config/subchannel_index.c", - "src/core/client_config/subchannel_index.h", - "src/core/client_config/uri_parser.c", - "src/core/client_config/uri_parser.h", - "src/core/compression/algorithm_metadata.h", - "src/core/compression/compression_algorithm.c", - "src/core/compression/message_compress.c", - "src/core/compression/message_compress.h", - "src/core/debug/trace.c", - "src/core/debug/trace.h", - "src/core/http/format_request.c", - "src/core/http/format_request.h", - "src/core/http/httpcli.c", - "src/core/http/httpcli.h", - "src/core/http/httpcli_security_connector.c", - "src/core/http/parser.c", - "src/core/http/parser.h", - "src/core/iomgr/closure.c", - "src/core/iomgr/closure.h", - "src/core/iomgr/endpoint.c", - "src/core/iomgr/endpoint.h", - "src/core/iomgr/endpoint_pair.h", - "src/core/iomgr/endpoint_pair_posix.c", - "src/core/iomgr/endpoint_pair_windows.c", - "src/core/iomgr/exec_ctx.c", - "src/core/iomgr/exec_ctx.h", - "src/core/iomgr/executor.c", - "src/core/iomgr/executor.h", - "src/core/iomgr/fd_posix.c", - "src/core/iomgr/fd_posix.h", - "src/core/iomgr/iocp_windows.c", - "src/core/iomgr/iocp_windows.h", - "src/core/iomgr/iomgr.c", - "src/core/iomgr/iomgr.h", - "src/core/iomgr/iomgr_internal.h", - "src/core/iomgr/iomgr_posix.c", - "src/core/iomgr/iomgr_posix.h", - "src/core/iomgr/iomgr_windows.c", - "src/core/iomgr/pollset.h", - "src/core/iomgr/pollset_multipoller_with_epoll.c", - "src/core/iomgr/pollset_multipoller_with_poll_posix.c", - "src/core/iomgr/pollset_posix.c", - "src/core/iomgr/pollset_posix.h", - "src/core/iomgr/pollset_set.h", - "src/core/iomgr/pollset_set_posix.c", - "src/core/iomgr/pollset_set_posix.h", - "src/core/iomgr/pollset_set_windows.c", - "src/core/iomgr/pollset_set_windows.h", - "src/core/iomgr/pollset_windows.c", - "src/core/iomgr/pollset_windows.h", - "src/core/iomgr/resolve_address.h", - "src/core/iomgr/resolve_address_posix.c", - "src/core/iomgr/resolve_address_windows.c", - "src/core/iomgr/sockaddr.h", - "src/core/iomgr/sockaddr_posix.h", - "src/core/iomgr/sockaddr_utils.c", - "src/core/iomgr/sockaddr_utils.h", - "src/core/iomgr/sockaddr_win32.h", - "src/core/iomgr/socket_utils_common_posix.c", - "src/core/iomgr/socket_utils_linux.c", - "src/core/iomgr/socket_utils_posix.c", - "src/core/iomgr/socket_utils_posix.h", - "src/core/iomgr/socket_windows.c", - "src/core/iomgr/socket_windows.h", - "src/core/iomgr/tcp_client.h", - "src/core/iomgr/tcp_client_posix.c", - "src/core/iomgr/tcp_client_windows.c", - "src/core/iomgr/tcp_posix.c", - "src/core/iomgr/tcp_posix.h", - "src/core/iomgr/tcp_server.h", - "src/core/iomgr/tcp_server_posix.c", - "src/core/iomgr/tcp_server_windows.c", - "src/core/iomgr/tcp_windows.c", - "src/core/iomgr/tcp_windows.h", - "src/core/iomgr/time_averaged_stats.c", - "src/core/iomgr/time_averaged_stats.h", - "src/core/iomgr/timer.c", - "src/core/iomgr/timer.h", - "src/core/iomgr/timer_heap.c", - "src/core/iomgr/timer_heap.h", - "src/core/iomgr/udp_server.c", - "src/core/iomgr/udp_server.h", - "src/core/iomgr/unix_sockets_posix.c", - "src/core/iomgr/unix_sockets_posix.h", - "src/core/iomgr/unix_sockets_posix_noop.c", - "src/core/iomgr/wakeup_fd_eventfd.c", - "src/core/iomgr/wakeup_fd_nospecial.c", - "src/core/iomgr/wakeup_fd_pipe.c", - "src/core/iomgr/wakeup_fd_pipe.h", - "src/core/iomgr/wakeup_fd_posix.c", - "src/core/iomgr/wakeup_fd_posix.h", - "src/core/iomgr/workqueue.h", - "src/core/iomgr/workqueue_posix.c", - "src/core/iomgr/workqueue_posix.h", - "src/core/iomgr/workqueue_windows.c", - "src/core/iomgr/workqueue_windows.h", - "src/core/json/json.c", - "src/core/json/json.h", - "src/core/json/json_common.h", - "src/core/json/json_reader.c", - "src/core/json/json_reader.h", - "src/core/json/json_string.c", - "src/core/json/json_writer.c", - "src/core/json/json_writer.h", - "src/core/proto/grpc/lb/v0/load_balancer.pb.c", - "src/core/proto/grpc/lb/v0/load_balancer.pb.h", - "src/core/security/auth_filters.h", - "src/core/security/b64.c", - "src/core/security/b64.h", - "src/core/security/client_auth_filter.c", - "src/core/security/credentials.c", - "src/core/security/credentials.h", - "src/core/security/credentials_metadata.c", - "src/core/security/credentials_posix.c", - "src/core/security/credentials_win32.c", - "src/core/security/google_default_credentials.c", - "src/core/security/handshake.c", - "src/core/security/handshake.h", - "src/core/security/json_token.c", - "src/core/security/json_token.h", - "src/core/security/jwt_verifier.c", - "src/core/security/jwt_verifier.h", - "src/core/security/secure_endpoint.c", - "src/core/security/secure_endpoint.h", - "src/core/security/security_connector.c", - "src/core/security/security_connector.h", - "src/core/security/security_context.c", - "src/core/security/security_context.h", - "src/core/security/server_auth_filter.c", - "src/core/security/server_secure_chttp2.c", - "src/core/statistics/census_interface.h", - "src/core/statistics/census_rpc_stats.h", - "src/core/surface/alarm.c", - "src/core/surface/api_trace.c", - "src/core/surface/api_trace.h", - "src/core/surface/byte_buffer.c", - "src/core/surface/byte_buffer_reader.c", - "src/core/surface/call.c", - "src/core/surface/call.h", - "src/core/surface/call_details.c", - "src/core/surface/call_log_batch.c", - "src/core/surface/call_test_only.h", - "src/core/surface/channel.c", - "src/core/surface/channel.h", - "src/core/surface/channel_connectivity.c", - "src/core/surface/channel_create.c", - "src/core/surface/channel_init.c", - "src/core/surface/channel_init.h", - "src/core/surface/channel_ping.c", - "src/core/surface/channel_stack_type.c", - "src/core/surface/channel_stack_type.h", - "src/core/surface/completion_queue.c", - "src/core/surface/completion_queue.h", - "src/core/surface/event_string.c", - "src/core/surface/event_string.h", - "src/core/surface/init.c", - "src/core/surface/init.h", - "src/core/surface/init_secure.c", - "src/core/surface/lame_client.c", - "src/core/surface/lame_client.h", - "src/core/surface/metadata_array.c", - "src/core/surface/secure_channel_create.c", - "src/core/surface/server.c", - "src/core/surface/server.h", - "src/core/surface/server_chttp2.c", - "src/core/surface/surface_trace.h", - "src/core/surface/validate_metadata.c", - "src/core/surface/version.c", - "src/core/transport/byte_stream.c", - "src/core/transport/byte_stream.h", - "src/core/transport/chttp2/alpn.c", - "src/core/transport/chttp2/alpn.h", - "src/core/transport/chttp2/bin_encoder.c", - "src/core/transport/chttp2/bin_encoder.h", - "src/core/transport/chttp2/frame.h", - "src/core/transport/chttp2/frame_data.c", - "src/core/transport/chttp2/frame_data.h", - "src/core/transport/chttp2/frame_goaway.c", - "src/core/transport/chttp2/frame_goaway.h", - "src/core/transport/chttp2/frame_ping.c", - "src/core/transport/chttp2/frame_ping.h", - "src/core/transport/chttp2/frame_rst_stream.c", - "src/core/transport/chttp2/frame_rst_stream.h", - "src/core/transport/chttp2/frame_settings.c", - "src/core/transport/chttp2/frame_settings.h", - "src/core/transport/chttp2/frame_window_update.c", - "src/core/transport/chttp2/frame_window_update.h", - "src/core/transport/chttp2/hpack_encoder.c", - "src/core/transport/chttp2/hpack_encoder.h", - "src/core/transport/chttp2/hpack_parser.c", - "src/core/transport/chttp2/hpack_parser.h", - "src/core/transport/chttp2/hpack_table.c", - "src/core/transport/chttp2/hpack_table.h", - "src/core/transport/chttp2/http2_errors.h", - "src/core/transport/chttp2/huffsyms.c", - "src/core/transport/chttp2/huffsyms.h", - "src/core/transport/chttp2/incoming_metadata.c", - "src/core/transport/chttp2/incoming_metadata.h", - "src/core/transport/chttp2/internal.h", - "src/core/transport/chttp2/parsing.c", - "src/core/transport/chttp2/status_conversion.c", - "src/core/transport/chttp2/status_conversion.h", - "src/core/transport/chttp2/stream_lists.c", - "src/core/transport/chttp2/stream_map.c", - "src/core/transport/chttp2/stream_map.h", - "src/core/transport/chttp2/timeout_encoding.c", - "src/core/transport/chttp2/timeout_encoding.h", - "src/core/transport/chttp2/varint.c", - "src/core/transport/chttp2/varint.h", - "src/core/transport/chttp2/writing.c", - "src/core/transport/chttp2_transport.c", - "src/core/transport/chttp2_transport.h", - "src/core/transport/connectivity_state.c", - "src/core/transport/connectivity_state.h", - "src/core/transport/metadata.c", - "src/core/transport/metadata.h", - "src/core/transport/metadata_batch.c", - "src/core/transport/metadata_batch.h", - "src/core/transport/static_metadata.c", - "src/core/transport/static_metadata.h", - "src/core/transport/transport.c", - "src/core/transport/transport.h", - "src/core/transport/transport_impl.h", - "src/core/transport/transport_op_string.c", - "src/core/tsi/fake_transport_security.c", - "src/core/tsi/fake_transport_security.h", - "src/core/tsi/ssl_transport_security.c", - "src/core/tsi/ssl_transport_security.h", - "src/core/tsi/ssl_types.h", - "src/core/tsi/transport_security.c", - "src/core/tsi/transport_security.h", - "src/core/tsi/transport_security_interface.h" + "src/core/lib/census/aggregation.h", + "src/core/lib/census/context.c", + "src/core/lib/census/grpc_context.c", + "src/core/lib/census/grpc_filter.c", + "src/core/lib/census/grpc_filter.h", + "src/core/lib/census/grpc_plugin.c", + "src/core/lib/census/grpc_plugin.h", + "src/core/lib/census/initialize.c", + "src/core/lib/census/mlog.c", + "src/core/lib/census/mlog.h", + "src/core/lib/census/operation.c", + "src/core/lib/census/placeholders.c", + "src/core/lib/census/rpc_metric_id.h", + "src/core/lib/census/tracing.c", + "src/core/lib/channel/channel_args.c", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.c", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.c", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/client_channel.c", + "src/core/lib/channel/client_channel.h", + "src/core/lib/channel/compress_filter.c", + "src/core/lib/channel/compress_filter.h", + "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/http_client_filter.c", + "src/core/lib/channel/http_client_filter.h", + "src/core/lib/channel/http_server_filter.c", + "src/core/lib/channel/http_server_filter.h", + "src/core/lib/channel/subchannel_call_holder.c", + "src/core/lib/channel/subchannel_call_holder.h", + "src/core/lib/client_config/client_config.c", + "src/core/lib/client_config/client_config.h", + "src/core/lib/client_config/connector.c", + "src/core/lib/client_config/connector.h", + "src/core/lib/client_config/default_initial_connect_string.c", + "src/core/lib/client_config/initial_connect_string.c", + "src/core/lib/client_config/initial_connect_string.h", + "src/core/lib/client_config/lb_policies/load_balancer_api.c", + "src/core/lib/client_config/lb_policies/load_balancer_api.h", + "src/core/lib/client_config/lb_policies/pick_first.c", + "src/core/lib/client_config/lb_policies/pick_first.h", + "src/core/lib/client_config/lb_policies/round_robin.c", + "src/core/lib/client_config/lb_policies/round_robin.h", + "src/core/lib/client_config/lb_policy.c", + "src/core/lib/client_config/lb_policy.h", + "src/core/lib/client_config/lb_policy_factory.c", + "src/core/lib/client_config/lb_policy_factory.h", + "src/core/lib/client_config/lb_policy_registry.c", + "src/core/lib/client_config/lb_policy_registry.h", + "src/core/lib/client_config/resolver.c", + "src/core/lib/client_config/resolver.h", + "src/core/lib/client_config/resolver_factory.c", + "src/core/lib/client_config/resolver_factory.h", + "src/core/lib/client_config/resolver_registry.c", + "src/core/lib/client_config/resolver_registry.h", + "src/core/lib/client_config/resolvers/dns_resolver.c", + "src/core/lib/client_config/resolvers/dns_resolver.h", + "src/core/lib/client_config/resolvers/sockaddr_resolver.c", + "src/core/lib/client_config/resolvers/sockaddr_resolver.h", + "src/core/lib/client_config/subchannel.c", + "src/core/lib/client_config/subchannel.h", + "src/core/lib/client_config/subchannel_factory.c", + "src/core/lib/client_config/subchannel_factory.h", + "src/core/lib/client_config/subchannel_index.c", + "src/core/lib/client_config/subchannel_index.h", + "src/core/lib/client_config/uri_parser.c", + "src/core/lib/client_config/uri_parser.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/compression_algorithm.c", + "src/core/lib/compression/message_compress.c", + "src/core/lib/compression/message_compress.h", + "src/core/lib/debug/trace.c", + "src/core/lib/debug/trace.h", + "src/core/lib/http/format_request.c", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.c", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/httpcli_security_connector.c", + "src/core/lib/http/parser.c", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/closure.c", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/endpoint.c", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/endpoint_pair_posix.c", + "src/core/lib/iomgr/endpoint_pair_windows.c", + "src/core/lib/iomgr/exec_ctx.c", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.c", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/fd_posix.c", + "src/core/lib/iomgr/fd_posix.h", + "src/core/lib/iomgr/iocp_windows.c", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.c", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.c", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/iomgr_windows.c", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_multipoller_with_epoll.c", + "src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c", + "src/core/lib/iomgr/pollset_posix.c", + "src/core/lib/iomgr/pollset_posix.h", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_posix.c", + "src/core/lib/iomgr/pollset_set_posix.h", + "src/core/lib/iomgr/pollset_set_windows.c", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_windows.c", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/resolve_address_posix.c", + "src/core/lib/iomgr/resolve_address_windows.c", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_utils.c", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_win32.h", + "src/core/lib/iomgr/socket_utils_common_posix.c", + "src/core/lib/iomgr/socket_utils_linux.c", + "src/core/lib/iomgr/socket_utils_posix.c", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_windows.c", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_client_posix.c", + "src/core/lib/iomgr/tcp_client_windows.c", + "src/core/lib/iomgr/tcp_posix.c", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_server_posix.c", + "src/core/lib/iomgr/tcp_server_windows.c", + "src/core/lib/iomgr/tcp_windows.c", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.c", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.c", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_heap.c", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/udp_server.c", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.c", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_eventfd.c", + "src/core/lib/iomgr/wakeup_fd_nospecial.c", + "src/core/lib/iomgr/wakeup_fd_pipe.c", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.c", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/iomgr/workqueue.h", + "src/core/lib/iomgr/workqueue_posix.c", + "src/core/lib/iomgr/workqueue_posix.h", + "src/core/lib/iomgr/workqueue_windows.c", + "src/core/lib/iomgr/workqueue_windows.h", + "src/core/lib/json/json.c", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.c", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_string.c", + "src/core/lib/json/json_writer.c", + "src/core/lib/json/json_writer.h", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h", + "src/core/lib/security/auth_filters.h", + "src/core/lib/security/b64.c", + "src/core/lib/security/b64.h", + "src/core/lib/security/client_auth_filter.c", + "src/core/lib/security/credentials.c", + "src/core/lib/security/credentials.h", + "src/core/lib/security/credentials_metadata.c", + "src/core/lib/security/credentials_posix.c", + "src/core/lib/security/credentials_win32.c", + "src/core/lib/security/google_default_credentials.c", + "src/core/lib/security/handshake.c", + "src/core/lib/security/handshake.h", + "src/core/lib/security/json_token.c", + "src/core/lib/security/json_token.h", + "src/core/lib/security/jwt_verifier.c", + "src/core/lib/security/jwt_verifier.h", + "src/core/lib/security/secure_endpoint.c", + "src/core/lib/security/secure_endpoint.h", + "src/core/lib/security/security_connector.c", + "src/core/lib/security/security_connector.h", + "src/core/lib/security/security_context.c", + "src/core/lib/security/security_context.h", + "src/core/lib/security/server_auth_filter.c", + "src/core/lib/security/server_secure_chttp2.c", + "src/core/lib/statistics/census_interface.h", + "src/core/lib/statistics/census_rpc_stats.h", + "src/core/lib/surface/alarm.c", + "src/core/lib/surface/api_trace.c", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/byte_buffer.c", + "src/core/lib/surface/byte_buffer_reader.c", + "src/core/lib/surface/call.c", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_details.c", + "src/core/lib/surface/call_log_batch.c", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.c", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_connectivity.c", + "src/core/lib/surface/channel_create.c", + "src/core/lib/surface/channel_init.c", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_ping.c", + "src/core/lib/surface/channel_stack_type.c", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.c", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/event_string.c", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.c", + "src/core/lib/surface/init.h", + "src/core/lib/surface/init_secure.c", + "src/core/lib/surface/lame_client.c", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/metadata_array.c", + "src/core/lib/surface/secure_channel_create.c", + "src/core/lib/surface/server.c", + "src/core/lib/surface/server.h", + "src/core/lib/surface/server_chttp2.c", + "src/core/lib/surface/surface_trace.h", + "src/core/lib/surface/validate_metadata.c", + "src/core/lib/surface/version.c", + "src/core/lib/transport/byte_stream.c", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/chttp2/alpn.c", + "src/core/lib/transport/chttp2/alpn.h", + "src/core/lib/transport/chttp2/bin_encoder.c", + "src/core/lib/transport/chttp2/bin_encoder.h", + "src/core/lib/transport/chttp2/frame.h", + "src/core/lib/transport/chttp2/frame_data.c", + "src/core/lib/transport/chttp2/frame_data.h", + "src/core/lib/transport/chttp2/frame_goaway.c", + "src/core/lib/transport/chttp2/frame_goaway.h", + "src/core/lib/transport/chttp2/frame_ping.c", + "src/core/lib/transport/chttp2/frame_ping.h", + "src/core/lib/transport/chttp2/frame_rst_stream.c", + "src/core/lib/transport/chttp2/frame_rst_stream.h", + "src/core/lib/transport/chttp2/frame_settings.c", + "src/core/lib/transport/chttp2/frame_settings.h", + "src/core/lib/transport/chttp2/frame_window_update.c", + "src/core/lib/transport/chttp2/frame_window_update.h", + "src/core/lib/transport/chttp2/hpack_encoder.c", + "src/core/lib/transport/chttp2/hpack_encoder.h", + "src/core/lib/transport/chttp2/hpack_parser.c", + "src/core/lib/transport/chttp2/hpack_parser.h", + "src/core/lib/transport/chttp2/hpack_table.c", + "src/core/lib/transport/chttp2/hpack_table.h", + "src/core/lib/transport/chttp2/http2_errors.h", + "src/core/lib/transport/chttp2/huffsyms.c", + "src/core/lib/transport/chttp2/huffsyms.h", + "src/core/lib/transport/chttp2/incoming_metadata.c", + "src/core/lib/transport/chttp2/incoming_metadata.h", + "src/core/lib/transport/chttp2/internal.h", + "src/core/lib/transport/chttp2/parsing.c", + "src/core/lib/transport/chttp2/status_conversion.c", + "src/core/lib/transport/chttp2/status_conversion.h", + "src/core/lib/transport/chttp2/stream_lists.c", + "src/core/lib/transport/chttp2/stream_map.c", + "src/core/lib/transport/chttp2/stream_map.h", + "src/core/lib/transport/chttp2/timeout_encoding.c", + "src/core/lib/transport/chttp2/timeout_encoding.h", + "src/core/lib/transport/chttp2/varint.c", + "src/core/lib/transport/chttp2/varint.h", + "src/core/lib/transport/chttp2/writing.c", + "src/core/lib/transport/chttp2_transport.c", + "src/core/lib/transport/chttp2_transport.h", + "src/core/lib/transport/connectivity_state.c", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/metadata.c", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.c", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/transport.c", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", + "src/core/lib/transport/transport_op_string.c", + "src/core/lib/tsi/fake_transport_security.c", + "src/core/lib/tsi/fake_transport_security.h", + "src/core/lib/tsi/ssl_transport_security.c", + "src/core/lib/tsi/ssl_transport_security.h", + "src/core/lib/tsi/ssl_types.h", + "src/core/lib/tsi/transport_security.c", + "src/core/lib/tsi/transport_security.h", + "src/core/lib/tsi/transport_security_interface.h" ], "third_party": false, "type": "lib" @@ -4552,129 +4552,129 @@ "include/grpc/impl/codegen/propagation_bits.h", "include/grpc/impl/codegen/status.h", "include/grpc/status.h", - "src/core/census/aggregation.h", - "src/core/census/grpc_filter.h", - "src/core/census/grpc_plugin.h", - "src/core/census/mlog.h", - "src/core/census/rpc_metric_id.h", - "src/core/channel/channel_args.h", - "src/core/channel/channel_stack.h", - "src/core/channel/channel_stack_builder.h", - "src/core/channel/client_channel.h", - "src/core/channel/compress_filter.h", - "src/core/channel/connected_channel.h", - "src/core/channel/context.h", - "src/core/channel/http_client_filter.h", - "src/core/channel/http_server_filter.h", - "src/core/channel/subchannel_call_holder.h", - "src/core/client_config/client_config.h", - "src/core/client_config/connector.h", - "src/core/client_config/initial_connect_string.h", - "src/core/client_config/lb_policies/load_balancer_api.h", - "src/core/client_config/lb_policies/pick_first.h", - "src/core/client_config/lb_policies/round_robin.h", - "src/core/client_config/lb_policy.h", - "src/core/client_config/lb_policy_factory.h", - "src/core/client_config/lb_policy_registry.h", - "src/core/client_config/resolver.h", - "src/core/client_config/resolver_factory.h", - "src/core/client_config/resolver_registry.h", - "src/core/client_config/resolvers/dns_resolver.h", - "src/core/client_config/resolvers/sockaddr_resolver.h", - "src/core/client_config/subchannel.h", - "src/core/client_config/subchannel_factory.h", - "src/core/client_config/subchannel_index.h", - "src/core/client_config/uri_parser.h", - "src/core/compression/algorithm_metadata.h", - "src/core/compression/message_compress.h", - "src/core/debug/trace.h", - "src/core/http/format_request.h", - "src/core/http/httpcli.h", - "src/core/http/parser.h", - "src/core/iomgr/closure.h", - "src/core/iomgr/endpoint.h", - "src/core/iomgr/endpoint_pair.h", - "src/core/iomgr/exec_ctx.h", - "src/core/iomgr/executor.h", - "src/core/iomgr/fd_posix.h", - "src/core/iomgr/iocp_windows.h", - "src/core/iomgr/iomgr.h", - "src/core/iomgr/iomgr_internal.h", - "src/core/iomgr/iomgr_posix.h", - "src/core/iomgr/pollset.h", - "src/core/iomgr/pollset_posix.h", - "src/core/iomgr/pollset_set.h", - "src/core/iomgr/pollset_set_posix.h", - "src/core/iomgr/pollset_set_windows.h", - "src/core/iomgr/pollset_windows.h", - "src/core/iomgr/resolve_address.h", - "src/core/iomgr/sockaddr.h", - "src/core/iomgr/sockaddr_posix.h", - "src/core/iomgr/sockaddr_utils.h", - "src/core/iomgr/sockaddr_win32.h", - "src/core/iomgr/socket_utils_posix.h", - "src/core/iomgr/socket_windows.h", - "src/core/iomgr/tcp_client.h", - "src/core/iomgr/tcp_posix.h", - "src/core/iomgr/tcp_server.h", - "src/core/iomgr/tcp_windows.h", - "src/core/iomgr/time_averaged_stats.h", - "src/core/iomgr/timer.h", - "src/core/iomgr/timer_heap.h", - "src/core/iomgr/udp_server.h", - "src/core/iomgr/unix_sockets_posix.h", - "src/core/iomgr/wakeup_fd_pipe.h", - "src/core/iomgr/wakeup_fd_posix.h", - "src/core/iomgr/workqueue.h", - "src/core/iomgr/workqueue_posix.h", - "src/core/iomgr/workqueue_windows.h", - "src/core/json/json.h", - "src/core/json/json_common.h", - "src/core/json/json_reader.h", - "src/core/json/json_writer.h", - "src/core/proto/grpc/lb/v0/load_balancer.pb.h", - "src/core/statistics/census_interface.h", - "src/core/statistics/census_rpc_stats.h", - "src/core/surface/api_trace.h", - "src/core/surface/call.h", - "src/core/surface/call_test_only.h", - "src/core/surface/channel.h", - "src/core/surface/channel_init.h", - "src/core/surface/channel_stack_type.h", - "src/core/surface/completion_queue.h", - "src/core/surface/event_string.h", - "src/core/surface/init.h", - "src/core/surface/lame_client.h", - "src/core/surface/server.h", - "src/core/surface/surface_trace.h", - "src/core/transport/byte_stream.h", - "src/core/transport/chttp2/alpn.h", - "src/core/transport/chttp2/bin_encoder.h", - "src/core/transport/chttp2/frame.h", - "src/core/transport/chttp2/frame_data.h", - "src/core/transport/chttp2/frame_goaway.h", - "src/core/transport/chttp2/frame_ping.h", - "src/core/transport/chttp2/frame_rst_stream.h", - "src/core/transport/chttp2/frame_settings.h", - "src/core/transport/chttp2/frame_window_update.h", - "src/core/transport/chttp2/hpack_encoder.h", - "src/core/transport/chttp2/hpack_parser.h", - "src/core/transport/chttp2/hpack_table.h", - "src/core/transport/chttp2/http2_errors.h", - "src/core/transport/chttp2/huffsyms.h", - "src/core/transport/chttp2/incoming_metadata.h", - "src/core/transport/chttp2/internal.h", - "src/core/transport/chttp2/status_conversion.h", - "src/core/transport/chttp2/stream_map.h", - "src/core/transport/chttp2/timeout_encoding.h", - "src/core/transport/chttp2/varint.h", - "src/core/transport/chttp2_transport.h", - "src/core/transport/connectivity_state.h", - "src/core/transport/metadata.h", - "src/core/transport/metadata_batch.h", - "src/core/transport/static_metadata.h", - "src/core/transport/transport.h", - "src/core/transport/transport_impl.h", + "src/core/lib/census/aggregation.h", + "src/core/lib/census/grpc_filter.h", + "src/core/lib/census/grpc_plugin.h", + "src/core/lib/census/mlog.h", + "src/core/lib/census/rpc_metric_id.h", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/client_channel.h", + "src/core/lib/channel/compress_filter.h", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/http_client_filter.h", + "src/core/lib/channel/http_server_filter.h", + "src/core/lib/channel/subchannel_call_holder.h", + "src/core/lib/client_config/client_config.h", + "src/core/lib/client_config/connector.h", + "src/core/lib/client_config/initial_connect_string.h", + "src/core/lib/client_config/lb_policies/load_balancer_api.h", + "src/core/lib/client_config/lb_policies/pick_first.h", + "src/core/lib/client_config/lb_policies/round_robin.h", + "src/core/lib/client_config/lb_policy.h", + "src/core/lib/client_config/lb_policy_factory.h", + "src/core/lib/client_config/lb_policy_registry.h", + "src/core/lib/client_config/resolver.h", + "src/core/lib/client_config/resolver_factory.h", + "src/core/lib/client_config/resolver_registry.h", + "src/core/lib/client_config/resolvers/dns_resolver.h", + "src/core/lib/client_config/resolvers/sockaddr_resolver.h", + "src/core/lib/client_config/subchannel.h", + "src/core/lib/client_config/subchannel_factory.h", + "src/core/lib/client_config/subchannel_index.h", + "src/core/lib/client_config/uri_parser.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/message_compress.h", + "src/core/lib/debug/trace.h", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/fd_posix.h", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_posix.h", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_posix.h", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_win32.h", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/iomgr/workqueue.h", + "src/core/lib/iomgr/workqueue_posix.h", + "src/core/lib/iomgr/workqueue_windows.h", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_writer.h", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h", + "src/core/lib/statistics/census_interface.h", + "src/core/lib/statistics/census_rpc_stats.h", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.h", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/server.h", + "src/core/lib/surface/surface_trace.h", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/chttp2/alpn.h", + "src/core/lib/transport/chttp2/bin_encoder.h", + "src/core/lib/transport/chttp2/frame.h", + "src/core/lib/transport/chttp2/frame_data.h", + "src/core/lib/transport/chttp2/frame_goaway.h", + "src/core/lib/transport/chttp2/frame_ping.h", + "src/core/lib/transport/chttp2/frame_rst_stream.h", + "src/core/lib/transport/chttp2/frame_settings.h", + "src/core/lib/transport/chttp2/frame_window_update.h", + "src/core/lib/transport/chttp2/hpack_encoder.h", + "src/core/lib/transport/chttp2/hpack_parser.h", + "src/core/lib/transport/chttp2/hpack_table.h", + "src/core/lib/transport/chttp2/http2_errors.h", + "src/core/lib/transport/chttp2/huffsyms.h", + "src/core/lib/transport/chttp2/incoming_metadata.h", + "src/core/lib/transport/chttp2/internal.h", + "src/core/lib/transport/chttp2/status_conversion.h", + "src/core/lib/transport/chttp2/stream_map.h", + "src/core/lib/transport/chttp2/timeout_encoding.h", + "src/core/lib/transport/chttp2/varint.h", + "src/core/lib/transport/chttp2_transport.h", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", "third_party/nanopb/pb.h", "third_party/nanopb/pb_common.h", "third_party/nanopb/pb_decode.h", @@ -4695,270 +4695,270 @@ "include/grpc/impl/codegen/propagation_bits.h", "include/grpc/impl/codegen/status.h", "include/grpc/status.h", - "src/core/census/aggregation.h", - "src/core/census/context.c", - "src/core/census/grpc_context.c", - "src/core/census/grpc_filter.c", - "src/core/census/grpc_filter.h", - "src/core/census/grpc_plugin.c", - "src/core/census/grpc_plugin.h", - "src/core/census/initialize.c", - "src/core/census/mlog.c", - "src/core/census/mlog.h", - "src/core/census/operation.c", - "src/core/census/placeholders.c", - "src/core/census/rpc_metric_id.h", - "src/core/census/tracing.c", - "src/core/channel/channel_args.c", - "src/core/channel/channel_args.h", - "src/core/channel/channel_stack.c", - "src/core/channel/channel_stack.h", - "src/core/channel/channel_stack_builder.c", - "src/core/channel/channel_stack_builder.h", - "src/core/channel/client_channel.c", - "src/core/channel/client_channel.h", - "src/core/channel/compress_filter.c", - "src/core/channel/compress_filter.h", - "src/core/channel/connected_channel.c", - "src/core/channel/connected_channel.h", - "src/core/channel/context.h", - "src/core/channel/http_client_filter.c", - "src/core/channel/http_client_filter.h", - "src/core/channel/http_server_filter.c", - "src/core/channel/http_server_filter.h", - "src/core/channel/subchannel_call_holder.c", - "src/core/channel/subchannel_call_holder.h", - "src/core/client_config/client_config.c", - "src/core/client_config/client_config.h", - "src/core/client_config/connector.c", - "src/core/client_config/connector.h", - "src/core/client_config/default_initial_connect_string.c", - "src/core/client_config/initial_connect_string.c", - "src/core/client_config/initial_connect_string.h", - "src/core/client_config/lb_policies/load_balancer_api.c", - "src/core/client_config/lb_policies/load_balancer_api.h", - "src/core/client_config/lb_policies/pick_first.c", - "src/core/client_config/lb_policies/pick_first.h", - "src/core/client_config/lb_policies/round_robin.c", - "src/core/client_config/lb_policies/round_robin.h", - "src/core/client_config/lb_policy.c", - "src/core/client_config/lb_policy.h", - "src/core/client_config/lb_policy_factory.c", - "src/core/client_config/lb_policy_factory.h", - "src/core/client_config/lb_policy_registry.c", - "src/core/client_config/lb_policy_registry.h", - "src/core/client_config/resolver.c", - "src/core/client_config/resolver.h", - "src/core/client_config/resolver_factory.c", - "src/core/client_config/resolver_factory.h", - "src/core/client_config/resolver_registry.c", - "src/core/client_config/resolver_registry.h", - "src/core/client_config/resolvers/dns_resolver.c", - "src/core/client_config/resolvers/dns_resolver.h", - "src/core/client_config/resolvers/sockaddr_resolver.c", - "src/core/client_config/resolvers/sockaddr_resolver.h", - "src/core/client_config/subchannel.c", - "src/core/client_config/subchannel.h", - "src/core/client_config/subchannel_factory.c", - "src/core/client_config/subchannel_factory.h", - "src/core/client_config/subchannel_index.c", - "src/core/client_config/subchannel_index.h", - "src/core/client_config/uri_parser.c", - "src/core/client_config/uri_parser.h", - "src/core/compression/algorithm_metadata.h", - "src/core/compression/compression_algorithm.c", - "src/core/compression/message_compress.c", - "src/core/compression/message_compress.h", - "src/core/debug/trace.c", - "src/core/debug/trace.h", - "src/core/http/format_request.c", - "src/core/http/format_request.h", - "src/core/http/httpcli.c", - "src/core/http/httpcli.h", - "src/core/http/parser.c", - "src/core/http/parser.h", - "src/core/iomgr/closure.c", - "src/core/iomgr/closure.h", - "src/core/iomgr/endpoint.c", - "src/core/iomgr/endpoint.h", - "src/core/iomgr/endpoint_pair.h", - "src/core/iomgr/endpoint_pair_posix.c", - "src/core/iomgr/endpoint_pair_windows.c", - "src/core/iomgr/exec_ctx.c", - "src/core/iomgr/exec_ctx.h", - "src/core/iomgr/executor.c", - "src/core/iomgr/executor.h", - "src/core/iomgr/fd_posix.c", - "src/core/iomgr/fd_posix.h", - "src/core/iomgr/iocp_windows.c", - "src/core/iomgr/iocp_windows.h", - "src/core/iomgr/iomgr.c", - "src/core/iomgr/iomgr.h", - "src/core/iomgr/iomgr_internal.h", - "src/core/iomgr/iomgr_posix.c", - "src/core/iomgr/iomgr_posix.h", - "src/core/iomgr/iomgr_windows.c", - "src/core/iomgr/pollset.h", - "src/core/iomgr/pollset_multipoller_with_epoll.c", - "src/core/iomgr/pollset_multipoller_with_poll_posix.c", - "src/core/iomgr/pollset_posix.c", - "src/core/iomgr/pollset_posix.h", - "src/core/iomgr/pollset_set.h", - "src/core/iomgr/pollset_set_posix.c", - "src/core/iomgr/pollset_set_posix.h", - "src/core/iomgr/pollset_set_windows.c", - "src/core/iomgr/pollset_set_windows.h", - "src/core/iomgr/pollset_windows.c", - "src/core/iomgr/pollset_windows.h", - "src/core/iomgr/resolve_address.h", - "src/core/iomgr/resolve_address_posix.c", - "src/core/iomgr/resolve_address_windows.c", - "src/core/iomgr/sockaddr.h", - "src/core/iomgr/sockaddr_posix.h", - "src/core/iomgr/sockaddr_utils.c", - "src/core/iomgr/sockaddr_utils.h", - "src/core/iomgr/sockaddr_win32.h", - "src/core/iomgr/socket_utils_common_posix.c", - "src/core/iomgr/socket_utils_linux.c", - "src/core/iomgr/socket_utils_posix.c", - "src/core/iomgr/socket_utils_posix.h", - "src/core/iomgr/socket_windows.c", - "src/core/iomgr/socket_windows.h", - "src/core/iomgr/tcp_client.h", - "src/core/iomgr/tcp_client_posix.c", - "src/core/iomgr/tcp_client_windows.c", - "src/core/iomgr/tcp_posix.c", - "src/core/iomgr/tcp_posix.h", - "src/core/iomgr/tcp_server.h", - "src/core/iomgr/tcp_server_posix.c", - "src/core/iomgr/tcp_server_windows.c", - "src/core/iomgr/tcp_windows.c", - "src/core/iomgr/tcp_windows.h", - "src/core/iomgr/time_averaged_stats.c", - "src/core/iomgr/time_averaged_stats.h", - "src/core/iomgr/timer.c", - "src/core/iomgr/timer.h", - "src/core/iomgr/timer_heap.c", - "src/core/iomgr/timer_heap.h", - "src/core/iomgr/udp_server.c", - "src/core/iomgr/udp_server.h", - "src/core/iomgr/unix_sockets_posix.c", - "src/core/iomgr/unix_sockets_posix.h", - "src/core/iomgr/unix_sockets_posix_noop.c", - "src/core/iomgr/wakeup_fd_eventfd.c", - "src/core/iomgr/wakeup_fd_nospecial.c", - "src/core/iomgr/wakeup_fd_pipe.c", - "src/core/iomgr/wakeup_fd_pipe.h", - "src/core/iomgr/wakeup_fd_posix.c", - "src/core/iomgr/wakeup_fd_posix.h", - "src/core/iomgr/workqueue.h", - "src/core/iomgr/workqueue_posix.c", - "src/core/iomgr/workqueue_posix.h", - "src/core/iomgr/workqueue_windows.c", - "src/core/iomgr/workqueue_windows.h", - "src/core/json/json.c", - "src/core/json/json.h", - "src/core/json/json_common.h", - "src/core/json/json_reader.c", - "src/core/json/json_reader.h", - "src/core/json/json_string.c", - "src/core/json/json_writer.c", - "src/core/json/json_writer.h", - "src/core/proto/grpc/lb/v0/load_balancer.pb.c", - "src/core/proto/grpc/lb/v0/load_balancer.pb.h", - "src/core/statistics/census_interface.h", - "src/core/statistics/census_rpc_stats.h", - "src/core/surface/alarm.c", - "src/core/surface/api_trace.c", - "src/core/surface/api_trace.h", - "src/core/surface/byte_buffer.c", - "src/core/surface/byte_buffer_reader.c", - "src/core/surface/call.c", - "src/core/surface/call.h", - "src/core/surface/call_details.c", - "src/core/surface/call_log_batch.c", - "src/core/surface/call_test_only.h", - "src/core/surface/channel.c", - "src/core/surface/channel.h", - "src/core/surface/channel_connectivity.c", - "src/core/surface/channel_create.c", - "src/core/surface/channel_init.c", - "src/core/surface/channel_init.h", - "src/core/surface/channel_ping.c", - "src/core/surface/channel_stack_type.c", - "src/core/surface/channel_stack_type.h", - "src/core/surface/completion_queue.c", - "src/core/surface/completion_queue.h", - "src/core/surface/event_string.c", - "src/core/surface/event_string.h", - "src/core/surface/init.c", - "src/core/surface/init.h", - "src/core/surface/init_unsecure.c", - "src/core/surface/lame_client.c", - "src/core/surface/lame_client.h", - "src/core/surface/metadata_array.c", - "src/core/surface/server.c", - "src/core/surface/server.h", - "src/core/surface/server_chttp2.c", - "src/core/surface/surface_trace.h", - "src/core/surface/validate_metadata.c", - "src/core/surface/version.c", - "src/core/transport/byte_stream.c", - "src/core/transport/byte_stream.h", - "src/core/transport/chttp2/alpn.c", - "src/core/transport/chttp2/alpn.h", - "src/core/transport/chttp2/bin_encoder.c", - "src/core/transport/chttp2/bin_encoder.h", - "src/core/transport/chttp2/frame.h", - "src/core/transport/chttp2/frame_data.c", - "src/core/transport/chttp2/frame_data.h", - "src/core/transport/chttp2/frame_goaway.c", - "src/core/transport/chttp2/frame_goaway.h", - "src/core/transport/chttp2/frame_ping.c", - "src/core/transport/chttp2/frame_ping.h", - "src/core/transport/chttp2/frame_rst_stream.c", - "src/core/transport/chttp2/frame_rst_stream.h", - "src/core/transport/chttp2/frame_settings.c", - "src/core/transport/chttp2/frame_settings.h", - "src/core/transport/chttp2/frame_window_update.c", - "src/core/transport/chttp2/frame_window_update.h", - "src/core/transport/chttp2/hpack_encoder.c", - "src/core/transport/chttp2/hpack_encoder.h", - "src/core/transport/chttp2/hpack_parser.c", - "src/core/transport/chttp2/hpack_parser.h", - "src/core/transport/chttp2/hpack_table.c", - "src/core/transport/chttp2/hpack_table.h", - "src/core/transport/chttp2/http2_errors.h", - "src/core/transport/chttp2/huffsyms.c", - "src/core/transport/chttp2/huffsyms.h", - "src/core/transport/chttp2/incoming_metadata.c", - "src/core/transport/chttp2/incoming_metadata.h", - "src/core/transport/chttp2/internal.h", - "src/core/transport/chttp2/parsing.c", - "src/core/transport/chttp2/status_conversion.c", - "src/core/transport/chttp2/status_conversion.h", - "src/core/transport/chttp2/stream_lists.c", - "src/core/transport/chttp2/stream_map.c", - "src/core/transport/chttp2/stream_map.h", - "src/core/transport/chttp2/timeout_encoding.c", - "src/core/transport/chttp2/timeout_encoding.h", - "src/core/transport/chttp2/varint.c", - "src/core/transport/chttp2/varint.h", - "src/core/transport/chttp2/writing.c", - "src/core/transport/chttp2_transport.c", - "src/core/transport/chttp2_transport.h", - "src/core/transport/connectivity_state.c", - "src/core/transport/connectivity_state.h", - "src/core/transport/metadata.c", - "src/core/transport/metadata.h", - "src/core/transport/metadata_batch.c", - "src/core/transport/metadata_batch.h", - "src/core/transport/static_metadata.c", - "src/core/transport/static_metadata.h", - "src/core/transport/transport.c", - "src/core/transport/transport.h", - "src/core/transport/transport_impl.h", - "src/core/transport/transport_op_string.c" + "src/core/lib/census/aggregation.h", + "src/core/lib/census/context.c", + "src/core/lib/census/grpc_context.c", + "src/core/lib/census/grpc_filter.c", + "src/core/lib/census/grpc_filter.h", + "src/core/lib/census/grpc_plugin.c", + "src/core/lib/census/grpc_plugin.h", + "src/core/lib/census/initialize.c", + "src/core/lib/census/mlog.c", + "src/core/lib/census/mlog.h", + "src/core/lib/census/operation.c", + "src/core/lib/census/placeholders.c", + "src/core/lib/census/rpc_metric_id.h", + "src/core/lib/census/tracing.c", + "src/core/lib/channel/channel_args.c", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.c", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.c", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/client_channel.c", + "src/core/lib/channel/client_channel.h", + "src/core/lib/channel/compress_filter.c", + "src/core/lib/channel/compress_filter.h", + "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/http_client_filter.c", + "src/core/lib/channel/http_client_filter.h", + "src/core/lib/channel/http_server_filter.c", + "src/core/lib/channel/http_server_filter.h", + "src/core/lib/channel/subchannel_call_holder.c", + "src/core/lib/channel/subchannel_call_holder.h", + "src/core/lib/client_config/client_config.c", + "src/core/lib/client_config/client_config.h", + "src/core/lib/client_config/connector.c", + "src/core/lib/client_config/connector.h", + "src/core/lib/client_config/default_initial_connect_string.c", + "src/core/lib/client_config/initial_connect_string.c", + "src/core/lib/client_config/initial_connect_string.h", + "src/core/lib/client_config/lb_policies/load_balancer_api.c", + "src/core/lib/client_config/lb_policies/load_balancer_api.h", + "src/core/lib/client_config/lb_policies/pick_first.c", + "src/core/lib/client_config/lb_policies/pick_first.h", + "src/core/lib/client_config/lb_policies/round_robin.c", + "src/core/lib/client_config/lb_policies/round_robin.h", + "src/core/lib/client_config/lb_policy.c", + "src/core/lib/client_config/lb_policy.h", + "src/core/lib/client_config/lb_policy_factory.c", + "src/core/lib/client_config/lb_policy_factory.h", + "src/core/lib/client_config/lb_policy_registry.c", + "src/core/lib/client_config/lb_policy_registry.h", + "src/core/lib/client_config/resolver.c", + "src/core/lib/client_config/resolver.h", + "src/core/lib/client_config/resolver_factory.c", + "src/core/lib/client_config/resolver_factory.h", + "src/core/lib/client_config/resolver_registry.c", + "src/core/lib/client_config/resolver_registry.h", + "src/core/lib/client_config/resolvers/dns_resolver.c", + "src/core/lib/client_config/resolvers/dns_resolver.h", + "src/core/lib/client_config/resolvers/sockaddr_resolver.c", + "src/core/lib/client_config/resolvers/sockaddr_resolver.h", + "src/core/lib/client_config/subchannel.c", + "src/core/lib/client_config/subchannel.h", + "src/core/lib/client_config/subchannel_factory.c", + "src/core/lib/client_config/subchannel_factory.h", + "src/core/lib/client_config/subchannel_index.c", + "src/core/lib/client_config/subchannel_index.h", + "src/core/lib/client_config/uri_parser.c", + "src/core/lib/client_config/uri_parser.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/compression_algorithm.c", + "src/core/lib/compression/message_compress.c", + "src/core/lib/compression/message_compress.h", + "src/core/lib/debug/trace.c", + "src/core/lib/debug/trace.h", + "src/core/lib/http/format_request.c", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.c", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/parser.c", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/closure.c", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/endpoint.c", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/endpoint_pair_posix.c", + "src/core/lib/iomgr/endpoint_pair_windows.c", + "src/core/lib/iomgr/exec_ctx.c", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.c", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/fd_posix.c", + "src/core/lib/iomgr/fd_posix.h", + "src/core/lib/iomgr/iocp_windows.c", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.c", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.c", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/iomgr_windows.c", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_multipoller_with_epoll.c", + "src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c", + "src/core/lib/iomgr/pollset_posix.c", + "src/core/lib/iomgr/pollset_posix.h", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_posix.c", + "src/core/lib/iomgr/pollset_set_posix.h", + "src/core/lib/iomgr/pollset_set_windows.c", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_windows.c", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/resolve_address_posix.c", + "src/core/lib/iomgr/resolve_address_windows.c", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_utils.c", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_win32.h", + "src/core/lib/iomgr/socket_utils_common_posix.c", + "src/core/lib/iomgr/socket_utils_linux.c", + "src/core/lib/iomgr/socket_utils_posix.c", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_windows.c", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_client_posix.c", + "src/core/lib/iomgr/tcp_client_windows.c", + "src/core/lib/iomgr/tcp_posix.c", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_server_posix.c", + "src/core/lib/iomgr/tcp_server_windows.c", + "src/core/lib/iomgr/tcp_windows.c", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.c", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.c", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_heap.c", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/udp_server.c", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.c", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_eventfd.c", + "src/core/lib/iomgr/wakeup_fd_nospecial.c", + "src/core/lib/iomgr/wakeup_fd_pipe.c", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.c", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/iomgr/workqueue.h", + "src/core/lib/iomgr/workqueue_posix.c", + "src/core/lib/iomgr/workqueue_posix.h", + "src/core/lib/iomgr/workqueue_windows.c", + "src/core/lib/iomgr/workqueue_windows.h", + "src/core/lib/json/json.c", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.c", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_string.c", + "src/core/lib/json/json_writer.c", + "src/core/lib/json/json_writer.h", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c", + "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h", + "src/core/lib/statistics/census_interface.h", + "src/core/lib/statistics/census_rpc_stats.h", + "src/core/lib/surface/alarm.c", + "src/core/lib/surface/api_trace.c", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/byte_buffer.c", + "src/core/lib/surface/byte_buffer_reader.c", + "src/core/lib/surface/call.c", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_details.c", + "src/core/lib/surface/call_log_batch.c", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.c", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_connectivity.c", + "src/core/lib/surface/channel_create.c", + "src/core/lib/surface/channel_init.c", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_ping.c", + "src/core/lib/surface/channel_stack_type.c", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.c", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/event_string.c", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.c", + "src/core/lib/surface/init.h", + "src/core/lib/surface/init_unsecure.c", + "src/core/lib/surface/lame_client.c", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/metadata_array.c", + "src/core/lib/surface/server.c", + "src/core/lib/surface/server.h", + "src/core/lib/surface/server_chttp2.c", + "src/core/lib/surface/surface_trace.h", + "src/core/lib/surface/validate_metadata.c", + "src/core/lib/surface/version.c", + "src/core/lib/transport/byte_stream.c", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/chttp2/alpn.c", + "src/core/lib/transport/chttp2/alpn.h", + "src/core/lib/transport/chttp2/bin_encoder.c", + "src/core/lib/transport/chttp2/bin_encoder.h", + "src/core/lib/transport/chttp2/frame.h", + "src/core/lib/transport/chttp2/frame_data.c", + "src/core/lib/transport/chttp2/frame_data.h", + "src/core/lib/transport/chttp2/frame_goaway.c", + "src/core/lib/transport/chttp2/frame_goaway.h", + "src/core/lib/transport/chttp2/frame_ping.c", + "src/core/lib/transport/chttp2/frame_ping.h", + "src/core/lib/transport/chttp2/frame_rst_stream.c", + "src/core/lib/transport/chttp2/frame_rst_stream.h", + "src/core/lib/transport/chttp2/frame_settings.c", + "src/core/lib/transport/chttp2/frame_settings.h", + "src/core/lib/transport/chttp2/frame_window_update.c", + "src/core/lib/transport/chttp2/frame_window_update.h", + "src/core/lib/transport/chttp2/hpack_encoder.c", + "src/core/lib/transport/chttp2/hpack_encoder.h", + "src/core/lib/transport/chttp2/hpack_parser.c", + "src/core/lib/transport/chttp2/hpack_parser.h", + "src/core/lib/transport/chttp2/hpack_table.c", + "src/core/lib/transport/chttp2/hpack_table.h", + "src/core/lib/transport/chttp2/http2_errors.h", + "src/core/lib/transport/chttp2/huffsyms.c", + "src/core/lib/transport/chttp2/huffsyms.h", + "src/core/lib/transport/chttp2/incoming_metadata.c", + "src/core/lib/transport/chttp2/incoming_metadata.h", + "src/core/lib/transport/chttp2/internal.h", + "src/core/lib/transport/chttp2/parsing.c", + "src/core/lib/transport/chttp2/status_conversion.c", + "src/core/lib/transport/chttp2/status_conversion.h", + "src/core/lib/transport/chttp2/stream_lists.c", + "src/core/lib/transport/chttp2/stream_map.c", + "src/core/lib/transport/chttp2/stream_map.h", + "src/core/lib/transport/chttp2/timeout_encoding.c", + "src/core/lib/transport/chttp2/timeout_encoding.h", + "src/core/lib/transport/chttp2/varint.c", + "src/core/lib/transport/chttp2/varint.h", + "src/core/lib/transport/chttp2/writing.c", + "src/core/lib/transport/chttp2_transport.c", + "src/core/lib/transport/chttp2_transport.h", + "src/core/lib/transport/connectivity_state.c", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/metadata.c", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.c", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/transport.c", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", + "src/core/lib/transport/transport_op_string.c" ], "third_party": false, "type": "lib" @@ -4970,14 +4970,14 @@ ], "headers": [ "include/grpc/grpc_zookeeper.h", - "src/core/client_config/resolvers/zookeeper_resolver.h" + "src/core/lib/client_config/resolvers/zookeeper_resolver.h" ], "language": "c", "name": "grpc_zookeeper", "src": [ "include/grpc/grpc_zookeeper.h", - "src/core/client_config/resolvers/zookeeper_resolver.c", - "src/core/client_config/resolvers/zookeeper_resolver.h" + "src/core/lib/client_config/resolvers/zookeeper_resolver.c", + "src/core/lib/client_config/resolvers/zookeeper_resolver.h" ], "third_party": false, "type": "lib" diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj index 9281fa3995..cdb128e48e 100644 --- a/vsprojects/vcxproj/gpr/gpr.vcxproj +++ b/vsprojects/vcxproj/gpr/gpr.vcxproj @@ -191,107 +191,107 @@ - - - - - - - - - - - - + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters index b85060f385..8af6fdd44c 100644 --- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters +++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters @@ -1,137 +1,137 @@ - - src\core\profiling + + src\core\lib\profiling - - src\core\profiling + + src\core\lib\profiling - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support @@ -263,41 +263,41 @@ - - src\core\profiling + + src\core\lib\profiling - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support - - src\core\support + + src\core\lib\support @@ -323,11 +323,14 @@ {c5e1baa7-de77-beb1-9675-942261648f79} - - {93b7086c-8c8a-6bbf-fb14-1f166bf0146a} + + {52037bcb-5719-a548-224d-834fbe569045} - - {bb116f2a-ea2a-c233-82da-0c54e3cbfec1} + + {ba38d79d-d5de-a89e-9ca2-c5235a03ca7f} + + + {a4812158-7fba-959e-4e09-50167fe38df8} diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index ebc3674360..b09abb28c4 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -282,470 +282,470 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index e5bff0e4f3..81136ebb93 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -1,488 +1,488 @@ - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config\lb_policies + + src\core\lib\client_config\lb_policies - - src\core\client_config\lb_policies + + src\core\lib\client_config\lb_policies - - src\core\client_config\lb_policies + + src\core\lib\client_config\lb_policies - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config\resolvers + + src\core\lib\client_config\resolvers - - src\core\client_config\resolvers + + src\core\lib\client_config\resolvers - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\compression + + src\core\lib\compression - - src\core\compression + + src\core\lib\compression - - src\core\debug + + src\core\lib\debug - - src\core\http + + src\core\lib\http - - src\core\http + + src\core\lib\http - - src\core\http + + src\core\lib\http - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\json + + src\core\lib\json - - src\core\json + + src\core\lib\json - - src\core\json + + src\core\lib\json - - src\core\json + + src\core\lib\json - - src\core\proto\grpc\lb\v0 + + src\core\lib\proto\grpc\lb\v0 - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\transport + + src\core\lib\transport - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\http + + src\core\lib\http - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\tsi + + src\core\lib\tsi - - src\core\tsi + + src\core\lib\tsi - - src\core\tsi + + src\core\lib\tsi - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census third_party\nanopb @@ -536,416 +536,416 @@ - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config\lb_policies + + src\core\lib\client_config\lb_policies - - src\core\client_config\lb_policies + + src\core\lib\client_config\lb_policies - - src\core\client_config\lb_policies + + src\core\lib\client_config\lb_policies - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config\resolvers + + src\core\lib\client_config\resolvers - - src\core\client_config\resolvers + + src\core\lib\client_config\resolvers - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\compression + + src\core\lib\compression - - src\core\compression + + src\core\lib\compression - - src\core\debug + + src\core\lib\debug - - src\core\http + + src\core\lib\http - - src\core\http + + src\core\lib\http - - src\core\http + + src\core\lib\http - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\json + + src\core\lib\json - - src\core\json + + src\core\lib\json - - src\core\json + + src\core\lib\json - - src\core\json + + src\core\lib\json - - src\core\proto\grpc\lb\v0 + + src\core\lib\proto\grpc\lb\v0 - - src\core\statistics + + src\core\lib\statistics - - src\core\statistics + + src\core\lib\statistics - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\transport + + src\core\lib\transport - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\security + + src\core\lib\security - - src\core\tsi + + src\core\lib\tsi - - src\core\tsi + + src\core\lib\tsi - - src\core\tsi + + src\core\lib\tsi - - src\core\tsi + + src\core\lib\tsi - - src\core\tsi + + src\core\lib\tsi - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census third_party\nanopb @@ -980,65 +980,68 @@ {ea745680-21ea-9c5e-679b-64dc40562d08} - - {fb3aefc2-8205-b0bf-525f-ab5e339f7f76} + + {5b2ded3f-84a5-f6b4-2060-286c7d1dc945} - - {d897b6c3-c555-234e-a589-b4f008063615} + + {f4108884-98c3-ac2e-c669-83cd41343975} - - {e71e6928-b1e3-0616-0961-1505370458ab} + + {1931b044-90f3-cd68-b5f8-23be77ca8efc} - - {a3eca4d5-f760-61a6-7251-556b828c8b44} + + {2f3260de-be57-d18d-6882-61d115baa159} - - {6d97b8d9-2c15-927a-892a-709d073c02ab} + + {118d2bb5-086f-54f3-11de-26d7d7f73f9d} - - {263cb913-dfe6-42a4-096b-cac231f76305} + + {b9d8db6c-2c68-1c90-fe5e-37da90f47ae6} - - {1da7ef8a-a06d-5499-b3de-19fee4a4214d} + + {dadf7fe9-3f15-d431-e4f6-f987b090536c} - - {404fdb9e-a69c-81d4-035b-465c826115a9} + + {19122742-9b92-5b67-9fb9-e552ac62ca5d} - - {1baf3894-af37-e647-bdbc-95dc17ed0073} + + {dab8f03a-73de-8cfa-88fb-6e04402efb54} - - {e665cc0e-b994-d7c5-cc18-2007392019f0} + + {5468ba38-b8a3-85b1-216f-48a2364e18df} - - {1ff04466-0905-8a5d-d6f4-7ff2df4c13b5} + + {cb2b0073-f2a7-5c63-d182-8874b24bdf36} - - {7c7ad0b3-bf85-5bd3-e0c8-4f5468a8e2e6} + + {b4b19f9a-1575-8a21-0bca-537746f858b7} - - {3d533dad-8100-e8a3-b7c3-1fc13a4d60da} + + {cbc8ce67-4a97-d533-8dc3-f949c63e2771} - - {0ffcf868-7617-5fed-b6ce-2162d9d09148} + + {933530ae-447b-ea8d-3531-98f0556960b0} - - {1d850ac6-e639-4eab-5338-4ba40272fcc9} + + {c33f944f-37d4-42fd-abc3-61f0d4400462} - - {0ef49896-2313-4a3f-1ce2-716fa0e5c6ca} + + {c4661d64-349f-01c1-1ba8-0602f9047595} - - {aeb18e82-5d25-0aad-8b02-a0a3470073ce} + + {4dc3c48b-e931-ed47-ffa2-b4ea3a7956ec} - - {168fa1b1-1c18-eb55-9a4d-746bc58df2c1} + + {a21971fb-304f-da08-b1b2-7bd8df8ac373} - - {b8b623c3-a168-a2b1-0d5f-b70a1f1cd8d2} + + {e9d0d3fc-c100-f3e6-89b8-649f241155bf} - - {0b0f9ab1-efa4-7f03-e446-6fb9b5227e84} + + {a47fedfc-b6c6-d588-14fc-6645d736bcd6} + + + {95ad2811-c8d0-7a42-2a73-baf03fcbf699} {aaab30a4-2a15-732e-c141-3fbc0f0f5a7a} diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index 4f2336aab2..0512501cfc 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -272,416 +272,416 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index e31ece741d..5309b18729 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -1,428 +1,428 @@ - - src\core\surface + + src\core\lib\surface - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config\lb_policies + + src\core\lib\client_config\lb_policies - - src\core\client_config\lb_policies + + src\core\lib\client_config\lb_policies - - src\core\client_config\lb_policies + + src\core\lib\client_config\lb_policies - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config\resolvers + + src\core\lib\client_config\resolvers - - src\core\client_config\resolvers + + src\core\lib\client_config\resolvers - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\compression + + src\core\lib\compression - - src\core\compression + + src\core\lib\compression - - src\core\debug + + src\core\lib\debug - - src\core\http + + src\core\lib\http - - src\core\http + + src\core\lib\http - - src\core\http + + src\core\lib\http - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\json + + src\core\lib\json - - src\core\json + + src\core\lib\json - - src\core\json + + src\core\lib\json - - src\core\json + + src\core\lib\json - - src\core\proto\grpc\lb\v0 + + src\core\lib\proto\grpc\lb\v0 - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\transport + + src\core\lib\transport - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census third_party\nanopb @@ -473,374 +473,374 @@ - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\channel + + src\core\lib\channel - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config\lb_policies + + src\core\lib\client_config\lb_policies - - src\core\client_config\lb_policies + + src\core\lib\client_config\lb_policies - - src\core\client_config\lb_policies + + src\core\lib\client_config\lb_policies - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config\resolvers + + src\core\lib\client_config\resolvers - - src\core\client_config\resolvers + + src\core\lib\client_config\resolvers - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\client_config + + src\core\lib\client_config - - src\core\compression + + src\core\lib\compression - - src\core\compression + + src\core\lib\compression - - src\core\debug + + src\core\lib\debug - - src\core\http + + src\core\lib\http - - src\core\http + + src\core\lib\http - - src\core\http + + src\core\lib\http - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\iomgr + + src\core\lib\iomgr - - src\core\json + + src\core\lib\json - - src\core\json + + src\core\lib\json - - src\core\json + + src\core\lib\json - - src\core\json + + src\core\lib\json - - src\core\proto\grpc\lb\v0 + + src\core\lib\proto\grpc\lb\v0 - - src\core\statistics + + src\core\lib\statistics - - src\core\statistics + + src\core\lib\statistics - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\surface + + src\core\lib\surface - - src\core\transport + + src\core\lib\transport - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport\chttp2 + + src\core\lib\transport\chttp2 - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\transport + + src\core\lib\transport - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census - - src\core\census + + src\core\lib\census third_party\nanopb @@ -875,59 +875,62 @@ {88491077-386b-2039-d14c-0c40136b5f7a} - - {a7596ee2-afee-3a82-7e6e-bd8b8f904e04} + + {8bd5b461-bff8-6aa8-b5a6-85da2834eb8a} - - {cc102c4b-66ff-cf4c-2288-d76327e1a183} + + {19582d5a-dab7-9dc1-c7e9-cc147fd52e5f} - - {02bd7340-02ee-4337-ffa5-0b6ecc7cf60c} + + {fb964f3d-a59c-a7ba-fee5-6072dbb94a7b} - - {308af086-46c7-fa66-9021-19b1c3d4a6bd} + + {29ca2974-89e4-1a74-3e4d-0d63e2f77566} - - {dd617c24-6f07-fdff-80d5-c8610d6f815e} + + {6c7e36d4-6117-e0cd-c886-b9eb3c994927} - - {2e3aca1d-223d-10a1-b282-7f9fc68ee6f5} + + {2d959ef9-9703-dc92-a56f-9fe136dadfb9} - - {6d8d5774-7291-554d-fafa-583463cd3fd9} + + {b88002e9-185e-4e64-49f5-2d8989ce87f6} - - {46faed8e-5cd4-98b0-05ed-ff2ac7bc2d46} + + {7f23789d-f18a-2a2d-60fe-a87dc656f539} - - {a9df8b24-ecea-ff6d-8999-d8fa54cd70bf} + + {748c8078-2027-8641-f485-1d4c66466e79} - - {443ffc61-1bea-2477-6e54-1ddf8c139264} + + {bb1a1cf2-6824-08f0-a9bd-3fafcaf13042} - - {7f4bb22a-65ba-0f8f-6387-66b1f6677a80} + + {681cdaeb-c47f-8853-d985-bf13c2873947} - - {9c2bd164-c317-8a13-564d-3b28b0fd79cf} + + {4bfbd6c6-f6a8-c6b3-5186-b788f4e11e23} - - {2bad8e10-4fc5-d8b3-e026-4abbd0c25cda} + + {60f3ab7d-ea44-348f-671e-77fdebbd18bb} - - {4475c8ed-e01b-8906-47d0-8a504189c0d5} + + {bcd33510-32e7-c2fb-e11d-a3655f97bc84} - - {e084164c-a069-00e3-db35-4e0b1cd6f0b7} + + {bb9b8c80-9eff-5ab6-5b29-c2d54f0fc192} - - {6cd0127e-c24b-d43c-38f5-198db8d4322a} + + {d0ab6d54-ae25-fc49-3656-91d9db57366a} - - {6687ff98-e36e-c0b1-2756-1bc79edec406} + + {506dc3b3-d884-2b59-0dfa-57ed6affa2d3} - - {5fcd6206-f774-9ae6-4b85-305d6a723843} + + {6c3394d1-27e9-003e-19ed-8116d210f7cc} + + + {212a6997-9b9c-3b47-d953-aaff34d608b1} {025c051e-8eba-125b-67f9-173f95176eb2} -- cgit v1.2.3 From 9a4dddd8b5d4ae968e5ddd52edbef7af92b7a440 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 25 Mar 2016 17:08:13 -0700 Subject: Fix include guards --- src/core/lib/census/aggregation.h | 6 +++--- src/core/lib/census/grpc_filter.h | 6 +++--- src/core/lib/census/grpc_plugin.h | 6 +++--- src/core/lib/census/mlog.h | 6 +++--- src/core/lib/census/rpc_metric_id.h | 6 +++--- src/core/lib/channel/channel_args.h | 6 +++--- src/core/lib/channel/channel_stack.h | 6 +++--- src/core/lib/channel/channel_stack_builder.h | 6 +++--- src/core/lib/channel/client_channel.h | 6 +++--- src/core/lib/channel/compress_filter.h | 6 +++--- src/core/lib/channel/connected_channel.h | 6 +++--- src/core/lib/channel/context.h | 6 +++--- src/core/lib/channel/http_client_filter.h | 6 +++--- src/core/lib/channel/http_server_filter.h | 6 +++--- src/core/lib/channel/subchannel_call_holder.h | 6 +++--- src/core/lib/client_config/client_config.h | 6 +++--- src/core/lib/client_config/connector.h | 6 +++--- src/core/lib/client_config/initial_connect_string.h | 6 +++--- src/core/lib/client_config/lb_policies/load_balancer_api.h | 6 +++--- src/core/lib/client_config/lb_policies/pick_first.h | 6 +++--- src/core/lib/client_config/lb_policies/round_robin.h | 6 +++--- src/core/lib/client_config/lb_policy.h | 6 +++--- src/core/lib/client_config/lb_policy_factory.h | 6 +++--- src/core/lib/client_config/lb_policy_registry.h | 6 +++--- src/core/lib/client_config/resolver.h | 6 +++--- src/core/lib/client_config/resolver_factory.h | 6 +++--- src/core/lib/client_config/resolver_registry.h | 6 +++--- src/core/lib/client_config/resolvers/dns_resolver.h | 6 +++--- src/core/lib/client_config/resolvers/sockaddr_resolver.h | 6 +++--- src/core/lib/client_config/resolvers/zookeeper_resolver.h | 6 +++--- src/core/lib/client_config/subchannel.h | 6 +++--- src/core/lib/client_config/subchannel_factory.h | 6 +++--- src/core/lib/client_config/subchannel_index.h | 6 +++--- src/core/lib/client_config/uri_parser.h | 6 +++--- src/core/lib/compression/algorithm_metadata.h | 6 +++--- src/core/lib/compression/message_compress.h | 6 +++--- src/core/lib/debug/trace.h | 6 +++--- src/core/lib/http/format_request.h | 6 +++--- src/core/lib/http/httpcli.h | 6 +++--- src/core/lib/http/parser.h | 6 +++--- src/core/lib/iomgr/closure.h | 6 +++--- src/core/lib/iomgr/endpoint.h | 6 +++--- src/core/lib/iomgr/endpoint_pair.h | 6 +++--- src/core/lib/iomgr/exec_ctx.h | 6 +++--- src/core/lib/iomgr/executor.h | 6 +++--- src/core/lib/iomgr/fd_posix.h | 6 +++--- src/core/lib/iomgr/iocp_windows.h | 6 +++--- src/core/lib/iomgr/iomgr.h | 6 +++--- src/core/lib/iomgr/iomgr_internal.h | 6 +++--- src/core/lib/iomgr/iomgr_posix.h | 6 +++--- src/core/lib/iomgr/pollset.h | 6 +++--- src/core/lib/iomgr/pollset_posix.h | 6 +++--- src/core/lib/iomgr/pollset_set.h | 6 +++--- src/core/lib/iomgr/pollset_set_posix.h | 6 +++--- src/core/lib/iomgr/pollset_set_windows.h | 6 +++--- src/core/lib/iomgr/pollset_windows.h | 6 +++--- src/core/lib/iomgr/resolve_address.h | 6 +++--- src/core/lib/iomgr/sockaddr.h | 6 +++--- src/core/lib/iomgr/sockaddr_posix.h | 6 +++--- src/core/lib/iomgr/sockaddr_utils.h | 6 +++--- src/core/lib/iomgr/sockaddr_win32.h | 6 +++--- src/core/lib/iomgr/socket_utils_posix.h | 6 +++--- src/core/lib/iomgr/socket_windows.h | 6 +++--- src/core/lib/iomgr/tcp_client.h | 6 +++--- src/core/lib/iomgr/tcp_posix.h | 6 +++--- src/core/lib/iomgr/tcp_server.h | 6 +++--- src/core/lib/iomgr/tcp_windows.h | 6 +++--- src/core/lib/iomgr/time_averaged_stats.h | 6 +++--- src/core/lib/iomgr/timer.h | 6 +++--- src/core/lib/iomgr/timer_heap.h | 6 +++--- src/core/lib/iomgr/udp_server.h | 6 +++--- src/core/lib/iomgr/unix_sockets_posix.h | 6 +++--- src/core/lib/iomgr/wakeup_fd_pipe.h | 6 +++--- src/core/lib/iomgr/wakeup_fd_posix.h | 6 +++--- src/core/lib/iomgr/workqueue.h | 6 +++--- src/core/lib/iomgr/workqueue_posix.h | 6 +++--- src/core/lib/iomgr/workqueue_windows.h | 6 +++--- src/core/lib/json/json.h | 6 +++--- src/core/lib/json/json_common.h | 6 +++--- src/core/lib/json/json_reader.h | 6 +++--- src/core/lib/json/json_writer.h | 6 +++--- src/core/lib/profiling/timers.h | 6 +++--- src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h | 6 +++--- src/core/lib/security/auth_filters.h | 6 +++--- src/core/lib/security/b64.h | 6 +++--- src/core/lib/security/credentials.h | 6 +++--- src/core/lib/security/handshake.h | 6 +++--- src/core/lib/security/json_token.h | 6 +++--- src/core/lib/security/jwt_verifier.h | 6 +++--- src/core/lib/security/secure_endpoint.h | 6 +++--- src/core/lib/security/security_connector.h | 6 +++--- src/core/lib/security/security_context.h | 6 +++--- src/core/lib/statistics/census_interface.h | 6 +++--- src/core/lib/statistics/census_log.h | 6 +++--- src/core/lib/statistics/census_rpc_stats.h | 6 +++--- src/core/lib/statistics/census_tracing.h | 6 +++--- src/core/lib/statistics/hash_table.h | 6 +++--- src/core/lib/statistics/window_stats.h | 6 +++--- src/core/lib/support/backoff.h | 6 +++--- src/core/lib/support/block_annotate.h | 6 +++--- src/core/lib/support/env.h | 6 +++--- src/core/lib/support/load_file.h | 6 +++--- src/core/lib/support/murmur_hash.h | 6 +++--- src/core/lib/support/stack_lockfree.h | 6 +++--- src/core/lib/support/string.h | 6 +++--- src/core/lib/support/string_win32.h | 6 +++--- src/core/lib/support/thd_internal.h | 6 +++--- src/core/lib/support/time_precise.h | 6 +++--- src/core/lib/support/tmpfile.h | 6 +++--- src/core/lib/surface/api_trace.h | 6 +++--- src/core/lib/surface/call.h | 6 +++--- src/core/lib/surface/call_test_only.h | 6 +++--- src/core/lib/surface/channel.h | 6 +++--- src/core/lib/surface/channel_init.h | 6 +++--- src/core/lib/surface/channel_stack_type.h | 6 +++--- src/core/lib/surface/completion_queue.h | 6 +++--- src/core/lib/surface/event_string.h | 6 +++--- src/core/lib/surface/init.h | 6 +++--- src/core/lib/surface/lame_client.h | 6 +++--- src/core/lib/surface/server.h | 6 +++--- src/core/lib/surface/surface_trace.h | 6 +++--- src/core/lib/transport/byte_stream.h | 6 +++--- src/core/lib/transport/chttp2/alpn.h | 6 +++--- src/core/lib/transport/chttp2/bin_encoder.h | 6 +++--- src/core/lib/transport/chttp2/frame.h | 6 +++--- src/core/lib/transport/chttp2/frame_data.h | 6 +++--- src/core/lib/transport/chttp2/frame_goaway.h | 6 +++--- src/core/lib/transport/chttp2/frame_ping.h | 6 +++--- src/core/lib/transport/chttp2/frame_rst_stream.h | 6 +++--- src/core/lib/transport/chttp2/frame_settings.h | 6 +++--- src/core/lib/transport/chttp2/frame_window_update.h | 6 +++--- src/core/lib/transport/chttp2/hpack_encoder.h | 6 +++--- src/core/lib/transport/chttp2/hpack_parser.h | 6 +++--- src/core/lib/transport/chttp2/hpack_table.h | 6 +++--- src/core/lib/transport/chttp2/http2_errors.h | 6 +++--- src/core/lib/transport/chttp2/huffsyms.h | 6 +++--- src/core/lib/transport/chttp2/incoming_metadata.h | 6 +++--- src/core/lib/transport/chttp2/internal.h | 6 +++--- src/core/lib/transport/chttp2/status_conversion.h | 6 +++--- src/core/lib/transport/chttp2/stream_map.h | 6 +++--- src/core/lib/transport/chttp2/timeout_encoding.h | 6 +++--- src/core/lib/transport/chttp2/varint.h | 6 +++--- src/core/lib/transport/chttp2_transport.h | 6 +++--- src/core/lib/transport/connectivity_state.h | 6 +++--- src/core/lib/transport/metadata.h | 6 +++--- src/core/lib/transport/metadata_batch.h | 6 +++--- src/core/lib/transport/static_metadata.h | 6 +++--- src/core/lib/transport/transport.h | 6 +++--- src/core/lib/transport/transport_impl.h | 6 +++--- src/core/lib/tsi/fake_transport_security.h | 6 +++--- src/core/lib/tsi/ssl_transport_security.h | 6 +++--- src/core/lib/tsi/ssl_types.h | 6 +++--- src/core/lib/tsi/transport_security.h | 6 +++--- src/core/lib/tsi/transport_security_interface.h | 6 +++--- 154 files changed, 462 insertions(+), 462 deletions(-) (limited to 'src') diff --git a/src/core/lib/census/aggregation.h b/src/core/lib/census/aggregation.h index e0ef9630c9..f353368b97 100644 --- a/src/core/lib/census/aggregation.h +++ b/src/core/lib/census/aggregation.h @@ -33,8 +33,8 @@ #include -#ifndef GRPC_CORE_CENSUS_AGGREGATION_H -#define GRPC_CORE_CENSUS_AGGREGATION_H +#ifndef GRPC_CORE_LIB_CENSUS_AGGREGATION_H +#define GRPC_CORE_LIB_CENSUS_AGGREGATION_H /** Structure used to describe an aggregation type. */ struct census_aggregation_ops { @@ -63,4 +63,4 @@ struct census_aggregation_ops { size_t (*print)(const void *aggregation, char *buffer, size_t n); }; -#endif /* GRPC_CORE_CENSUS_AGGREGATION_H */ +#endif /* GRPC_CORE_LIB_CENSUS_AGGREGATION_H */ diff --git a/src/core/lib/census/grpc_filter.h b/src/core/lib/census/grpc_filter.h index 4699e4d692..e71346b357 100644 --- a/src/core/lib/census/grpc_filter.h +++ b/src/core/lib/census/grpc_filter.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CENSUS_GRPC_FILTER_H -#define GRPC_CORE_CENSUS_GRPC_FILTER_H +#ifndef GRPC_CORE_LIB_CENSUS_GRPC_FILTER_H +#define GRPC_CORE_LIB_CENSUS_GRPC_FILTER_H #include "src/core/channel/channel_stack.h" @@ -41,4 +41,4 @@ extern const grpc_channel_filter grpc_client_census_filter; extern const grpc_channel_filter grpc_server_census_filter; -#endif /* GRPC_CORE_CENSUS_GRPC_FILTER_H */ +#endif /* GRPC_CORE_LIB_CENSUS_GRPC_FILTER_H */ diff --git a/src/core/lib/census/grpc_plugin.h b/src/core/lib/census/grpc_plugin.h index 9321c2c30f..33e5f0b701 100644 --- a/src/core/lib/census/grpc_plugin.h +++ b/src/core/lib/census/grpc_plugin.h @@ -31,10 +31,10 @@ * */ -#ifndef GRPC_CORE_CENSUS_GRPC_PLUGIN_H -#define GRPC_CORE_CENSUS_GRPC_PLUGIN_H +#ifndef GRPC_CORE_LIB_CENSUS_GRPC_PLUGIN_H +#define GRPC_CORE_LIB_CENSUS_GRPC_PLUGIN_H void census_grpc_plugin_init(void); void census_grpc_plugin_destroy(void); -#endif /* GRPC_CORE_CENSUS_GRPC_PLUGIN_H */ +#endif /* GRPC_CORE_LIB_CENSUS_GRPC_PLUGIN_H */ diff --git a/src/core/lib/census/mlog.h b/src/core/lib/census/mlog.h index bc6eaeaf28..7fbdeda986 100644 --- a/src/core/lib/census/mlog.h +++ b/src/core/lib/census/mlog.h @@ -33,8 +33,8 @@ /* A very fast in-memory log, optimized for multiple writers. */ -#ifndef GRPC_CORE_CENSUS_MLOG_H -#define GRPC_CORE_CENSUS_MLOG_H +#ifndef GRPC_CORE_LIB_CENSUS_MLOG_H +#define GRPC_CORE_LIB_CENSUS_MLOG_H #include #include @@ -92,4 +92,4 @@ size_t census_log_remaining_space(void); out-of-space. */ int64_t census_log_out_of_space_count(void); -#endif /* GRPC_CORE_CENSUS_MLOG_H */ +#endif /* GRPC_CORE_LIB_CENSUS_MLOG_H */ diff --git a/src/core/lib/census/rpc_metric_id.h b/src/core/lib/census/rpc_metric_id.h index f8d8dad0bf..aad0588fb3 100644 --- a/src/core/lib/census/rpc_metric_id.h +++ b/src/core/lib/census/rpc_metric_id.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CENSUS_RPC_METRIC_ID_H -#define GRPC_CORE_CENSUS_RPC_METRIC_ID_H +#ifndef GRPC_CORE_LIB_CENSUS_RPC_METRIC_ID_H +#define GRPC_CORE_LIB_CENSUS_RPC_METRIC_ID_H /* Metric ID's used for RPC measurements. */ /* Count of client requests sent. */ @@ -48,4 +48,4 @@ /* Server side request latency. */ #define CENSUS_METRIC_RPC_SERVER_LATENCY ((uint32_t)5) -#endif /* GRPC_CORE_CENSUS_RPC_METRIC_ID_H */ +#endif /* GRPC_CORE_LIB_CENSUS_RPC_METRIC_ID_H */ diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h index e19440f76f..67d287ec6b 100644 --- a/src/core/lib/channel/channel_args.h +++ b/src/core/lib/channel/channel_args.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CHANNEL_CHANNEL_ARGS_H -#define GRPC_CORE_CHANNEL_CHANNEL_ARGS_H +#ifndef GRPC_CORE_LIB_CHANNEL_CHANNEL_ARGS_H +#define GRPC_CORE_LIB_CHANNEL_CHANNEL_ARGS_H #include #include @@ -91,4 +91,4 @@ int grpc_channel_args_compression_algorithm_get_states( int grpc_channel_args_compare(const grpc_channel_args *a, const grpc_channel_args *b); -#endif /* GRPC_CORE_CHANNEL_CHANNEL_ARGS_H */ +#endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_ARGS_H */ diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 52362f0b20..d91a65cb70 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CHANNEL_CHANNEL_STACK_H -#define GRPC_CORE_CHANNEL_CHANNEL_STACK_H +#ifndef GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_H +#define GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_H /* A channel filter defines how operations on a channel are implemented. Channel filters are chained together to create full channels, and if those @@ -257,4 +257,4 @@ extern int grpc_trace_channel; #define GRPC_CALL_LOG_OP(sev, elem, op) \ if (grpc_trace_channel) grpc_call_log_op(sev, elem, op) -#endif /* GRPC_CORE_CHANNEL_CHANNEL_STACK_H */ +#endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_H */ diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h index 15f395e8b8..ca285a9b23 100644 --- a/src/core/lib/channel/channel_stack_builder.h +++ b/src/core/lib/channel/channel_stack_builder.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CHANNEL_CHANNEL_STACK_BUILDER_H -#define GRPC_CORE_CHANNEL_CHANNEL_STACK_BUILDER_H +#ifndef GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H +#define GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H #include @@ -152,4 +152,4 @@ void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder); extern int grpc_trace_channel_stack_builder; -#endif /* GRPC_CORE_CHANNEL_CHANNEL_STACK_BUILDER_H */ +#endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H */ diff --git a/src/core/lib/channel/client_channel.h b/src/core/lib/channel/client_channel.h index 422f7f8374..dacdd3bb69 100644 --- a/src/core/lib/channel/client_channel.h +++ b/src/core/lib/channel/client_channel.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CHANNEL_CLIENT_CHANNEL_H -#define GRPC_CORE_CHANNEL_CLIENT_CHANNEL_H +#ifndef GRPC_CORE_LIB_CHANNEL_CLIENT_CHANNEL_H +#define GRPC_CORE_LIB_CHANNEL_CLIENT_CHANNEL_H #include "src/core/channel/channel_stack.h" #include "src/core/client_config/resolver.h" @@ -60,4 +60,4 @@ void grpc_client_channel_watch_connectivity_state( grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset, grpc_connectivity_state *state, grpc_closure *on_complete); -#endif /* GRPC_CORE_CHANNEL_CLIENT_CHANNEL_H */ +#endif /* GRPC_CORE_LIB_CHANNEL_CLIENT_CHANNEL_H */ diff --git a/src/core/lib/channel/compress_filter.h b/src/core/lib/channel/compress_filter.h index 8c208ac799..73eb271731 100644 --- a/src/core/lib/channel/compress_filter.h +++ b/src/core/lib/channel/compress_filter.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CHANNEL_COMPRESS_FILTER_H -#define GRPC_CORE_CHANNEL_COMPRESS_FILTER_H +#ifndef GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H +#define GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H #include "src/core/channel/channel_stack.h" @@ -62,4 +62,4 @@ extern const grpc_channel_filter grpc_compress_filter; -#endif /* GRPC_CORE_CHANNEL_COMPRESS_FILTER_H */ +#endif /* GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H */ diff --git a/src/core/lib/channel/connected_channel.h b/src/core/lib/channel/connected_channel.h index 7c0c8359a4..971bc913bc 100644 --- a/src/core/lib/channel/connected_channel.h +++ b/src/core/lib/channel/connected_channel.h @@ -31,12 +31,12 @@ * */ -#ifndef GRPC_CORE_CHANNEL_CONNECTED_CHANNEL_H -#define GRPC_CORE_CHANNEL_CONNECTED_CHANNEL_H +#ifndef GRPC_CORE_LIB_CHANNEL_CONNECTED_CHANNEL_H +#define GRPC_CORE_LIB_CHANNEL_CONNECTED_CHANNEL_H #include "src/core/channel/channel_stack_builder.h" bool grpc_add_connected_filter(grpc_channel_stack_builder *builder, void *arg_must_be_null); -#endif /* GRPC_CORE_CHANNEL_CONNECTED_CHANNEL_H */ +#endif /* GRPC_CORE_LIB_CHANNEL_CONNECTED_CHANNEL_H */ diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h index db217dc133..bca102da9a 100644 --- a/src/core/lib/channel/context.h +++ b/src/core/lib/channel/context.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CHANNEL_CONTEXT_H -#define GRPC_CORE_CHANNEL_CONTEXT_H +#ifndef GRPC_CORE_LIB_CHANNEL_CONTEXT_H +#define GRPC_CORE_LIB_CHANNEL_CONTEXT_H /* Call object context pointers */ typedef enum { @@ -46,4 +46,4 @@ typedef struct { void (*destroy)(void *); } grpc_call_context_element; -#endif /* GRPC_CORE_CHANNEL_CONTEXT_H */ +#endif /* GRPC_CORE_LIB_CHANNEL_CONTEXT_H */ diff --git a/src/core/lib/channel/http_client_filter.h b/src/core/lib/channel/http_client_filter.h index 6f619bbf00..d2ccdda0a4 100644 --- a/src/core/lib/channel/http_client_filter.h +++ b/src/core/lib/channel/http_client_filter.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CHANNEL_HTTP_CLIENT_FILTER_H -#define GRPC_CORE_CHANNEL_HTTP_CLIENT_FILTER_H +#ifndef GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H +#define GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H #include "src/core/channel/channel_stack.h" @@ -41,4 +41,4 @@ extern const grpc_channel_filter grpc_http_client_filter; #define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme" -#endif /* GRPC_CORE_CHANNEL_HTTP_CLIENT_FILTER_H */ +#endif /* GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H */ diff --git a/src/core/lib/channel/http_server_filter.h b/src/core/lib/channel/http_server_filter.h index 528c8648fd..3e6f5782bc 100644 --- a/src/core/lib/channel/http_server_filter.h +++ b/src/core/lib/channel/http_server_filter.h @@ -31,12 +31,12 @@ * */ -#ifndef GRPC_CORE_CHANNEL_HTTP_SERVER_FILTER_H -#define GRPC_CORE_CHANNEL_HTTP_SERVER_FILTER_H +#ifndef GRPC_CORE_LIB_CHANNEL_HTTP_SERVER_FILTER_H +#define GRPC_CORE_LIB_CHANNEL_HTTP_SERVER_FILTER_H #include "src/core/channel/channel_stack.h" /* Processes metadata on the client side for HTTP2 transports */ extern const grpc_channel_filter grpc_http_server_filter; -#endif /* GRPC_CORE_CHANNEL_HTTP_SERVER_FILTER_H */ +#endif /* GRPC_CORE_LIB_CHANNEL_HTTP_SERVER_FILTER_H */ diff --git a/src/core/lib/channel/subchannel_call_holder.h b/src/core/lib/channel/subchannel_call_holder.h index 84b4657db4..17b4910ac5 100644 --- a/src/core/lib/channel/subchannel_call_holder.h +++ b/src/core/lib/channel/subchannel_call_holder.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CHANNEL_SUBCHANNEL_CALL_HOLDER_H -#define GRPC_CORE_CHANNEL_SUBCHANNEL_CALL_HOLDER_H +#ifndef GRPC_CORE_LIB_CHANNEL_SUBCHANNEL_CALL_HOLDER_H +#define GRPC_CORE_LIB_CHANNEL_SUBCHANNEL_CALL_HOLDER_H #include "src/core/client_config/subchannel.h" @@ -94,4 +94,4 @@ void grpc_subchannel_call_holder_perform_op(grpc_exec_ctx *exec_ctx, char *grpc_subchannel_call_holder_get_peer(grpc_exec_ctx *exec_ctx, grpc_subchannel_call_holder *holder); -#endif /* GRPC_CORE_CHANNEL_SUBCHANNEL_CALL_HOLDER_H */ +#endif /* GRPC_CORE_LIB_CHANNEL_SUBCHANNEL_CALL_HOLDER_H */ diff --git a/src/core/lib/client_config/client_config.h b/src/core/lib/client_config/client_config.h index 9b37fdc211..c2b5eb7bf3 100644 --- a/src/core/lib/client_config/client_config.h +++ b/src/core/lib/client_config/client_config.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H -#define GRPC_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_CLIENT_CONFIG_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_CLIENT_CONFIG_H #include "src/core/client_config/lb_policy.h" @@ -50,4 +50,4 @@ void grpc_client_config_set_lb_policy(grpc_client_config *client_config, grpc_lb_policy *grpc_client_config_get_lb_policy( grpc_client_config *client_config); -#endif /* GRPC_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_CLIENT_CONFIG_H */ diff --git a/src/core/lib/client_config/connector.h b/src/core/lib/client_config/connector.h index 93248fca4b..34a7c26bae 100644 --- a/src/core/lib/client_config/connector.h +++ b/src/core/lib/client_config/connector.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_CONNECTOR_H -#define GRPC_CORE_CLIENT_CONFIG_CONNECTOR_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_CONNECTOR_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_CONNECTOR_H #include "src/core/channel/channel_stack.h" #include "src/core/iomgr/sockaddr.h" @@ -89,4 +89,4 @@ void grpc_connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *connector, void grpc_connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *connector); -#endif /* GRPC_CORE_CLIENT_CONFIG_CONNECTOR_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_CONNECTOR_H */ diff --git a/src/core/lib/client_config/initial_connect_string.h b/src/core/lib/client_config/initial_connect_string.h index e6d2d8f8fe..ce8096a28a 100644 --- a/src/core/lib/client_config/initial_connect_string.h +++ b/src/core/lib/client_config/initial_connect_string.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H -#define GRPC_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H #include #include "src/core/iomgr/sockaddr.h" @@ -47,4 +47,4 @@ void grpc_test_set_initial_connect_string_function( void grpc_set_initial_connect_string(struct sockaddr **addr, size_t *addr_len, gpr_slice *connect_string); -#endif /* GRPC_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H */ diff --git a/src/core/lib/client_config/lb_policies/load_balancer_api.h b/src/core/lib/client_config/lb_policies/load_balancer_api.h index b7a4c9c8f5..b0ccfaff1f 100644 --- a/src/core/lib/client_config/lb_policies/load_balancer_api.h +++ b/src/core/lib/client_config/lb_policies/load_balancer_api.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H -#define GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H #include @@ -82,4 +82,4 @@ void grpc_grpclb_response_destroy(grpc_grpclb_response *response); } #endif -#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H */ diff --git a/src/core/lib/client_config/lb_policies/pick_first.h b/src/core/lib/client_config/lb_policies/pick_first.h index 3a3f195df5..141d354fd2 100644 --- a/src/core/lib/client_config/lb_policies/pick_first.h +++ b/src/core/lib/client_config/lb_policies/pick_first.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H -#define GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H #include "src/core/client_config/lb_policy_factory.h" @@ -40,4 +40,4 @@ * the first subchannel from \a subchannels to succesfully connect */ grpc_lb_policy_factory *grpc_pick_first_lb_factory_create(); -#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H */ diff --git a/src/core/lib/client_config/lb_policies/round_robin.h b/src/core/lib/client_config/lb_policies/round_robin.h index 7e6f1769e4..2f01147897 100644 --- a/src/core/lib/client_config/lb_policies/round_robin.h +++ b/src/core/lib/client_config/lb_policies/round_robin.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H -#define GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H #include "src/core/client_config/lb_policy.h" @@ -43,4 +43,4 @@ extern int grpc_lb_round_robin_trace; /** Returns a load balancing factory for the round robin policy */ grpc_lb_policy_factory *grpc_round_robin_lb_factory_create(); -#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H */ diff --git a/src/core/lib/client_config/lb_policy.h b/src/core/lib/client_config/lb_policy.h index ffebc2a69c..2ccd314d51 100644 --- a/src/core/lib/client_config/lb_policy.h +++ b/src/core/lib/client_config/lb_policy.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_LB_POLICY_H -#define GRPC_CORE_CLIENT_CONFIG_LB_POLICY_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_H #include "src/core/client_config/subchannel.h" #include "src/core/transport/connectivity_state.h" @@ -141,4 +141,4 @@ void grpc_lb_policy_notify_on_state_change(grpc_exec_ctx *exec_ctx, grpc_connectivity_state grpc_lb_policy_check_connectivity( grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); -#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICY_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_H */ diff --git a/src/core/lib/client_config/lb_policy_factory.h b/src/core/lib/client_config/lb_policy_factory.h index 842ba96098..41eabadefa 100644 --- a/src/core/lib/client_config/lb_policy_factory.h +++ b/src/core/lib/client_config/lb_policy_factory.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_LB_POLICY_FACTORY_H -#define GRPC_CORE_CLIENT_CONFIG_LB_POLICY_FACTORY_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_FACTORY_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_FACTORY_H #include "src/core/client_config/lb_policy.h" #include "src/core/client_config/subchannel.h" @@ -70,4 +70,4 @@ void grpc_lb_policy_factory_unref(grpc_lb_policy_factory *factory); grpc_lb_policy *grpc_lb_policy_factory_create_lb_policy( grpc_lb_policy_factory *factory, grpc_lb_policy_args *args); -#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICY_FACTORY_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_FACTORY_H */ diff --git a/src/core/lib/client_config/lb_policy_registry.h b/src/core/lib/client_config/lb_policy_registry.h index f3a08a3558..bc82371bbe 100644 --- a/src/core/lib/client_config/lb_policy_registry.h +++ b/src/core/lib/client_config/lb_policy_registry.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H -#define GRPC_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_REGISTRY_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_REGISTRY_H #include "src/core/client_config/lb_policy_factory.h" @@ -51,4 +51,4 @@ void grpc_register_lb_policy(grpc_lb_policy_factory *factory); grpc_lb_policy *grpc_lb_policy_create(const char *name, grpc_lb_policy_args *args); -#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_REGISTRY_H */ diff --git a/src/core/lib/client_config/resolver.h b/src/core/lib/client_config/resolver.h index 96f88fef84..358f73fa27 100644 --- a/src/core/lib/client_config/resolver.h +++ b/src/core/lib/client_config/resolver.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_RESOLVER_H -#define GRPC_CORE_CLIENT_CONFIG_RESOLVER_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_H #include "src/core/client_config/client_config.h" #include "src/core/client_config/subchannel.h" @@ -91,4 +91,4 @@ void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, grpc_client_config **target_config, grpc_closure *on_complete); -#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVER_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_H */ diff --git a/src/core/lib/client_config/resolver_factory.h b/src/core/lib/client_config/resolver_factory.h index 477f8db7f7..3d309c85f8 100644 --- a/src/core/lib/client_config/resolver_factory.h +++ b/src/core/lib/client_config/resolver_factory.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_RESOLVER_FACTORY_H -#define GRPC_CORE_CLIENT_CONFIG_RESOLVER_FACTORY_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_FACTORY_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_FACTORY_H #include "src/core/client_config/resolver.h" #include "src/core/client_config/subchannel_factory.h" @@ -79,4 +79,4 @@ grpc_resolver *grpc_resolver_factory_create_resolver( char *grpc_resolver_factory_get_default_authority( grpc_resolver_factory *factory, grpc_uri *uri); -#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVER_FACTORY_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_FACTORY_H */ diff --git a/src/core/lib/client_config/resolver_registry.h b/src/core/lib/client_config/resolver_registry.h index 1e4cebee0b..72db20bf00 100644 --- a/src/core/lib/client_config/resolver_registry.h +++ b/src/core/lib/client_config/resolver_registry.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H -#define GRPC_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_REGISTRY_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_REGISTRY_H #include "src/core/client_config/resolver_factory.h" @@ -62,4 +62,4 @@ grpc_resolver *grpc_resolver_create( representing the default authority to pass from a client. */ char *grpc_get_default_authority(const char *target); -#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_REGISTRY_H */ diff --git a/src/core/lib/client_config/resolvers/dns_resolver.h b/src/core/lib/client_config/resolvers/dns_resolver.h index b24280b507..7dada84278 100644 --- a/src/core/lib/client_config/resolvers/dns_resolver.h +++ b/src/core/lib/client_config/resolvers/dns_resolver.h @@ -31,12 +31,12 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H -#define GRPC_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H #include "src/core/client_config/resolver_factory.h" /** Create a dns resolver factory */ grpc_resolver_factory *grpc_dns_resolver_factory_create(void); -#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H */ diff --git a/src/core/lib/client_config/resolvers/sockaddr_resolver.h b/src/core/lib/client_config/resolvers/sockaddr_resolver.h index f050329431..3bbcf1dd81 100644 --- a/src/core/lib/client_config/resolvers/sockaddr_resolver.h +++ b/src/core/lib/client_config/resolvers/sockaddr_resolver.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H -#define GRPC_CORE_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H #include @@ -47,4 +47,4 @@ grpc_resolver_factory *grpc_ipv6_resolver_factory_create(void); grpc_resolver_factory *grpc_unix_resolver_factory_create(void); #endif -#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H */ diff --git a/src/core/lib/client_config/resolvers/zookeeper_resolver.h b/src/core/lib/client_config/resolvers/zookeeper_resolver.h index 04bd3ca875..603097e5f8 100644 --- a/src/core/lib/client_config/resolvers/zookeeper_resolver.h +++ b/src/core/lib/client_config/resolvers/zookeeper_resolver.h @@ -31,12 +31,12 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H -#define GRPC_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H #include "src/core/client_config/resolver_factory.h" /** Create a zookeeper resolver factory */ grpc_resolver_factory *grpc_zookeeper_resolver_factory_create(void); -#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H */ diff --git a/src/core/lib/client_config/subchannel.h b/src/core/lib/client_config/subchannel.h index 83e1c58a4c..a8fcbe7b0e 100644 --- a/src/core/lib/client_config/subchannel.h +++ b/src/core/lib/client_config/subchannel.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_H -#define GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_H #include "src/core/channel/channel_stack.h" #include "src/core/client_config/connector.h" @@ -171,4 +171,4 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx, grpc_connector *connector, grpc_subchannel_args *args); -#endif /* GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_H */ diff --git a/src/core/lib/client_config/subchannel_factory.h b/src/core/lib/client_config/subchannel_factory.h index c638f377a6..1017b13fcd 100644 --- a/src/core/lib/client_config/subchannel_factory.h +++ b/src/core/lib/client_config/subchannel_factory.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H -#define GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H #include "src/core/channel/channel_stack.h" #include "src/core/client_config/subchannel.h" @@ -63,4 +63,4 @@ grpc_subchannel *grpc_subchannel_factory_create_subchannel( grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory, grpc_subchannel_args *args); -#endif /* GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H */ diff --git a/src/core/lib/client_config/subchannel_index.h b/src/core/lib/client_config/subchannel_index.h index 3cd5d12349..f5627dfaf7 100644 --- a/src/core/lib/client_config/subchannel_index.h +++ b/src/core/lib/client_config/subchannel_index.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H -#define GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_INDEX_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_INDEX_H #include "src/core/client_config/connector.h" #include "src/core/client_config/subchannel.h" @@ -74,4 +74,4 @@ void grpc_subchannel_index_init(void); /** Shutdown the subchannel index (global) */ void grpc_subchannel_index_shutdown(void); -#endif /* GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_INDEX_H */ diff --git a/src/core/lib/client_config/uri_parser.h b/src/core/lib/client_config/uri_parser.h index af013d8cac..d70d451e60 100644 --- a/src/core/lib/client_config/uri_parser.h +++ b/src/core/lib/client_config/uri_parser.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_CLIENT_CONFIG_URI_PARSER_H -#define GRPC_CORE_CLIENT_CONFIG_URI_PARSER_H +#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_URI_PARSER_H +#define GRPC_CORE_LIB_CLIENT_CONFIG_URI_PARSER_H typedef struct { char *scheme; @@ -48,4 +48,4 @@ grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors); /** destroy a uri */ void grpc_uri_destroy(grpc_uri *uri); -#endif /* GRPC_CORE_CLIENT_CONFIG_URI_PARSER_H */ +#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_URI_PARSER_H */ diff --git a/src/core/lib/compression/algorithm_metadata.h b/src/core/lib/compression/algorithm_metadata.h index 34abf1dba2..6ebde1e8fd 100644 --- a/src/core/lib/compression/algorithm_metadata.h +++ b/src/core/lib/compression/algorithm_metadata.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_COMPRESSION_ALGORITHM_METADATA_H -#define GRPC_CORE_COMPRESSION_ALGORITHM_METADATA_H +#ifndef GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H +#define GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H #include #include "src/core/transport/metadata.h" @@ -50,4 +50,4 @@ grpc_mdelem *grpc_compression_encoding_mdelem( grpc_compression_algorithm grpc_compression_algorithm_from_mdstr( grpc_mdstr *str); -#endif /* GRPC_CORE_COMPRESSION_ALGORITHM_METADATA_H */ +#endif /* GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H */ diff --git a/src/core/lib/compression/message_compress.h b/src/core/lib/compression/message_compress.h index 20b78c063b..b71608139e 100644 --- a/src/core/lib/compression/message_compress.h +++ b/src/core/lib/compression/message_compress.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_COMPRESSION_MESSAGE_COMPRESS_H -#define GRPC_CORE_COMPRESSION_MESSAGE_COMPRESS_H +#ifndef GRPC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H +#define GRPC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H #include #include @@ -49,4 +49,4 @@ int grpc_msg_compress(grpc_compression_algorithm algorithm, int grpc_msg_decompress(grpc_compression_algorithm algorithm, gpr_slice_buffer* input, gpr_slice_buffer* output); -#endif /* GRPC_CORE_COMPRESSION_MESSAGE_COMPRESS_H */ +#endif /* GRPC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H */ diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h index 91ec14052e..76ea5a7c64 100644 --- a/src/core/lib/debug/trace.h +++ b/src/core/lib/debug/trace.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_DEBUG_TRACE_H -#define GRPC_CORE_DEBUG_TRACE_H +#ifndef GRPC_CORE_LIB_DEBUG_TRACE_H +#define GRPC_CORE_LIB_DEBUG_TRACE_H #include @@ -40,4 +40,4 @@ void grpc_register_tracer(const char *name, int *flag); void grpc_tracer_init(const char *env_var_name); void grpc_tracer_shutdown(void); -#endif /* GRPC_CORE_DEBUG_TRACE_H */ +#endif /* GRPC_CORE_LIB_DEBUG_TRACE_H */ diff --git a/src/core/lib/http/format_request.h b/src/core/lib/http/format_request.h index dfd6fadbde..eb8e3267b6 100644 --- a/src/core/lib/http/format_request.h +++ b/src/core/lib/http/format_request.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_HTTP_FORMAT_REQUEST_H -#define GRPC_CORE_HTTP_FORMAT_REQUEST_H +#ifndef GRPC_CORE_LIB_HTTP_FORMAT_REQUEST_H +#define GRPC_CORE_LIB_HTTP_FORMAT_REQUEST_H #include #include "src/core/http/httpcli.h" @@ -42,4 +42,4 @@ gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, const char *body_bytes, size_t body_size); -#endif /* GRPC_CORE_HTTP_FORMAT_REQUEST_H */ +#endif /* GRPC_CORE_LIB_HTTP_FORMAT_REQUEST_H */ diff --git a/src/core/lib/http/httpcli.h b/src/core/lib/http/httpcli.h index 0bf4f2f445..f28d6d7481 100644 --- a/src/core/lib/http/httpcli.h +++ b/src/core/lib/http/httpcli.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_HTTP_HTTPCLI_H -#define GRPC_CORE_HTTP_HTTPCLI_H +#ifndef GRPC_CORE_LIB_HTTP_HTTPCLI_H +#define GRPC_CORE_LIB_HTTP_HTTPCLI_H #include @@ -141,4 +141,4 @@ typedef int (*grpc_httpcli_post_override)( void grpc_httpcli_set_override(grpc_httpcli_get_override get, grpc_httpcli_post_override post); -#endif /* GRPC_CORE_HTTP_HTTPCLI_H */ +#endif /* GRPC_CORE_LIB_HTTP_HTTPCLI_H */ diff --git a/src/core/lib/http/parser.h b/src/core/lib/http/parser.h index 39517e485a..6a72174aa6 100644 --- a/src/core/lib/http/parser.h +++ b/src/core/lib/http/parser.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_HTTP_PARSER_H -#define GRPC_CORE_HTTP_PARSER_H +#ifndef GRPC_CORE_LIB_HTTP_PARSER_H +#define GRPC_CORE_LIB_HTTP_PARSER_H #include #include @@ -113,4 +113,4 @@ void grpc_http_parser_destroy(grpc_http_parser *parser); int grpc_http_parser_parse(grpc_http_parser *parser, gpr_slice slice); int grpc_http_parser_eof(grpc_http_parser *parser); -#endif /* GRPC_CORE_HTTP_PARSER_H */ +#endif /* GRPC_CORE_LIB_HTTP_PARSER_H */ diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h index d5e1f455b9..2597cf1706 100644 --- a/src/core/lib/iomgr/closure.h +++ b/src/core/lib/iomgr/closure.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_CLOSURE_H -#define GRPC_CORE_IOMGR_CLOSURE_H +#ifndef GRPC_CORE_LIB_IOMGR_CLOSURE_H +#define GRPC_CORE_LIB_IOMGR_CLOSURE_H #include #include @@ -95,4 +95,4 @@ bool grpc_closure_list_empty(grpc_closure_list list); /** return the next pointer for a queued closure list */ grpc_closure *grpc_closure_next(grpc_closure *closure); -#endif /* GRPC_CORE_IOMGR_CLOSURE_H */ +#endif /* GRPC_CORE_LIB_IOMGR_CLOSURE_H */ diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h index b4be852e33..740ec50c6a 100644 --- a/src/core/lib/iomgr/endpoint.h +++ b/src/core/lib/iomgr/endpoint.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_ENDPOINT_H -#define GRPC_CORE_IOMGR_ENDPOINT_H +#ifndef GRPC_CORE_LIB_IOMGR_ENDPOINT_H +#define GRPC_CORE_LIB_IOMGR_ENDPOINT_H #include #include @@ -99,4 +99,4 @@ struct grpc_endpoint { const grpc_endpoint_vtable *vtable; }; -#endif /* GRPC_CORE_IOMGR_ENDPOINT_H */ +#endif /* GRPC_CORE_LIB_IOMGR_ENDPOINT_H */ diff --git a/src/core/lib/iomgr/endpoint_pair.h b/src/core/lib/iomgr/endpoint_pair.h index 59015d8ffb..39af04c9df 100644 --- a/src/core/lib/iomgr/endpoint_pair.h +++ b/src/core/lib/iomgr/endpoint_pair.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_ENDPOINT_PAIR_H -#define GRPC_CORE_IOMGR_ENDPOINT_PAIR_H +#ifndef GRPC_CORE_LIB_IOMGR_ENDPOINT_PAIR_H +#define GRPC_CORE_LIB_IOMGR_ENDPOINT_PAIR_H #include "src/core/iomgr/endpoint.h" @@ -44,4 +44,4 @@ typedef struct { grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name, size_t read_slice_size); -#endif /* GRPC_CORE_IOMGR_ENDPOINT_PAIR_H */ +#endif /* GRPC_CORE_LIB_IOMGR_ENDPOINT_PAIR_H */ diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index 07b54a0ab8..a6551cf1d4 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_EXEC_CTX_H -#define GRPC_CORE_IOMGR_EXEC_CTX_H +#ifndef GRPC_CORE_LIB_IOMGR_EXEC_CTX_H +#define GRPC_CORE_LIB_IOMGR_EXEC_CTX_H #include "src/core/iomgr/closure.h" @@ -95,4 +95,4 @@ void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx, void grpc_exec_ctx_global_init(void); void grpc_exec_ctx_global_shutdown(void); -#endif /* GRPC_CORE_IOMGR_EXEC_CTX_H */ +#endif /* GRPC_CORE_LIB_IOMGR_EXEC_CTX_H */ diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h index f66b3560e3..7197c3f24a 100644 --- a/src/core/lib/iomgr/executor.h +++ b/src/core/lib/iomgr/executor.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_EXECUTOR_H -#define GRPC_CORE_IOMGR_EXECUTOR_H +#ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_H +#define GRPC_CORE_LIB_IOMGR_EXECUTOR_H #include "src/core/iomgr/closure.h" @@ -50,4 +50,4 @@ void grpc_executor_enqueue(grpc_closure *closure, bool success); /** Shutdown the executor, running all pending work as part of the call */ void grpc_executor_shutdown(); -#endif /* GRPC_CORE_IOMGR_EXECUTOR_H */ +#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */ diff --git a/src/core/lib/iomgr/fd_posix.h b/src/core/lib/iomgr/fd_posix.h index 1993ada79f..a14c39f722 100644 --- a/src/core/lib/iomgr/fd_posix.h +++ b/src/core/lib/iomgr/fd_posix.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_FD_POSIX_H -#define GRPC_CORE_IOMGR_FD_POSIX_H +#ifndef GRPC_CORE_LIB_IOMGR_FD_POSIX_H +#define GRPC_CORE_LIB_IOMGR_FD_POSIX_H #include #include @@ -189,4 +189,4 @@ void grpc_fd_unref(grpc_fd *fd); void grpc_fd_global_init(void); void grpc_fd_global_shutdown(void); -#endif /* GRPC_CORE_IOMGR_FD_POSIX_H */ +#endif /* GRPC_CORE_LIB_IOMGR_FD_POSIX_H */ diff --git a/src/core/lib/iomgr/iocp_windows.h b/src/core/lib/iomgr/iocp_windows.h index 570b8925aa..9444dd4fce 100644 --- a/src/core/lib/iomgr/iocp_windows.h +++ b/src/core/lib/iomgr/iocp_windows.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_IOCP_WINDOWS_H -#define GRPC_CORE_IOMGR_IOCP_WINDOWS_H +#ifndef GRPC_CORE_LIB_IOMGR_IOCP_WINDOWS_H +#define GRPC_CORE_LIB_IOMGR_IOCP_WINDOWS_H #include @@ -60,4 +60,4 @@ void grpc_socket_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_winsocket *winsocket, grpc_closure *closure); -#endif /* GRPC_CORE_IOMGR_IOCP_WINDOWS_H */ +#endif /* GRPC_CORE_LIB_IOMGR_IOCP_WINDOWS_H */ diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h index e1237a4533..babf0a85b7 100644 --- a/src/core/lib/iomgr/iomgr.h +++ b/src/core/lib/iomgr/iomgr.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_IOMGR_H -#define GRPC_CORE_IOMGR_IOMGR_H +#ifndef GRPC_CORE_LIB_IOMGR_IOMGR_H +#define GRPC_CORE_LIB_IOMGR_IOMGR_H /** Initializes the iomgr. */ void grpc_iomgr_init(void); @@ -40,4 +40,4 @@ void grpc_iomgr_init(void); /** Signals the intention to shutdown the iomgr. */ void grpc_iomgr_shutdown(void); -#endif /* GRPC_CORE_IOMGR_IOMGR_H */ +#endif /* GRPC_CORE_LIB_IOMGR_IOMGR_H */ diff --git a/src/core/lib/iomgr/iomgr_internal.h b/src/core/lib/iomgr/iomgr_internal.h index 1cad3182ec..2aeee7f6ae 100644 --- a/src/core/lib/iomgr/iomgr_internal.h +++ b/src/core/lib/iomgr/iomgr_internal.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_IOMGR_INTERNAL_H -#define GRPC_CORE_IOMGR_IOMGR_INTERNAL_H +#ifndef GRPC_CORE_LIB_IOMGR_IOMGR_INTERNAL_H +#define GRPC_CORE_LIB_IOMGR_IOMGR_INTERNAL_H #include @@ -59,4 +59,4 @@ void grpc_iomgr_platform_shutdown(void); bool grpc_iomgr_abort_on_leaks(void); -#endif /* GRPC_CORE_IOMGR_IOMGR_INTERNAL_H */ +#endif /* GRPC_CORE_LIB_IOMGR_IOMGR_INTERNAL_H */ diff --git a/src/core/lib/iomgr/iomgr_posix.h b/src/core/lib/iomgr/iomgr_posix.h index 698fb6aee7..83fb082665 100644 --- a/src/core/lib/iomgr/iomgr_posix.h +++ b/src/core/lib/iomgr/iomgr_posix.h @@ -31,9 +31,9 @@ * */ -#ifndef GRPC_CORE_IOMGR_IOMGR_POSIX_H -#define GRPC_CORE_IOMGR_IOMGR_POSIX_H +#ifndef GRPC_CORE_LIB_IOMGR_IOMGR_POSIX_H +#define GRPC_CORE_LIB_IOMGR_IOMGR_POSIX_H #include "src/core/iomgr/iomgr_internal.h" -#endif /* GRPC_CORE_IOMGR_IOMGR_POSIX_H */ +#endif /* GRPC_CORE_LIB_IOMGR_IOMGR_POSIX_H */ diff --git a/src/core/lib/iomgr/pollset.h b/src/core/lib/iomgr/pollset.h index 9500b1a73a..db13f8ac69 100644 --- a/src/core/lib/iomgr/pollset.h +++ b/src/core/lib/iomgr/pollset.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_POLLSET_H -#define GRPC_CORE_IOMGR_POLLSET_H +#ifndef GRPC_CORE_LIB_IOMGR_POLLSET_H +#define GRPC_CORE_LIB_IOMGR_POLLSET_H #include #include @@ -91,4 +91,4 @@ void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, void grpc_pollset_kick(grpc_pollset *pollset, grpc_pollset_worker *specific_worker); -#endif /* GRPC_CORE_IOMGR_POLLSET_H */ +#endif /* GRPC_CORE_LIB_IOMGR_POLLSET_H */ diff --git a/src/core/lib/iomgr/pollset_posix.h b/src/core/lib/iomgr/pollset_posix.h index e0cfc44395..c4d1977a0b 100644 --- a/src/core/lib/iomgr/pollset_posix.h +++ b/src/core/lib/iomgr/pollset_posix.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_POLLSET_POSIX_H -#define GRPC_CORE_IOMGR_POLLSET_POSIX_H +#ifndef GRPC_CORE_LIB_IOMGR_POLLSET_POSIX_H +#define GRPC_CORE_LIB_IOMGR_POLLSET_POSIX_H #include @@ -150,4 +150,4 @@ typedef int (*grpc_poll_function_type)(struct pollfd *, nfds_t, int); extern grpc_poll_function_type grpc_poll_function; extern grpc_wakeup_fd grpc_global_wakeup_fd; -#endif /* GRPC_CORE_IOMGR_POLLSET_POSIX_H */ +#endif /* GRPC_CORE_LIB_IOMGR_POLLSET_POSIX_H */ diff --git a/src/core/lib/iomgr/pollset_set.h b/src/core/lib/iomgr/pollset_set.h index 204c625933..7af72a0297 100644 --- a/src/core/lib/iomgr/pollset_set.h +++ b/src/core/lib/iomgr/pollset_set.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_POLLSET_SET_H -#define GRPC_CORE_IOMGR_POLLSET_SET_H +#ifndef GRPC_CORE_LIB_IOMGR_POLLSET_SET_H +#define GRPC_CORE_LIB_IOMGR_POLLSET_SET_H #include "src/core/iomgr/pollset.h" @@ -58,4 +58,4 @@ void grpc_pollset_set_del_pollset_set(grpc_exec_ctx *exec_ctx, grpc_pollset_set *bag, grpc_pollset_set *item); -#endif /* GRPC_CORE_IOMGR_POLLSET_SET_H */ +#endif /* GRPC_CORE_LIB_IOMGR_POLLSET_SET_H */ diff --git a/src/core/lib/iomgr/pollset_set_posix.h b/src/core/lib/iomgr/pollset_set_posix.h index 80f487718e..db997e1bf0 100644 --- a/src/core/lib/iomgr/pollset_set_posix.h +++ b/src/core/lib/iomgr/pollset_set_posix.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_POLLSET_SET_POSIX_H -#define GRPC_CORE_IOMGR_POLLSET_SET_POSIX_H +#ifndef GRPC_CORE_LIB_IOMGR_POLLSET_SET_POSIX_H +#define GRPC_CORE_LIB_IOMGR_POLLSET_SET_POSIX_H #include "src/core/iomgr/fd_posix.h" #include "src/core/iomgr/pollset_set.h" @@ -42,4 +42,4 @@ void grpc_pollset_set_add_fd(grpc_exec_ctx *exec_ctx, void grpc_pollset_set_del_fd(grpc_exec_ctx *exec_ctx, grpc_pollset_set *pollset_set, grpc_fd *fd); -#endif /* GRPC_CORE_IOMGR_POLLSET_SET_POSIX_H */ +#endif /* GRPC_CORE_LIB_IOMGR_POLLSET_SET_POSIX_H */ diff --git a/src/core/lib/iomgr/pollset_set_windows.h b/src/core/lib/iomgr/pollset_set_windows.h index 0f040fef82..f0b37f8d21 100644 --- a/src/core/lib/iomgr/pollset_set_windows.h +++ b/src/core/lib/iomgr/pollset_set_windows.h @@ -31,9 +31,9 @@ * */ -#ifndef GRPC_CORE_IOMGR_POLLSET_SET_WINDOWS_H -#define GRPC_CORE_IOMGR_POLLSET_SET_WINDOWS_H +#ifndef GRPC_CORE_LIB_IOMGR_POLLSET_SET_WINDOWS_H +#define GRPC_CORE_LIB_IOMGR_POLLSET_SET_WINDOWS_H #include "src/core/iomgr/pollset_set.h" -#endif /* GRPC_CORE_IOMGR_POLLSET_SET_WINDOWS_H */ +#endif /* GRPC_CORE_LIB_IOMGR_POLLSET_SET_WINDOWS_H */ diff --git a/src/core/lib/iomgr/pollset_windows.h b/src/core/lib/iomgr/pollset_windows.h index f1d1585922..ff8e0a7b46 100644 --- a/src/core/lib/iomgr/pollset_windows.h +++ b/src/core/lib/iomgr/pollset_windows.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_POLLSET_WINDOWS_H -#define GRPC_CORE_IOMGR_POLLSET_WINDOWS_H +#ifndef GRPC_CORE_LIB_IOMGR_POLLSET_WINDOWS_H +#define GRPC_CORE_LIB_IOMGR_POLLSET_WINDOWS_H #include @@ -72,4 +72,4 @@ struct grpc_pollset { grpc_closure *on_shutdown; }; -#endif /* GRPC_CORE_IOMGR_POLLSET_WINDOWS_H */ +#endif /* GRPC_CORE_LIB_IOMGR_POLLSET_WINDOWS_H */ diff --git a/src/core/lib/iomgr/resolve_address.h b/src/core/lib/iomgr/resolve_address.h index aa0d7d194b..d3da7cc33e 100644 --- a/src/core/lib/iomgr/resolve_address.h +++ b/src/core/lib/iomgr/resolve_address.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_RESOLVE_ADDRESS_H -#define GRPC_CORE_IOMGR_RESOLVE_ADDRESS_H +#ifndef GRPC_CORE_LIB_IOMGR_RESOLVE_ADDRESS_H +#define GRPC_CORE_LIB_IOMGR_RESOLVE_ADDRESS_H #include #include "src/core/iomgr/exec_ctx.h" @@ -69,4 +69,4 @@ void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addresses); extern grpc_resolved_addresses *(*grpc_blocking_resolve_address)( const char *name, const char *default_port); -#endif /* GRPC_CORE_IOMGR_RESOLVE_ADDRESS_H */ +#endif /* GRPC_CORE_LIB_IOMGR_RESOLVE_ADDRESS_H */ diff --git a/src/core/lib/iomgr/sockaddr.h b/src/core/lib/iomgr/sockaddr.h index 68241bdd55..e59a98e4ae 100644 --- a/src/core/lib/iomgr/sockaddr.h +++ b/src/core/lib/iomgr/sockaddr.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_SOCKADDR_H -#define GRPC_CORE_IOMGR_SOCKADDR_H +#ifndef GRPC_CORE_LIB_IOMGR_SOCKADDR_H +#define GRPC_CORE_LIB_IOMGR_SOCKADDR_H #include @@ -44,4 +44,4 @@ #include "src/core/iomgr/sockaddr_posix.h" #endif -#endif /* GRPC_CORE_IOMGR_SOCKADDR_H */ +#endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_H */ diff --git a/src/core/lib/iomgr/sockaddr_posix.h b/src/core/lib/iomgr/sockaddr_posix.h index a398096837..79a7467c5d 100644 --- a/src/core/lib/iomgr/sockaddr_posix.h +++ b/src/core/lib/iomgr/sockaddr_posix.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_SOCKADDR_POSIX_H -#define GRPC_CORE_IOMGR_SOCKADDR_POSIX_H +#ifndef GRPC_CORE_LIB_IOMGR_SOCKADDR_POSIX_H +#define GRPC_CORE_LIB_IOMGR_SOCKADDR_POSIX_H #include #include @@ -41,4 +41,4 @@ #include #include -#endif /* GRPC_CORE_IOMGR_SOCKADDR_POSIX_H */ +#endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_POSIX_H */ diff --git a/src/core/lib/iomgr/sockaddr_utils.h b/src/core/lib/iomgr/sockaddr_utils.h index 43dc7a45ec..58f30fca2b 100644 --- a/src/core/lib/iomgr/sockaddr_utils.h +++ b/src/core/lib/iomgr/sockaddr_utils.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_SOCKADDR_UTILS_H -#define GRPC_CORE_IOMGR_SOCKADDR_UTILS_H +#ifndef GRPC_CORE_LIB_IOMGR_SOCKADDR_UTILS_H +#define GRPC_CORE_LIB_IOMGR_SOCKADDR_UTILS_H #include "src/core/iomgr/sockaddr.h" @@ -86,4 +86,4 @@ int grpc_sockaddr_to_string(char **out, const struct sockaddr *addr, char *grpc_sockaddr_to_uri(const struct sockaddr *addr); -#endif /* GRPC_CORE_IOMGR_SOCKADDR_UTILS_H */ +#endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_UTILS_H */ diff --git a/src/core/lib/iomgr/sockaddr_win32.h b/src/core/lib/iomgr/sockaddr_win32.h index ef306e3cc3..2dd7111240 100644 --- a/src/core/lib/iomgr/sockaddr_win32.h +++ b/src/core/lib/iomgr/sockaddr_win32.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_SOCKADDR_WIN32_H -#define GRPC_CORE_IOMGR_SOCKADDR_WIN32_H +#ifndef GRPC_CORE_LIB_IOMGR_SOCKADDR_WIN32_H +#define GRPC_CORE_LIB_IOMGR_SOCKADDR_WIN32_H #include #include @@ -40,4 +40,4 @@ // must be included after the above #include -#endif /* GRPC_CORE_IOMGR_SOCKADDR_WIN32_H */ +#endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_WIN32_H */ diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h index 3908550380..063f298d72 100644 --- a/src/core/lib/iomgr/socket_utils_posix.h +++ b/src/core/lib/iomgr/socket_utils_posix.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_SOCKET_UTILS_POSIX_H -#define GRPC_CORE_IOMGR_SOCKET_UTILS_POSIX_H +#ifndef GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H +#define GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H #include #include @@ -110,4 +110,4 @@ extern int grpc_forbid_dualstack_sockets_for_testing; int grpc_create_dualstack_socket(const struct sockaddr *addr, int type, int protocol, grpc_dualstack_mode *dsmode); -#endif /* GRPC_CORE_IOMGR_SOCKET_UTILS_POSIX_H */ +#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H */ diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 6fe3c6e080..033aec695f 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_SOCKET_WINDOWS_H -#define GRPC_CORE_IOMGR_SOCKET_WINDOWS_H +#ifndef GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H +#define GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H #include #include @@ -108,4 +108,4 @@ void grpc_winsocket_shutdown(grpc_winsocket *socket); /* Destroy a socket. Should only be called if there's no pending operation. */ void grpc_winsocket_destroy(grpc_winsocket *socket); -#endif /* GRPC_CORE_IOMGR_SOCKET_WINDOWS_H */ +#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H */ diff --git a/src/core/lib/iomgr/tcp_client.h b/src/core/lib/iomgr/tcp_client.h index c36f8de713..8f012e248c 100644 --- a/src/core/lib/iomgr/tcp_client.h +++ b/src/core/lib/iomgr/tcp_client.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_TCP_CLIENT_H -#define GRPC_CORE_IOMGR_TCP_CLIENT_H +#ifndef GRPC_CORE_LIB_IOMGR_TCP_CLIENT_H +#define GRPC_CORE_LIB_IOMGR_TCP_CLIENT_H #include #include "src/core/iomgr/endpoint.h" @@ -50,4 +50,4 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_connect, const struct sockaddr *addr, size_t addr_len, gpr_timespec deadline); -#endif /* GRPC_CORE_IOMGR_TCP_CLIENT_H */ +#endif /* GRPC_CORE_LIB_IOMGR_TCP_CLIENT_H */ diff --git a/src/core/lib/iomgr/tcp_posix.h b/src/core/lib/iomgr/tcp_posix.h index d846ec570f..b12fef5ecd 100644 --- a/src/core/lib/iomgr/tcp_posix.h +++ b/src/core/lib/iomgr/tcp_posix.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_TCP_POSIX_H -#define GRPC_CORE_IOMGR_TCP_POSIX_H +#ifndef GRPC_CORE_LIB_IOMGR_TCP_POSIX_H +#define GRPC_CORE_LIB_IOMGR_TCP_POSIX_H /* Low level TCP "bottom half" implementation, for use by transports built on top of a TCP connection. @@ -68,4 +68,4 @@ int grpc_tcp_fd(grpc_endpoint *ep); void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, int *fd, grpc_closure *done); -#endif /* GRPC_CORE_IOMGR_TCP_POSIX_H */ +#endif /* GRPC_CORE_LIB_IOMGR_TCP_POSIX_H */ diff --git a/src/core/lib/iomgr/tcp_server.h b/src/core/lib/iomgr/tcp_server.h index 93247e9e4e..e27fd233cd 100644 --- a/src/core/lib/iomgr/tcp_server.h +++ b/src/core/lib/iomgr/tcp_server.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_TCP_SERVER_H -#define GRPC_CORE_IOMGR_TCP_SERVER_H +#ifndef GRPC_CORE_LIB_IOMGR_TCP_SERVER_H +#define GRPC_CORE_LIB_IOMGR_TCP_SERVER_H #include "src/core/iomgr/closure.h" #include "src/core/iomgr/endpoint.h" @@ -100,4 +100,4 @@ void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s, a call (exec_ctx!=NULL) to shutdown_complete. */ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s); -#endif /* GRPC_CORE_IOMGR_TCP_SERVER_H */ +#endif /* GRPC_CORE_LIB_IOMGR_TCP_SERVER_H */ diff --git a/src/core/lib/iomgr/tcp_windows.h b/src/core/lib/iomgr/tcp_windows.h index 78bc13389a..c9e508f296 100644 --- a/src/core/lib/iomgr/tcp_windows.h +++ b/src/core/lib/iomgr/tcp_windows.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_TCP_WINDOWS_H -#define GRPC_CORE_IOMGR_TCP_WINDOWS_H +#ifndef GRPC_CORE_LIB_IOMGR_TCP_WINDOWS_H +#define GRPC_CORE_LIB_IOMGR_TCP_WINDOWS_H /* Low level TCP "bottom half" implementation, for use by transports built on top of a TCP connection. @@ -54,4 +54,4 @@ grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket, char *peer_string); int grpc_tcp_prepare_socket(SOCKET sock); -#endif /* GRPC_CORE_IOMGR_TCP_WINDOWS_H */ +#endif /* GRPC_CORE_LIB_IOMGR_TCP_WINDOWS_H */ diff --git a/src/core/lib/iomgr/time_averaged_stats.h b/src/core/lib/iomgr/time_averaged_stats.h index 048e244bcc..4a662e17ec 100644 --- a/src/core/lib/iomgr/time_averaged_stats.h +++ b/src/core/lib/iomgr/time_averaged_stats.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_TIME_AVERAGED_STATS_H -#define GRPC_CORE_IOMGR_TIME_AVERAGED_STATS_H +#ifndef GRPC_CORE_LIB_IOMGR_TIME_AVERAGED_STATS_H +#define GRPC_CORE_LIB_IOMGR_TIME_AVERAGED_STATS_H /* This tracks a time-decaying weighted average. It works by collecting batches of samples and then mixing their average into a time-decaying @@ -85,4 +85,4 @@ void grpc_time_averaged_stats_add_sample(grpc_time_averaged_stats* stats, value. */ double grpc_time_averaged_stats_update_average(grpc_time_averaged_stats* stats); -#endif /* GRPC_CORE_IOMGR_TIME_AVERAGED_STATS_H */ +#endif /* GRPC_CORE_LIB_IOMGR_TIME_AVERAGED_STATS_H */ diff --git a/src/core/lib/iomgr/timer.h b/src/core/lib/iomgr/timer.h index 1e2d1cbfbd..616a886743 100644 --- a/src/core/lib/iomgr/timer.h +++ b/src/core/lib/iomgr/timer.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_TIMER_H -#define GRPC_CORE_IOMGR_TIMER_H +#ifndef GRPC_CORE_LIB_IOMGR_TIMER_H +#define GRPC_CORE_LIB_IOMGR_TIMER_H #include #include @@ -105,4 +105,4 @@ void grpc_timer_list_shutdown(grpc_exec_ctx *exec_ctx); void grpc_kick_poller(void); -#endif /* GRPC_CORE_IOMGR_TIMER_H */ +#endif /* GRPC_CORE_LIB_IOMGR_TIMER_H */ diff --git a/src/core/lib/iomgr/timer_heap.h b/src/core/lib/iomgr/timer_heap.h index c2912ef45d..d6b4f083d8 100644 --- a/src/core/lib/iomgr/timer_heap.h +++ b/src/core/lib/iomgr/timer_heap.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_TIMER_HEAP_H -#define GRPC_CORE_IOMGR_TIMER_HEAP_H +#ifndef GRPC_CORE_LIB_IOMGR_TIMER_HEAP_H +#define GRPC_CORE_LIB_IOMGR_TIMER_HEAP_H #include "src/core/iomgr/timer.h" @@ -54,4 +54,4 @@ void grpc_timer_heap_pop(grpc_timer_heap *heap); int grpc_timer_heap_is_empty(grpc_timer_heap *heap); -#endif /* GRPC_CORE_IOMGR_TIMER_HEAP_H */ +#endif /* GRPC_CORE_LIB_IOMGR_TIMER_HEAP_H */ diff --git a/src/core/lib/iomgr/udp_server.h b/src/core/lib/iomgr/udp_server.h index 148c04fa9b..ac70124727 100644 --- a/src/core/lib/iomgr/udp_server.h +++ b/src/core/lib/iomgr/udp_server.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_UDP_SERVER_H -#define GRPC_CORE_IOMGR_UDP_SERVER_H +#ifndef GRPC_CORE_LIB_IOMGR_UDP_SERVER_H +#define GRPC_CORE_LIB_IOMGR_UDP_SERVER_H #include "src/core/iomgr/endpoint.h" #include "src/core/iomgr/fd_posix.h" @@ -74,4 +74,4 @@ int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *server, grpc_closure *on_done); -#endif /* GRPC_CORE_IOMGR_UDP_SERVER_H */ +#endif /* GRPC_CORE_LIB_IOMGR_UDP_SERVER_H */ diff --git a/src/core/lib/iomgr/unix_sockets_posix.h b/src/core/lib/iomgr/unix_sockets_posix.h index e842ba3770..6382c92480 100644 --- a/src/core/lib/iomgr/unix_sockets_posix.h +++ b/src/core/lib/iomgr/unix_sockets_posix.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_UNIX_SOCKETS_POSIX_H -#define GRPC_CORE_IOMGR_UNIX_SOCKETS_POSIX_H +#ifndef GRPC_CORE_LIB_IOMGR_UNIX_SOCKETS_POSIX_H +#define GRPC_CORE_LIB_IOMGR_UNIX_SOCKETS_POSIX_H #include @@ -58,4 +58,4 @@ char *grpc_unix_get_default_authority(grpc_resolver_factory *factory, char *grpc_sockaddr_to_uri_unix_if_possible(const struct sockaddr *addr); -#endif /* GRPC_CORE_IOMGR_UNIX_SOCKETS_POSIX_H */ +#endif /* GRPC_CORE_LIB_IOMGR_UNIX_SOCKETS_POSIX_H */ diff --git a/src/core/lib/iomgr/wakeup_fd_pipe.h b/src/core/lib/iomgr/wakeup_fd_pipe.h index eb3e02b482..dd8275800a 100644 --- a/src/core/lib/iomgr/wakeup_fd_pipe.h +++ b/src/core/lib/iomgr/wakeup_fd_pipe.h @@ -31,11 +31,11 @@ * */ -#ifndef GRPC_CORE_IOMGR_WAKEUP_FD_PIPE_H -#define GRPC_CORE_IOMGR_WAKEUP_FD_PIPE_H +#ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_PIPE_H +#define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_PIPE_H #include "src/core/iomgr/wakeup_fd_posix.h" extern grpc_wakeup_fd_vtable grpc_pipe_wakeup_fd_vtable; -#endif /* GRPC_CORE_IOMGR_WAKEUP_FD_PIPE_H */ +#endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_PIPE_H */ diff --git a/src/core/lib/iomgr/wakeup_fd_posix.h b/src/core/lib/iomgr/wakeup_fd_posix.h index d7e3cf4673..20988d5fd3 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.h +++ b/src/core/lib/iomgr/wakeup_fd_posix.h @@ -59,8 +59,8 @@ * 2. If the polling thread was awakened by a wakeup_fd event, call * grpc_wakeup_fd_consume_wakeup() on it. */ -#ifndef GRPC_CORE_IOMGR_WAKEUP_FD_POSIX_H -#define GRPC_CORE_IOMGR_WAKEUP_FD_POSIX_H +#ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_POSIX_H +#define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_POSIX_H void grpc_wakeup_fd_global_init(void); void grpc_wakeup_fd_global_destroy(void); @@ -98,4 +98,4 @@ void grpc_wakeup_fd_destroy(grpc_wakeup_fd* fd_info); * wakeup_fd_nospecial.c if no such implementation exists. */ extern const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable; -#endif /* GRPC_CORE_IOMGR_WAKEUP_FD_POSIX_H */ +#endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_POSIX_H */ diff --git a/src/core/lib/iomgr/workqueue.h b/src/core/lib/iomgr/workqueue.h index 2b923ba152..d11fc77d82 100644 --- a/src/core/lib/iomgr/workqueue.h +++ b/src/core/lib/iomgr/workqueue.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_WORKQUEUE_H -#define GRPC_CORE_IOMGR_WORKQUEUE_H +#ifndef GRPC_CORE_LIB_IOMGR_WORKQUEUE_H +#define GRPC_CORE_LIB_IOMGR_WORKQUEUE_H #include "src/core/iomgr/closure.h" #include "src/core/iomgr/exec_ctx.h" @@ -80,4 +80,4 @@ void grpc_workqueue_add_to_pollset(grpc_exec_ctx *exec_ctx, void grpc_workqueue_push(grpc_workqueue *workqueue, grpc_closure *closure, int success); -#endif /* GRPC_CORE_IOMGR_WORKQUEUE_H */ +#endif /* GRPC_CORE_LIB_IOMGR_WORKQUEUE_H */ diff --git a/src/core/lib/iomgr/workqueue_posix.h b/src/core/lib/iomgr/workqueue_posix.h index 89937b1ea8..02e1dad44f 100644 --- a/src/core/lib/iomgr/workqueue_posix.h +++ b/src/core/lib/iomgr/workqueue_posix.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_IOMGR_WORKQUEUE_POSIX_H -#define GRPC_CORE_IOMGR_WORKQUEUE_POSIX_H +#ifndef GRPC_CORE_LIB_IOMGR_WORKQUEUE_POSIX_H +#define GRPC_CORE_LIB_IOMGR_WORKQUEUE_POSIX_H #include "src/core/iomgr/wakeup_fd_posix.h" @@ -50,4 +50,4 @@ struct grpc_workqueue { grpc_closure read_closure; }; -#endif /* GRPC_CORE_IOMGR_WORKQUEUE_POSIX_H */ +#endif /* GRPC_CORE_LIB_IOMGR_WORKQUEUE_POSIX_H */ diff --git a/src/core/lib/iomgr/workqueue_windows.h b/src/core/lib/iomgr/workqueue_windows.h index 7e8186921e..8e6980b6d9 100644 --- a/src/core/lib/iomgr/workqueue_windows.h +++ b/src/core/lib/iomgr/workqueue_windows.h @@ -31,7 +31,7 @@ * */ -#ifndef GRPC_CORE_IOMGR_WORKQUEUE_WINDOWS_H -#define GRPC_CORE_IOMGR_WORKQUEUE_WINDOWS_H +#ifndef GRPC_CORE_LIB_IOMGR_WORKQUEUE_WINDOWS_H +#define GRPC_CORE_LIB_IOMGR_WORKQUEUE_WINDOWS_H -#endif /* GRPC_CORE_IOMGR_WORKQUEUE_WINDOWS_H */ +#endif /* GRPC_CORE_LIB_IOMGR_WORKQUEUE_WINDOWS_H */ diff --git a/src/core/lib/json/json.h b/src/core/lib/json/json.h index aea9d5dadb..89d15846ce 100644 --- a/src/core/lib/json/json.h +++ b/src/core/lib/json/json.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_JSON_JSON_H -#define GRPC_CORE_JSON_JSON_H +#ifndef GRPC_CORE_LIB_JSON_JSON_H +#define GRPC_CORE_LIB_JSON_JSON_H #include @@ -85,4 +85,4 @@ char *grpc_json_dump_to_string(grpc_json *json, int indent); grpc_json *grpc_json_create(grpc_json_type type); void grpc_json_destroy(grpc_json *json); -#endif /* GRPC_CORE_JSON_JSON_H */ +#endif /* GRPC_CORE_LIB_JSON_JSON_H */ diff --git a/src/core/lib/json/json_common.h b/src/core/lib/json/json_common.h index 7205a94685..ce980040f8 100644 --- a/src/core/lib/json/json_common.h +++ b/src/core/lib/json/json_common.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_JSON_JSON_COMMON_H -#define GRPC_CORE_JSON_JSON_COMMON_H +#ifndef GRPC_CORE_LIB_JSON_JSON_COMMON_H +#define GRPC_CORE_LIB_JSON_JSON_COMMON_H /* The various json types. */ typedef enum { @@ -46,4 +46,4 @@ typedef enum { GRPC_JSON_TOP_LEVEL } grpc_json_type; -#endif /* GRPC_CORE_JSON_JSON_COMMON_H */ +#endif /* GRPC_CORE_LIB_JSON_JSON_COMMON_H */ diff --git a/src/core/lib/json/json_reader.h b/src/core/lib/json/json_reader.h index f25f44b2ef..a49d6fef68 100644 --- a/src/core/lib/json/json_reader.h +++ b/src/core/lib/json/json_reader.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_JSON_JSON_READER_H -#define GRPC_CORE_JSON_JSON_READER_H +#ifndef GRPC_CORE_LIB_JSON_JSON_READER_H +#define GRPC_CORE_LIB_JSON_JSON_READER_H #include #include "src/core/json/json_common.h" @@ -157,4 +157,4 @@ void grpc_json_reader_init(grpc_json_reader *reader, */ int grpc_json_reader_is_complete(grpc_json_reader *reader); -#endif /* GRPC_CORE_JSON_JSON_READER_H */ +#endif /* GRPC_CORE_LIB_JSON_JSON_READER_H */ diff --git a/src/core/lib/json/json_writer.h b/src/core/lib/json/json_writer.h index c392126950..90b6bc753c 100644 --- a/src/core/lib/json/json_writer.h +++ b/src/core/lib/json/json_writer.h @@ -43,8 +43,8 @@ * a valid UTF-8 string overall. */ -#ifndef GRPC_CORE_JSON_JSON_WRITER_H -#define GRPC_CORE_JSON_JSON_WRITER_H +#ifndef GRPC_CORE_LIB_JSON_JSON_WRITER_H +#define GRPC_CORE_LIB_JSON_JSON_WRITER_H #include @@ -94,4 +94,4 @@ void grpc_json_writer_value_raw_with_len(grpc_json_writer *writer, void grpc_json_writer_value_string(grpc_json_writer *writer, const char *string); -#endif /* GRPC_CORE_JSON_JSON_WRITER_H */ +#endif /* GRPC_CORE_LIB_JSON_JSON_WRITER_H */ diff --git a/src/core/lib/profiling/timers.h b/src/core/lib/profiling/timers.h index 6a188dc566..c8567e8137 100644 --- a/src/core/lib/profiling/timers.h +++ b/src/core/lib/profiling/timers.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_PROFILING_TIMERS_H -#define GRPC_CORE_PROFILING_TIMERS_H +#ifndef GRPC_CORE_LIB_PROFILING_TIMERS_H +#define GRPC_CORE_LIB_PROFILING_TIMERS_H #ifdef __cplusplus extern "C" { @@ -116,4 +116,4 @@ class ProfileScope { #endif #endif -#endif /* GRPC_CORE_PROFILING_TIMERS_H */ +#endif /* GRPC_CORE_LIB_PROFILING_TIMERS_H */ diff --git a/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h b/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h index 3599f881bb..671fb9a60b 100644 --- a/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h +++ b/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h @@ -33,8 +33,8 @@ /* Automatically generated nanopb header */ /* Generated by nanopb-0.3.5-dev */ -#ifndef PB_LOAD_BALANCER_PB_H_INCLUDED -#define PB_LOAD_BALANCER_PB_H_INCLUDED +#ifndef GRPC_CORE_LIB_PROTO_GRPC_LB_V0_LOAD_BALANCER_PB_H0_LOAD_BALANCER_PB_H +#define GRPC_CORE_LIB_PROTO_GRPC_LB_V0_LOAD_BALANCER_PB_H0_LOAD_BALANCER_PB_H #include "third_party/nanopb/pb.h" #if PB_PROTO_HEADER_VERSION != 30 #error Regenerate this file with the current version of nanopb generator. @@ -179,4 +179,4 @@ extern const pb_field_t grpc_lb_v0_Server_fields[5]; } /* extern "C" */ #endif -#endif +#endif /* GRPC_CORE_LIB_PROTO_GRPC_LB_V0_LOAD_BALANCER_PB_H */ diff --git a/src/core/lib/security/auth_filters.h b/src/core/lib/security/auth_filters.h index 1154a1d914..0fb19e7382 100644 --- a/src/core/lib/security/auth_filters.h +++ b/src/core/lib/security/auth_filters.h @@ -31,12 +31,12 @@ * */ -#ifndef GRPC_CORE_SECURITY_AUTH_FILTERS_H -#define GRPC_CORE_SECURITY_AUTH_FILTERS_H +#ifndef GRPC_CORE_LIB_SECURITY_AUTH_FILTERS_H +#define GRPC_CORE_LIB_SECURITY_AUTH_FILTERS_H #include "src/core/channel/channel_stack.h" extern const grpc_channel_filter grpc_client_auth_filter; extern const grpc_channel_filter grpc_server_auth_filter; -#endif /* GRPC_CORE_SECURITY_AUTH_FILTERS_H */ +#endif /* GRPC_CORE_LIB_SECURITY_AUTH_FILTERS_H */ diff --git a/src/core/lib/security/b64.h b/src/core/lib/security/b64.h index d18f69563d..0bf372a1e7 100644 --- a/src/core/lib/security/b64.h +++ b/src/core/lib/security/b64.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SECURITY_B64_H -#define GRPC_CORE_SECURITY_B64_H +#ifndef GRPC_CORE_LIB_SECURITY_B64_H +#define GRPC_CORE_LIB_SECURITY_B64_H #include @@ -49,4 +49,4 @@ gpr_slice grpc_base64_decode(const char *b64, int url_safe); gpr_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len, int url_safe); -#endif /* GRPC_CORE_SECURITY_B64_H */ +#endif /* GRPC_CORE_LIB_SECURITY_B64_H */ diff --git a/src/core/lib/security/credentials.h b/src/core/lib/security/credentials.h index bfa7cc71bd..c1f451ded1 100644 --- a/src/core/lib/security/credentials.h +++ b/src/core/lib/security/credentials.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SECURITY_CREDENTIALS_H -#define GRPC_CORE_SECURITY_CREDENTIALS_H +#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_H +#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_H #include #include @@ -374,4 +374,4 @@ typedef struct { grpc_credentials_md_store *plugin_md; } grpc_plugin_credentials; -#endif /* GRPC_CORE_SECURITY_CREDENTIALS_H */ +#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_H */ diff --git a/src/core/lib/security/handshake.h b/src/core/lib/security/handshake.h index 4872045874..2b1f8b9212 100644 --- a/src/core/lib/security/handshake.h +++ b/src/core/lib/security/handshake.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SECURITY_HANDSHAKE_H -#define GRPC_CORE_SECURITY_HANDSHAKE_H +#ifndef GRPC_CORE_LIB_SECURITY_HANDSHAKE_H +#define GRPC_CORE_LIB_SECURITY_HANDSHAKE_H #include "src/core/iomgr/endpoint.h" #include "src/core/security/security_connector.h" @@ -48,4 +48,4 @@ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx, void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake); -#endif /* GRPC_CORE_SECURITY_HANDSHAKE_H */ +#endif /* GRPC_CORE_LIB_SECURITY_HANDSHAKE_H */ diff --git a/src/core/lib/security/json_token.h b/src/core/lib/security/json_token.h index d183f9b3a3..08ed4bfef3 100644 --- a/src/core/lib/security/json_token.h +++ b/src/core/lib/security/json_token.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SECURITY_JSON_TOKEN_H -#define GRPC_CORE_SECURITY_JSON_TOKEN_H +#ifndef GRPC_CORE_LIB_SECURITY_JSON_TOKEN_H +#define GRPC_CORE_LIB_SECURITY_JSON_TOKEN_H #include #include @@ -115,4 +115,4 @@ grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json( /* Destructs the object. */ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token); -#endif /* GRPC_CORE_SECURITY_JSON_TOKEN_H */ +#endif /* GRPC_CORE_LIB_SECURITY_JSON_TOKEN_H */ diff --git a/src/core/lib/security/jwt_verifier.h b/src/core/lib/security/jwt_verifier.h index d898d2193f..7db7e6d7b4 100644 --- a/src/core/lib/security/jwt_verifier.h +++ b/src/core/lib/security/jwt_verifier.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SECURITY_JWT_VERIFIER_H -#define GRPC_CORE_SECURITY_JWT_VERIFIER_H +#ifndef GRPC_CORE_LIB_SECURITY_JWT_VERIFIER_H +#define GRPC_CORE_LIB_SECURITY_JWT_VERIFIER_H #include "src/core/iomgr/pollset.h" #include "src/core/json/json.h" @@ -133,4 +133,4 @@ grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, gpr_slice buffer); grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims, const char *audience); -#endif /* GRPC_CORE_SECURITY_JWT_VERIFIER_H */ +#endif /* GRPC_CORE_LIB_SECURITY_JWT_VERIFIER_H */ diff --git a/src/core/lib/security/secure_endpoint.h b/src/core/lib/security/secure_endpoint.h index 7368f8424b..f13a4cca44 100644 --- a/src/core/lib/security/secure_endpoint.h +++ b/src/core/lib/security/secure_endpoint.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SECURITY_SECURE_ENDPOINT_H -#define GRPC_CORE_SECURITY_SECURE_ENDPOINT_H +#ifndef GRPC_CORE_LIB_SECURITY_SECURE_ENDPOINT_H +#define GRPC_CORE_LIB_SECURITY_SECURE_ENDPOINT_H #include #include "src/core/iomgr/endpoint.h" @@ -46,4 +46,4 @@ grpc_endpoint *grpc_secure_endpoint_create( struct tsi_frame_protector *protector, grpc_endpoint *to_wrap, gpr_slice *leftover_slices, size_t leftover_nslices); -#endif /* GRPC_CORE_SECURITY_SECURE_ENDPOINT_H */ +#endif /* GRPC_CORE_LIB_SECURITY_SECURE_ENDPOINT_H */ diff --git a/src/core/lib/security/security_connector.h b/src/core/lib/security/security_connector.h index 6f915ebb9d..2818299235 100644 --- a/src/core/lib/security/security_connector.h +++ b/src/core/lib/security/security_connector.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SECURITY_SECURITY_CONNECTOR_H -#define GRPC_CORE_SECURITY_SECURITY_CONNECTOR_H +#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_H #include #include "src/core/iomgr/endpoint.h" @@ -263,4 +263,4 @@ tsi_peer tsi_shallow_peer_from_ssl_auth_context( const grpc_auth_context *auth_context); void tsi_shallow_peer_destruct(tsi_peer *peer); -#endif /* GRPC_CORE_SECURITY_SECURITY_CONNECTOR_H */ +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_H */ diff --git a/src/core/lib/security/security_context.h b/src/core/lib/security/security_context.h index 61601f538b..e205229081 100644 --- a/src/core/lib/security/security_context.h +++ b/src/core/lib/security/security_context.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SECURITY_SECURITY_CONTEXT_H -#define GRPC_CORE_SECURITY_SECURITY_CONTEXT_H +#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONTEXT_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONTEXT_H #include "src/core/iomgr/pollset.h" #include "src/core/security/credentials.h" @@ -111,4 +111,4 @@ grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg); grpc_auth_context *grpc_find_auth_context_in_args( const grpc_channel_args *args); -#endif /* GRPC_CORE_SECURITY_SECURITY_CONTEXT_H */ +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONTEXT_H */ diff --git a/src/core/lib/statistics/census_interface.h b/src/core/lib/statistics/census_interface.h index ce8ff92cd4..b3b3439072 100644 --- a/src/core/lib/statistics/census_interface.h +++ b/src/core/lib/statistics/census_interface.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_STATISTICS_CENSUS_INTERFACE_H -#define GRPC_CORE_STATISTICS_CENSUS_INTERFACE_H +#ifndef GRPC_CORE_LIB_STATISTICS_CENSUS_INTERFACE_H +#define GRPC_CORE_LIB_STATISTICS_CENSUS_INTERFACE_H #include @@ -73,4 +73,4 @@ census_op_id census_tracing_start_op(void); /* Ends tracing. Calling this function will invalidate the input op_id. */ void census_tracing_end_op(census_op_id op_id); -#endif /* GRPC_CORE_STATISTICS_CENSUS_INTERFACE_H */ +#endif /* GRPC_CORE_LIB_STATISTICS_CENSUS_INTERFACE_H */ diff --git a/src/core/lib/statistics/census_log.h b/src/core/lib/statistics/census_log.h index e7ce0d4433..c3fbd555ba 100644 --- a/src/core/lib/statistics/census_log.h +++ b/src/core/lib/statistics/census_log.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_STATISTICS_CENSUS_LOG_H -#define GRPC_CORE_STATISTICS_CENSUS_LOG_H +#ifndef GRPC_CORE_LIB_STATISTICS_CENSUS_LOG_H +#define GRPC_CORE_LIB_STATISTICS_CENSUS_LOG_H #include @@ -88,4 +88,4 @@ size_t census_log_remaining_space(void); out-of-space. */ int census_log_out_of_space_count(void); -#endif /* GRPC_CORE_STATISTICS_CENSUS_LOG_H */ +#endif /* GRPC_CORE_LIB_STATISTICS_CENSUS_LOG_H */ diff --git a/src/core/lib/statistics/census_rpc_stats.h b/src/core/lib/statistics/census_rpc_stats.h index f7f220e45f..1b45872be8 100644 --- a/src/core/lib/statistics/census_rpc_stats.h +++ b/src/core/lib/statistics/census_rpc_stats.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_STATISTICS_CENSUS_RPC_STATS_H -#define GRPC_CORE_STATISTICS_CENSUS_RPC_STATS_H +#ifndef GRPC_CORE_LIB_STATISTICS_CENSUS_RPC_STATS_H +#define GRPC_CORE_LIB_STATISTICS_CENSUS_RPC_STATS_H #include #include "src/core/statistics/census_interface.h" @@ -98,4 +98,4 @@ void census_stats_store_shutdown(void); } #endif -#endif /* GRPC_CORE_STATISTICS_CENSUS_RPC_STATS_H */ +#endif /* GRPC_CORE_LIB_STATISTICS_CENSUS_RPC_STATS_H */ diff --git a/src/core/lib/statistics/census_tracing.h b/src/core/lib/statistics/census_tracing.h index b611e95bf4..e497bc354d 100644 --- a/src/core/lib/statistics/census_tracing.h +++ b/src/core/lib/statistics/census_tracing.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_STATISTICS_CENSUS_TRACING_H -#define GRPC_CORE_STATISTICS_CENSUS_TRACING_H +#ifndef GRPC_CORE_LIB_STATISTICS_CENSUS_TRACING_H +#define GRPC_CORE_LIB_STATISTICS_CENSUS_TRACING_H #include #include "src/core/statistics/census_rpc_stats.h" @@ -93,4 +93,4 @@ census_trace_obj **census_get_active_ops(int *num_active_ops); } #endif -#endif /* GRPC_CORE_STATISTICS_CENSUS_TRACING_H */ +#endif /* GRPC_CORE_LIB_STATISTICS_CENSUS_TRACING_H */ diff --git a/src/core/lib/statistics/hash_table.h b/src/core/lib/statistics/hash_table.h index f4bf2ba49a..8f74ec82aa 100644 --- a/src/core/lib/statistics/hash_table.h +++ b/src/core/lib/statistics/hash_table.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_STATISTICS_HASH_TABLE_H -#define GRPC_CORE_STATISTICS_HASH_TABLE_H +#ifndef GRPC_CORE_LIB_STATISTICS_HASH_TABLE_H +#define GRPC_CORE_LIB_STATISTICS_HASH_TABLE_H #include @@ -128,4 +128,4 @@ typedef void (*census_ht_itr_cb)(census_ht_key key, const void *val_ptr, should not invalidate data entries. */ uint64_t census_ht_for_all(const census_ht *ht, census_ht_itr_cb); -#endif /* GRPC_CORE_STATISTICS_HASH_TABLE_H */ +#endif /* GRPC_CORE_LIB_STATISTICS_HASH_TABLE_H */ diff --git a/src/core/lib/statistics/window_stats.h b/src/core/lib/statistics/window_stats.h index 774277180f..8dec50d620 100644 --- a/src/core/lib/statistics/window_stats.h +++ b/src/core/lib/statistics/window_stats.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_STATISTICS_WINDOW_STATS_H -#define GRPC_CORE_STATISTICS_WINDOW_STATS_H +#ifndef GRPC_CORE_LIB_STATISTICS_WINDOW_STATS_H +#define GRPC_CORE_LIB_STATISTICS_WINDOW_STATS_H #include @@ -170,4 +170,4 @@ void census_window_stats_get_sums(const struct census_window_stats *wstats, assertion failure). This function is thread-compatible. */ void census_window_stats_destroy(struct census_window_stats *wstats); -#endif /* GRPC_CORE_STATISTICS_WINDOW_STATS_H */ +#endif /* GRPC_CORE_LIB_STATISTICS_WINDOW_STATS_H */ diff --git a/src/core/lib/support/backoff.h b/src/core/lib/support/backoff.h index 0f933c3149..6d40c15546 100644 --- a/src/core/lib/support/backoff.h +++ b/src/core/lib/support/backoff.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SUPPORT_BACKOFF_H -#define GRPC_CORE_SUPPORT_BACKOFF_H +#ifndef GRPC_CORE_LIB_SUPPORT_BACKOFF_H +#define GRPC_CORE_LIB_SUPPORT_BACKOFF_H #include @@ -65,4 +65,4 @@ gpr_timespec gpr_backoff_step(gpr_backoff *backoff, gpr_timespec now); /// instead void gpr_backoff_reset(gpr_backoff *backoff); -#endif /* GRPC_CORE_SUPPORT_BACKOFF_H */ +#endif /* GRPC_CORE_LIB_SUPPORT_BACKOFF_H */ diff --git a/src/core/lib/support/block_annotate.h b/src/core/lib/support/block_annotate.h index 79a18039f4..bd3071655e 100644 --- a/src/core/lib/support/block_annotate.h +++ b/src/core/lib/support/block_annotate.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SUPPORT_BLOCK_ANNOTATE_H -#define GRPC_CORE_SUPPORT_BLOCK_ANNOTATE_H +#ifndef GRPC_CORE_LIB_SUPPORT_BLOCK_ANNOTATE_H +#define GRPC_CORE_LIB_SUPPORT_BLOCK_ANNOTATE_H /* These annotations identify the beginning and end of regions where the code may block for reasons other than synchronization functions. @@ -45,4 +45,4 @@ do { \ } while (0) -#endif /* GRPC_CORE_SUPPORT_BLOCK_ANNOTATE_H */ +#endif /* GRPC_CORE_LIB_SUPPORT_BLOCK_ANNOTATE_H */ diff --git a/src/core/lib/support/env.h b/src/core/lib/support/env.h index 2902456947..ddc4ee3c6d 100644 --- a/src/core/lib/support/env.h +++ b/src/core/lib/support/env.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SUPPORT_ENV_H -#define GRPC_CORE_SUPPORT_ENV_H +#ifndef GRPC_CORE_LIB_SUPPORT_ENV_H +#define GRPC_CORE_LIB_SUPPORT_ENV_H #include @@ -57,4 +57,4 @@ void gpr_setenv(const char *name, const char *value); } #endif -#endif /* GRPC_CORE_SUPPORT_ENV_H */ +#endif /* GRPC_CORE_LIB_SUPPORT_ENV_H */ diff --git a/src/core/lib/support/load_file.h b/src/core/lib/support/load_file.h index 5896654e9a..fe030c967e 100644 --- a/src/core/lib/support/load_file.h +++ b/src/core/lib/support/load_file.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SUPPORT_LOAD_FILE_H -#define GRPC_CORE_SUPPORT_LOAD_FILE_H +#ifndef GRPC_CORE_LIB_SUPPORT_LOAD_FILE_H +#define GRPC_CORE_LIB_SUPPORT_LOAD_FILE_H #include @@ -52,4 +52,4 @@ gpr_slice gpr_load_file(const char *filename, int add_null_terminator, } #endif -#endif /* GRPC_CORE_SUPPORT_LOAD_FILE_H */ +#endif /* GRPC_CORE_LIB_SUPPORT_LOAD_FILE_H */ diff --git a/src/core/lib/support/murmur_hash.h b/src/core/lib/support/murmur_hash.h index 0f0b399e5d..e54cdf2592 100644 --- a/src/core/lib/support/murmur_hash.h +++ b/src/core/lib/support/murmur_hash.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SUPPORT_MURMUR_HASH_H -#define GRPC_CORE_SUPPORT_MURMUR_HASH_H +#ifndef GRPC_CORE_LIB_SUPPORT_MURMUR_HASH_H +#define GRPC_CORE_LIB_SUPPORT_MURMUR_HASH_H #include @@ -41,4 +41,4 @@ /* compute the hash of key (length len) */ uint32_t gpr_murmur_hash3(const void *key, size_t len, uint32_t seed); -#endif /* GRPC_CORE_SUPPORT_MURMUR_HASH_H */ +#endif /* GRPC_CORE_LIB_SUPPORT_MURMUR_HASH_H */ diff --git a/src/core/lib/support/stack_lockfree.h b/src/core/lib/support/stack_lockfree.h index d6fd06d67c..a030a01d1f 100644 --- a/src/core/lib/support/stack_lockfree.h +++ b/src/core/lib/support/stack_lockfree.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SUPPORT_STACK_LOCKFREE_H -#define GRPC_CORE_SUPPORT_STACK_LOCKFREE_H +#ifndef GRPC_CORE_LIB_SUPPORT_STACK_LOCKFREE_H +#define GRPC_CORE_LIB_SUPPORT_STACK_LOCKFREE_H #include @@ -50,4 +50,4 @@ int gpr_stack_lockfree_push(gpr_stack_lockfree *, int entry); /* Returns -1 on empty or the actual entry number */ int gpr_stack_lockfree_pop(gpr_stack_lockfree *stack); -#endif /* GRPC_CORE_SUPPORT_STACK_LOCKFREE_H */ +#endif /* GRPC_CORE_LIB_SUPPORT_STACK_LOCKFREE_H */ diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h index 8ff16882ab..68c02878e0 100644 --- a/src/core/lib/support/string.h +++ b/src/core/lib/support/string.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SUPPORT_STRING_H -#define GRPC_CORE_SUPPORT_STRING_H +#ifndef GRPC_CORE_LIB_SUPPORT_STRING_H +#define GRPC_CORE_LIB_SUPPORT_STRING_H #include @@ -118,4 +118,4 @@ char *gpr_strvec_flatten(gpr_strvec *strs, size_t *total_length); } #endif -#endif /* GRPC_CORE_SUPPORT_STRING_H */ +#endif /* GRPC_CORE_LIB_SUPPORT_STRING_H */ diff --git a/src/core/lib/support/string_win32.h b/src/core/lib/support/string_win32.h index c9ae8d9932..f47d567715 100644 --- a/src/core/lib/support/string_win32.h +++ b/src/core/lib/support/string_win32.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SUPPORT_STRING_WIN32_H -#define GRPC_CORE_SUPPORT_STRING_WIN32_H +#ifndef GRPC_CORE_LIB_SUPPORT_STRING_WIN32_H +#define GRPC_CORE_LIB_SUPPORT_STRING_WIN32_H #include @@ -44,4 +44,4 @@ LPSTR gpr_tchar_to_char(LPCTSTR input); #endif /* GPR_WIN32 */ -#endif /* GRPC_CORE_SUPPORT_STRING_WIN32_H */ +#endif /* GRPC_CORE_LIB_SUPPORT_STRING_WIN32_H */ diff --git a/src/core/lib/support/thd_internal.h b/src/core/lib/support/thd_internal.h index 33b904e59b..f269a3249e 100644 --- a/src/core/lib/support/thd_internal.h +++ b/src/core/lib/support/thd_internal.h @@ -31,9 +31,9 @@ * */ -#ifndef GRPC_CORE_SUPPORT_THD_INTERNAL_H -#define GRPC_CORE_SUPPORT_THD_INTERNAL_H +#ifndef GRPC_CORE_LIB_SUPPORT_THD_INTERNAL_H +#define GRPC_CORE_LIB_SUPPORT_THD_INTERNAL_H /* Internal interfaces between modules within the gpr support library. */ -#endif /* GRPC_CORE_SUPPORT_THD_INTERNAL_H */ +#endif /* GRPC_CORE_LIB_SUPPORT_THD_INTERNAL_H */ diff --git a/src/core/lib/support/time_precise.h b/src/core/lib/support/time_precise.h index 871c99a623..e1faee1f9f 100644 --- a/src/core/lib/support/time_precise.h +++ b/src/core/lib/support/time_precise.h @@ -31,12 +31,12 @@ * */ -#ifndef GRPC_CORE_SUPPORT_TIME_PRECISE_H -#define GRPC_CORE_SUPPORT_TIME_PRECISE_H +#ifndef GRPC_CORE_LIB_SUPPORT_TIME_PRECISE_H +#define GRPC_CORE_LIB_SUPPORT_TIME_PRECISE_H #include void gpr_precise_clock_init(void); void gpr_precise_clock_now(gpr_timespec *clk); -#endif /* GRPC_CORE_SUPPORT_TIME_PRECISE_H */ +#endif /* GRPC_CORE_LIB_SUPPORT_TIME_PRECISE_H */ diff --git a/src/core/lib/support/tmpfile.h b/src/core/lib/support/tmpfile.h index df6f8692bb..4fec2076e3 100644 --- a/src/core/lib/support/tmpfile.h +++ b/src/core/lib/support/tmpfile.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SUPPORT_TMPFILE_H -#define GRPC_CORE_SUPPORT_TMPFILE_H +#ifndef GRPC_CORE_LIB_SUPPORT_TMPFILE_H +#define GRPC_CORE_LIB_SUPPORT_TMPFILE_H #include @@ -52,4 +52,4 @@ FILE *gpr_tmpfile(const char *prefix, char **tmp_filename); } #endif -#endif /* GRPC_CORE_SUPPORT_TMPFILE_H */ +#endif /* GRPC_CORE_LIB_SUPPORT_TMPFILE_H */ diff --git a/src/core/lib/surface/api_trace.h b/src/core/lib/surface/api_trace.h index af53829de4..00d71677e5 100644 --- a/src/core/lib/surface/api_trace.h +++ b/src/core/lib/surface/api_trace.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SURFACE_API_TRACE_H -#define GRPC_CORE_SURFACE_API_TRACE_H +#ifndef GRPC_CORE_LIB_SURFACE_API_TRACE_H +#define GRPC_CORE_LIB_SURFACE_API_TRACE_H #include #include "src/core/debug/trace.h" @@ -62,4 +62,4 @@ extern int grpc_api_trace; gpr_log(GPR_INFO, fmt GRPC_API_TRACE_UNWRAP##nargs args); \ } -#endif /* GRPC_CORE_SURFACE_API_TRACE_H */ +#endif /* GRPC_CORE_LIB_SURFACE_API_TRACE_H */ diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index d2edf03d45..09e19dc779 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SURFACE_CALL_H -#define GRPC_CORE_SURFACE_CALL_H +#ifndef GRPC_CORE_LIB_SURFACE_CALL_H +#define GRPC_CORE_LIB_SURFACE_CALL_H #include "src/core/channel/channel_stack.h" #include "src/core/channel/context.h" @@ -113,4 +113,4 @@ grpc_compression_algorithm grpc_call_compression_for_level( } #endif -#endif /* GRPC_CORE_SURFACE_CALL_H */ +#endif /* GRPC_CORE_LIB_SURFACE_CALL_H */ diff --git a/src/core/lib/surface/call_test_only.h b/src/core/lib/surface/call_test_only.h index fdc43a383b..400214189e 100644 --- a/src/core/lib/surface/call_test_only.h +++ b/src/core/lib/surface/call_test_only.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SURFACE_CALL_TEST_ONLY_H -#define GRPC_CORE_SURFACE_CALL_TEST_ONLY_H +#ifndef GRPC_CORE_LIB_SURFACE_CALL_TEST_ONLY_H +#define GRPC_CORE_LIB_SURFACE_CALL_TEST_ONLY_H #include @@ -61,4 +61,4 @@ uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call); } #endif -#endif /* GRPC_CORE_SURFACE_CALL_TEST_ONLY_H */ +#endif /* GRPC_CORE_LIB_SURFACE_CALL_TEST_ONLY_H */ diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h index 6a803ffe23..d0e15bbeb8 100644 --- a/src/core/lib/surface/channel.h +++ b/src/core/lib/surface/channel.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SURFACE_CHANNEL_H -#define GRPC_CORE_SURFACE_CHANNEL_H +#ifndef GRPC_CORE_LIB_SURFACE_CHANNEL_H +#define GRPC_CORE_LIB_SURFACE_CHANNEL_H #include "src/core/channel/channel_stack.h" #include "src/core/client_config/subchannel_factory.h" @@ -72,4 +72,4 @@ void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, grpc_channel_internal_unref(exec_ctx, channel) #endif -#endif /* GRPC_CORE_SURFACE_CHANNEL_H */ +#endif /* GRPC_CORE_LIB_SURFACE_CHANNEL_H */ diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index 06faef6ddb..ef994b940f 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SURFACE_CHANNEL_INIT_H -#define GRPC_CORE_SURFACE_CHANNEL_INIT_H +#ifndef GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H +#define GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H #include "src/core/channel/channel_stack_builder.h" #include "src/core/surface/channel_stack_type.h" @@ -83,4 +83,4 @@ void *grpc_channel_init_create_stack( const grpc_channel_args *args, int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg, grpc_transport *optional_transport); -#endif /* GRPC_CORE_SURFACE_CHANNEL_INIT_H */ +#endif /* GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H */ diff --git a/src/core/lib/surface/channel_stack_type.h b/src/core/lib/surface/channel_stack_type.h index 75a1b9c072..16608fa386 100644 --- a/src/core/lib/surface/channel_stack_type.h +++ b/src/core/lib/surface/channel_stack_type.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SURFACE_CHANNEL_STACK_TYPE_H -#define GRPC_CORE_SURFACE_CHANNEL_STACK_TYPE_H +#ifndef GRPC_CORE_LIB_SURFACE_CHANNEL_STACK_TYPE_H +#define GRPC_CORE_LIB_SURFACE_CHANNEL_STACK_TYPE_H #include @@ -55,4 +55,4 @@ typedef enum { bool grpc_channel_stack_type_is_client(grpc_channel_stack_type type); -#endif /* GRPC_CORE_SURFACE_CHANNEL_STACK_TYPE_H */ +#endif /* GRPC_CORE_LIB_SURFACE_CHANNEL_STACK_TYPE_H */ diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index 213d89c079..08c07f3baa 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SURFACE_COMPLETION_QUEUE_H -#define GRPC_CORE_SURFACE_COMPLETION_QUEUE_H +#ifndef GRPC_CORE_LIB_SURFACE_COMPLETION_QUEUE_H +#define GRPC_CORE_LIB_SURFACE_COMPLETION_QUEUE_H /* Internal API for completion queues */ @@ -88,4 +88,4 @@ int grpc_cq_is_server_cq(grpc_completion_queue *cc); void grpc_cq_global_init(void); void grpc_cq_global_shutdown(void); -#endif /* GRPC_CORE_SURFACE_COMPLETION_QUEUE_H */ +#endif /* GRPC_CORE_LIB_SURFACE_COMPLETION_QUEUE_H */ diff --git a/src/core/lib/surface/event_string.h b/src/core/lib/surface/event_string.h index d0598cecca..577e9c718f 100644 --- a/src/core/lib/surface/event_string.h +++ b/src/core/lib/surface/event_string.h @@ -31,12 +31,12 @@ * */ -#ifndef GRPC_CORE_SURFACE_EVENT_STRING_H -#define GRPC_CORE_SURFACE_EVENT_STRING_H +#ifndef GRPC_CORE_LIB_SURFACE_EVENT_STRING_H +#define GRPC_CORE_LIB_SURFACE_EVENT_STRING_H #include /* Returns a string describing an event. Must be later freed with gpr_free() */ char *grpc_event_string(grpc_event *ev); -#endif /* GRPC_CORE_SURFACE_EVENT_STRING_H */ +#endif /* GRPC_CORE_LIB_SURFACE_EVENT_STRING_H */ diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index 5e358c7022..10e2a5896e 100644 --- a/src/core/lib/surface/init.h +++ b/src/core/lib/surface/init.h @@ -31,11 +31,11 @@ * */ -#ifndef GRPC_CORE_SURFACE_INIT_H -#define GRPC_CORE_SURFACE_INIT_H +#ifndef GRPC_CORE_LIB_SURFACE_INIT_H +#define GRPC_CORE_LIB_SURFACE_INIT_H void grpc_register_security_filters(void); void grpc_security_pre_init(void); int grpc_is_initialized(void); -#endif /* GRPC_CORE_SURFACE_INIT_H */ +#endif /* GRPC_CORE_LIB_SURFACE_INIT_H */ diff --git a/src/core/lib/surface/lame_client.h b/src/core/lib/surface/lame_client.h index 3f3abd2ffe..cee9500f3e 100644 --- a/src/core/lib/surface/lame_client.h +++ b/src/core/lib/surface/lame_client.h @@ -31,11 +31,11 @@ * */ -#ifndef GRPC_CORE_SURFACE_LAME_CLIENT_H -#define GRPC_CORE_SURFACE_LAME_CLIENT_H +#ifndef GRPC_CORE_LIB_SURFACE_LAME_CLIENT_H +#define GRPC_CORE_LIB_SURFACE_LAME_CLIENT_H #include "src/core/channel/channel_stack.h" extern const grpc_channel_filter grpc_lame_filter; -#endif /* GRPC_CORE_SURFACE_LAME_CLIENT_H */ +#endif /* GRPC_CORE_LIB_SURFACE_LAME_CLIENT_H */ diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index cd62eadd7f..969d268053 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SURFACE_SERVER_H -#define GRPC_CORE_SURFACE_SERVER_H +#ifndef GRPC_CORE_LIB_SURFACE_SERVER_H +#define GRPC_CORE_LIB_SURFACE_SERVER_H #include #include "src/core/channel/channel_stack.h" @@ -59,4 +59,4 @@ const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server); int grpc_server_has_open_connections(grpc_server *server); -#endif /* GRPC_CORE_SURFACE_SERVER_H */ +#endif /* GRPC_CORE_LIB_SURFACE_SERVER_H */ diff --git a/src/core/lib/surface/surface_trace.h b/src/core/lib/surface/surface_trace.h index a55a88e44d..1046eb0c83 100644 --- a/src/core/lib/surface/surface_trace.h +++ b/src/core/lib/surface/surface_trace.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_SURFACE_SURFACE_TRACE_H -#define GRPC_CORE_SURFACE_SURFACE_TRACE_H +#ifndef GRPC_CORE_LIB_SURFACE_SURFACE_TRACE_H +#define GRPC_CORE_LIB_SURFACE_SURFACE_TRACE_H #include #include "src/core/debug/trace.h" @@ -45,4 +45,4 @@ gpr_free(_ev); \ } -#endif /* GRPC_CORE_SURFACE_SURFACE_TRACE_H */ +#endif /* GRPC_CORE_LIB_SURFACE_SURFACE_TRACE_H */ diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h index ab42d07e7e..ae01f91295 100644 --- a/src/core/lib/transport/byte_stream.h +++ b/src/core/lib/transport/byte_stream.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_BYTE_STREAM_H -#define GRPC_CORE_TRANSPORT_BYTE_STREAM_H +#ifndef GRPC_CORE_LIB_TRANSPORT_BYTE_STREAM_H +#define GRPC_CORE_LIB_TRANSPORT_BYTE_STREAM_H #include #include "src/core/iomgr/exec_ctx.h" @@ -86,4 +86,4 @@ void grpc_slice_buffer_stream_init(grpc_slice_buffer_stream *stream, gpr_slice_buffer *slice_buffer, uint32_t flags); -#endif /* GRPC_CORE_TRANSPORT_BYTE_STREAM_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_BYTE_STREAM_H */ diff --git a/src/core/lib/transport/chttp2/alpn.h b/src/core/lib/transport/chttp2/alpn.h index 68010e3155..a9184e63a4 100644 --- a/src/core/lib/transport/chttp2/alpn.h +++ b/src/core/lib/transport/chttp2/alpn.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_ALPN_H -#define GRPC_CORE_TRANSPORT_CHTTP2_ALPN_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_ALPN_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_ALPN_H #include @@ -46,4 +46,4 @@ size_t grpc_chttp2_num_alpn_versions(void); * grpc_chttp2_num_alpn_versions()) */ const char *grpc_chttp2_get_alpn_version_index(size_t i); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_ALPN_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_ALPN_H */ diff --git a/src/core/lib/transport/chttp2/bin_encoder.h b/src/core/lib/transport/chttp2/bin_encoder.h index edb6f2dad1..1c5cd1e1c6 100644 --- a/src/core/lib/transport/chttp2/bin_encoder.h +++ b/src/core/lib/transport/chttp2/bin_encoder.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H -#define GRPC_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_BIN_ENCODER_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_BIN_ENCODER_H #include @@ -51,4 +51,4 @@ gpr_slice grpc_chttp2_huffman_compress(gpr_slice input); return y; */ gpr_slice grpc_chttp2_base64_encode_and_huffman_compress(gpr_slice input); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_BIN_ENCODER_H */ diff --git a/src/core/lib/transport/chttp2/frame.h b/src/core/lib/transport/chttp2/frame.h index 560a6675af..4674bc9703 100644 --- a/src/core/lib/transport/chttp2/frame.h +++ b/src/core/lib/transport/chttp2/frame.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_H #include #include @@ -66,4 +66,4 @@ typedef struct grpc_chttp2_transport_parsing grpc_chttp2_transport_parsing; #define GRPC_CHTTP2_DATA_FLAG_PADDED 8 #define GRPC_CHTTP2_FLAG_HAS_PRIORITY 0x20 -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_H */ diff --git a/src/core/lib/transport/chttp2/frame_data.h b/src/core/lib/transport/chttp2/frame_data.h index 9dbaa60d44..725863bbb7 100644 --- a/src/core/lib/transport/chttp2/frame_data.h +++ b/src/core/lib/transport/chttp2/frame_data.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_DATA_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_DATA_H /* Parser for GRPC streams embedded in DATA frames */ @@ -98,4 +98,4 @@ void grpc_chttp2_encode_data(uint32_t id, gpr_slice_buffer *inbuf, uint32_t write_bytes, int is_eof, gpr_slice_buffer *outbuf); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_DATA_H */ diff --git a/src/core/lib/transport/chttp2/frame_goaway.h b/src/core/lib/transport/chttp2/frame_goaway.h index b980e47723..1ed2b62ec6 100644 --- a/src/core/lib/transport/chttp2/frame_goaway.h +++ b/src/core/lib/transport/chttp2/frame_goaway.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_GOAWAY_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_GOAWAY_H #include #include @@ -74,4 +74,4 @@ void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code, gpr_slice debug_data, gpr_slice_buffer *slice_buffer); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_GOAWAY_H */ diff --git a/src/core/lib/transport/chttp2/frame_ping.h b/src/core/lib/transport/chttp2/frame_ping.h index 2412cd7a6f..87bf1d3257 100644 --- a/src/core/lib/transport/chttp2/frame_ping.h +++ b/src/core/lib/transport/chttp2/frame_ping.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_PING_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_PING_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_PING_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_PING_H #include #include "src/core/iomgr/exec_ctx.h" @@ -53,4 +53,4 @@ grpc_chttp2_parse_error grpc_chttp2_ping_parser_parse( grpc_chttp2_transport_parsing *transport_parsing, grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_PING_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_PING_H */ diff --git a/src/core/lib/transport/chttp2/frame_rst_stream.h b/src/core/lib/transport/chttp2/frame_rst_stream.h index f725c5d767..2dd009d3c2 100644 --- a/src/core/lib/transport/chttp2/frame_rst_stream.h +++ b/src/core/lib/transport/chttp2/frame_rst_stream.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H #include #include "src/core/iomgr/exec_ctx.h" @@ -52,4 +52,4 @@ grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_parse( grpc_chttp2_transport_parsing *transport_parsing, grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H */ diff --git a/src/core/lib/transport/chttp2/frame_settings.h b/src/core/lib/transport/chttp2/frame_settings.h index 59dbff9b40..fa1db96638 100644 --- a/src/core/lib/transport/chttp2/frame_settings.h +++ b/src/core/lib/transport/chttp2/frame_settings.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_SETTINGS_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_SETTINGS_H #include #include @@ -100,4 +100,4 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse( grpc_chttp2_transport_parsing *transport_parsing, grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_SETTINGS_H */ diff --git a/src/core/lib/transport/chttp2/frame_window_update.h b/src/core/lib/transport/chttp2/frame_window_update.h index 9b7ca3ce63..88e458bbfb 100644 --- a/src/core/lib/transport/chttp2/frame_window_update.h +++ b/src/core/lib/transport/chttp2/frame_window_update.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H -#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H #include #include "src/core/iomgr/exec_ctx.h" @@ -53,4 +53,4 @@ grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse( grpc_chttp2_transport_parsing *transport_parsing, grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H */ diff --git a/src/core/lib/transport/chttp2/hpack_encoder.h b/src/core/lib/transport/chttp2/hpack_encoder.h index 6d86eb7c83..e842f5719e 100644 --- a/src/core/lib/transport/chttp2/hpack_encoder.h +++ b/src/core/lib/transport/chttp2/hpack_encoder.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H -#define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_HPACK_ENCODER_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_HPACK_ENCODER_H #include #include @@ -92,4 +92,4 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, uint32_t id, grpc_metadata_batch *metadata, int is_eof, gpr_slice_buffer *outbuf); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_HPACK_ENCODER_H */ diff --git a/src/core/lib/transport/chttp2/hpack_parser.h b/src/core/lib/transport/chttp2/hpack_parser.h index 6a6d136da2..2a47cdf93c 100644 --- a/src/core/lib/transport/chttp2/hpack_parser.h +++ b/src/core/lib/transport/chttp2/hpack_parser.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H -#define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_HPACK_PARSER_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_HPACK_PARSER_H #include @@ -113,4 +113,4 @@ grpc_chttp2_parse_error grpc_chttp2_header_parser_parse( grpc_chttp2_transport_parsing *transport_parsing, grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_HPACK_PARSER_H */ diff --git a/src/core/lib/transport/chttp2/hpack_table.h b/src/core/lib/transport/chttp2/hpack_table.h index c984ca35e4..eddb99ee1c 100644 --- a/src/core/lib/transport/chttp2/hpack_table.h +++ b/src/core/lib/transport/chttp2/hpack_table.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H -#define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_HPACK_TABLE_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_HPACK_TABLE_H #include #include @@ -105,4 +105,4 @@ typedef struct { grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find( const grpc_chttp2_hptbl *tbl, grpc_mdelem *md); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_HPACK_TABLE_H */ diff --git a/src/core/lib/transport/chttp2/http2_errors.h b/src/core/lib/transport/chttp2/http2_errors.h index 4290df3d89..0238f9d80b 100644 --- a/src/core/lib/transport/chttp2/http2_errors.h +++ b/src/core/lib/transport/chttp2/http2_errors.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H -#define GRPC_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_HTTP2_ERRORS_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_HTTP2_ERRORS_H /* error codes for RST_STREAM from http2 draft 14 section 7 */ typedef enum { @@ -53,4 +53,4 @@ typedef enum { GRPC_CHTTP2__ERROR_DO_NOT_USE = -1 } grpc_chttp2_error_code; -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_HTTP2_ERRORS_H */ diff --git a/src/core/lib/transport/chttp2/huffsyms.h b/src/core/lib/transport/chttp2/huffsyms.h index 9c4f09dcf6..1ca77b9207 100644 --- a/src/core/lib/transport/chttp2/huffsyms.h +++ b/src/core/lib/transport/chttp2/huffsyms.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H -#define GRPC_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_HUFFSYMS_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_HUFFSYMS_H /* HPACK static huffman table */ @@ -45,4 +45,4 @@ typedef struct { extern const grpc_chttp2_huffsym grpc_chttp2_huffsyms[GRPC_CHTTP2_NUM_HUFFSYMS]; -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_HUFFSYMS_H */ diff --git a/src/core/lib/transport/chttp2/incoming_metadata.h b/src/core/lib/transport/chttp2/incoming_metadata.h index 52454f348c..87f360e1f2 100644 --- a/src/core/lib/transport/chttp2/incoming_metadata.h +++ b/src/core/lib/transport/chttp2/incoming_metadata.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_INCOMING_METADATA_H -#define GRPC_CORE_TRANSPORT_CHTTP2_INCOMING_METADATA_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_INCOMING_METADATA_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_INCOMING_METADATA_H #include "src/core/transport/transport.h" @@ -57,4 +57,4 @@ void grpc_chttp2_incoming_metadata_buffer_add( void grpc_chttp2_incoming_metadata_buffer_set_deadline( grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_INCOMING_METADATA_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_INCOMING_METADATA_H */ diff --git a/src/core/lib/transport/chttp2/internal.h b/src/core/lib/transport/chttp2/internal.h index 0690cb37cd..2e7b334426 100644 --- a/src/core/lib/transport/chttp2/internal.h +++ b/src/core/lib/transport/chttp2/internal.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_INTERNAL_H -#define GRPC_CORE_TRANSPORT_CHTTP2_INTERNAL_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_INTERNAL_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_INTERNAL_H #include #include @@ -777,4 +777,4 @@ void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_INTERNAL_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_INTERNAL_H */ diff --git a/src/core/lib/transport/chttp2/status_conversion.h b/src/core/lib/transport/chttp2/status_conversion.h index c6e066bb5d..12720c05f9 100644 --- a/src/core/lib/transport/chttp2/status_conversion.h +++ b/src/core/lib/transport/chttp2/status_conversion.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H -#define GRPC_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_STATUS_CONVERSION_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_STATUS_CONVERSION_H #include #include "src/core/transport/chttp2/http2_errors.h" @@ -47,4 +47,4 @@ grpc_status_code grpc_chttp2_http2_error_to_grpc_status( grpc_status_code grpc_chttp2_http2_status_to_grpc_status(int status); int grpc_chttp2_grpc_status_to_http2_status(grpc_status_code status); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_STATUS_CONVERSION_H */ diff --git a/src/core/lib/transport/chttp2/stream_map.h b/src/core/lib/transport/chttp2/stream_map.h index 957a58a4f2..1c56b18e54 100644 --- a/src/core/lib/transport/chttp2/stream_map.h +++ b/src/core/lib/transport/chttp2/stream_map.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H -#define GRPC_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_STREAM_MAP_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_STREAM_MAP_H #include @@ -81,4 +81,4 @@ void grpc_chttp2_stream_map_for_each(grpc_chttp2_stream_map *map, void *value), void *user_data); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_STREAM_MAP_H */ diff --git a/src/core/lib/transport/chttp2/timeout_encoding.h b/src/core/lib/transport/chttp2/timeout_encoding.h index f8e25226eb..9bb3c36d72 100644 --- a/src/core/lib/transport/chttp2/timeout_encoding.h +++ b/src/core/lib/transport/chttp2/timeout_encoding.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H -#define GRPC_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H #include #include "src/core/support/string.h" @@ -44,4 +44,4 @@ void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer); int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H */ diff --git a/src/core/lib/transport/chttp2/varint.h b/src/core/lib/transport/chttp2/varint.h index 7ab9d22ab5..e4a0ae3c22 100644 --- a/src/core/lib/transport/chttp2/varint.h +++ b/src/core/lib/transport/chttp2/varint.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_VARINT_H -#define GRPC_CORE_TRANSPORT_CHTTP2_VARINT_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_VARINT_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_VARINT_H #include @@ -72,4 +72,4 @@ void grpc_chttp2_hpack_write_varint_tail(uint32_t tail_value, uint8_t* target, } \ } while (0) -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_VARINT_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_VARINT_H */ diff --git a/src/core/lib/transport/chttp2_transport.h b/src/core/lib/transport/chttp2_transport.h index 9a6cf0ed35..b188219982 100644 --- a/src/core/lib/transport/chttp2_transport.h +++ b/src/core/lib/transport/chttp2_transport.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CHTTP2_TRANSPORT_H -#define GRPC_CORE_TRANSPORT_CHTTP2_TRANSPORT_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_TRANSPORT_H +#define GRPC_CORE_LIB_TRANSPORT_CHTTP2_TRANSPORT_H #include "src/core/iomgr/endpoint.h" #include "src/core/transport/transport.h" @@ -48,4 +48,4 @@ void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, grpc_transport *transport, gpr_slice *slices, size_t nslices); -#endif /* GRPC_CORE_TRANSPORT_CHTTP2_TRANSPORT_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CHTTP2_TRANSPORT_H */ diff --git a/src/core/lib/transport/connectivity_state.h b/src/core/lib/transport/connectivity_state.h index b4a3ce924d..dc6623c46c 100644 --- a/src/core/lib/transport/connectivity_state.h +++ b/src/core/lib/transport/connectivity_state.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_CONNECTIVITY_STATE_H -#define GRPC_CORE_TRANSPORT_CONNECTIVITY_STATE_H +#ifndef GRPC_CORE_LIB_TRANSPORT_CONNECTIVITY_STATE_H +#define GRPC_CORE_LIB_TRANSPORT_CONNECTIVITY_STATE_H #include #include "src/core/iomgr/exec_ctx.h" @@ -82,4 +82,4 @@ int grpc_connectivity_state_notify_on_state_change( grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker, grpc_connectivity_state *current, grpc_closure *notify); -#endif /* GRPC_CORE_TRANSPORT_CONNECTIVITY_STATE_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_CONNECTIVITY_STATE_H */ diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 5ab397848c..d72ec9accc 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_METADATA_H -#define GRPC_CORE_TRANSPORT_METADATA_H +#ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_H +#define GRPC_CORE_LIB_TRANSPORT_METADATA_H #include #include @@ -153,4 +153,4 @@ int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s); void grpc_mdctx_global_init(void); void grpc_mdctx_global_shutdown(void); -#endif /* GRPC_CORE_TRANSPORT_METADATA_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */ diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index 9337b28328..4c9395e6c0 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_METADATA_BATCH_H -#define GRPC_CORE_TRANSPORT_METADATA_BATCH_H +#ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H +#define GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H #include #include @@ -122,4 +122,4 @@ void grpc_metadata_batch_assert_ok(grpc_metadata_batch *comd); } while (0) #endif -#endif /* GRPC_CORE_TRANSPORT_METADATA_BATCH_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H */ diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 85442f8107..bfcb010387 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -43,8 +43,8 @@ * explanation of what's going on. */ -#ifndef GRPC_CORE_TRANSPORT_STATIC_METADATA_H -#define GRPC_CORE_TRANSPORT_STATIC_METADATA_H +#ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H +#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H #include "src/core/transport/metadata.h" @@ -405,4 +405,4 @@ extern const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT]; extern const uint8_t grpc_static_accept_encoding_metadata[8]; #define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \ (&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]]) -#endif /* GRPC_CORE_TRANSPORT_STATIC_METADATA_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */ diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index f43e56f23c..4174f049d5 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_TRANSPORT_H -#define GRPC_CORE_TRANSPORT_TRANSPORT_H +#ifndef GRPC_CORE_LIB_TRANSPORT_TRANSPORT_H +#define GRPC_CORE_LIB_TRANSPORT_TRANSPORT_H #include @@ -239,4 +239,4 @@ void grpc_transport_destroy(grpc_exec_ctx *exec_ctx, grpc_transport *transport); char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *transport); -#endif /* GRPC_CORE_TRANSPORT_TRANSPORT_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_TRANSPORT_H */ diff --git a/src/core/lib/transport/transport_impl.h b/src/core/lib/transport/transport_impl.h index d9ecc4d2ba..60fd27a8dc 100644 --- a/src/core/lib/transport/transport_impl.h +++ b/src/core/lib/transport/transport_impl.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TRANSPORT_TRANSPORT_IMPL_H -#define GRPC_CORE_TRANSPORT_TRANSPORT_IMPL_H +#ifndef GRPC_CORE_LIB_TRANSPORT_TRANSPORT_IMPL_H +#define GRPC_CORE_LIB_TRANSPORT_TRANSPORT_IMPL_H #include "src/core/transport/transport.h" @@ -78,4 +78,4 @@ struct grpc_transport { const grpc_transport_vtable *vtable; }; -#endif /* GRPC_CORE_TRANSPORT_TRANSPORT_IMPL_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_TRANSPORT_IMPL_H */ diff --git a/src/core/lib/tsi/fake_transport_security.h b/src/core/lib/tsi/fake_transport_security.h index 6b8e596290..718c1a50db 100644 --- a/src/core/lib/tsi/fake_transport_security.h +++ b/src/core/lib/tsi/fake_transport_security.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H -#define GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H +#ifndef GRPC_CORE_LIB_TSI_FAKE_TRANSPORT_SECURITY_H +#define GRPC_CORE_LIB_TSI_FAKE_TRANSPORT_SECURITY_H #include "src/core/tsi/transport_security_interface.h" @@ -58,4 +58,4 @@ tsi_frame_protector *tsi_create_fake_protector( } #endif -#endif /* GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H */ +#endif /* GRPC_CORE_LIB_TSI_FAKE_TRANSPORT_SECURITY_H */ diff --git a/src/core/lib/tsi/ssl_transport_security.h b/src/core/lib/tsi/ssl_transport_security.h index 612f5c64cc..441b010e4e 100644 --- a/src/core/lib/tsi/ssl_transport_security.h +++ b/src/core/lib/tsi/ssl_transport_security.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H -#define GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H +#ifndef GRPC_CORE_LIB_TSI_SSL_TRANSPORT_SECURITY_H +#define GRPC_CORE_LIB_TSI_SSL_TRANSPORT_SECURITY_H #include "src/core/tsi/transport_security_interface.h" @@ -171,4 +171,4 @@ int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name); } #endif -#endif /* GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H */ +#endif /* GRPC_CORE_LIB_TSI_SSL_TRANSPORT_SECURITY_H */ diff --git a/src/core/lib/tsi/ssl_types.h b/src/core/lib/tsi/ssl_types.h index 6ea85fe6d4..c6e68c01ad 100644 --- a/src/core/lib/tsi/ssl_types.h +++ b/src/core/lib/tsi/ssl_types.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TSI_SSL_TYPES_H -#define GRPC_CORE_TSI_SSL_TYPES_H +#ifndef GRPC_CORE_LIB_TSI_SSL_TYPES_H +#define GRPC_CORE_LIB_TSI_SSL_TYPES_H /* A collection of macros to cast between various integer types that are * used differently between BoringSSL and OpenSSL: @@ -52,4 +52,4 @@ #define TSI_SIZE_AS_SIZE(x) ((int)(x)) #endif -#endif /* GRPC_CORE_TSI_SSL_TYPES_H */ +#endif /* GRPC_CORE_LIB_TSI_SSL_TYPES_H */ diff --git a/src/core/lib/tsi/transport_security.h b/src/core/lib/tsi/transport_security.h index ecc037193b..292af7ffb9 100644 --- a/src/core/lib/tsi/transport_security.h +++ b/src/core/lib/tsi/transport_security.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_H -#define GRPC_CORE_TSI_TRANSPORT_SECURITY_H +#ifndef GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H +#define GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H #include "src/core/tsi/transport_security_interface.h" @@ -108,4 +108,4 @@ char *tsi_strdup(const char *src); /* Sadly, no strdup in C89. */ } #endif -#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_H */ +#endif /* GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H */ diff --git a/src/core/lib/tsi/transport_security_interface.h b/src/core/lib/tsi/transport_security_interface.h index 08501802f5..f88f1516a9 100644 --- a/src/core/lib/tsi/transport_security_interface.h +++ b/src/core/lib/tsi/transport_security_interface.h @@ -31,8 +31,8 @@ * */ -#ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H -#define GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H +#ifndef GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_INTERFACE_H +#define GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_INTERFACE_H #include #include @@ -341,4 +341,4 @@ void tsi_handshaker_destroy(tsi_handshaker *self); } #endif -#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H */ +#endif /* GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_INTERFACE_H */ -- cgit v1.2.3 From 8a9fd52b712cf8aa415a4c2cdcd5aa6ac96bb698 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 25 Mar 2016 17:09:29 -0700 Subject: Fix copyright --- src/core/lib/census/grpc_context.c | 2 +- src/core/lib/census/operation.c | 2 +- src/core/lib/census/tracing.c | 2 +- src/core/lib/channel/channel_stack.c | 2 +- src/core/lib/client_config/default_initial_connect_string.c | 2 +- src/core/lib/client_config/initial_connect_string.c | 2 +- src/core/lib/client_config/lb_policy_factory.c | 2 +- src/core/lib/client_config/lb_policy_registry.c | 2 +- src/core/lib/client_config/resolver.c | 2 +- src/core/lib/client_config/resolver_factory.c | 2 +- src/core/lib/client_config/resolver_registry.c | 2 +- src/core/lib/client_config/subchannel_factory.c | 2 +- src/core/lib/client_config/uri_parser.c | 2 +- src/core/lib/compression/message_compress.c | 2 +- src/core/lib/debug/trace.c | 2 +- src/core/lib/iomgr/endpoint.c | 2 +- src/core/lib/iomgr/socket_utils_posix.c | 2 +- src/core/lib/iomgr/time_averaged_stats.c | 2 +- src/core/lib/iomgr/wakeup_fd_eventfd.c | 2 +- src/core/lib/iomgr/workqueue_windows.c | 2 +- src/core/lib/json/json.c | 2 +- src/core/lib/json/json_reader.c | 2 +- src/core/lib/json/json_writer.c | 2 +- src/core/lib/profiling/stap_timers.c | 2 +- src/core/lib/profiling/timers.h | 2 +- src/core/lib/security/credentials_metadata.c | 2 +- src/core/lib/security/credentials_posix.c | 2 +- src/core/lib/security/credentials_win32.c | 2 +- src/core/lib/support/cpu_iphone.c | 2 +- src/core/lib/support/cpu_windows.c | 2 +- src/core/lib/support/log.c | 2 +- src/core/lib/support/murmur_hash.c | 2 +- src/core/lib/support/slice.c | 2 +- src/core/lib/support/slice_buffer.c | 2 +- src/core/lib/support/string.c | 2 +- src/core/lib/support/thd.c | 2 +- src/core/lib/support/time_precise.c | 2 +- src/core/lib/support/tls_pthread.c | 2 +- src/core/lib/surface/api_trace.c | 2 +- src/core/lib/surface/byte_buffer.c | 2 +- src/core/lib/surface/call_details.c | 2 +- src/core/lib/surface/metadata_array.c | 2 +- src/core/lib/transport/byte_stream.c | 2 +- src/core/lib/transport/chttp2/alpn.c | 2 +- src/core/lib/transport/chttp2/frame_goaway.c | 2 +- src/core/lib/transport/chttp2/frame_ping.c | 2 +- src/core/lib/transport/chttp2/frame_rst_stream.c | 2 +- src/core/lib/transport/chttp2/frame_settings.c | 2 +- src/core/lib/transport/chttp2/frame_window_update.c | 2 +- src/core/lib/transport/chttp2/hpack_table.c | 2 +- src/core/lib/transport/chttp2/incoming_metadata.c | 2 +- src/core/lib/transport/chttp2/status_conversion.c | 2 +- src/core/lib/transport/chttp2/stream_map.c | 2 +- src/core/lib/transport/chttp2/varint.c | 2 +- src/core/lib/transport/metadata_batch.c | 2 +- src/core/lib/tsi/transport_security.c | 2 +- 56 files changed, 56 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/core/lib/census/grpc_context.c b/src/core/lib/census/grpc_context.c index 4b61382a2c..09280da3d6 100644 --- a/src/core/lib/census/grpc_context.c +++ b/src/core/lib/census/grpc_context.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/census/operation.c b/src/core/lib/census/operation.c index 5c58704372..315f9c3534 100644 --- a/src/core/lib/census/operation.c +++ b/src/core/lib/census/operation.c @@ -1,5 +1,5 @@ /* - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/census/tracing.c b/src/core/lib/census/tracing.c index 3b5d6dab2b..e508996af3 100644 --- a/src/core/lib/census/tracing.c +++ b/src/core/lib/census/tracing.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c index 3e61688364..39ff1aed5a 100644 --- a/src/core/lib/channel/channel_stack.c +++ b/src/core/lib/channel/channel_stack.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/client_config/default_initial_connect_string.c b/src/core/lib/client_config/default_initial_connect_string.c index 6a4e23e6f2..90b4f96327 100644 --- a/src/core/lib/client_config/default_initial_connect_string.c +++ b/src/core/lib/client_config/default_initial_connect_string.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/client_config/initial_connect_string.c b/src/core/lib/client_config/initial_connect_string.c index 19afa1675a..d199efebde 100644 --- a/src/core/lib/client_config/initial_connect_string.c +++ b/src/core/lib/client_config/initial_connect_string.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/client_config/lb_policy_factory.c b/src/core/lib/client_config/lb_policy_factory.c index e49de544e3..a261922659 100644 --- a/src/core/lib/client_config/lb_policy_factory.c +++ b/src/core/lib/client_config/lb_policy_factory.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/client_config/lb_policy_registry.c b/src/core/lib/client_config/lb_policy_registry.c index fc302e82d7..e836456151 100644 --- a/src/core/lib/client_config/lb_policy_registry.c +++ b/src/core/lib/client_config/lb_policy_registry.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/client_config/resolver.c b/src/core/lib/client_config/resolver.c index eda01e72ba..8c677978f8 100644 --- a/src/core/lib/client_config/resolver.c +++ b/src/core/lib/client_config/resolver.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/client_config/resolver_factory.c b/src/core/lib/client_config/resolver_factory.c index e7e9196ac4..6ee56f0063 100644 --- a/src/core/lib/client_config/resolver_factory.c +++ b/src/core/lib/client_config/resolver_factory.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/client_config/resolver_registry.c b/src/core/lib/client_config/resolver_registry.c index 89a945c2d3..a38b3d8995 100644 --- a/src/core/lib/client_config/resolver_registry.c +++ b/src/core/lib/client_config/resolver_registry.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/client_config/subchannel_factory.c b/src/core/lib/client_config/subchannel_factory.c index 2c64219e8b..8caeaf11bf 100644 --- a/src/core/lib/client_config/subchannel_factory.c +++ b/src/core/lib/client_config/subchannel_factory.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/client_config/uri_parser.c b/src/core/lib/client_config/uri_parser.c index cbdfffcf8e..c1b64778b1 100644 --- a/src/core/lib/client_config/uri_parser.c +++ b/src/core/lib/client_config/uri_parser.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/compression/message_compress.c b/src/core/lib/compression/message_compress.c index edc21a9eb7..c3a21ec19f 100644 --- a/src/core/lib/compression/message_compress.c +++ b/src/core/lib/compression/message_compress.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/debug/trace.c b/src/core/lib/debug/trace.c index 3b35d81cd8..42150b1bc3 100644 --- a/src/core/lib/debug/trace.c +++ b/src/core/lib/debug/trace.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/iomgr/endpoint.c b/src/core/lib/iomgr/endpoint.c index bd64707669..f1bdd0fc6c 100644 --- a/src/core/lib/iomgr/endpoint.c +++ b/src/core/lib/iomgr/endpoint.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/iomgr/socket_utils_posix.c b/src/core/lib/iomgr/socket_utils_posix.c index 3c56b46744..794a5804ac 100644 --- a/src/core/lib/iomgr/socket_utils_posix.c +++ b/src/core/lib/iomgr/socket_utils_posix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/iomgr/time_averaged_stats.c b/src/core/lib/iomgr/time_averaged_stats.c index e075db4373..014162cc3b 100644 --- a/src/core/lib/iomgr/time_averaged_stats.c +++ b/src/core/lib/iomgr/time_averaged_stats.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/iomgr/wakeup_fd_eventfd.c b/src/core/lib/iomgr/wakeup_fd_eventfd.c index f67379e4fc..f4662965cd 100644 --- a/src/core/lib/iomgr/wakeup_fd_eventfd.c +++ b/src/core/lib/iomgr/wakeup_fd_eventfd.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/iomgr/workqueue_windows.c b/src/core/lib/iomgr/workqueue_windows.c index f9ca57557b..dd7fac8b35 100644 --- a/src/core/lib/iomgr/workqueue_windows.c +++ b/src/core/lib/iomgr/workqueue_windows.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/json/json.c b/src/core/lib/json/json.c index 96e11eebb1..b31ee49562 100644 --- a/src/core/lib/json/json.c +++ b/src/core/lib/json/json.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/json/json_reader.c b/src/core/lib/json/json_reader.c index 30da6f28f3..861323d10c 100644 --- a/src/core/lib/json/json_reader.c +++ b/src/core/lib/json/json_reader.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/json/json_writer.c b/src/core/lib/json/json_writer.c index 326ec2d431..abcb3efd98 100644 --- a/src/core/lib/json/json_writer.c +++ b/src/core/lib/json/json_writer.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/profiling/stap_timers.c b/src/core/lib/profiling/stap_timers.c index efcd1af4a1..d67541a339 100644 --- a/src/core/lib/profiling/stap_timers.c +++ b/src/core/lib/profiling/stap_timers.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/profiling/timers.h b/src/core/lib/profiling/timers.h index c8567e8137..1303593ffb 100644 --- a/src/core/lib/profiling/timers.h +++ b/src/core/lib/profiling/timers.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/security/credentials_metadata.c b/src/core/lib/security/credentials_metadata.c index b8a132f1ea..524c003eca 100644 --- a/src/core/lib/security/credentials_metadata.c +++ b/src/core/lib/security/credentials_metadata.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/security/credentials_posix.c b/src/core/lib/security/credentials_posix.c index 0c92bd4a96..488e60c3bc 100644 --- a/src/core/lib/security/credentials_posix.c +++ b/src/core/lib/security/credentials_posix.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/security/credentials_win32.c b/src/core/lib/security/credentials_win32.c index 8ee9f706a1..646b0c21d6 100644 --- a/src/core/lib/security/credentials_win32.c +++ b/src/core/lib/security/credentials_win32.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/support/cpu_iphone.c b/src/core/lib/support/cpu_iphone.c index 82b49b47bc..e83191bada 100644 --- a/src/core/lib/support/cpu_iphone.c +++ b/src/core/lib/support/cpu_iphone.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/support/cpu_windows.c b/src/core/lib/support/cpu_windows.c index ce32eb0a9d..0f84a9e5ea 100644 --- a/src/core/lib/support/cpu_windows.c +++ b/src/core/lib/support/cpu_windows.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/support/log.c b/src/core/lib/support/log.c index 04156a5b1f..cd6a0726cf 100644 --- a/src/core/lib/support/log.c +++ b/src/core/lib/support/log.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/support/murmur_hash.c b/src/core/lib/support/murmur_hash.c index a5261c0cc0..47e9777fec 100644 --- a/src/core/lib/support/murmur_hash.c +++ b/src/core/lib/support/murmur_hash.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/support/slice.c b/src/core/lib/support/slice.c index b9a7c77bda..cf3953ce4e 100644 --- a/src/core/lib/support/slice.c +++ b/src/core/lib/support/slice.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/support/slice_buffer.c b/src/core/lib/support/slice_buffer.c index 66f111d767..563e659dd7 100644 --- a/src/core/lib/support/slice_buffer.c +++ b/src/core/lib/support/slice_buffer.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c index 1f541de40f..e8021ddaba 100644 --- a/src/core/lib/support/string.c +++ b/src/core/lib/support/string.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/support/thd.c b/src/core/lib/support/thd.c index 41daeb5d0e..d59aace38d 100644 --- a/src/core/lib/support/thd.c +++ b/src/core/lib/support/thd.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/support/time_precise.c b/src/core/lib/support/time_precise.c index a2cf74bc84..31ac47e0f8 100644 --- a/src/core/lib/support/time_precise.c +++ b/src/core/lib/support/time_precise.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/support/tls_pthread.c b/src/core/lib/support/tls_pthread.c index 9683a6e547..bdc7ed14ae 100644 --- a/src/core/lib/support/tls_pthread.c +++ b/src/core/lib/support/tls_pthread.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/surface/api_trace.c b/src/core/lib/surface/api_trace.c index 9f0b900d46..06c65c0610 100644 --- a/src/core/lib/surface/api_trace.c +++ b/src/core/lib/surface/api_trace.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/surface/byte_buffer.c b/src/core/lib/surface/byte_buffer.c index fb39c4531d..03071ef92c 100644 --- a/src/core/lib/surface/byte_buffer.c +++ b/src/core/lib/surface/byte_buffer.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/surface/call_details.c b/src/core/lib/surface/call_details.c index 60f0029819..dc5ea22ee7 100644 --- a/src/core/lib/surface/call_details.c +++ b/src/core/lib/surface/call_details.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/surface/metadata_array.c b/src/core/lib/surface/metadata_array.c index 4c7bf17835..57096326a3 100644 --- a/src/core/lib/surface/metadata_array.c +++ b/src/core/lib/surface/metadata_array.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/byte_stream.c b/src/core/lib/transport/byte_stream.c index 8e6fb2cbef..cfba878dc4 100644 --- a/src/core/lib/transport/byte_stream.c +++ b/src/core/lib/transport/byte_stream.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/chttp2/alpn.c b/src/core/lib/transport/chttp2/alpn.c index 69da4e6718..67fff21229 100644 --- a/src/core/lib/transport/chttp2/alpn.c +++ b/src/core/lib/transport/chttp2/alpn.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/chttp2/frame_goaway.c b/src/core/lib/transport/chttp2/frame_goaway.c index 2fa525e989..45a8e2e270 100644 --- a/src/core/lib/transport/chttp2/frame_goaway.c +++ b/src/core/lib/transport/chttp2/frame_goaway.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/chttp2/frame_ping.c b/src/core/lib/transport/chttp2/frame_ping.c index c6ab522283..d619edb2d6 100644 --- a/src/core/lib/transport/chttp2/frame_ping.c +++ b/src/core/lib/transport/chttp2/frame_ping.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/chttp2/frame_rst_stream.c b/src/core/lib/transport/chttp2/frame_rst_stream.c index 754529e4b9..3b4aa623f2 100644 --- a/src/core/lib/transport/chttp2/frame_rst_stream.c +++ b/src/core/lib/transport/chttp2/frame_rst_stream.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/chttp2/frame_settings.c b/src/core/lib/transport/chttp2/frame_settings.c index cc49dd4f69..9c5ad9f30e 100644 --- a/src/core/lib/transport/chttp2/frame_settings.c +++ b/src/core/lib/transport/chttp2/frame_settings.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/chttp2/frame_window_update.c b/src/core/lib/transport/chttp2/frame_window_update.c index 62d9bac117..03b665c9cb 100644 --- a/src/core/lib/transport/chttp2/frame_window_update.c +++ b/src/core/lib/transport/chttp2/frame_window_update.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/chttp2/hpack_table.c b/src/core/lib/transport/chttp2/hpack_table.c index f1ce3b84fd..bf836e0139 100644 --- a/src/core/lib/transport/chttp2/hpack_table.c +++ b/src/core/lib/transport/chttp2/hpack_table.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/chttp2/incoming_metadata.c b/src/core/lib/transport/chttp2/incoming_metadata.c index 315bc2faa1..245d6ac15a 100644 --- a/src/core/lib/transport/chttp2/incoming_metadata.c +++ b/src/core/lib/transport/chttp2/incoming_metadata.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/chttp2/status_conversion.c b/src/core/lib/transport/chttp2/status_conversion.c index bf214b017a..cb566230fc 100644 --- a/src/core/lib/transport/chttp2/status_conversion.c +++ b/src/core/lib/transport/chttp2/status_conversion.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/chttp2/stream_map.c b/src/core/lib/transport/chttp2/stream_map.c index 555a16fb72..6c70229e42 100644 --- a/src/core/lib/transport/chttp2/stream_map.c +++ b/src/core/lib/transport/chttp2/stream_map.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/chttp2/varint.c b/src/core/lib/transport/chttp2/varint.c index 1cc235e989..1b0cf15eba 100644 --- a/src/core/lib/transport/chttp2/varint.c +++ b/src/core/lib/transport/chttp2/varint.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/transport/metadata_batch.c b/src/core/lib/transport/metadata_batch.c index 1266862f82..2e27b461c9 100644 --- a/src/core/lib/transport/metadata_batch.c +++ b/src/core/lib/transport/metadata_batch.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/core/lib/tsi/transport_security.c b/src/core/lib/tsi/transport_security.c index db219a50a6..64aac2c05a 100644 --- a/src/core/lib/tsi/transport_security.c +++ b/src/core/lib/tsi/transport_security.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.3 From 9533d042d4f52cc3cb04ea61ca179cce409e391c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 25 Mar 2016 17:11:06 -0700 Subject: Fix includes --- src/core/lib/census/context.c | 2 +- src/core/lib/census/grpc_context.c | 4 +- src/core/lib/census/grpc_filter.c | 10 ++-- src/core/lib/census/grpc_filter.h | 2 +- src/core/lib/census/grpc_plugin.c | 8 +-- src/core/lib/census/mlog.c | 2 +- src/core/lib/channel/channel_args.c | 4 +- src/core/lib/channel/channel_stack.c | 2 +- src/core/lib/channel/channel_stack.h | 4 +- src/core/lib/channel/channel_stack_builder.c | 2 +- src/core/lib/channel/channel_stack_builder.h | 4 +- src/core/lib/channel/client_channel.c | 18 +++---- src/core/lib/channel/client_channel.h | 4 +- src/core/lib/channel/compress_filter.c | 14 ++--- src/core/lib/channel/compress_filter.h | 2 +- src/core/lib/channel/connected_channel.c | 8 +-- src/core/lib/channel/connected_channel.h | 2 +- src/core/lib/channel/http_client_filter.c | 8 +-- src/core/lib/channel/http_client_filter.h | 2 +- src/core/lib/channel/http_server_filter.c | 6 +-- src/core/lib/channel/http_server_filter.h | 2 +- src/core/lib/channel/subchannel_call_holder.c | 4 +- src/core/lib/channel/subchannel_call_holder.h | 2 +- src/core/lib/client_config/client_config.c | 2 +- src/core/lib/client_config/client_config.h | 2 +- src/core/lib/client_config/connector.c | 2 +- src/core/lib/client_config/connector.h | 6 +-- .../client_config/default_initial_connect_string.c | 2 +- .../lib/client_config/initial_connect_string.c | 2 +- .../lib/client_config/initial_connect_string.h | 2 +- .../client_config/lb_policies/load_balancer_api.c | 2 +- .../client_config/lb_policies/load_balancer_api.h | 4 +- .../lib/client_config/lb_policies/pick_first.c | 6 +-- .../lib/client_config/lb_policies/pick_first.h | 2 +- .../lib/client_config/lb_policies/round_robin.c | 4 +- .../lib/client_config/lb_policies/round_robin.h | 4 +- src/core/lib/client_config/lb_policy.c | 2 +- src/core/lib/client_config/lb_policy.h | 4 +- src/core/lib/client_config/lb_policy_factory.c | 2 +- src/core/lib/client_config/lb_policy_factory.h | 4 +- src/core/lib/client_config/lb_policy_registry.c | 2 +- src/core/lib/client_config/lb_policy_registry.h | 2 +- src/core/lib/client_config/resolver.c | 2 +- src/core/lib/client_config/resolver.h | 6 +-- src/core/lib/client_config/resolver_factory.c | 2 +- src/core/lib/client_config/resolver_factory.h | 6 +-- src/core/lib/client_config/resolver_registry.c | 2 +- src/core/lib/client_config/resolver_registry.h | 2 +- .../lib/client_config/resolvers/dns_resolver.c | 12 ++--- .../lib/client_config/resolvers/dns_resolver.h | 2 +- .../client_config/resolvers/sockaddr_resolver.c | 10 ++-- .../client_config/resolvers/sockaddr_resolver.h | 2 +- .../client_config/resolvers/zookeeper_resolver.c | 14 ++--- .../client_config/resolvers/zookeeper_resolver.h | 2 +- src/core/lib/client_config/subchannel.c | 24 ++++----- src/core/lib/client_config/subchannel.h | 6 +-- src/core/lib/client_config/subchannel_factory.c | 2 +- src/core/lib/client_config/subchannel_factory.h | 4 +- src/core/lib/client_config/subchannel_index.c | 4 +- src/core/lib/client_config/subchannel_index.h | 4 +- src/core/lib/client_config/uri_parser.c | 2 +- src/core/lib/compression/algorithm_metadata.h | 2 +- src/core/lib/compression/compression_algorithm.c | 6 +-- src/core/lib/compression/message_compress.c | 2 +- src/core/lib/debug/trace.c | 4 +- src/core/lib/http/format_request.c | 4 +- src/core/lib/http/format_request.h | 2 +- src/core/lib/http/httpcli.c | 18 +++---- src/core/lib/http/httpcli.h | 8 +-- src/core/lib/http/httpcli_security_connector.c | 8 +-- src/core/lib/http/parser.c | 2 +- src/core/lib/iomgr/closure.c | 2 +- src/core/lib/iomgr/endpoint.c | 2 +- src/core/lib/iomgr/endpoint.h | 4 +- src/core/lib/iomgr/endpoint_pair.h | 2 +- src/core/lib/iomgr/endpoint_pair_posix.c | 10 ++-- src/core/lib/iomgr/endpoint_pair_windows.c | 8 +-- src/core/lib/iomgr/exec_ctx.c | 4 +- src/core/lib/iomgr/exec_ctx.h | 2 +- src/core/lib/iomgr/executor.c | 4 +- src/core/lib/iomgr/executor.h | 2 +- src/core/lib/iomgr/fd_posix.c | 4 +- src/core/lib/iomgr/fd_posix.h | 4 +- src/core/lib/iomgr/iocp_windows.c | 8 +-- src/core/lib/iomgr/iocp_windows.h | 2 +- src/core/lib/iomgr/iomgr.c | 12 ++--- src/core/lib/iomgr/iomgr_internal.h | 2 +- src/core/lib/iomgr/iomgr_posix.c | 8 +-- src/core/lib/iomgr/iomgr_posix.h | 2 +- src/core/lib/iomgr/iomgr_windows.c | 8 +-- src/core/lib/iomgr/pollset.h | 2 +- .../lib/iomgr/pollset_multipoller_with_epoll.c | 8 +-- .../iomgr/pollset_multipoller_with_poll_posix.c | 10 ++-- src/core/lib/iomgr/pollset_posix.c | 12 ++--- src/core/lib/iomgr/pollset_posix.h | 8 +-- src/core/lib/iomgr/pollset_set.h | 2 +- src/core/lib/iomgr/pollset_set_posix.c | 4 +- src/core/lib/iomgr/pollset_set_posix.h | 4 +- src/core/lib/iomgr/pollset_set_windows.c | 2 +- src/core/lib/iomgr/pollset_set_windows.h | 2 +- src/core/lib/iomgr/pollset_windows.c | 8 +-- src/core/lib/iomgr/pollset_windows.h | 2 +- src/core/lib/iomgr/resolve_address.h | 4 +- src/core/lib/iomgr/resolve_address_posix.c | 16 +++--- src/core/lib/iomgr/resolve_address_windows.c | 14 ++--- src/core/lib/iomgr/sockaddr.h | 4 +- src/core/lib/iomgr/sockaddr_utils.c | 6 +-- src/core/lib/iomgr/sockaddr_utils.h | 2 +- src/core/lib/iomgr/socket_utils_common_posix.c | 6 +-- src/core/lib/iomgr/socket_utils_linux.c | 2 +- src/core/lib/iomgr/socket_utils_posix.c | 2 +- src/core/lib/iomgr/socket_windows.c | 10 ++-- src/core/lib/iomgr/socket_windows.h | 4 +- src/core/lib/iomgr/tcp_client.h | 6 +-- src/core/lib/iomgr/tcp_client_posix.c | 20 ++++---- src/core/lib/iomgr/tcp_client_windows.c | 16 +++--- src/core/lib/iomgr/tcp_posix.c | 12 ++--- src/core/lib/iomgr/tcp_posix.h | 4 +- src/core/lib/iomgr/tcp_server.h | 4 +- src/core/lib/iomgr/tcp_server_posix.c | 16 +++--- src/core/lib/iomgr/tcp_server_windows.c | 12 ++--- src/core/lib/iomgr/tcp_windows.c | 14 ++--- src/core/lib/iomgr/tcp_windows.h | 4 +- src/core/lib/iomgr/time_averaged_stats.c | 2 +- src/core/lib/iomgr/timer.c | 6 +-- src/core/lib/iomgr/timer.h | 4 +- src/core/lib/iomgr/timer_heap.c | 2 +- src/core/lib/iomgr/timer_heap.h | 2 +- src/core/lib/iomgr/udp_server.c | 16 +++--- src/core/lib/iomgr/udp_server.h | 4 +- src/core/lib/iomgr/unix_sockets_posix.c | 2 +- src/core/lib/iomgr/unix_sockets_posix.h | 8 +-- src/core/lib/iomgr/unix_sockets_posix_noop.c | 2 +- src/core/lib/iomgr/wakeup_fd_eventfd.c | 4 +- src/core/lib/iomgr/wakeup_fd_nospecial.c | 2 +- src/core/lib/iomgr/wakeup_fd_pipe.c | 4 +- src/core/lib/iomgr/wakeup_fd_pipe.h | 2 +- src/core/lib/iomgr/wakeup_fd_posix.c | 4 +- src/core/lib/iomgr/workqueue.h | 12 ++--- src/core/lib/iomgr/workqueue_posix.c | 6 +-- src/core/lib/iomgr/workqueue_posix.h | 2 +- src/core/lib/iomgr/workqueue_windows.c | 2 +- src/core/lib/json/json.c | 2 +- src/core/lib/json/json.h | 2 +- src/core/lib/json/json_reader.c | 2 +- src/core/lib/json/json_reader.h | 2 +- src/core/lib/json/json_string.c | 6 +-- src/core/lib/json/json_writer.c | 2 +- src/core/lib/json/json_writer.h | 2 +- src/core/lib/profiling/basic_timers.c | 2 +- src/core/lib/profiling/stap_timers.c | 4 +- src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c | 2 +- src/core/lib/security/auth_filters.h | 2 +- src/core/lib/security/b64.c | 2 +- src/core/lib/security/client_auth_filter.c | 16 +++--- src/core/lib/security/credentials.c | 18 +++---- src/core/lib/security/credentials.h | 10 ++-- src/core/lib/security/credentials_metadata.c | 2 +- src/core/lib/security/credentials_posix.c | 6 +-- src/core/lib/security/credentials_win32.c | 6 +-- src/core/lib/security/google_default_credentials.c | 12 ++--- src/core/lib/security/handshake.c | 6 +-- src/core/lib/security/handshake.h | 4 +- src/core/lib/security/json_token.c | 6 +-- src/core/lib/security/json_token.h | 2 +- src/core/lib/security/jwt_verifier.c | 8 +-- src/core/lib/security/jwt_verifier.h | 4 +- src/core/lib/security/secure_endpoint.c | 8 +-- src/core/lib/security/secure_endpoint.h | 2 +- src/core/lib/security/security_connector.c | 22 ++++---- src/core/lib/security/security_connector.h | 6 +-- src/core/lib/security/security_context.c | 8 +-- src/core/lib/security/security_context.h | 4 +- src/core/lib/security/server_auth_filter.c | 6 +-- src/core/lib/security/server_secure_chttp2.c | 24 ++++----- src/core/lib/statistics/census_init.c | 6 +-- src/core/lib/statistics/census_log.c | 2 +- src/core/lib/statistics/census_rpc_stats.c | 14 ++--- src/core/lib/statistics/census_rpc_stats.h | 2 +- src/core/lib/statistics/census_tracing.c | 8 +-- src/core/lib/statistics/census_tracing.h | 2 +- src/core/lib/statistics/hash_table.c | 2 +- src/core/lib/statistics/window_stats.c | 2 +- src/core/lib/support/alloc.c | 2 +- src/core/lib/support/backoff.c | 2 +- src/core/lib/support/cmdline.c | 2 +- src/core/lib/support/env_linux.c | 4 +- src/core/lib/support/env_posix.c | 4 +- src/core/lib/support/env_win32.c | 4 +- src/core/lib/support/host_port.c | 2 +- src/core/lib/support/load_file.c | 6 +-- src/core/lib/support/log_win32.c | 4 +- src/core/lib/support/murmur_hash.c | 2 +- src/core/lib/support/stack_lockfree.c | 2 +- src/core/lib/support/string.c | 2 +- src/core/lib/support/string_win32.c | 2 +- src/core/lib/support/subprocess_windows.c | 4 +- src/core/lib/support/sync_posix.c | 2 +- src/core/lib/support/time_posix.c | 2 +- src/core/lib/support/time_win32.c | 2 +- src/core/lib/support/tmpfile_posix.c | 4 +- src/core/lib/support/tmpfile_win32.c | 4 +- src/core/lib/surface/alarm.c | 4 +- src/core/lib/surface/api_trace.c | 2 +- src/core/lib/surface/api_trace.h | 2 +- src/core/lib/surface/byte_buffer_reader.c | 2 +- src/core/lib/surface/call.c | 20 ++++---- src/core/lib/surface/call.h | 8 +-- src/core/lib/surface/call_details.c | 2 +- src/core/lib/surface/call_log_batch.c | 4 +- src/core/lib/surface/channel.c | 18 +++---- src/core/lib/surface/channel.h | 6 +-- src/core/lib/surface/channel_connectivity.c | 10 ++-- src/core/lib/surface/channel_create.c | 20 ++++---- src/core/lib/surface/channel_init.c | 2 +- src/core/lib/surface/channel_init.h | 6 +-- src/core/lib/surface/channel_ping.c | 6 +-- src/core/lib/surface/channel_stack_type.c | 2 +- src/core/lib/surface/completion_queue.c | 18 +++---- src/core/lib/surface/completion_queue.h | 2 +- src/core/lib/surface/event_string.c | 4 +- src/core/lib/surface/init.c | 60 +++++++++++----------- src/core/lib/surface/init_secure.c | 16 +++--- src/core/lib/surface/init_unsecure.c | 2 +- src/core/lib/surface/lame_client.c | 12 ++--- src/core/lib/surface/lame_client.h | 2 +- src/core/lib/surface/metadata_array.c | 2 +- src/core/lib/surface/secure_channel_create.c | 22 ++++---- src/core/lib/surface/server.c | 26 +++++----- src/core/lib/surface/server.h | 4 +- src/core/lib/surface/server_chttp2.c | 12 ++--- src/core/lib/surface/surface_trace.h | 4 +- src/core/lib/transport/byte_stream.c | 2 +- src/core/lib/transport/byte_stream.h | 2 +- src/core/lib/transport/chttp2/alpn.c | 2 +- src/core/lib/transport/chttp2/bin_encoder.c | 4 +- src/core/lib/transport/chttp2/frame_data.c | 8 +-- src/core/lib/transport/chttp2/frame_data.h | 6 +-- src/core/lib/transport/chttp2/frame_goaway.c | 4 +- src/core/lib/transport/chttp2/frame_goaway.h | 4 +- src/core/lib/transport/chttp2/frame_ping.c | 4 +- src/core/lib/transport/chttp2/frame_ping.h | 4 +- src/core/lib/transport/chttp2/frame_rst_stream.c | 6 +-- src/core/lib/transport/chttp2/frame_rst_stream.h | 4 +- src/core/lib/transport/chttp2/frame_settings.c | 12 ++--- src/core/lib/transport/chttp2/frame_settings.h | 4 +- .../lib/transport/chttp2/frame_window_update.c | 4 +- .../lib/transport/chttp2/frame_window_update.h | 4 +- src/core/lib/transport/chttp2/hpack_encoder.c | 12 ++--- src/core/lib/transport/chttp2/hpack_encoder.h | 6 +-- src/core/lib/transport/chttp2/hpack_parser.c | 10 ++-- src/core/lib/transport/chttp2/hpack_parser.h | 8 +-- src/core/lib/transport/chttp2/hpack_table.c | 4 +- src/core/lib/transport/chttp2/hpack_table.h | 2 +- src/core/lib/transport/chttp2/huffsyms.c | 2 +- src/core/lib/transport/chttp2/incoming_metadata.c | 4 +- src/core/lib/transport/chttp2/incoming_metadata.h | 2 +- src/core/lib/transport/chttp2/internal.h | 28 +++++----- src/core/lib/transport/chttp2/parsing.c | 12 ++--- src/core/lib/transport/chttp2/status_conversion.c | 2 +- src/core/lib/transport/chttp2/status_conversion.h | 2 +- src/core/lib/transport/chttp2/stream_lists.c | 2 +- src/core/lib/transport/chttp2/stream_map.c | 2 +- src/core/lib/transport/chttp2/timeout_encoding.c | 4 +- src/core/lib/transport/chttp2/timeout_encoding.h | 2 +- src/core/lib/transport/chttp2/varint.c | 2 +- src/core/lib/transport/chttp2/writing.c | 6 +-- src/core/lib/transport/chttp2_transport.c | 18 +++---- src/core/lib/transport/chttp2_transport.h | 4 +- src/core/lib/transport/connectivity_state.c | 2 +- src/core/lib/transport/connectivity_state.h | 2 +- src/core/lib/transport/metadata.c | 14 ++--- src/core/lib/transport/metadata_batch.c | 4 +- src/core/lib/transport/metadata_batch.h | 2 +- src/core/lib/transport/static_metadata.c | 2 +- src/core/lib/transport/static_metadata.h | 2 +- src/core/lib/transport/transport.c | 4 +- src/core/lib/transport/transport.h | 10 ++-- src/core/lib/transport/transport_impl.h | 2 +- src/core/lib/transport/transport_op_string.c | 4 +- src/core/lib/tsi/fake_transport_security.c | 4 +- src/core/lib/tsi/fake_transport_security.h | 2 +- src/core/lib/tsi/ssl_transport_security.c | 6 +-- src/core/lib/tsi/ssl_transport_security.h | 2 +- src/core/lib/tsi/transport_security.c | 2 +- src/core/lib/tsi/transport_security.h | 2 +- src/cpp/client/channel.cc | 2 +- src/cpp/client/client_context.cc | 2 +- src/cpp/common/channel_arguments.cc | 2 +- src/cpp/common/core_codegen.cc | 2 +- src/cpp/common/secure_channel_arguments.cc | 2 +- src/cpp/server/server.cc | 2 +- src/cpp/server/server_context.cc | 4 +- src/csharp/ext/grpc_csharp_ext.c | 2 +- test/core/bad_client/bad_client.c | 14 ++--- test/core/bad_client/tests/badreq.c | 2 +- test/core/bad_client/tests/connection_prefix.c | 2 +- test/core/bad_client/tests/headers.c | 2 +- .../core/bad_client/tests/initial_settings_frame.c | 2 +- .../bad_client/tests/server_registered_method.c | 2 +- test/core/bad_client/tests/simple_request.c | 2 +- test/core/bad_client/tests/unknown_frame.c | 2 +- test/core/bad_client/tests/window_overflow.c | 2 +- test/core/bad_ssl/bad_ssl_test.c | 4 +- test/core/bad_ssl/servers/alpn.c | 2 +- test/core/bad_ssl/servers/cert.c | 2 +- test/core/census/mlog_test.c | 2 +- test/core/channel/channel_args_test.c | 2 +- test/core/channel/channel_stack_test.c | 2 +- test/core/client_config/lb_policies_test.c | 14 ++--- .../resolvers/dns_resolver_connectivity_test.c | 6 +-- .../client_config/resolvers/dns_resolver_test.c | 4 +- .../resolvers/sockaddr_resolver_test.c | 4 +- .../set_initial_connect_string_test.c | 8 +-- test/core/client_config/uri_parser_test.c | 2 +- test/core/compression/algorithm_test.c | 4 +- test/core/compression/message_compress_test.c | 4 +- test/core/end2end/cq_verifier.c | 4 +- test/core/end2end/dualstack_socket_test.c | 6 +-- test/core/end2end/fixtures/h2_census.c | 14 ++--- test/core/end2end/fixtures/h2_compress.c | 14 ++--- test/core/end2end/fixtures/h2_fakesec.c | 4 +- test/core/end2end/fixtures/h2_full+pipe.c | 14 ++--- test/core/end2end/fixtures/h2_full+poll+pipe.c | 16 +++--- test/core/end2end/fixtures/h2_full+poll.c | 14 ++--- test/core/end2end/fixtures/h2_full+trace.c | 14 ++--- test/core/end2end/fixtures/h2_full.c | 12 ++--- test/core/end2end/fixtures/h2_oauth2.c | 6 +-- test/core/end2end/fixtures/h2_proxy.c | 12 ++--- test/core/end2end/fixtures/h2_sockpair+trace.c | 22 ++++---- test/core/end2end/fixtures/h2_sockpair.c | 20 ++++---- test/core/end2end/fixtures/h2_sockpair_1byte.c | 20 ++++---- test/core/end2end/fixtures/h2_ssl+poll.c | 12 ++--- test/core/end2end/fixtures/h2_ssl.c | 10 ++-- test/core/end2end/fixtures/h2_ssl_proxy.c | 10 ++-- test/core/end2end/fixtures/h2_uds+poll.c | 16 +++--- test/core/end2end/fixtures/h2_uds.c | 14 ++--- test/core/end2end/tests/bad_hostname.c | 2 +- test/core/end2end/tests/call_creds.c | 4 +- test/core/end2end/tests/cancel_with_status.c | 2 +- test/core/end2end/tests/compressed_payload.c | 6 +-- test/core/end2end/tests/default_host.c | 2 +- test/core/end2end/tests/empty_batch.c | 2 +- test/core/end2end/tests/high_initial_seqno.c | 2 +- test/core/end2end/tests/hpack_size.c | 2 +- test/core/end2end/tests/negative_deadline.c | 2 +- test/core/end2end/tests/registered_call.c | 2 +- test/core/end2end/tests/request_with_flags.c | 2 +- test/core/end2end/tests/server_finishes_request.c | 2 +- test/core/end2end/tests/simple_request.c | 2 +- test/core/fling/client.c | 2 +- test/core/fling/fling_stream_test.c | 2 +- test/core/fling/fling_test.c | 2 +- test/core/fling/server.c | 2 +- test/core/http/format_request_test.c | 2 +- test/core/http/httpcli_test.c | 4 +- test/core/http/httpscli_test.c | 4 +- test/core/http/parser_test.c | 2 +- test/core/iomgr/endpoint_pair_test.c | 4 +- test/core/iomgr/endpoint_tests.h | 2 +- test/core/iomgr/fd_conservation_posix_test.c | 4 +- test/core/iomgr/fd_posix_test.c | 4 +- test/core/iomgr/resolve_address_test.c | 4 +- test/core/iomgr/sockaddr_utils_test.c | 2 +- test/core/iomgr/socket_utils_test.c | 2 +- test/core/iomgr/tcp_client_posix_test.c | 8 +-- test/core/iomgr/tcp_posix_test.c | 2 +- test/core/iomgr/tcp_server_posix_test.c | 6 +-- test/core/iomgr/time_averaged_stats_test.c | 2 +- test/core/iomgr/timer_heap_test.c | 2 +- test/core/iomgr/timer_list_test.c | 2 +- test/core/iomgr/udp_server_test.c | 6 +-- test/core/iomgr/workqueue_test.c | 2 +- test/core/json/json_rewrite.c | 4 +- test/core/json/json_rewrite_test.c | 4 +- test/core/json/json_stream_error_test.c | 4 +- test/core/json/json_test.c | 4 +- test/core/network_benchmarks/low_level_ping_pong.c | 2 +- test/core/profiling/timers_test.c | 2 +- test/core/security/auth_context_test.c | 4 +- test/core/security/b64_test.c | 2 +- test/core/security/create_jwt.c | 6 +-- test/core/security/credentials_test.c | 12 ++--- test/core/security/fetch_oauth2.c | 4 +- test/core/security/json_token_test.c | 6 +-- test/core/security/jwt_verifier_test.c | 8 +-- test/core/security/oauth2_utils.c | 2 +- test/core/security/oauth2_utils.h | 2 +- .../security/print_google_default_creds_token.c | 4 +- test/core/security/secure_endpoint_test.c | 8 +-- test/core/security/security_connector_test.c | 14 ++--- test/core/security/verify_jwt.c | 2 +- test/core/statistics/census_log_tests.c | 2 +- test/core/statistics/census_stub_test.c | 4 +- test/core/statistics/hash_table_test.c | 6 +-- test/core/statistics/rpc_stats_test.c | 6 +-- test/core/statistics/trace_test.c | 6 +-- test/core/statistics/window_stats_test.c | 2 +- test/core/support/backoff_test.c | 2 +- test/core/support/env_test.c | 4 +- test/core/support/load_file_test.c | 6 +-- test/core/support/murmur_hash_test.c | 2 +- test/core/support/stack_lockfree_test.c | 2 +- test/core/support/string_test.c | 2 +- test/core/surface/byte_buffer_reader_test.c | 2 +- test/core/surface/channel_create_test.c | 2 +- test/core/surface/completion_queue_test.c | 4 +- test/core/surface/lame_client_test.c | 8 +-- test/core/surface/secure_channel_create_test.c | 8 +-- test/core/surface/server_chttp2_test.c | 4 +- test/core/transport/chttp2/alpn_test.c | 2 +- test/core/transport/chttp2/bin_encoder_test.c | 4 +- test/core/transport/chttp2/hpack_encoder_test.c | 8 +-- test/core/transport/chttp2/hpack_parser_test.c | 2 +- test/core/transport/chttp2/hpack_table_test.c | 4 +- .../core/transport/chttp2/status_conversion_test.c | 2 +- test/core/transport/chttp2/stream_map_test.c | 2 +- test/core/transport/chttp2/timeout_encoding_test.c | 4 +- test/core/transport/chttp2/varint_test.c | 2 +- test/core/transport/connectivity_state_test.c | 2 +- test/core/transport/metadata_test.c | 6 +-- test/core/tsi/transport_security_test.c | 8 +-- test/core/util/port_posix.c | 4 +- test/core/util/port_server_client.c | 2 +- test/core/util/port_windows.c | 6 +-- test/core/util/reconnect_server.c | 6 +-- test/core/util/test_config.c | 2 +- test/core/util/test_tcp_server.c | 6 +-- test/core/util/test_tcp_server.h | 2 +- test/cpp/common/auth_property_iterator_test.cc | 2 +- test/cpp/common/secure_auth_context_test.cc | 2 +- test/cpp/end2end/async_end2end_test.cc | 2 +- test/cpp/end2end/end2end_test.cc | 2 +- test/cpp/end2end/shutdown_test.cc | 2 +- test/cpp/end2end/thread_stress_test.cc | 2 +- test/cpp/end2end/zookeeper_test.cc | 2 +- test/cpp/grpclb/grpclb_api_test.cc | 2 +- test/cpp/interop/client_helper.h | 2 +- test/cpp/interop/interop_client.cc | 2 +- test/cpp/interop/interop_test.cc | 4 +- test/cpp/interop/server_helper.cc | 2 +- test/cpp/qps/client_sync.cc | 2 +- test/cpp/qps/driver.cc | 2 +- test/cpp/qps/qps_test_with_poll.cc | 2 +- 444 files changed, 1185 insertions(+), 1185 deletions(-) (limited to 'src') diff --git a/src/core/lib/census/context.c b/src/core/lib/census/context.c index 89b8ee0b39..5a118f46a9 100644 --- a/src/core/lib/census/context.c +++ b/src/core/lib/census/context.c @@ -38,7 +38,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" // Functions in this file support the public context API, including // encoding/decoding as part of context propagation across RPC's. The overall diff --git a/src/core/lib/census/grpc_context.c b/src/core/lib/census/grpc_context.c index 09280da3d6..457c176355 100644 --- a/src/core/lib/census/grpc_context.c +++ b/src/core/lib/census/grpc_context.c @@ -33,8 +33,8 @@ #include #include -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/call.h" void grpc_census_call_set_context(grpc_call *call, census_context *context) { GRPC_API_TRACE("grpc_census_call_set_context(call=%p, census_context=%p)", 2, diff --git a/src/core/lib/census/grpc_filter.c b/src/core/lib/census/grpc_filter.c index 11120a28d1..d27d789aa1 100644 --- a/src/core/lib/census/grpc_filter.c +++ b/src/core/lib/census/grpc_filter.c @@ -31,7 +31,7 @@ * */ -#include "src/core/census/grpc_filter.h" +#include "src/core/lib/census/grpc_filter.h" #include #include @@ -42,10 +42,10 @@ #include #include -#include "src/core/channel/channel_stack.h" -#include "src/core/statistics/census_interface.h" -#include "src/core/statistics/census_rpc_stats.h" -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/statistics/census_interface.h" +#include "src/core/lib/statistics/census_rpc_stats.h" +#include "src/core/lib/transport/static_metadata.h" typedef struct call_data { census_op_id op_id; diff --git a/src/core/lib/census/grpc_filter.h b/src/core/lib/census/grpc_filter.h index e71346b357..7ceafe56e4 100644 --- a/src/core/lib/census/grpc_filter.h +++ b/src/core/lib/census/grpc_filter.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_CENSUS_GRPC_FILTER_H #define GRPC_CORE_LIB_CENSUS_GRPC_FILTER_H -#include "src/core/channel/channel_stack.h" +#include "src/core/lib/channel/channel_stack.h" /* Census filters: provides tracing and stats collection functionalities. It needs to reside right below the surface filter in the channel stack. */ diff --git a/src/core/lib/census/grpc_plugin.c b/src/core/lib/census/grpc_plugin.c index 3ca9400f7e..12aca76745 100644 --- a/src/core/lib/census/grpc_plugin.c +++ b/src/core/lib/census/grpc_plugin.c @@ -31,15 +31,15 @@ * */ -#include "src/core/census/grpc_plugin.h" +#include "src/core/lib/census/grpc_plugin.h" #include #include -#include "src/core/census/grpc_filter.h" -#include "src/core/channel/channel_stack_builder.h" -#include "src/core/surface/channel_init.h" +#include "src/core/lib/census/grpc_filter.h" +#include "src/core/lib/channel/channel_stack_builder.h" +#include "src/core/lib/surface/channel_init.h" static bool maybe_add_census_filter(grpc_channel_stack_builder *builder, void *arg_must_be_null) { diff --git a/src/core/lib/census/mlog.c b/src/core/lib/census/mlog.c index a2cc46d3f2..9d47e80297 100644 --- a/src/core/lib/census/mlog.c +++ b/src/core/lib/census/mlog.c @@ -88,7 +88,7 @@ // include the name of the structure, which will be passed as the first // argument. E.g. cl_block_initialize() will initialize a cl_block. -#include "src/core/census/mlog.h" +#include "src/core/lib/census/mlog.h" #include #include #include diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c index e0382fa0d9..1a02f1f4aa 100644 --- a/src/core/lib/channel/channel_args.c +++ b/src/core/lib/channel/channel_args.c @@ -31,9 +31,9 @@ * */ -#include "src/core/channel/channel_args.h" +#include "src/core/lib/channel/channel_args.h" #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include #include diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c index 39ff1aed5a..52283e35fa 100644 --- a/src/core/lib/channel/channel_stack.c +++ b/src/core/lib/channel/channel_stack.c @@ -31,7 +31,7 @@ * */ -#include "src/core/channel/channel_stack.h" +#include "src/core/lib/channel/channel_stack.h" #include #include diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index d91a65cb70..b29bee411d 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -45,8 +45,8 @@ #include #include -#include "src/core/debug/trace.h" -#include "src/core/transport/transport.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/transport/transport.h" typedef struct grpc_channel_element grpc_channel_element; typedef struct grpc_call_element grpc_call_element; diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c index 1b1004e5f9..1ce0c4e07f 100644 --- a/src/core/lib/channel/channel_stack_builder.c +++ b/src/core/lib/channel/channel_stack_builder.c @@ -31,7 +31,7 @@ * */ -#include "src/core/channel/channel_stack_builder.h" +#include "src/core/lib/channel/channel_stack_builder.h" #include diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h index ca285a9b23..8532c4462a 100644 --- a/src/core/lib/channel/channel_stack_builder.h +++ b/src/core/lib/channel/channel_stack_builder.h @@ -36,8 +36,8 @@ #include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/channel_stack.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channel_stack.h" /// grpc_channel_stack_builder offers a programmatic interface to selected /// and order channel filters diff --git a/src/core/lib/channel/client_channel.c b/src/core/lib/channel/client_channel.c index ad1ded9ab7..9fdf803ecf 100644 --- a/src/core/lib/channel/client_channel.c +++ b/src/core/lib/channel/client_channel.c @@ -31,7 +31,7 @@ * */ -#include "src/core/channel/client_channel.h" +#include "src/core/lib/channel/client_channel.h" #include #include @@ -41,14 +41,14 @@ #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/subchannel_call_holder.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/surface/channel.h" -#include "src/core/transport/connectivity_state.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/subchannel_call_holder.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/transport/connectivity_state.h" /* Client channel implementation */ diff --git a/src/core/lib/channel/client_channel.h b/src/core/lib/channel/client_channel.h index dacdd3bb69..8777796fb6 100644 --- a/src/core/lib/channel/client_channel.h +++ b/src/core/lib/channel/client_channel.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_LIB_CHANNEL_CLIENT_CHANNEL_H #define GRPC_CORE_LIB_CHANNEL_CLIENT_CHANNEL_H -#include "src/core/channel/channel_stack.h" -#include "src/core/client_config/resolver.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/client_config/resolver.h" /* A client channel is a channel that begins disconnected, and can connect to some endpoint on demand. If that endpoint disconnects, it will be diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c index 6f5a9740ad..04bb7cc76f 100644 --- a/src/core/lib/channel/compress_filter.c +++ b/src/core/lib/channel/compress_filter.c @@ -39,13 +39,13 @@ #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/compress_filter.h" -#include "src/core/compression/algorithm_metadata.h" -#include "src/core/compression/message_compress.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/compress_filter.h" +#include "src/core/lib/compression/algorithm_metadata.h" +#include "src/core/lib/compression/message_compress.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/static_metadata.h" typedef struct call_data { gpr_slice_buffer slices; /**< Buffers up input slices to be compressed */ diff --git a/src/core/lib/channel/compress_filter.h b/src/core/lib/channel/compress_filter.h index 73eb271731..9010074335 100644 --- a/src/core/lib/channel/compress_filter.h +++ b/src/core/lib/channel/compress_filter.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H #define GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H -#include "src/core/channel/channel_stack.h" +#include "src/core/lib/channel/channel_stack.h" #define GRPC_COMPRESS_REQUEST_ALGORITHM_KEY "grpc-internal-encoding-request" diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c index df11d54297..5e3a8974ce 100644 --- a/src/core/lib/channel/connected_channel.c +++ b/src/core/lib/channel/connected_channel.c @@ -31,7 +31,7 @@ * */ -#include "src/core/channel/connected_channel.h" +#include "src/core/lib/channel/connected_channel.h" #include #include @@ -41,9 +41,9 @@ #include #include #include -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/transport/transport.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/transport.h" #define MAX_BUFFER_LENGTH 8192 diff --git a/src/core/lib/channel/connected_channel.h b/src/core/lib/channel/connected_channel.h index 971bc913bc..4f20b751cc 100644 --- a/src/core/lib/channel/connected_channel.h +++ b/src/core/lib/channel/connected_channel.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_CHANNEL_CONNECTED_CHANNEL_H #define GRPC_CORE_LIB_CHANNEL_CONNECTED_CHANNEL_H -#include "src/core/channel/channel_stack_builder.h" +#include "src/core/lib/channel/channel_stack_builder.h" bool grpc_add_connected_filter(grpc_channel_stack_builder *builder, void *arg_must_be_null); diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index 582427daf9..7dbac38414 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -30,14 +30,14 @@ * */ -#include "src/core/channel/http_client_filter.h" +#include "src/core/lib/channel/http_client_filter.h" #include #include #include #include -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/static_metadata.h" typedef struct call_data { grpc_linked_mdelem method; diff --git a/src/core/lib/channel/http_client_filter.h b/src/core/lib/channel/http_client_filter.h index d2ccdda0a4..418426e9cc 100644 --- a/src/core/lib/channel/http_client_filter.h +++ b/src/core/lib/channel/http_client_filter.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H #define GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H -#include "src/core/channel/channel_stack.h" +#include "src/core/lib/channel/channel_stack.h" /* Processes metadata on the client side for HTTP2 transports */ extern const grpc_channel_filter grpc_http_client_filter; diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c index 1a2e0c5db3..df99b77ab3 100644 --- a/src/core/lib/channel/http_server_filter.c +++ b/src/core/lib/channel/http_server_filter.c @@ -31,13 +31,13 @@ * */ -#include "src/core/channel/http_server_filter.h" +#include "src/core/lib/channel/http_server_filter.h" #include #include #include -#include "src/core/profiling/timers.h" -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/transport/static_metadata.h" typedef struct call_data { uint8_t seen_path; diff --git a/src/core/lib/channel/http_server_filter.h b/src/core/lib/channel/http_server_filter.h index 3e6f5782bc..c8cf920ded 100644 --- a/src/core/lib/channel/http_server_filter.h +++ b/src/core/lib/channel/http_server_filter.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_CHANNEL_HTTP_SERVER_FILTER_H #define GRPC_CORE_LIB_CHANNEL_HTTP_SERVER_FILTER_H -#include "src/core/channel/channel_stack.h" +#include "src/core/lib/channel/channel_stack.h" /* Processes metadata on the client side for HTTP2 transports */ extern const grpc_channel_filter grpc_http_server_filter; diff --git a/src/core/lib/channel/subchannel_call_holder.c b/src/core/lib/channel/subchannel_call_holder.c index 9c087dc2a1..6c6d42dd73 100644 --- a/src/core/lib/channel/subchannel_call_holder.c +++ b/src/core/lib/channel/subchannel_call_holder.c @@ -31,11 +31,11 @@ * */ -#include "src/core/channel/subchannel_call_holder.h" +#include "src/core/lib/channel/subchannel_call_holder.h" #include -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" #define GET_CALL(holder) \ ((grpc_subchannel_call *)(gpr_atm_acq_load(&(holder)->subchannel_call))) diff --git a/src/core/lib/channel/subchannel_call_holder.h b/src/core/lib/channel/subchannel_call_holder.h index 17b4910ac5..882f366792 100644 --- a/src/core/lib/channel/subchannel_call_holder.h +++ b/src/core/lib/channel/subchannel_call_holder.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_CHANNEL_SUBCHANNEL_CALL_HOLDER_H #define GRPC_CORE_LIB_CHANNEL_SUBCHANNEL_CALL_HOLDER_H -#include "src/core/client_config/subchannel.h" +#include "src/core/lib/client_config/subchannel.h" /** Pick a subchannel for grpc_subchannel_call_holder; Return 1 if subchannel is available immediately (in which case on_ready diff --git a/src/core/lib/client_config/client_config.c b/src/core/lib/client_config/client_config.c index c500af25ee..82c8d68099 100644 --- a/src/core/lib/client_config/client_config.c +++ b/src/core/lib/client_config/client_config.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/client_config.h" +#include "src/core/lib/client_config/client_config.h" #include diff --git a/src/core/lib/client_config/client_config.h b/src/core/lib/client_config/client_config.h index c2b5eb7bf3..404ec0d3a5 100644 --- a/src/core/lib/client_config/client_config.h +++ b/src/core/lib/client_config/client_config.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_CLIENT_CONFIG_H #define GRPC_CORE_LIB_CLIENT_CONFIG_CLIENT_CONFIG_H -#include "src/core/client_config/lb_policy.h" +#include "src/core/lib/client_config/lb_policy.h" /** Total configuration for a client. Provided, and updated, by grpc_resolver */ diff --git a/src/core/lib/client_config/connector.c b/src/core/lib/client_config/connector.c index aa34aa7fab..f51d862c6d 100644 --- a/src/core/lib/client_config/connector.c +++ b/src/core/lib/client_config/connector.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/connector.h" +#include "src/core/lib/client_config/connector.h" grpc_connector* grpc_connector_ref(grpc_connector* connector) { connector->vtable->ref(connector); diff --git a/src/core/lib/client_config/connector.h b/src/core/lib/client_config/connector.h index 34a7c26bae..21b925aade 100644 --- a/src/core/lib/client_config/connector.h +++ b/src/core/lib/client_config/connector.h @@ -34,9 +34,9 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_CONNECTOR_H #define GRPC_CORE_LIB_CLIENT_CONFIG_CONNECTOR_H -#include "src/core/channel/channel_stack.h" -#include "src/core/iomgr/sockaddr.h" -#include "src/core/transport/transport.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/transport/transport.h" typedef struct grpc_connector grpc_connector; typedef struct grpc_connector_vtable grpc_connector_vtable; diff --git a/src/core/lib/client_config/default_initial_connect_string.c b/src/core/lib/client_config/default_initial_connect_string.c index 90b4f96327..86eb37de77 100644 --- a/src/core/lib/client_config/default_initial_connect_string.c +++ b/src/core/lib/client_config/default_initial_connect_string.c @@ -32,7 +32,7 @@ */ #include -#include "src/core/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/sockaddr.h" void grpc_set_default_initial_connect_string(struct sockaddr **addr, size_t *addr_len, diff --git a/src/core/lib/client_config/initial_connect_string.c b/src/core/lib/client_config/initial_connect_string.c index d199efebde..95ae728316 100644 --- a/src/core/lib/client_config/initial_connect_string.c +++ b/src/core/lib/client_config/initial_connect_string.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/initial_connect_string.h" +#include "src/core/lib/client_config/initial_connect_string.h" #include diff --git a/src/core/lib/client_config/initial_connect_string.h b/src/core/lib/client_config/initial_connect_string.h index ce8096a28a..eec42fa240 100644 --- a/src/core/lib/client_config/initial_connect_string.h +++ b/src/core/lib/client_config/initial_connect_string.h @@ -35,7 +35,7 @@ #define GRPC_CORE_LIB_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H #include -#include "src/core/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/sockaddr.h" typedef void (*grpc_set_initial_connect_string_func)(struct sockaddr **addr, size_t *addr_len, diff --git a/src/core/lib/client_config/lb_policies/load_balancer_api.c b/src/core/lib/client_config/lb_policies/load_balancer_api.c index a6b5785fe4..4cbed200df 100644 --- a/src/core/lib/client_config/lb_policies/load_balancer_api.c +++ b/src/core/lib/client_config/lb_policies/load_balancer_api.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/lb_policies/load_balancer_api.h" +#include "src/core/lib/client_config/lb_policies/load_balancer_api.h" #include "third_party/nanopb/pb_decode.h" #include "third_party/nanopb/pb_encode.h" diff --git a/src/core/lib/client_config/lb_policies/load_balancer_api.h b/src/core/lib/client_config/lb_policies/load_balancer_api.h index b0ccfaff1f..83299adfa9 100644 --- a/src/core/lib/client_config/lb_policies/load_balancer_api.h +++ b/src/core/lib/client_config/lb_policies/load_balancer_api.h @@ -36,8 +36,8 @@ #include -#include "src/core/client_config/lb_policy_factory.h" -#include "src/core/proto/grpc/lb/v0/load_balancer.pb.h" +#include "src/core/lib/client_config/lb_policy_factory.h" +#include "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h" #ifdef __cplusplus extern "C" { diff --git a/src/core/lib/client_config/lb_policies/pick_first.c b/src/core/lib/client_config/lb_policies/pick_first.c index 2833f112f4..2e399b73f9 100644 --- a/src/core/lib/client_config/lb_policies/pick_first.c +++ b/src/core/lib/client_config/lb_policies/pick_first.c @@ -31,13 +31,13 @@ * */ -#include "src/core/client_config/lb_policies/pick_first.h" -#include "src/core/client_config/lb_policy_factory.h" +#include "src/core/lib/client_config/lb_policies/pick_first.h" +#include "src/core/lib/client_config/lb_policy_factory.h" #include #include -#include "src/core/transport/connectivity_state.h" +#include "src/core/lib/transport/connectivity_state.h" typedef struct pending_pick { struct pending_pick *next; diff --git a/src/core/lib/client_config/lb_policies/pick_first.h b/src/core/lib/client_config/lb_policies/pick_first.h index 141d354fd2..dba86ea7ad 100644 --- a/src/core/lib/client_config/lb_policies/pick_first.h +++ b/src/core/lib/client_config/lb_policies/pick_first.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H #define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H -#include "src/core/client_config/lb_policy_factory.h" +#include "src/core/lib/client_config/lb_policy_factory.h" /** Returns a load balancing factory for the pick first policy, which picks up * the first subchannel from \a subchannels to succesfully connect */ diff --git a/src/core/lib/client_config/lb_policies/round_robin.c b/src/core/lib/client_config/lb_policies/round_robin.c index 114ece6e4d..c904c5f921 100644 --- a/src/core/lib/client_config/lb_policies/round_robin.c +++ b/src/core/lib/client_config/lb_policies/round_robin.c @@ -31,12 +31,12 @@ * */ -#include "src/core/client_config/lb_policies/round_robin.h" +#include "src/core/lib/client_config/lb_policies/round_robin.h" #include #include -#include "src/core/transport/connectivity_state.h" +#include "src/core/lib/transport/connectivity_state.h" typedef struct round_robin_lb_policy round_robin_lb_policy; diff --git a/src/core/lib/client_config/lb_policies/round_robin.h b/src/core/lib/client_config/lb_policies/round_robin.h index 2f01147897..52db1caa0c 100644 --- a/src/core/lib/client_config/lb_policies/round_robin.h +++ b/src/core/lib/client_config/lb_policies/round_robin.h @@ -34,11 +34,11 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H #define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H -#include "src/core/client_config/lb_policy.h" +#include "src/core/lib/client_config/lb_policy.h" extern int grpc_lb_round_robin_trace; -#include "src/core/client_config/lb_policy_factory.h" +#include "src/core/lib/client_config/lb_policy_factory.h" /** Returns a load balancing factory for the round robin policy */ grpc_lb_policy_factory *grpc_round_robin_lb_factory_create(); diff --git a/src/core/lib/client_config/lb_policy.c b/src/core/lib/client_config/lb_policy.c index 0d8b007336..ee20ccd76a 100644 --- a/src/core/lib/client_config/lb_policy.c +++ b/src/core/lib/client_config/lb_policy.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/lb_policy.h" +#include "src/core/lib/client_config/lb_policy.h" #define WEAK_REF_BITS 16 diff --git a/src/core/lib/client_config/lb_policy.h b/src/core/lib/client_config/lb_policy.h index 2ccd314d51..58a0a04d85 100644 --- a/src/core/lib/client_config/lb_policy.h +++ b/src/core/lib/client_config/lb_policy.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_H #define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_H -#include "src/core/client_config/subchannel.h" -#include "src/core/transport/connectivity_state.h" +#include "src/core/lib/client_config/subchannel.h" +#include "src/core/lib/transport/connectivity_state.h" /** A load balancing policy: specified by a vtable and a struct (which is expected to be extended to contain some parameters) */ diff --git a/src/core/lib/client_config/lb_policy_factory.c b/src/core/lib/client_config/lb_policy_factory.c index a261922659..2ca6f42f89 100644 --- a/src/core/lib/client_config/lb_policy_factory.c +++ b/src/core/lib/client_config/lb_policy_factory.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/lb_policy_factory.h" +#include "src/core/lib/client_config/lb_policy_factory.h" void grpc_lb_policy_factory_ref(grpc_lb_policy_factory* factory) { factory->vtable->ref(factory); diff --git a/src/core/lib/client_config/lb_policy_factory.h b/src/core/lib/client_config/lb_policy_factory.h index 41eabadefa..36eaf178d9 100644 --- a/src/core/lib/client_config/lb_policy_factory.h +++ b/src/core/lib/client_config/lb_policy_factory.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_FACTORY_H #define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_FACTORY_H -#include "src/core/client_config/lb_policy.h" -#include "src/core/client_config/subchannel.h" +#include "src/core/lib/client_config/lb_policy.h" +#include "src/core/lib/client_config/subchannel.h" typedef struct grpc_lb_policy_factory grpc_lb_policy_factory; typedef struct grpc_lb_policy_factory_vtable grpc_lb_policy_factory_vtable; diff --git a/src/core/lib/client_config/lb_policy_registry.c b/src/core/lib/client_config/lb_policy_registry.c index e836456151..13acfe78cd 100644 --- a/src/core/lib/client_config/lb_policy_registry.c +++ b/src/core/lib/client_config/lb_policy_registry.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/lb_policy_registry.h" +#include "src/core/lib/client_config/lb_policy_registry.h" #include diff --git a/src/core/lib/client_config/lb_policy_registry.h b/src/core/lib/client_config/lb_policy_registry.h index bc82371bbe..c251fd9f08 100644 --- a/src/core/lib/client_config/lb_policy_registry.h +++ b/src/core/lib/client_config/lb_policy_registry.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_REGISTRY_H #define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_REGISTRY_H -#include "src/core/client_config/lb_policy_factory.h" +#include "src/core/lib/client_config/lb_policy_factory.h" /** Initialize the registry and set \a default_factory as the factory to be * returned when no name is provided in a lookup */ diff --git a/src/core/lib/client_config/resolver.c b/src/core/lib/client_config/resolver.c index 8c677978f8..32f0643adb 100644 --- a/src/core/lib/client_config/resolver.c +++ b/src/core/lib/client_config/resolver.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/resolver.h" +#include "src/core/lib/client_config/resolver.h" void grpc_resolver_init(grpc_resolver *resolver, const grpc_resolver_vtable *vtable) { diff --git a/src/core/lib/client_config/resolver.h b/src/core/lib/client_config/resolver.h index 358f73fa27..1ee879293a 100644 --- a/src/core/lib/client_config/resolver.h +++ b/src/core/lib/client_config/resolver.h @@ -34,9 +34,9 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_H #define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_H -#include "src/core/client_config/client_config.h" -#include "src/core/client_config/subchannel.h" -#include "src/core/iomgr/iomgr.h" +#include "src/core/lib/client_config/client_config.h" +#include "src/core/lib/client_config/subchannel.h" +#include "src/core/lib/iomgr/iomgr.h" typedef struct grpc_resolver grpc_resolver; typedef struct grpc_resolver_vtable grpc_resolver_vtable; diff --git a/src/core/lib/client_config/resolver_factory.c b/src/core/lib/client_config/resolver_factory.c index 6ee56f0063..0f76c664fa 100644 --- a/src/core/lib/client_config/resolver_factory.c +++ b/src/core/lib/client_config/resolver_factory.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/resolver_factory.h" +#include "src/core/lib/client_config/resolver_factory.h" void grpc_resolver_factory_ref(grpc_resolver_factory* factory) { factory->vtable->ref(factory); diff --git a/src/core/lib/client_config/resolver_factory.h b/src/core/lib/client_config/resolver_factory.h index 3d309c85f8..7765c3c844 100644 --- a/src/core/lib/client_config/resolver_factory.h +++ b/src/core/lib/client_config/resolver_factory.h @@ -34,9 +34,9 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_FACTORY_H #define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_FACTORY_H -#include "src/core/client_config/resolver.h" -#include "src/core/client_config/subchannel_factory.h" -#include "src/core/client_config/uri_parser.h" +#include "src/core/lib/client_config/resolver.h" +#include "src/core/lib/client_config/subchannel_factory.h" +#include "src/core/lib/client_config/uri_parser.h" typedef struct grpc_resolver_factory grpc_resolver_factory; typedef struct grpc_resolver_factory_vtable grpc_resolver_factory_vtable; diff --git a/src/core/lib/client_config/resolver_registry.c b/src/core/lib/client_config/resolver_registry.c index a38b3d8995..29bd00c284 100644 --- a/src/core/lib/client_config/resolver_registry.c +++ b/src/core/lib/client_config/resolver_registry.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/resolver_registry.h" +#include "src/core/lib/client_config/resolver_registry.h" #include diff --git a/src/core/lib/client_config/resolver_registry.h b/src/core/lib/client_config/resolver_registry.h index 72db20bf00..22289ca6bd 100644 --- a/src/core/lib/client_config/resolver_registry.h +++ b/src/core/lib/client_config/resolver_registry.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_REGISTRY_H #define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVER_REGISTRY_H -#include "src/core/client_config/resolver_factory.h" +#include "src/core/lib/client_config/resolver_factory.h" void grpc_resolver_registry_init(const char *default_prefix); void grpc_resolver_registry_shutdown(void); diff --git a/src/core/lib/client_config/resolvers/dns_resolver.c b/src/core/lib/client_config/resolvers/dns_resolver.c index 2b2ee97e12..ab445730ad 100644 --- a/src/core/lib/client_config/resolvers/dns_resolver.c +++ b/src/core/lib/client_config/resolvers/dns_resolver.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/resolvers/dns_resolver.h" +#include "src/core/lib/client_config/resolvers/dns_resolver.h" #include @@ -39,11 +39,11 @@ #include #include -#include "src/core/client_config/lb_policy_registry.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/timer.h" -#include "src/core/support/backoff.h" -#include "src/core/support/string.h" +#include "src/core/lib/client_config/lb_policy_registry.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/support/backoff.h" +#include "src/core/lib/support/string.h" #define BACKOFF_MULTIPLIER 1.6 #define BACKOFF_JITTER 0.2 diff --git a/src/core/lib/client_config/resolvers/dns_resolver.h b/src/core/lib/client_config/resolvers/dns_resolver.h index 7dada84278..eb46e41c77 100644 --- a/src/core/lib/client_config/resolvers/dns_resolver.h +++ b/src/core/lib/client_config/resolvers/dns_resolver.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H #define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H -#include "src/core/client_config/resolver_factory.h" +#include "src/core/lib/client_config/resolver_factory.h" /** Create a dns resolver factory */ grpc_resolver_factory *grpc_dns_resolver_factory_create(void); diff --git a/src/core/lib/client_config/resolvers/sockaddr_resolver.c b/src/core/lib/client_config/resolvers/sockaddr_resolver.c index 3cb7d79b67..66cddc3ed9 100644 --- a/src/core/lib/client_config/resolvers/sockaddr_resolver.c +++ b/src/core/lib/client_config/resolvers/sockaddr_resolver.c @@ -33,7 +33,7 @@ #include -#include "src/core/client_config/resolvers/sockaddr_resolver.h" +#include "src/core/lib/client_config/resolvers/sockaddr_resolver.h" #include #include @@ -42,10 +42,10 @@ #include #include -#include "src/core/client_config/lb_policy_registry.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/unix_sockets_posix.h" -#include "src/core/support/string.h" +#include "src/core/lib/client_config/lb_policy_registry.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/support/string.h" typedef struct { /** base class: must be first */ diff --git a/src/core/lib/client_config/resolvers/sockaddr_resolver.h b/src/core/lib/client_config/resolvers/sockaddr_resolver.h index 3bbcf1dd81..45c55bd160 100644 --- a/src/core/lib/client_config/resolvers/sockaddr_resolver.h +++ b/src/core/lib/client_config/resolvers/sockaddr_resolver.h @@ -36,7 +36,7 @@ #include -#include "src/core/client_config/resolver_factory.h" +#include "src/core/lib/client_config/resolver_factory.h" grpc_resolver_factory *grpc_ipv4_resolver_factory_create(void); diff --git a/src/core/lib/client_config/resolvers/zookeeper_resolver.c b/src/core/lib/client_config/resolvers/zookeeper_resolver.c index e0e18792a2..3bb0bbdf5c 100644 --- a/src/core/lib/client_config/resolvers/zookeeper_resolver.c +++ b/src/core/lib/client_config/resolvers/zookeeper_resolver.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/resolvers/zookeeper_resolver.h" +#include "src/core/lib/client_config/resolvers/zookeeper_resolver.h" #include @@ -41,12 +41,12 @@ #include #include -#include "src/core/client_config/lb_policy_registry.h" -#include "src/core/client_config/resolver_registry.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/json/json.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" +#include "src/core/lib/client_config/lb_policy_registry.h" +#include "src/core/lib/client_config/resolver_registry.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/api_trace.h" /** Zookeeper session expiration time in milliseconds */ #define GRPC_ZOOKEEPER_SESSION_TIMEOUT 15000 diff --git a/src/core/lib/client_config/resolvers/zookeeper_resolver.h b/src/core/lib/client_config/resolvers/zookeeper_resolver.h index 603097e5f8..7ee7604360 100644 --- a/src/core/lib/client_config/resolvers/zookeeper_resolver.h +++ b/src/core/lib/client_config/resolvers/zookeeper_resolver.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H #define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H -#include "src/core/client_config/resolver_factory.h" +#include "src/core/lib/client_config/resolver_factory.h" /** Create a zookeeper resolver factory */ grpc_resolver_factory *grpc_zookeeper_resolver_factory_create(void); diff --git a/src/core/lib/client_config/subchannel.c b/src/core/lib/client_config/subchannel.c index c5cd504929..41242f0dd7 100644 --- a/src/core/lib/client_config/subchannel.c +++ b/src/core/lib/client_config/subchannel.c @@ -31,24 +31,24 @@ * */ -#include "src/core/client_config/subchannel.h" +#include "src/core/lib/client_config/subchannel.h" #include #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/client_config/initial_connect_string.h" -#include "src/core/client_config/subchannel_index.h" -#include "src/core/iomgr/timer.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/backoff.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/channel_init.h" -#include "src/core/transport/connectivity_state.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/client_config/initial_connect_string.h" +#include "src/core/lib/client_config/subchannel_index.h" +#include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/backoff.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/channel_init.h" +#include "src/core/lib/transport/connectivity_state.h" #define INTERNAL_REF_BITS 16 #define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1)) diff --git a/src/core/lib/client_config/subchannel.h b/src/core/lib/client_config/subchannel.h index a8fcbe7b0e..b4f545be52 100644 --- a/src/core/lib/client_config/subchannel.h +++ b/src/core/lib/client_config/subchannel.h @@ -34,9 +34,9 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_H #define GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_H -#include "src/core/channel/channel_stack.h" -#include "src/core/client_config/connector.h" -#include "src/core/transport/connectivity_state.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/client_config/connector.h" +#include "src/core/lib/transport/connectivity_state.h" /** A (sub-)channel that knows how to connect to exactly one target address. Provides a target for load balancing. */ diff --git a/src/core/lib/client_config/subchannel_factory.c b/src/core/lib/client_config/subchannel_factory.c index 8caeaf11bf..727a48a6c8 100644 --- a/src/core/lib/client_config/subchannel_factory.c +++ b/src/core/lib/client_config/subchannel_factory.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/subchannel_factory.h" +#include "src/core/lib/client_config/subchannel_factory.h" void grpc_subchannel_factory_ref(grpc_subchannel_factory* factory) { factory->vtable->ref(factory); diff --git a/src/core/lib/client_config/subchannel_factory.h b/src/core/lib/client_config/subchannel_factory.h index 1017b13fcd..3ba2f860fe 100644 --- a/src/core/lib/client_config/subchannel_factory.h +++ b/src/core/lib/client_config/subchannel_factory.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H #define GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H -#include "src/core/channel/channel_stack.h" -#include "src/core/client_config/subchannel.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/client_config/subchannel.h" typedef struct grpc_subchannel_factory grpc_subchannel_factory; typedef struct grpc_subchannel_factory_vtable grpc_subchannel_factory_vtable; diff --git a/src/core/lib/client_config/subchannel_index.c b/src/core/lib/client_config/subchannel_index.c index 24cc76cf22..2c545002a2 100644 --- a/src/core/lib/client_config/subchannel_index.c +++ b/src/core/lib/client_config/subchannel_index.c @@ -31,7 +31,7 @@ // // -#include "src/core/client_config/subchannel_index.h" +#include "src/core/lib/client_config/subchannel_index.h" #include #include @@ -40,7 +40,7 @@ #include #include -#include "src/core/channel/channel_args.h" +#include "src/core/lib/channel/channel_args.h" // a map of subchannel_key --> subchannel, used for detecting connections // to the same destination in order to share them diff --git a/src/core/lib/client_config/subchannel_index.h b/src/core/lib/client_config/subchannel_index.h index f5627dfaf7..bc5f03beb4 100644 --- a/src/core/lib/client_config/subchannel_index.h +++ b/src/core/lib/client_config/subchannel_index.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_INDEX_H #define GRPC_CORE_LIB_CLIENT_CONFIG_SUBCHANNEL_INDEX_H -#include "src/core/client_config/connector.h" -#include "src/core/client_config/subchannel.h" +#include "src/core/lib/client_config/connector.h" +#include "src/core/lib/client_config/subchannel.h" /** \file Provides an index of active subchannels so that they can be shared amongst channels */ diff --git a/src/core/lib/client_config/uri_parser.c b/src/core/lib/client_config/uri_parser.c index c1b64778b1..d3228dec5f 100644 --- a/src/core/lib/client_config/uri_parser.c +++ b/src/core/lib/client_config/uri_parser.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/uri_parser.h" +#include "src/core/lib/client_config/uri_parser.h" #include diff --git a/src/core/lib/compression/algorithm_metadata.h b/src/core/lib/compression/algorithm_metadata.h index 6ebde1e8fd..47f33abdc7 100644 --- a/src/core/lib/compression/algorithm_metadata.h +++ b/src/core/lib/compression/algorithm_metadata.h @@ -35,7 +35,7 @@ #define GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H #include -#include "src/core/transport/metadata.h" +#include "src/core/lib/transport/metadata.h" /** Return compression algorithm based metadata value */ grpc_mdstr *grpc_compression_algorithm_mdstr( diff --git a/src/core/lib/compression/compression_algorithm.c b/src/core/lib/compression/compression_algorithm.c index 2810a38b68..f781b45042 100644 --- a/src/core/lib/compression/compression_algorithm.c +++ b/src/core/lib/compression/compression_algorithm.c @@ -37,9 +37,9 @@ #include #include -#include "src/core/compression/algorithm_metadata.h" -#include "src/core/surface/api_trace.h" -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/compression/algorithm_metadata.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/transport/static_metadata.h" int grpc_compression_algorithm_parse(const char *name, size_t name_length, grpc_compression_algorithm *algorithm) { diff --git a/src/core/lib/compression/message_compress.c b/src/core/lib/compression/message_compress.c index c3a21ec19f..b4b6a2d75e 100644 --- a/src/core/lib/compression/message_compress.c +++ b/src/core/lib/compression/message_compress.c @@ -31,7 +31,7 @@ * */ -#include "src/core/compression/message_compress.h" +#include "src/core/lib/compression/message_compress.h" #include diff --git a/src/core/lib/debug/trace.c b/src/core/lib/debug/trace.c index 42150b1bc3..786dd9324f 100644 --- a/src/core/lib/debug/trace.c +++ b/src/core/lib/debug/trace.c @@ -31,14 +31,14 @@ * */ -#include "src/core/debug/trace.h" +#include "src/core/lib/debug/trace.h" #include #include #include #include -#include "src/core/support/env.h" +#include "src/core/lib/support/env.h" typedef struct tracer { const char *name; diff --git a/src/core/lib/http/format_request.c b/src/core/lib/http/format_request.c index ac9bb8aeb8..95b3918646 100644 --- a/src/core/lib/http/format_request.c +++ b/src/core/lib/http/format_request.c @@ -31,7 +31,7 @@ * */ -#include "src/core/http/format_request.h" +#include "src/core/lib/http/format_request.h" #include #include @@ -41,7 +41,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" static void fill_common_header(const grpc_httpcli_request *request, gpr_strvec *buf) { diff --git a/src/core/lib/http/format_request.h b/src/core/lib/http/format_request.h index eb8e3267b6..2e933d804b 100644 --- a/src/core/lib/http/format_request.h +++ b/src/core/lib/http/format_request.h @@ -35,7 +35,7 @@ #define GRPC_CORE_LIB_HTTP_FORMAT_REQUEST_H #include -#include "src/core/http/httpcli.h" +#include "src/core/lib/http/httpcli.h" gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request); gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, diff --git a/src/core/lib/http/httpcli.c b/src/core/lib/http/httpcli.c index 1c0d3336ea..aab28ad8b6 100644 --- a/src/core/lib/http/httpcli.c +++ b/src/core/lib/http/httpcli.c @@ -31,8 +31,8 @@ * */ -#include "src/core/http/httpcli.h" -#include "src/core/iomgr/sockaddr.h" +#include "src/core/lib/http/httpcli.h" +#include "src/core/lib/iomgr/sockaddr.h" #include @@ -40,13 +40,13 @@ #include #include -#include "src/core/http/format_request.h" -#include "src/core/http/parser.h" -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/support/string.h" +#include "src/core/lib/http/format_request.h" +#include "src/core/lib/http/parser.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/support/string.h" typedef struct { gpr_slice request_text; diff --git a/src/core/lib/http/httpcli.h b/src/core/lib/http/httpcli.h index f28d6d7481..b8d54a8586 100644 --- a/src/core/lib/http/httpcli.h +++ b/src/core/lib/http/httpcli.h @@ -38,10 +38,10 @@ #include -#include "src/core/http/parser.h" -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/pollset_set.h" +#include "src/core/lib/http/parser.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/pollset_set.h" /* User agent this library reports */ #define GRPC_HTTPCLI_USER_AGENT "grpc-httpcli/0.0" diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c index a1a32f7558..6f1630ac1f 100644 --- a/src/core/lib/http/httpcli_security_connector.c +++ b/src/core/lib/http/httpcli_security_connector.c @@ -31,16 +31,16 @@ * */ -#include "src/core/http/httpcli.h" +#include "src/core/lib/http/httpcli.h" #include #include #include #include -#include "src/core/security/handshake.h" -#include "src/core/support/string.h" -#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/lib/security/handshake.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/tsi/ssl_transport_security.h" typedef struct { grpc_channel_security_connector base; diff --git a/src/core/lib/http/parser.c b/src/core/lib/http/parser.c index ebec8a5157..5d4e304615 100644 --- a/src/core/lib/http/parser.c +++ b/src/core/lib/http/parser.c @@ -31,7 +31,7 @@ * */ -#include "src/core/http/parser.h" +#include "src/core/lib/http/parser.h" #include diff --git a/src/core/lib/iomgr/closure.c b/src/core/lib/iomgr/closure.c index 3a96f7385f..724ebc284a 100644 --- a/src/core/lib/iomgr/closure.c +++ b/src/core/lib/iomgr/closure.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/closure.h" +#include "src/core/lib/iomgr/closure.h" #include diff --git a/src/core/lib/iomgr/endpoint.c b/src/core/lib/iomgr/endpoint.c index f1bdd0fc6c..576b5a6e5c 100644 --- a/src/core/lib/iomgr/endpoint.c +++ b/src/core/lib/iomgr/endpoint.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/endpoint.h" +#include "src/core/lib/iomgr/endpoint.h" void grpc_endpoint_read(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep, gpr_slice_buffer* slices, grpc_closure* cb) { diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h index 740ec50c6a..918e705fbd 100644 --- a/src/core/lib/iomgr/endpoint.h +++ b/src/core/lib/iomgr/endpoint.h @@ -37,8 +37,8 @@ #include #include #include -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/pollset_set.h" +#include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/iomgr/pollset_set.h" /* An endpoint caps a streaming channel between two communicating processes. Examples may be: a tcp socket, , or some shared memory. */ diff --git a/src/core/lib/iomgr/endpoint_pair.h b/src/core/lib/iomgr/endpoint_pair.h index 39af04c9df..bef8bb3518 100644 --- a/src/core/lib/iomgr/endpoint_pair.h +++ b/src/core/lib/iomgr/endpoint_pair.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_IOMGR_ENDPOINT_PAIR_H #define GRPC_CORE_LIB_IOMGR_ENDPOINT_PAIR_H -#include "src/core/iomgr/endpoint.h" +#include "src/core/lib/iomgr/endpoint.h" typedef struct { grpc_endpoint *client; diff --git a/src/core/lib/iomgr/endpoint_pair_posix.c b/src/core/lib/iomgr/endpoint_pair_posix.c index 66d19a486c..e0ce47c773 100644 --- a/src/core/lib/iomgr/endpoint_pair_posix.c +++ b/src/core/lib/iomgr/endpoint_pair_posix.c @@ -35,9 +35,9 @@ #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/endpoint_pair.h" -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/iomgr/unix_sockets_posix.h" +#include "src/core/lib/iomgr/endpoint_pair.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" +#include "src/core/lib/iomgr/unix_sockets_posix.h" #include #include @@ -48,8 +48,8 @@ #include #include #include -#include "src/core/iomgr/tcp_posix.h" -#include "src/core/support/string.h" +#include "src/core/lib/iomgr/tcp_posix.h" +#include "src/core/lib/support/string.h" static void create_sockets(int sv[2]) { int flags; diff --git a/src/core/lib/iomgr/endpoint_pair_windows.c b/src/core/lib/iomgr/endpoint_pair_windows.c index 2024f58143..cba18db81f 100644 --- a/src/core/lib/iomgr/endpoint_pair_windows.c +++ b/src/core/lib/iomgr/endpoint_pair_windows.c @@ -34,16 +34,16 @@ #include #ifdef GPR_WINSOCK_SOCKET -#include "src/core/iomgr/endpoint_pair.h" -#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/endpoint_pair.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" #include #include #include #include -#include "src/core/iomgr/socket_windows.h" -#include "src/core/iomgr/tcp_windows.h" +#include "src/core/lib/iomgr/socket_windows.h" +#include "src/core/lib/iomgr/tcp_windows.h" static void create_sockets(SOCKET sv[2]) { SOCKET svr_sock = INVALID_SOCKET; diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c index 893fe4515c..1ed6da623a 100644 --- a/src/core/lib/iomgr/exec_ctx.c +++ b/src/core/lib/iomgr/exec_ctx.c @@ -31,13 +31,13 @@ * */ -#include "src/core/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include #include #include -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" #ifndef GRPC_EXECUTION_CONTEXT_SANITIZER bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index a6551cf1d4..e62ea2dedf 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_IOMGR_EXEC_CTX_H #define GRPC_CORE_LIB_IOMGR_EXEC_CTX_H -#include "src/core/iomgr/closure.h" +#include "src/core/lib/iomgr/closure.h" /* #define GRPC_EXECUTION_CONTEXT_SANITIZER 1 */ diff --git a/src/core/lib/iomgr/executor.c b/src/core/lib/iomgr/executor.c index f22d8f30ac..42a9db3cbb 100644 --- a/src/core/lib/iomgr/executor.c +++ b/src/core/lib/iomgr/executor.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/executor.h" +#include "src/core/lib/iomgr/executor.h" #include @@ -39,7 +39,7 @@ #include #include #include -#include "src/core/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/exec_ctx.h" typedef struct grpc_executor_data { int busy; /**< is the thread currently running? */ diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h index 7197c3f24a..f1871416a0 100644 --- a/src/core/lib/iomgr/executor.h +++ b/src/core/lib/iomgr/executor.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_H #define GRPC_CORE_LIB_IOMGR_EXECUTOR_H -#include "src/core/iomgr/closure.h" +#include "src/core/lib/iomgr/closure.h" /** Initialize the global executor. * diff --git a/src/core/lib/iomgr/fd_posix.c b/src/core/lib/iomgr/fd_posix.c index b4d038a3a1..72c924bdcb 100644 --- a/src/core/lib/iomgr/fd_posix.c +++ b/src/core/lib/iomgr/fd_posix.c @@ -35,7 +35,7 @@ #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/fd_posix.h" +#include "src/core/lib/iomgr/fd_posix.h" #include #include @@ -46,7 +46,7 @@ #include #include -#include "src/core/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/pollset_posix.h" #define CLOSURE_NOT_READY ((grpc_closure *)0) #define CLOSURE_READY ((grpc_closure *)1) diff --git a/src/core/lib/iomgr/fd_posix.h b/src/core/lib/iomgr/fd_posix.h index a14c39f722..69d09ef5e3 100644 --- a/src/core/lib/iomgr/fd_posix.h +++ b/src/core/lib/iomgr/fd_posix.h @@ -37,8 +37,8 @@ #include #include #include -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/pollset.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/pollset.h" typedef struct grpc_fd grpc_fd; diff --git a/src/core/lib/iomgr/iocp_windows.c b/src/core/lib/iomgr/iocp_windows.c index 37e277dcc1..682a32c0da 100644 --- a/src/core/lib/iomgr/iocp_windows.c +++ b/src/core/lib/iomgr/iocp_windows.c @@ -42,10 +42,10 @@ #include #include -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/socket_windows.h" -#include "src/core/iomgr/timer.h" +#include "src/core/lib/iomgr/iocp_windows.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/socket_windows.h" +#include "src/core/lib/iomgr/timer.h" static ULONG g_iocp_kick_token; static OVERLAPPED g_iocp_custom_overlap; diff --git a/src/core/lib/iomgr/iocp_windows.h b/src/core/lib/iomgr/iocp_windows.h index 9444dd4fce..856c837fb4 100644 --- a/src/core/lib/iomgr/iocp_windows.h +++ b/src/core/lib/iomgr/iocp_windows.h @@ -36,7 +36,7 @@ #include -#include "src/core/iomgr/socket_windows.h" +#include "src/core/lib/iomgr/socket_windows.h" typedef enum { GRPC_IOCP_WORK_WORK, diff --git a/src/core/lib/iomgr/iomgr.c b/src/core/lib/iomgr/iomgr.c index 3ab4430668..bb544c8280 100644 --- a/src/core/lib/iomgr/iomgr.c +++ b/src/core/lib/iomgr/iomgr.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/iomgr.h" +#include "src/core/lib/iomgr/iomgr.h" #include #include @@ -43,11 +43,11 @@ #include #include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/timer.h" -#include "src/core/support/env.h" -#include "src/core/support/string.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" static gpr_mu g_mu; static gpr_cv g_rcv; diff --git a/src/core/lib/iomgr/iomgr_internal.h b/src/core/lib/iomgr/iomgr_internal.h index 2aeee7f6ae..0963630c61 100644 --- a/src/core/lib/iomgr/iomgr_internal.h +++ b/src/core/lib/iomgr/iomgr_internal.h @@ -37,7 +37,7 @@ #include #include -#include "src/core/iomgr/iomgr.h" +#include "src/core/lib/iomgr/iomgr.h" typedef struct grpc_iomgr_object { char *name; diff --git a/src/core/lib/iomgr/iomgr_posix.c b/src/core/lib/iomgr/iomgr_posix.c index 2f7f34746b..e4990f7bce 100644 --- a/src/core/lib/iomgr/iomgr_posix.c +++ b/src/core/lib/iomgr/iomgr_posix.c @@ -35,10 +35,10 @@ #ifdef GPR_POSIX_SOCKET -#include "src/core/debug/trace.h" -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/iomgr_posix.h" -#include "src/core/iomgr/tcp_posix.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/iomgr/fd_posix.h" +#include "src/core/lib/iomgr/iomgr_posix.h" +#include "src/core/lib/iomgr/tcp_posix.h" void grpc_iomgr_platform_init(void) { grpc_fd_global_init(); diff --git a/src/core/lib/iomgr/iomgr_posix.h b/src/core/lib/iomgr/iomgr_posix.h index 83fb082665..6a8996e403 100644 --- a/src/core/lib/iomgr/iomgr_posix.h +++ b/src/core/lib/iomgr/iomgr_posix.h @@ -34,6 +34,6 @@ #ifndef GRPC_CORE_LIB_IOMGR_IOMGR_POSIX_H #define GRPC_CORE_LIB_IOMGR_IOMGR_POSIX_H -#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/iomgr_internal.h" #endif /* GRPC_CORE_LIB_IOMGR_IOMGR_POSIX_H */ diff --git a/src/core/lib/iomgr/iomgr_windows.c b/src/core/lib/iomgr/iomgr_windows.c index 2d104130f7..af7e616394 100644 --- a/src/core/lib/iomgr/iomgr_windows.c +++ b/src/core/lib/iomgr/iomgr_windows.c @@ -35,13 +35,13 @@ #ifdef GPR_WINSOCK_SOCKET -#include "src/core/iomgr/sockaddr_win32.h" +#include "src/core/lib/iomgr/sockaddr_win32.h" #include -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/iomgr/socket_windows.h" +#include "src/core/lib/iomgr/iocp_windows.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/socket_windows.h" /* Windows' io manager is going to be fully designed using IO completion ports. All of what we're doing here is basically make sure that diff --git a/src/core/lib/iomgr/pollset.h b/src/core/lib/iomgr/pollset.h index db13f8ac69..6156124862 100644 --- a/src/core/lib/iomgr/pollset.h +++ b/src/core/lib/iomgr/pollset.h @@ -38,7 +38,7 @@ #include #include -#include "src/core/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/exec_ctx.h" #define GRPC_POLLSET_KICK_BROADCAST ((grpc_pollset_worker *)1) diff --git a/src/core/lib/iomgr/pollset_multipoller_with_epoll.c b/src/core/lib/iomgr/pollset_multipoller_with_epoll.c index 2e0f27fab8..fa1b0d2d84 100644 --- a/src/core/lib/iomgr/pollset_multipoller_with_epoll.c +++ b/src/core/lib/iomgr/pollset_multipoller_with_epoll.c @@ -44,10 +44,10 @@ #include #include #include -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/block_annotate.h" +#include "src/core/lib/iomgr/fd_posix.h" +#include "src/core/lib/iomgr/pollset_posix.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/block_annotate.h" struct epoll_fd_list { int *epoll_fds; diff --git a/src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c b/src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c index 92d6fb7241..9b33f6dbb2 100644 --- a/src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c +++ b/src/core/lib/iomgr/pollset_multipoller_with_poll_posix.c @@ -35,7 +35,7 @@ #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/pollset_posix.h" #include #include @@ -46,10 +46,10 @@ #include #include -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/support/block_annotate.h" +#include "src/core/lib/iomgr/fd_posix.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/pollset_posix.h" +#include "src/core/lib/support/block_annotate.h" typedef struct { /* all polled fds */ diff --git a/src/core/lib/iomgr/pollset_posix.c b/src/core/lib/iomgr/pollset_posix.c index e895a77884..259c7bc194 100644 --- a/src/core/lib/iomgr/pollset_posix.c +++ b/src/core/lib/iomgr/pollset_posix.c @@ -35,7 +35,7 @@ #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/pollset_posix.h" #include #include @@ -47,11 +47,11 @@ #include #include #include -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/block_annotate.h" +#include "src/core/lib/iomgr/fd_posix.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/block_annotate.h" GPR_TLS_DECL(g_current_thread_poller); GPR_TLS_DECL(g_current_thread_worker); diff --git a/src/core/lib/iomgr/pollset_posix.h b/src/core/lib/iomgr/pollset_posix.h index c4d1977a0b..7d8e9fc279 100644 --- a/src/core/lib/iomgr/pollset_posix.h +++ b/src/core/lib/iomgr/pollset_posix.h @@ -38,10 +38,10 @@ #include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/iomgr/wakeup_fd_posix.h" typedef struct grpc_pollset_vtable grpc_pollset_vtable; diff --git a/src/core/lib/iomgr/pollset_set.h b/src/core/lib/iomgr/pollset_set.h index 7af72a0297..fb29d692d7 100644 --- a/src/core/lib/iomgr/pollset_set.h +++ b/src/core/lib/iomgr/pollset_set.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_IOMGR_POLLSET_SET_H #define GRPC_CORE_LIB_IOMGR_POLLSET_SET_H -#include "src/core/iomgr/pollset.h" +#include "src/core/lib/iomgr/pollset.h" /* A grpc_pollset_set is a set of pollsets that are interested in an action. Adding a pollset to a pollset_set automatically adds any diff --git a/src/core/lib/iomgr/pollset_set_posix.c b/src/core/lib/iomgr/pollset_set_posix.c index 9dc9aff4a8..d6142f9b6b 100644 --- a/src/core/lib/iomgr/pollset_set_posix.c +++ b/src/core/lib/iomgr/pollset_set_posix.c @@ -41,8 +41,8 @@ #include #include -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/iomgr/pollset_set_posix.h" +#include "src/core/lib/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/pollset_set_posix.h" struct grpc_pollset_set { gpr_mu mu; diff --git a/src/core/lib/iomgr/pollset_set_posix.h b/src/core/lib/iomgr/pollset_set_posix.h index db997e1bf0..4e6b063c6f 100644 --- a/src/core/lib/iomgr/pollset_set_posix.h +++ b/src/core/lib/iomgr/pollset_set_posix.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_LIB_IOMGR_POLLSET_SET_POSIX_H #define GRPC_CORE_LIB_IOMGR_POLLSET_SET_POSIX_H -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/pollset_set.h" +#include "src/core/lib/iomgr/fd_posix.h" +#include "src/core/lib/iomgr/pollset_set.h" void grpc_pollset_set_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset_set *pollset_set, grpc_fd *fd); diff --git a/src/core/lib/iomgr/pollset_set_windows.c b/src/core/lib/iomgr/pollset_set_windows.c index 3b8eca28e6..0b14e446ae 100644 --- a/src/core/lib/iomgr/pollset_set_windows.c +++ b/src/core/lib/iomgr/pollset_set_windows.c @@ -35,7 +35,7 @@ #ifdef GPR_WINSOCK_SOCKET -#include "src/core/iomgr/pollset_set_windows.h" +#include "src/core/lib/iomgr/pollset_set_windows.h" grpc_pollset_set* grpc_pollset_set_create(pollset_set) { return NULL; } diff --git a/src/core/lib/iomgr/pollset_set_windows.h b/src/core/lib/iomgr/pollset_set_windows.h index f0b37f8d21..7c2cea23de 100644 --- a/src/core/lib/iomgr/pollset_set_windows.h +++ b/src/core/lib/iomgr/pollset_set_windows.h @@ -34,6 +34,6 @@ #ifndef GRPC_CORE_LIB_IOMGR_POLLSET_SET_WINDOWS_H #define GRPC_CORE_LIB_IOMGR_POLLSET_SET_WINDOWS_H -#include "src/core/iomgr/pollset_set.h" +#include "src/core/lib/iomgr/pollset_set.h" #endif /* GRPC_CORE_LIB_IOMGR_POLLSET_SET_WINDOWS_H */ diff --git a/src/core/lib/iomgr/pollset_windows.c b/src/core/lib/iomgr/pollset_windows.c index 1a99224c80..6b339127a8 100644 --- a/src/core/lib/iomgr/pollset_windows.c +++ b/src/core/lib/iomgr/pollset_windows.c @@ -38,10 +38,10 @@ #include #include -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/pollset_windows.h" +#include "src/core/lib/iomgr/iocp_windows.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/iomgr/pollset_windows.h" gpr_mu grpc_polling_mu; static grpc_pollset_worker *g_active_poller; diff --git a/src/core/lib/iomgr/pollset_windows.h b/src/core/lib/iomgr/pollset_windows.h index ff8e0a7b46..fa9553ffea 100644 --- a/src/core/lib/iomgr/pollset_windows.h +++ b/src/core/lib/iomgr/pollset_windows.h @@ -36,7 +36,7 @@ #include -#include "src/core/iomgr/socket_windows.h" +#include "src/core/lib/iomgr/socket_windows.h" /* There isn't really any such thing as a pollset under Windows, due to the nature of the IO completion ports. A Windows "pollset" is merely a mutex diff --git a/src/core/lib/iomgr/resolve_address.h b/src/core/lib/iomgr/resolve_address.h index d3da7cc33e..f748288685 100644 --- a/src/core/lib/iomgr/resolve_address.h +++ b/src/core/lib/iomgr/resolve_address.h @@ -35,8 +35,8 @@ #define GRPC_CORE_LIB_IOMGR_RESOLVE_ADDRESS_H #include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/iomgr/iomgr.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/iomgr.h" #define GRPC_MAX_SOCKADDR_SIZE 128 diff --git a/src/core/lib/iomgr/resolve_address_posix.c b/src/core/lib/iomgr/resolve_address_posix.c index 26b3aa8189..ebecb39c16 100644 --- a/src/core/lib/iomgr/resolve_address_posix.c +++ b/src/core/lib/iomgr/resolve_address_posix.c @@ -34,8 +34,8 @@ #include #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/sockaddr.h" #include #include @@ -47,12 +47,12 @@ #include #include #include -#include "src/core/iomgr/executor.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/unix_sockets_posix.h" -#include "src/core/support/block_annotate.h" -#include "src/core/support/string.h" +#include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/support/block_annotate.h" +#include "src/core/lib/support/string.h" typedef struct { char *name; diff --git a/src/core/lib/iomgr/resolve_address_windows.c b/src/core/lib/iomgr/resolve_address_windows.c index 472e797163..bde1f1b7f7 100644 --- a/src/core/lib/iomgr/resolve_address_windows.c +++ b/src/core/lib/iomgr/resolve_address_windows.c @@ -34,8 +34,8 @@ #include #ifdef GPR_WINSOCK_SOCKET -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/sockaddr.h" #include #include @@ -47,11 +47,11 @@ #include #include #include -#include "src/core/iomgr/executor.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/support/block_annotate.h" -#include "src/core/support/string.h" +#include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/support/block_annotate.h" +#include "src/core/lib/support/string.h" typedef struct { char *name; diff --git a/src/core/lib/iomgr/sockaddr.h b/src/core/lib/iomgr/sockaddr.h index e59a98e4ae..66a930ee6a 100644 --- a/src/core/lib/iomgr/sockaddr.h +++ b/src/core/lib/iomgr/sockaddr.h @@ -37,11 +37,11 @@ #include #ifdef GPR_WIN32 -#include "src/core/iomgr/sockaddr_win32.h" +#include "src/core/lib/iomgr/sockaddr_win32.h" #endif #ifdef GPR_POSIX_SOCKETADDR -#include "src/core/iomgr/sockaddr_posix.h" +#include "src/core/lib/iomgr/sockaddr_posix.h" #endif #endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_H */ diff --git a/src/core/lib/iomgr/sockaddr_utils.c b/src/core/lib/iomgr/sockaddr_utils.c index a3c3a874c1..127d95c618 100644 --- a/src/core/lib/iomgr/sockaddr_utils.c +++ b/src/core/lib/iomgr/sockaddr_utils.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" #include #include @@ -42,8 +42,8 @@ #include #include -#include "src/core/iomgr/unix_sockets_posix.h" -#include "src/core/support/string.h" +#include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/support/string.h" static const uint8_t kV4MappedPrefix[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}; diff --git a/src/core/lib/iomgr/sockaddr_utils.h b/src/core/lib/iomgr/sockaddr_utils.h index 58f30fca2b..20a3e3bec3 100644 --- a/src/core/lib/iomgr/sockaddr_utils.h +++ b/src/core/lib/iomgr/sockaddr_utils.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_IOMGR_SOCKADDR_UTILS_H #define GRPC_CORE_LIB_IOMGR_SOCKADDR_UTILS_H -#include "src/core/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/sockaddr.h" /* Returns true if addr is an IPv4-mapped IPv6 address within the ::ffff:0.0.0.0/96 range, or false otherwise. diff --git a/src/core/lib/iomgr/socket_utils_common_posix.c b/src/core/lib/iomgr/socket_utils_common_posix.c index 570daccc9e..9dbc2784e4 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.c +++ b/src/core/lib/iomgr/socket_utils_common_posix.c @@ -35,7 +35,7 @@ #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" #include #include @@ -53,8 +53,8 @@ #include #include #include -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/support/string.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/support/string.h" /* set a socket to non blocking mode */ int grpc_set_socket_nonblocking(int fd, int non_blocking) { diff --git a/src/core/lib/iomgr/socket_utils_linux.c b/src/core/lib/iomgr/socket_utils_linux.c index e16885f231..e7dfe892ca 100644 --- a/src/core/lib/iomgr/socket_utils_linux.c +++ b/src/core/lib/iomgr/socket_utils_linux.c @@ -35,7 +35,7 @@ #ifdef GPR_LINUX_SOCKETUTILS -#include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" #include #include diff --git a/src/core/lib/iomgr/socket_utils_posix.c b/src/core/lib/iomgr/socket_utils_posix.c index 794a5804ac..b2fa00c5c1 100644 --- a/src/core/lib/iomgr/socket_utils_posix.c +++ b/src/core/lib/iomgr/socket_utils_posix.c @@ -35,7 +35,7 @@ #ifdef GPR_POSIX_SOCKETUTILS -#include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" #include #include diff --git a/src/core/lib/iomgr/socket_windows.c b/src/core/lib/iomgr/socket_windows.c index c1f419e273..1023a6d4f8 100644 --- a/src/core/lib/iomgr/socket_windows.c +++ b/src/core/lib/iomgr/socket_windows.c @@ -45,11 +45,11 @@ #include #include -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/pollset_windows.h" -#include "src/core/iomgr/socket_windows.h" +#include "src/core/lib/iomgr/iocp_windows.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/iomgr/pollset_windows.h" +#include "src/core/lib/iomgr/socket_windows.h" grpc_winsocket *grpc_winsocket_create(SOCKET socket, const char *name) { char *final_name; diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 033aec695f..74447896c9 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -40,8 +40,8 @@ #include #include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/iomgr_internal.h" /* This holds the data for an outstanding read or write on a socket. The mutex to protect the concurrent access to that data is the one diff --git a/src/core/lib/iomgr/tcp_client.h b/src/core/lib/iomgr/tcp_client.h index 8f012e248c..6bbe26445a 100644 --- a/src/core/lib/iomgr/tcp_client.h +++ b/src/core/lib/iomgr/tcp_client.h @@ -35,9 +35,9 @@ #define GRPC_CORE_LIB_IOMGR_TCP_CLIENT_H #include -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/pollset_set.h" -#include "src/core/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/iomgr/sockaddr.h" /* Asynchronously connect to an address (specified as (addr, len)), and call cb with arg and the completed connection when done (or call cb with arg and diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c index 1d3f9b6555..b8ef643298 100644 --- a/src/core/lib/iomgr/tcp_client_posix.c +++ b/src/core/lib/iomgr/tcp_client_posix.c @@ -35,7 +35,7 @@ #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/tcp_client.h" +#include "src/core/lib/iomgr/tcp_client.h" #include #include @@ -47,15 +47,15 @@ #include #include -#include "src/core/iomgr/iomgr_posix.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/iomgr/pollset_set_posix.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/iomgr/tcp_posix.h" -#include "src/core/iomgr/timer.h" -#include "src/core/iomgr/unix_sockets_posix.h" -#include "src/core/support/string.h" +#include "src/core/lib/iomgr/iomgr_posix.h" +#include "src/core/lib/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/pollset_set_posix.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" +#include "src/core/lib/iomgr/tcp_posix.h" +#include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/support/string.h" extern int grpc_tcp_trace; diff --git a/src/core/lib/iomgr/tcp_client_windows.c b/src/core/lib/iomgr/tcp_client_windows.c index da83f7b79c..86b8d58975 100644 --- a/src/core/lib/iomgr/tcp_client_windows.c +++ b/src/core/lib/iomgr/tcp_client_windows.c @@ -35,7 +35,7 @@ #ifdef GPR_WINSOCK_SOCKET -#include "src/core/iomgr/sockaddr_win32.h" +#include "src/core/lib/iomgr/sockaddr_win32.h" #include #include @@ -43,13 +43,13 @@ #include #include -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/sockaddr.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/socket_windows.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/iomgr/tcp_windows.h" -#include "src/core/iomgr/timer.h" +#include "src/core/lib/iomgr/iocp_windows.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/socket_windows.h" +#include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/iomgr/tcp_windows.h" +#include "src/core/lib/iomgr/timer.h" typedef struct { grpc_closure *on_done; diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c index e8f73811ce..1898d96901 100644 --- a/src/core/lib/iomgr/tcp_posix.c +++ b/src/core/lib/iomgr/tcp_posix.c @@ -35,7 +35,7 @@ #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/tcp_posix.h" +#include "src/core/lib/iomgr/tcp_posix.h" #include #include @@ -51,11 +51,11 @@ #include #include -#include "src/core/debug/trace.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/iomgr/pollset_set_posix.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/pollset_set_posix.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/string.h" #ifdef GPR_HAVE_MSG_NOSIGNAL #define SENDMSG_FLAGS MSG_NOSIGNAL diff --git a/src/core/lib/iomgr/tcp_posix.h b/src/core/lib/iomgr/tcp_posix.h index b12fef5ecd..09c4436f1f 100644 --- a/src/core/lib/iomgr/tcp_posix.h +++ b/src/core/lib/iomgr/tcp_posix.h @@ -44,8 +44,8 @@ otherwise specified. */ -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/fd_posix.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/fd_posix.h" #define GRPC_TCP_DEFAULT_READ_SLICE_SIZE 8192 diff --git a/src/core/lib/iomgr/tcp_server.h b/src/core/lib/iomgr/tcp_server.h index e27fd233cd..81edb61997 100644 --- a/src/core/lib/iomgr/tcp_server.h +++ b/src/core/lib/iomgr/tcp_server.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_LIB_IOMGR_TCP_SERVER_H #define GRPC_CORE_LIB_IOMGR_TCP_SERVER_H -#include "src/core/iomgr/closure.h" -#include "src/core/iomgr/endpoint.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/endpoint.h" /* Forward decl of grpc_tcp_server */ typedef struct grpc_tcp_server grpc_tcp_server; diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index 74ee68a6f1..ef1bf9aa94 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -40,7 +40,7 @@ #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/tcp_server.h" +#include "src/core/lib/iomgr/tcp_server.h" #include #include @@ -59,13 +59,13 @@ #include #include #include -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/iomgr/tcp_posix.h" -#include "src/core/iomgr/unix_sockets_posix.h" -#include "src/core/support/string.h" +#include "src/core/lib/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" +#include "src/core/lib/iomgr/tcp_posix.h" +#include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/support/string.h" #define MIN_SAFE_ACCEPT_QUEUE_SIZE 100 diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c index a4abc5b974..3d6a29b2e2 100644 --- a/src/core/lib/iomgr/tcp_server_windows.c +++ b/src/core/lib/iomgr/tcp_server_windows.c @@ -37,7 +37,7 @@ #include -#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" #include #include @@ -46,11 +46,11 @@ #include #include -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/pollset_windows.h" -#include "src/core/iomgr/socket_windows.h" -#include "src/core/iomgr/tcp_server.h" -#include "src/core/iomgr/tcp_windows.h" +#include "src/core/lib/iomgr/iocp_windows.h" +#include "src/core/lib/iomgr/pollset_windows.h" +#include "src/core/lib/iomgr/socket_windows.h" +#include "src/core/lib/iomgr/tcp_server.h" +#include "src/core/lib/iomgr/tcp_windows.h" #define MIN_SAFE_ACCEPT_QUEUE_SIZE 100 diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c index 9b1db5fa7e..c1ce725f2c 100644 --- a/src/core/lib/iomgr/tcp_windows.c +++ b/src/core/lib/iomgr/tcp_windows.c @@ -35,7 +35,7 @@ #ifdef GPR_WINSOCK_SOCKET -#include "src/core/iomgr/sockaddr_win32.h" +#include "src/core/lib/iomgr/sockaddr_win32.h" #include #include @@ -44,12 +44,12 @@ #include #include -#include "src/core/iomgr/iocp_windows.h" -#include "src/core/iomgr/sockaddr.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/socket_windows.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/iomgr/timer.h" +#include "src/core/lib/iomgr/iocp_windows.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/socket_windows.h" +#include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/iomgr/timer.h" static int set_non_block(SOCKET sock) { int status; diff --git a/src/core/lib/iomgr/tcp_windows.h b/src/core/lib/iomgr/tcp_windows.h index c9e508f296..7a9ebd85eb 100644 --- a/src/core/lib/iomgr/tcp_windows.h +++ b/src/core/lib/iomgr/tcp_windows.h @@ -44,8 +44,8 @@ otherwise specified. */ -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/socket_windows.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/socket_windows.h" /* Create a tcp endpoint given a winsock handle. * Takes ownership of the handle. diff --git a/src/core/lib/iomgr/time_averaged_stats.c b/src/core/lib/iomgr/time_averaged_stats.c index 014162cc3b..f24d68087e 100644 --- a/src/core/lib/iomgr/time_averaged_stats.c +++ b/src/core/lib/iomgr/time_averaged_stats.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/time_averaged_stats.h" +#include "src/core/lib/iomgr/time_averaged_stats.h" void grpc_time_averaged_stats_init(grpc_time_averaged_stats* stats, double init_avg, double regress_weight, diff --git a/src/core/lib/iomgr/timer.c b/src/core/lib/iomgr/timer.c index f444643428..4748f9b270 100644 --- a/src/core/lib/iomgr/timer.c +++ b/src/core/lib/iomgr/timer.c @@ -31,13 +31,13 @@ * */ -#include "src/core/iomgr/timer.h" +#include "src/core/lib/iomgr/timer.h" #include #include #include -#include "src/core/iomgr/time_averaged_stats.h" -#include "src/core/iomgr/timer_heap.h" +#include "src/core/lib/iomgr/time_averaged_stats.h" +#include "src/core/lib/iomgr/timer_heap.h" #define INVALID_HEAP_INDEX 0xffffffffu diff --git a/src/core/lib/iomgr/timer.h b/src/core/lib/iomgr/timer.h index 616a886743..54f301c5ed 100644 --- a/src/core/lib/iomgr/timer.h +++ b/src/core/lib/iomgr/timer.h @@ -36,8 +36,8 @@ #include #include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/iomgr/iomgr.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/iomgr.h" typedef struct grpc_timer { gpr_timespec deadline; diff --git a/src/core/lib/iomgr/timer_heap.c b/src/core/lib/iomgr/timer_heap.c index b5df566c45..d43b6ccf75 100644 --- a/src/core/lib/iomgr/timer_heap.c +++ b/src/core/lib/iomgr/timer_heap.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/timer_heap.h" +#include "src/core/lib/iomgr/timer_heap.h" #include diff --git a/src/core/lib/iomgr/timer_heap.h b/src/core/lib/iomgr/timer_heap.h index d6b4f083d8..d5112cf0de 100644 --- a/src/core/lib/iomgr/timer_heap.h +++ b/src/core/lib/iomgr/timer_heap.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_IOMGR_TIMER_HEAP_H #define GRPC_CORE_LIB_IOMGR_TIMER_HEAP_H -#include "src/core/iomgr/timer.h" +#include "src/core/lib/iomgr/timer.h" typedef struct { grpc_timer **timers; diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c index 174159170f..3d8bcc9c81 100644 --- a/src/core/lib/iomgr/udp_server.c +++ b/src/core/lib/iomgr/udp_server.c @@ -41,7 +41,7 @@ #ifdef GRPC_NEED_UDP #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/udp_server.h" +#include "src/core/lib/iomgr/udp_server.h" #include #include @@ -60,13 +60,13 @@ #include #include #include -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/iomgr/unix_sockets_posix.h" -#include "src/core/support/string.h" +#include "src/core/lib/iomgr/fd_posix.h" +#include "src/core/lib/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" +#include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/support/string.h" #define INIT_PORT_CAP 2 diff --git a/src/core/lib/iomgr/udp_server.h b/src/core/lib/iomgr/udp_server.h index ac70124727..316845ad66 100644 --- a/src/core/lib/iomgr/udp_server.h +++ b/src/core/lib/iomgr/udp_server.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_LIB_IOMGR_UDP_SERVER_H #define GRPC_CORE_LIB_IOMGR_UDP_SERVER_H -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/fd_posix.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/fd_posix.h" /* Forward decl of struct grpc_server */ /* This is not typedef'ed to avoid a typedef-redefinition error */ diff --git a/src/core/lib/iomgr/unix_sockets_posix.c b/src/core/lib/iomgr/unix_sockets_posix.c index 174a7e7abf..42e44989e0 100644 --- a/src/core/lib/iomgr/unix_sockets_posix.c +++ b/src/core/lib/iomgr/unix_sockets_posix.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/unix_sockets_posix.h" +#include "src/core/lib/iomgr/unix_sockets_posix.h" #ifdef GPR_HAVE_UNIX_SOCKET diff --git a/src/core/lib/iomgr/unix_sockets_posix.h b/src/core/lib/iomgr/unix_sockets_posix.h index 6382c92480..752cab85a5 100644 --- a/src/core/lib/iomgr/unix_sockets_posix.h +++ b/src/core/lib/iomgr/unix_sockets_posix.h @@ -38,10 +38,10 @@ #include -#include "src/core/client_config/resolver_factory.h" -#include "src/core/client_config/uri_parser.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/sockaddr.h" +#include "src/core/lib/client_config/resolver_factory.h" +#include "src/core/lib/client_config/uri_parser.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/sockaddr.h" void grpc_create_socketpair_if_unix(int sv[2]); diff --git a/src/core/lib/iomgr/unix_sockets_posix_noop.c b/src/core/lib/iomgr/unix_sockets_posix_noop.c index 045467bea4..06f6ee05e7 100644 --- a/src/core/lib/iomgr/unix_sockets_posix_noop.c +++ b/src/core/lib/iomgr/unix_sockets_posix_noop.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/unix_sockets_posix.h" +#include "src/core/lib/iomgr/unix_sockets_posix.h" #ifndef GPR_HAVE_UNIX_SOCKET diff --git a/src/core/lib/iomgr/wakeup_fd_eventfd.c b/src/core/lib/iomgr/wakeup_fd_eventfd.c index f4662965cd..41ded0ca4d 100644 --- a/src/core/lib/iomgr/wakeup_fd_eventfd.c +++ b/src/core/lib/iomgr/wakeup_fd_eventfd.c @@ -41,8 +41,8 @@ #include -#include "src/core/iomgr/wakeup_fd_posix.h" -#include "src/core/profiling/timers.h" +#include "src/core/lib/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/profiling/timers.h" static void eventfd_create(grpc_wakeup_fd* fd_info) { int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); diff --git a/src/core/lib/iomgr/wakeup_fd_nospecial.c b/src/core/lib/iomgr/wakeup_fd_nospecial.c index 7b2be9ed52..39defa65c6 100644 --- a/src/core/lib/iomgr/wakeup_fd_nospecial.c +++ b/src/core/lib/iomgr/wakeup_fd_nospecial.c @@ -41,7 +41,7 @@ #ifdef GPR_POSIX_NO_SPECIAL_WAKEUP_FD #include -#include "src/core/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/iomgr/wakeup_fd_posix.h" static int check_availability_invalid(void) { return 0; } diff --git a/src/core/lib/iomgr/wakeup_fd_pipe.c b/src/core/lib/iomgr/wakeup_fd_pipe.c index dd2fd1f057..820919e4dd 100644 --- a/src/core/lib/iomgr/wakeup_fd_pipe.c +++ b/src/core/lib/iomgr/wakeup_fd_pipe.c @@ -35,7 +35,7 @@ #ifdef GPR_POSIX_WAKEUP_FD -#include "src/core/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/iomgr/wakeup_fd_posix.h" #include #include @@ -43,7 +43,7 @@ #include -#include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" static void pipe_init(grpc_wakeup_fd* fd_info) { int pipefd[2]; diff --git a/src/core/lib/iomgr/wakeup_fd_pipe.h b/src/core/lib/iomgr/wakeup_fd_pipe.h index dd8275800a..bbdb1fc448 100644 --- a/src/core/lib/iomgr/wakeup_fd_pipe.h +++ b/src/core/lib/iomgr/wakeup_fd_pipe.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_PIPE_H #define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_PIPE_H -#include "src/core/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/iomgr/wakeup_fd_posix.h" extern grpc_wakeup_fd_vtable grpc_pipe_wakeup_fd_vtable; diff --git a/src/core/lib/iomgr/wakeup_fd_posix.c b/src/core/lib/iomgr/wakeup_fd_posix.c index 07778c408e..c4d174fb34 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.c +++ b/src/core/lib/iomgr/wakeup_fd_posix.c @@ -36,8 +36,8 @@ #ifdef GPR_POSIX_WAKEUP_FD #include -#include "src/core/iomgr/wakeup_fd_pipe.h" -#include "src/core/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/iomgr/wakeup_fd_pipe.h" +#include "src/core/lib/iomgr/wakeup_fd_posix.h" static const grpc_wakeup_fd_vtable *wakeup_fd_vtable = NULL; int grpc_allow_specialized_wakeup_fd = 1; diff --git a/src/core/lib/iomgr/workqueue.h b/src/core/lib/iomgr/workqueue.h index d11fc77d82..9c420c57de 100644 --- a/src/core/lib/iomgr/workqueue.h +++ b/src/core/lib/iomgr/workqueue.h @@ -34,17 +34,17 @@ #ifndef GRPC_CORE_LIB_IOMGR_WORKQUEUE_H #define GRPC_CORE_LIB_IOMGR_WORKQUEUE_H -#include "src/core/iomgr/closure.h" -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/iomgr/pollset.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/pollset.h" #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/workqueue_posix.h" +#include "src/core/lib/iomgr/workqueue_posix.h" #endif #ifdef GPR_WIN32 -#include "src/core/iomgr/workqueue_windows.h" +#include "src/core/lib/iomgr/workqueue_windows.h" #endif /* grpc_workqueue is forward declared in exec_ctx.h */ diff --git a/src/core/lib/iomgr/workqueue_posix.c b/src/core/lib/iomgr/workqueue_posix.c index 2b42e6d4fb..76830ef12d 100644 --- a/src/core/lib/iomgr/workqueue_posix.c +++ b/src/core/lib/iomgr/workqueue_posix.c @@ -35,7 +35,7 @@ #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/workqueue.h" +#include "src/core/lib/iomgr/workqueue.h" #include @@ -43,8 +43,8 @@ #include #include -#include "src/core/iomgr/fd_posix.h" -#include "src/core/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/fd_posix.h" +#include "src/core/lib/iomgr/pollset_posix.h" static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, bool success); diff --git a/src/core/lib/iomgr/workqueue_posix.h b/src/core/lib/iomgr/workqueue_posix.h index 02e1dad44f..956de8fb27 100644 --- a/src/core/lib/iomgr/workqueue_posix.h +++ b/src/core/lib/iomgr/workqueue_posix.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_IOMGR_WORKQUEUE_POSIX_H #define GRPC_CORE_LIB_IOMGR_WORKQUEUE_POSIX_H -#include "src/core/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/iomgr/wakeup_fd_posix.h" struct grpc_fd; diff --git a/src/core/lib/iomgr/workqueue_windows.c b/src/core/lib/iomgr/workqueue_windows.c index dd7fac8b35..6697f93498 100644 --- a/src/core/lib/iomgr/workqueue_windows.c +++ b/src/core/lib/iomgr/workqueue_windows.c @@ -35,6 +35,6 @@ #ifdef GPR_WIN32 -#include "src/core/iomgr/workqueue.h" +#include "src/core/lib/iomgr/workqueue.h" #endif /* GPR_WIN32 */ diff --git a/src/core/lib/json/json.c b/src/core/lib/json/json.c index b31ee49562..9793045d91 100644 --- a/src/core/lib/json/json.c +++ b/src/core/lib/json/json.c @@ -35,7 +35,7 @@ #include -#include "src/core/json/json.h" +#include "src/core/lib/json/json.h" grpc_json *grpc_json_create(grpc_json_type type) { grpc_json *json = gpr_malloc(sizeof(*json)); diff --git a/src/core/lib/json/json.h b/src/core/lib/json/json.h index 89d15846ce..41d87dd5ce 100644 --- a/src/core/lib/json/json.h +++ b/src/core/lib/json/json.h @@ -36,7 +36,7 @@ #include -#include "src/core/json/json_common.h" +#include "src/core/lib/json/json_common.h" /* A tree-like structure to hold json values. The key and value pointers * are not owned by it. diff --git a/src/core/lib/json/json_reader.c b/src/core/lib/json/json_reader.c index 861323d10c..0807f029ce 100644 --- a/src/core/lib/json/json_reader.c +++ b/src/core/lib/json/json_reader.c @@ -37,7 +37,7 @@ #include -#include "src/core/json/json_reader.h" +#include "src/core/lib/json/json_reader.h" static void json_reader_string_clear(grpc_json_reader *reader) { reader->vtable->string_clear(reader->userdata); diff --git a/src/core/lib/json/json_reader.h b/src/core/lib/json/json_reader.h index a49d6fef68..37a838889d 100644 --- a/src/core/lib/json/json_reader.h +++ b/src/core/lib/json/json_reader.h @@ -35,7 +35,7 @@ #define GRPC_CORE_LIB_JSON_JSON_READER_H #include -#include "src/core/json/json_common.h" +#include "src/core/lib/json/json_common.h" typedef enum { GRPC_JSON_STATE_OBJECT_KEY_BEGIN, diff --git a/src/core/lib/json/json_string.c b/src/core/lib/json/json_string.c index d4ebce18e1..8e6f1253dc 100644 --- a/src/core/lib/json/json_string.c +++ b/src/core/lib/json/json_string.c @@ -37,9 +37,9 @@ #include #include -#include "src/core/json/json.h" -#include "src/core/json/json_reader.h" -#include "src/core/json/json_writer.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/json/json_reader.h" +#include "src/core/lib/json/json_writer.h" /* The json reader will construct a bunch of grpc_json objects and * link them all up together in a tree-like structure that will represent diff --git a/src/core/lib/json/json_writer.c b/src/core/lib/json/json_writer.c index abcb3efd98..d614a72fc4 100644 --- a/src/core/lib/json/json_writer.c +++ b/src/core/lib/json/json_writer.c @@ -35,7 +35,7 @@ #include -#include "src/core/json/json_writer.h" +#include "src/core/lib/json/json_writer.h" static void json_writer_output_char(grpc_json_writer *writer, char c) { writer->vtable->output_char(writer->userdata, c); diff --git a/src/core/lib/json/json_writer.h b/src/core/lib/json/json_writer.h index 90b6bc753c..f90e79cd74 100644 --- a/src/core/lib/json/json_writer.h +++ b/src/core/lib/json/json_writer.h @@ -48,7 +48,7 @@ #include -#include "src/core/json/json_common.h" +#include "src/core/lib/json/json_common.h" typedef struct grpc_json_writer_vtable { /* Adds a character to the output stream. */ diff --git a/src/core/lib/profiling/basic_timers.c b/src/core/lib/profiling/basic_timers.c index 3067f52c21..15a9584981 100644 --- a/src/core/lib/profiling/basic_timers.c +++ b/src/core/lib/profiling/basic_timers.c @@ -35,7 +35,7 @@ #ifdef GRPC_BASIC_PROFILER -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" #include #include diff --git a/src/core/lib/profiling/stap_timers.c b/src/core/lib/profiling/stap_timers.c index d67541a339..f55c1a569a 100644 --- a/src/core/lib/profiling/stap_timers.c +++ b/src/core/lib/profiling/stap_timers.c @@ -35,11 +35,11 @@ #ifdef GRPC_STAP_PROFILER -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" #include /* Generated from src/core/profiling/stap_probes.d */ -#include "src/core/profiling/stap_probes.h" +#include "src/core/lib/profiling/stap_probes.h" /* Latency profiler API implementation. */ void gpr_timer_add_mark(int tag, const char *tagstr, void *id, const char *file, diff --git a/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c b/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c index 59aae30cff..8f82141f96 100644 --- a/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c +++ b/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.c @@ -33,7 +33,7 @@ /* Automatically generated nanopb constant definitions */ /* Generated by nanopb-0.3.5-dev */ -#include "src/core/proto/grpc/lb/v0/load_balancer.pb.h" +#include "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h" #if PB_PROTO_HEADER_VERSION != 30 #error Regenerate this file with the current version of nanopb generator. diff --git a/src/core/lib/security/auth_filters.h b/src/core/lib/security/auth_filters.h index 0fb19e7382..162b60e2c8 100644 --- a/src/core/lib/security/auth_filters.h +++ b/src/core/lib/security/auth_filters.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_SECURITY_AUTH_FILTERS_H #define GRPC_CORE_LIB_SECURITY_AUTH_FILTERS_H -#include "src/core/channel/channel_stack.h" +#include "src/core/lib/channel/channel_stack.h" extern const grpc_channel_filter grpc_client_auth_filter; extern const grpc_channel_filter grpc_server_auth_filter; diff --git a/src/core/lib/security/b64.c b/src/core/lib/security/b64.c index c40b528e2f..1d3879534c 100644 --- a/src/core/lib/security/b64.c +++ b/src/core/lib/security/b64.c @@ -31,7 +31,7 @@ * */ -#include "src/core/security/b64.h" +#include "src/core/lib/security/b64.h" #include #include diff --git a/src/core/lib/security/client_auth_filter.c b/src/core/lib/security/client_auth_filter.c index e2c23ef98d..b9e5bf0339 100644 --- a/src/core/lib/security/client_auth_filter.c +++ b/src/core/lib/security/client_auth_filter.c @@ -31,7 +31,7 @@ * */ -#include "src/core/security/auth_filters.h" +#include "src/core/lib/security/auth_filters.h" #include @@ -39,13 +39,13 @@ #include #include -#include "src/core/channel/channel_stack.h" -#include "src/core/security/credentials.h" -#include "src/core/security/security_connector.h" -#include "src/core/security/security_context.h" -#include "src/core/support/string.h" -#include "src/core/surface/call.h" -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/security/security_connector.h" +#include "src/core/lib/security/security_context.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/call.h" +#include "src/core/lib/transport/static_metadata.h" #define MAX_CREDENTIALS_METADATA_COUNT 4 diff --git a/src/core/lib/security/credentials.c b/src/core/lib/security/credentials.c index c8348bc12c..99a07e5c13 100644 --- a/src/core/lib/security/credentials.c +++ b/src/core/lib/security/credentials.c @@ -31,19 +31,19 @@ * */ -#include "src/core/security/credentials.h" +#include "src/core/lib/security/credentials.h" #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/http_client_filter.h" -#include "src/core/http/httpcli.h" -#include "src/core/http/parser.h" -#include "src/core/iomgr/executor.h" -#include "src/core/json/json.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/http_client_filter.h" +#include "src/core/lib/http/httpcli.h" +#include "src/core/lib/http/parser.h" +#include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/api_trace.h" #include #include diff --git a/src/core/lib/security/credentials.h b/src/core/lib/security/credentials.h index c1f451ded1..7168b98942 100644 --- a/src/core/lib/security/credentials.h +++ b/src/core/lib/security/credentials.h @@ -37,12 +37,12 @@ #include #include #include -#include "src/core/transport/metadata_batch.h" +#include "src/core/lib/transport/metadata_batch.h" -#include "src/core/http/httpcli.h" -#include "src/core/http/parser.h" -#include "src/core/security/json_token.h" -#include "src/core/security/security_connector.h" +#include "src/core/lib/http/httpcli.h" +#include "src/core/lib/http/parser.h" +#include "src/core/lib/security/json_token.h" +#include "src/core/lib/security/security_connector.h" struct grpc_http_response; diff --git a/src/core/lib/security/credentials_metadata.c b/src/core/lib/security/credentials_metadata.c index 524c003eca..c3bfcb11b5 100644 --- a/src/core/lib/security/credentials_metadata.c +++ b/src/core/lib/security/credentials_metadata.c @@ -31,7 +31,7 @@ * */ -#include "src/core/security/credentials.h" +#include "src/core/lib/security/credentials.h" #include diff --git a/src/core/lib/security/credentials_posix.c b/src/core/lib/security/credentials_posix.c index 488e60c3bc..b758cd0a1a 100644 --- a/src/core/lib/security/credentials_posix.c +++ b/src/core/lib/security/credentials_posix.c @@ -35,14 +35,14 @@ #ifdef GPR_POSIX_FILE -#include "src/core/security/credentials.h" +#include "src/core/lib/security/credentials.h" #include #include #include -#include "src/core/support/env.h" -#include "src/core/support/string.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" char *grpc_get_well_known_google_credentials_file_path_impl(void) { char *result = NULL; diff --git a/src/core/lib/security/credentials_win32.c b/src/core/lib/security/credentials_win32.c index 646b0c21d6..a225ab0d7d 100644 --- a/src/core/lib/security/credentials_win32.c +++ b/src/core/lib/security/credentials_win32.c @@ -35,14 +35,14 @@ #ifdef GPR_WIN32 -#include "src/core/security/credentials.h" +#include "src/core/lib/security/credentials.h" #include #include #include -#include "src/core/support/env.h" -#include "src/core/support/string.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" char *grpc_get_well_known_google_credentials_file_path_impl(void) { char *result = NULL; diff --git a/src/core/lib/security/google_default_credentials.c b/src/core/lib/security/google_default_credentials.c index 3872e86993..5c342288cc 100644 --- a/src/core/lib/security/google_default_credentials.c +++ b/src/core/lib/security/google_default_credentials.c @@ -31,7 +31,7 @@ * */ -#include "src/core/security/credentials.h" +#include "src/core/lib/security/credentials.h" #include @@ -39,11 +39,11 @@ #include #include -#include "src/core/http/httpcli.h" -#include "src/core/http/parser.h" -#include "src/core/support/env.h" -#include "src/core/support/load_file.h" -#include "src/core/surface/api_trace.h" +#include "src/core/lib/http/httpcli.h" +#include "src/core/lib/http/parser.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/load_file.h" +#include "src/core/lib/surface/api_trace.h" /* -- Constants. -- */ diff --git a/src/core/lib/security/handshake.c b/src/core/lib/security/handshake.c index 9fb10a0ecb..adb6d7fe4e 100644 --- a/src/core/lib/security/handshake.c +++ b/src/core/lib/security/handshake.c @@ -31,7 +31,7 @@ * */ -#include "src/core/security/handshake.h" +#include "src/core/lib/security/handshake.h" #include #include @@ -39,8 +39,8 @@ #include #include #include -#include "src/core/security/secure_endpoint.h" -#include "src/core/security/security_context.h" +#include "src/core/lib/security/secure_endpoint.h" +#include "src/core/lib/security/security_context.h" #define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256 diff --git a/src/core/lib/security/handshake.h b/src/core/lib/security/handshake.h index 2b1f8b9212..b5d7bb3282 100644 --- a/src/core/lib/security/handshake.h +++ b/src/core/lib/security/handshake.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_LIB_SECURITY_HANDSHAKE_H #define GRPC_CORE_LIB_SECURITY_HANDSHAKE_H -#include "src/core/iomgr/endpoint.h" -#include "src/core/security/security_connector.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/security/security_connector.h" /* Calls the callback upon completion. Takes owership of handshaker. */ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/security/json_token.c b/src/core/lib/security/json_token.c index 372e5bfc5a..97054286d9 100644 --- a/src/core/lib/security/json_token.c +++ b/src/core/lib/security/json_token.c @@ -31,7 +31,7 @@ * */ -#include "src/core/security/json_token.h" +#include "src/core/lib/security/json_token.h" #include @@ -39,8 +39,8 @@ #include #include -#include "src/core/security/b64.h" -#include "src/core/support/string.h" +#include "src/core/lib/security/b64.h" +#include "src/core/lib/support/string.h" #include #include diff --git a/src/core/lib/security/json_token.h b/src/core/lib/security/json_token.h index 08ed4bfef3..376fb03875 100644 --- a/src/core/lib/security/json_token.h +++ b/src/core/lib/security/json_token.h @@ -37,7 +37,7 @@ #include #include -#include "src/core/json/json.h" +#include "src/core/lib/json/json.h" /* --- Constants. --- */ diff --git a/src/core/lib/security/jwt_verifier.c b/src/core/lib/security/jwt_verifier.c index 0bb8e05306..460b92f9a0 100644 --- a/src/core/lib/security/jwt_verifier.c +++ b/src/core/lib/security/jwt_verifier.c @@ -31,14 +31,14 @@ * */ -#include "src/core/security/jwt_verifier.h" +#include "src/core/lib/security/jwt_verifier.h" #include #include -#include "src/core/http/httpcli.h" -#include "src/core/security/b64.h" -#include "src/core/tsi/ssl_types.h" +#include "src/core/lib/http/httpcli.h" +#include "src/core/lib/security/b64.h" +#include "src/core/lib/tsi/ssl_types.h" #include #include diff --git a/src/core/lib/security/jwt_verifier.h b/src/core/lib/security/jwt_verifier.h index 7db7e6d7b4..28a9eff048 100644 --- a/src/core/lib/security/jwt_verifier.h +++ b/src/core/lib/security/jwt_verifier.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_LIB_SECURITY_JWT_VERIFIER_H #define GRPC_CORE_LIB_SECURITY_JWT_VERIFIER_H -#include "src/core/iomgr/pollset.h" -#include "src/core/json/json.h" +#include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/json/json.h" #include #include diff --git a/src/core/lib/security/secure_endpoint.c b/src/core/lib/security/secure_endpoint.c index 58b081dc4a..e233b081ef 100644 --- a/src/core/lib/security/secure_endpoint.c +++ b/src/core/lib/security/secure_endpoint.c @@ -31,15 +31,15 @@ * */ -#include "src/core/security/secure_endpoint.h" +#include "src/core/lib/security/secure_endpoint.h" #include #include #include #include #include -#include "src/core/debug/trace.h" -#include "src/core/support/string.h" -#include "src/core/tsi/transport_security_interface.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/tsi/transport_security_interface.h" #define STAGING_BUFFER_SIZE 8192 diff --git a/src/core/lib/security/secure_endpoint.h b/src/core/lib/security/secure_endpoint.h index f13a4cca44..57bd160a52 100644 --- a/src/core/lib/security/secure_endpoint.h +++ b/src/core/lib/security/secure_endpoint.h @@ -35,7 +35,7 @@ #define GRPC_CORE_LIB_SECURITY_SECURE_ENDPOINT_H #include -#include "src/core/iomgr/endpoint.h" +#include "src/core/lib/iomgr/endpoint.h" struct tsi_frame_protector; diff --git a/src/core/lib/security/security_connector.c b/src/core/lib/security/security_connector.c index fbec263eed..5474bc3a9e 100644 --- a/src/core/lib/security/security_connector.c +++ b/src/core/lib/security/security_connector.c @@ -31,7 +31,7 @@ * */ -#include "src/core/security/security_connector.h" +#include "src/core/lib/security/security_connector.h" #include #include @@ -42,16 +42,16 @@ #include #include -#include "src/core/security/credentials.h" -#include "src/core/security/handshake.h" -#include "src/core/security/secure_endpoint.h" -#include "src/core/security/security_context.h" -#include "src/core/support/env.h" -#include "src/core/support/load_file.h" -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/alpn.h" -#include "src/core/tsi/fake_transport_security.h" -#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/security/handshake.h" +#include "src/core/lib/security/secure_endpoint.h" +#include "src/core/lib/security/security_context.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/load_file.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/chttp2/alpn.h" +#include "src/core/lib/tsi/fake_transport_security.h" +#include "src/core/lib/tsi/ssl_transport_security.h" /* -- Constants. -- */ diff --git a/src/core/lib/security/security_connector.h b/src/core/lib/security/security_connector.h index 2818299235..d50091c628 100644 --- a/src/core/lib/security/security_connector.h +++ b/src/core/lib/security/security_connector.h @@ -35,9 +35,9 @@ #define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_H #include -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/tcp_server.h" -#include "src/core/tsi/transport_security_interface.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/tcp_server.h" +#include "src/core/lib/tsi/transport_security_interface.h" /* --- status enum. --- */ diff --git a/src/core/lib/security/security_context.c b/src/core/lib/security/security_context.c index f6afc0f633..0e66373bd8 100644 --- a/src/core/lib/security/security_context.c +++ b/src/core/lib/security/security_context.c @@ -33,10 +33,10 @@ #include -#include "src/core/security/security_context.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" +#include "src/core/lib/security/security_context.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/call.h" #include #include diff --git a/src/core/lib/security/security_context.h b/src/core/lib/security/security_context.h index e205229081..e9e4e503bc 100644 --- a/src/core/lib/security/security_context.h +++ b/src/core/lib/security/security_context.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONTEXT_H #define GRPC_CORE_LIB_SECURITY_SECURITY_CONTEXT_H -#include "src/core/iomgr/pollset.h" -#include "src/core/security/credentials.h" +#include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/security/credentials.h" /* --- grpc_auth_context --- diff --git a/src/core/lib/security/server_auth_filter.c b/src/core/lib/security/server_auth_filter.c index f3c411d6d4..158cde0e2c 100644 --- a/src/core/lib/security/server_auth_filter.c +++ b/src/core/lib/security/server_auth_filter.c @@ -33,9 +33,9 @@ #include -#include "src/core/security/auth_filters.h" -#include "src/core/security/credentials.h" -#include "src/core/security/security_context.h" +#include "src/core/lib/security/auth_filters.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/security/security_context.h" #include #include diff --git a/src/core/lib/security/server_secure_chttp2.c b/src/core/lib/security/server_secure_chttp2.c index da29ca934b..7c9dd221ed 100644 --- a/src/core/lib/security/server_secure_chttp2.c +++ b/src/core/lib/security/server_secure_chttp2.c @@ -39,18 +39,18 @@ #include #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/tcp_server.h" -#include "src/core/security/auth_filters.h" -#include "src/core/security/credentials.h" -#include "src/core/security/security_connector.h" -#include "src/core/security/security_context.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/channel_args.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" +#include "src/core/lib/iomgr/tcp_server.h" +#include "src/core/lib/security/auth_filters.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/security/security_connector.h" +#include "src/core/lib/security/security_context.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" typedef struct grpc_server_secure_state { grpc_server *server; diff --git a/src/core/lib/statistics/census_init.c b/src/core/lib/statistics/census_init.c index b6a962f228..bbecd62764 100644 --- a/src/core/lib/statistics/census_init.c +++ b/src/core/lib/statistics/census_init.c @@ -31,11 +31,11 @@ * */ -#include "src/core/statistics/census_interface.h" +#include "src/core/lib/statistics/census_interface.h" #include -#include "src/core/statistics/census_rpc_stats.h" -#include "src/core/statistics/census_tracing.h" +#include "src/core/lib/statistics/census_rpc_stats.h" +#include "src/core/lib/statistics/census_tracing.h" void census_init(void) { census_tracing_init(); diff --git a/src/core/lib/statistics/census_log.c b/src/core/lib/statistics/census_log.c index 3802d1cc7a..1fb942a78a 100644 --- a/src/core/lib/statistics/census_log.c +++ b/src/core/lib/statistics/census_log.c @@ -89,7 +89,7 @@ include the name of the structure, which will be passed as the first argument. E.g. cl_block_initialize() will initialize a cl_block. */ -#include "src/core/statistics/census_log.h" +#include "src/core/lib/statistics/census_log.h" #include #include #include diff --git a/src/core/lib/statistics/census_rpc_stats.c b/src/core/lib/statistics/census_rpc_stats.c index c78d6fd612..2182561668 100644 --- a/src/core/lib/statistics/census_rpc_stats.c +++ b/src/core/lib/statistics/census_rpc_stats.c @@ -36,13 +36,13 @@ #include #include #include -#include "src/core/statistics/census_interface.h" -#include "src/core/statistics/census_rpc_stats.h" -#include "src/core/statistics/census_tracing.h" -#include "src/core/statistics/hash_table.h" -#include "src/core/statistics/window_stats.h" -#include "src/core/support/murmur_hash.h" -#include "src/core/support/string.h" +#include "src/core/lib/statistics/census_interface.h" +#include "src/core/lib/statistics/census_rpc_stats.h" +#include "src/core/lib/statistics/census_tracing.h" +#include "src/core/lib/statistics/hash_table.h" +#include "src/core/lib/statistics/window_stats.h" +#include "src/core/lib/support/murmur_hash.h" +#include "src/core/lib/support/string.h" #define NUM_INTERVALS 3 #define MINUTE_INTERVAL 0 diff --git a/src/core/lib/statistics/census_rpc_stats.h b/src/core/lib/statistics/census_rpc_stats.h index 1b45872be8..00bb48205e 100644 --- a/src/core/lib/statistics/census_rpc_stats.h +++ b/src/core/lib/statistics/census_rpc_stats.h @@ -35,7 +35,7 @@ #define GRPC_CORE_LIB_STATISTICS_CENSUS_RPC_STATS_H #include -#include "src/core/statistics/census_interface.h" +#include "src/core/lib/statistics/census_interface.h" #ifdef __cplusplus extern "C" { diff --git a/src/core/lib/statistics/census_tracing.c b/src/core/lib/statistics/census_tracing.c index ad82498eba..b58ae733fc 100644 --- a/src/core/lib/statistics/census_tracing.c +++ b/src/core/lib/statistics/census_tracing.c @@ -31,8 +31,8 @@ * */ -#include "src/core/statistics/census_tracing.h" -#include "src/core/statistics/census_interface.h" +#include "src/core/lib/statistics/census_tracing.h" +#include "src/core/lib/statistics/census_interface.h" #include #include @@ -41,8 +41,8 @@ #include #include #include -#include "src/core/statistics/hash_table.h" -#include "src/core/support/string.h" +#include "src/core/lib/statistics/hash_table.h" +#include "src/core/lib/support/string.h" void census_trace_obj_destroy(census_trace_obj *obj) { census_trace_annotation *p = obj->annotations; diff --git a/src/core/lib/statistics/census_tracing.h b/src/core/lib/statistics/census_tracing.h index e497bc354d..a101abf3cb 100644 --- a/src/core/lib/statistics/census_tracing.h +++ b/src/core/lib/statistics/census_tracing.h @@ -35,7 +35,7 @@ #define GRPC_CORE_LIB_STATISTICS_CENSUS_TRACING_H #include -#include "src/core/statistics/census_rpc_stats.h" +#include "src/core/lib/statistics/census_rpc_stats.h" /* WARNING: The data structures and APIs provided by this file are for GRPC library's internal use ONLY. They might be changed in backward-incompatible diff --git a/src/core/lib/statistics/hash_table.c b/src/core/lib/statistics/hash_table.c index 3ef79c0d7d..18b7442a0c 100644 --- a/src/core/lib/statistics/hash_table.c +++ b/src/core/lib/statistics/hash_table.c @@ -31,7 +31,7 @@ * */ -#include "src/core/statistics/hash_table.h" +#include "src/core/lib/statistics/hash_table.h" #include #include diff --git a/src/core/lib/statistics/window_stats.c b/src/core/lib/statistics/window_stats.c index eb296865a0..53427a24bc 100644 --- a/src/core/lib/statistics/window_stats.c +++ b/src/core/lib/statistics/window_stats.c @@ -31,7 +31,7 @@ * */ -#include "src/core/statistics/window_stats.h" +#include "src/core/lib/statistics/window_stats.h" #include #include #include diff --git a/src/core/lib/support/alloc.c b/src/core/lib/support/alloc.c index fd9fb8f5e7..27fa6a95ed 100644 --- a/src/core/lib/support/alloc.c +++ b/src/core/lib/support/alloc.c @@ -36,7 +36,7 @@ #include #include #include -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" static gpr_allocation_functions g_alloc_functions = {malloc, realloc, free}; diff --git a/src/core/lib/support/backoff.c b/src/core/lib/support/backoff.c index 4ccfb774ed..e89ef47220 100644 --- a/src/core/lib/support/backoff.c +++ b/src/core/lib/support/backoff.c @@ -31,7 +31,7 @@ * */ -#include "src/core/support/backoff.h" +#include "src/core/lib/support/backoff.h" #include diff --git a/src/core/lib/support/cmdline.c b/src/core/lib/support/cmdline.c index eff46a1655..35c4990b22 100644 --- a/src/core/lib/support/cmdline.c +++ b/src/core/lib/support/cmdline.c @@ -40,7 +40,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" typedef enum { ARGTYPE_INT, ARGTYPE_BOOL, ARGTYPE_STRING } argtype; diff --git a/src/core/lib/support/env_linux.c b/src/core/lib/support/env_linux.c index fe51f846b7..a86133e6c3 100644 --- a/src/core/lib/support/env_linux.c +++ b/src/core/lib/support/env_linux.c @@ -40,7 +40,7 @@ #ifdef GPR_LINUX_ENV -#include "src/core/support/env.h" +#include "src/core/lib/support/env.h" #include #include @@ -51,7 +51,7 @@ #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" char *gpr_getenv(const char *name) { #if defined(GPR_BACKWARDS_COMPATIBILITY_MODE) diff --git a/src/core/lib/support/env_posix.c b/src/core/lib/support/env_posix.c index 256212be76..1b57b094a9 100644 --- a/src/core/lib/support/env_posix.c +++ b/src/core/lib/support/env_posix.c @@ -35,14 +35,14 @@ #ifdef GPR_POSIX_ENV -#include "src/core/support/env.h" +#include "src/core/lib/support/env.h" #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" char *gpr_getenv(const char *name) { char *result = getenv(name); diff --git a/src/core/lib/support/env_win32.c b/src/core/lib/support/env_win32.c index 10258283ba..566feee49e 100644 --- a/src/core/lib/support/env_win32.c +++ b/src/core/lib/support/env_win32.c @@ -35,8 +35,8 @@ #ifdef GPR_WIN32 -#include "src/core/support/env.h" -#include "src/core/support/string.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" #ifdef __MINGW32__ errno_t getenv_s(size_t *size_needed, char *buffer, size_t size, diff --git a/src/core/lib/support/host_port.c b/src/core/lib/support/host_port.c index 31243a7221..e03f6241ff 100644 --- a/src/core/lib/support/host_port.c +++ b/src/core/lib/support/host_port.c @@ -38,7 +38,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" int gpr_join_host_port(char **out, const char *host, int port) { if (host[0] != '[' && strchr(host, ':') != NULL) { diff --git a/src/core/lib/support/load_file.c b/src/core/lib/support/load_file.c index 650bd62ccb..0cecd5edd5 100644 --- a/src/core/lib/support/load_file.c +++ b/src/core/lib/support/load_file.c @@ -31,7 +31,7 @@ * */ -#include "src/core/support/load_file.h" +#include "src/core/lib/support/load_file.h" #include #include @@ -40,8 +40,8 @@ #include #include -#include "src/core/support/block_annotate.h" -#include "src/core/support/string.h" +#include "src/core/lib/support/block_annotate.h" +#include "src/core/lib/support/string.h" gpr_slice gpr_load_file(const char *filename, int add_null_terminator, int *success) { diff --git a/src/core/lib/support/log_win32.c b/src/core/lib/support/log_win32.c index 89ec0917d5..cec99440a5 100644 --- a/src/core/lib/support/log_win32.c +++ b/src/core/lib/support/log_win32.c @@ -44,8 +44,8 @@ #include #include -#include "src/core/support/string.h" -#include "src/core/support/string_win32.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/support/string_win32.h" void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format, ...) { diff --git a/src/core/lib/support/murmur_hash.c b/src/core/lib/support/murmur_hash.c index 47e9777fec..97832f1510 100644 --- a/src/core/lib/support/murmur_hash.c +++ b/src/core/lib/support/murmur_hash.c @@ -31,7 +31,7 @@ * */ -#include "src/core/support/murmur_hash.h" +#include "src/core/lib/support/murmur_hash.h" #define ROTL32(x, r) ((x) << (r)) | ((x) >> (32 - (r))) diff --git a/src/core/lib/support/stack_lockfree.c b/src/core/lib/support/stack_lockfree.c index 8e0bbfaee8..de80486132 100644 --- a/src/core/lib/support/stack_lockfree.c +++ b/src/core/lib/support/stack_lockfree.c @@ -31,7 +31,7 @@ * */ -#include "src/core/support/stack_lockfree.h" +#include "src/core/lib/support/stack_lockfree.h" #include #include diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c index e8021ddaba..365d861de3 100644 --- a/src/core/lib/support/string.c +++ b/src/core/lib/support/string.c @@ -31,7 +31,7 @@ * */ -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include #include diff --git a/src/core/lib/support/string_win32.c b/src/core/lib/support/string_win32.c index 0780907994..16b7e37f2a 100644 --- a/src/core/lib/support/string_win32.c +++ b/src/core/lib/support/string_win32.c @@ -43,7 +43,7 @@ #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" int gpr_asprintf(char **strp, const char *format, ...) { va_list args; diff --git a/src/core/lib/support/subprocess_windows.c b/src/core/lib/support/subprocess_windows.c index 6afbefeb2b..264306f1bd 100644 --- a/src/core/lib/support/subprocess_windows.c +++ b/src/core/lib/support/subprocess_windows.c @@ -42,8 +42,8 @@ #include #include #include -#include "src/core/support/string.h" -#include "src/core/support/string_win32.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/support/string_win32.h" struct gpr_subprocess { PROCESS_INFORMATION pi; diff --git a/src/core/lib/support/sync_posix.c b/src/core/lib/support/sync_posix.c index be4d0ac1c9..a5e59db8c7 100644 --- a/src/core/lib/support/sync_posix.c +++ b/src/core/lib/support/sync_posix.c @@ -40,7 +40,7 @@ #include #include #include -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" void gpr_mu_init(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_init(mu, NULL) == 0); } diff --git a/src/core/lib/support/time_posix.c b/src/core/lib/support/time_posix.c index f999e08cb0..6435af6340 100644 --- a/src/core/lib/support/time_posix.c +++ b/src/core/lib/support/time_posix.c @@ -44,7 +44,7 @@ #endif #include #include -#include "src/core/support/block_annotate.h" +#include "src/core/lib/support/block_annotate.h" static struct timespec timespec_from_gpr(gpr_timespec gts) { struct timespec rv; diff --git a/src/core/lib/support/time_win32.c b/src/core/lib/support/time_win32.c index 2c344d3f3b..4152f5db21 100644 --- a/src/core/lib/support/time_win32.c +++ b/src/core/lib/support/time_win32.c @@ -44,7 +44,7 @@ #include #include -#include "src/core/support/block_annotate.h" +#include "src/core/lib/support/block_annotate.h" static LARGE_INTEGER g_start_time; static double g_time_scale; diff --git a/src/core/lib/support/tmpfile_posix.c b/src/core/lib/support/tmpfile_posix.c index b16eeacf9d..743f45e1bc 100644 --- a/src/core/lib/support/tmpfile_posix.c +++ b/src/core/lib/support/tmpfile_posix.c @@ -35,7 +35,7 @@ #ifdef GPR_POSIX_FILE -#include "src/core/support/tmpfile.h" +#include "src/core/lib/support/tmpfile.h" #include #include @@ -46,7 +46,7 @@ #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" FILE *gpr_tmpfile(const char *prefix, char **tmp_filename) { FILE *result = NULL; diff --git a/src/core/lib/support/tmpfile_win32.c b/src/core/lib/support/tmpfile_win32.c index 3000f0029f..05d92b6036 100644 --- a/src/core/lib/support/tmpfile_win32.c +++ b/src/core/lib/support/tmpfile_win32.c @@ -44,8 +44,8 @@ #include #include -#include "src/core/support/string_win32.h" -#include "src/core/support/tmpfile.h" +#include "src/core/lib/support/string_win32.h" +#include "src/core/lib/support/tmpfile.h" FILE *gpr_tmpfile(const char *prefix, char **tmp_filename_out) { FILE *result = NULL; diff --git a/src/core/lib/surface/alarm.c b/src/core/lib/surface/alarm.c index 1085285f95..368683378e 100644 --- a/src/core/lib/surface/alarm.c +++ b/src/core/lib/surface/alarm.c @@ -33,8 +33,8 @@ #include #include -#include "src/core/iomgr/timer.h" -#include "src/core/surface/completion_queue.h" +#include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/surface/completion_queue.h" struct grpc_alarm { grpc_timer alarm; diff --git a/src/core/lib/surface/api_trace.c b/src/core/lib/surface/api_trace.c index 06c65c0610..3702c024db 100644 --- a/src/core/lib/surface/api_trace.c +++ b/src/core/lib/surface/api_trace.c @@ -31,6 +31,6 @@ * */ -#include "src/core/surface/api_trace.h" +#include "src/core/lib/surface/api_trace.h" int grpc_api_trace = 0; diff --git a/src/core/lib/surface/api_trace.h b/src/core/lib/surface/api_trace.h index 00d71677e5..b50011c9e5 100644 --- a/src/core/lib/surface/api_trace.h +++ b/src/core/lib/surface/api_trace.h @@ -35,7 +35,7 @@ #define GRPC_CORE_LIB_SURFACE_API_TRACE_H #include -#include "src/core/debug/trace.h" +#include "src/core/lib/debug/trace.h" extern int grpc_api_trace; diff --git a/src/core/lib/surface/byte_buffer_reader.c b/src/core/lib/surface/byte_buffer_reader.c index 4a418faaed..7248f5fe71 100644 --- a/src/core/lib/surface/byte_buffer_reader.c +++ b/src/core/lib/surface/byte_buffer_reader.c @@ -41,7 +41,7 @@ #include #include -#include "src/core/compression/message_compress.h" +#include "src/core/lib/compression/message_compress.h" static int is_compressed(grpc_byte_buffer *buffer) { switch (buffer->type) { diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 6f1cd1df10..d63a4a7401 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -43,16 +43,16 @@ #include #include -#include "src/core/channel/channel_stack.h" -#include "src/core/compression/algorithm_metadata.h" -#include "src/core/iomgr/timer.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/completion_queue.h" -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/compression/algorithm_metadata.h" +#include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/call.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/completion_queue.h" +#include "src/core/lib/transport/static_metadata.h" /** The maximum number of concurrent batches possible. Based upon the maximum number of individually queueable ops in the batch diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index 09e19dc779..e2e75865be 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -34,10 +34,10 @@ #ifndef GRPC_CORE_LIB_SURFACE_CALL_H #define GRPC_CORE_LIB_SURFACE_CALL_H -#include "src/core/channel/channel_stack.h" -#include "src/core/channel/context.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/surface_trace.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/channel/context.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/surface_trace.h" #include #include diff --git a/src/core/lib/surface/call_details.c b/src/core/lib/surface/call_details.c index dc5ea22ee7..08f606d84a 100644 --- a/src/core/lib/surface/call_details.c +++ b/src/core/lib/surface/call_details.c @@ -36,7 +36,7 @@ #include -#include "src/core/surface/api_trace.h" +#include "src/core/lib/surface/api_trace.h" void grpc_call_details_init(grpc_call_details* cd) { GRPC_API_TRACE("grpc_call_details_init(cd=%p)", 1, (cd)); diff --git a/src/core/lib/surface/call_log_batch.c b/src/core/lib/surface/call_log_batch.c index 044211616c..bc5a2ffb65 100644 --- a/src/core/lib/surface/call_log_batch.c +++ b/src/core/lib/surface/call_log_batch.c @@ -31,11 +31,11 @@ * */ -#include "src/core/surface/call.h" +#include "src/core/lib/surface/call.h" #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" static void add_metadata(gpr_strvec *b, const grpc_metadata *md, size_t count) { size_t i; diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c index 0010b64c7d..d815daa70c 100644 --- a/src/core/lib/surface/channel.c +++ b/src/core/lib/surface/channel.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/channel.h" +#include "src/core/lib/surface/channel.h" #include #include @@ -40,14 +40,14 @@ #include #include -#include "src/core/client_config/resolver_registry.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" -#include "src/core/surface/channel_init.h" -#include "src/core/surface/init.h" -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/client_config/resolver_registry.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/call.h" +#include "src/core/lib/surface/channel_init.h" +#include "src/core/lib/surface/init.h" +#include "src/core/lib/transport/static_metadata.h" /** Cache grpc-status: X mdelems for X = 0..NUM_CACHED_STATUS_ELEMS. * Avoids needing to take a metadata context lock for sending status diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h index d0e15bbeb8..09de0fccc9 100644 --- a/src/core/lib/surface/channel.h +++ b/src/core/lib/surface/channel.h @@ -34,9 +34,9 @@ #ifndef GRPC_CORE_LIB_SURFACE_CHANNEL_H #define GRPC_CORE_LIB_SURFACE_CHANNEL_H -#include "src/core/channel/channel_stack.h" -#include "src/core/client_config/subchannel_factory.h" -#include "src/core/surface/channel_stack_type.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/client_config/subchannel_factory.h" +#include "src/core/lib/surface/channel_stack_type.h" grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, const grpc_channel_args *args, diff --git a/src/core/lib/surface/channel_connectivity.c b/src/core/lib/surface/channel_connectivity.c index 18267939ed..2f5d763e70 100644 --- a/src/core/lib/surface/channel_connectivity.c +++ b/src/core/lib/surface/channel_connectivity.c @@ -31,15 +31,15 @@ * */ -#include "src/core/surface/channel.h" +#include "src/core/lib/surface/channel.h" #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/iomgr/timer.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/completion_queue.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/completion_queue.h" grpc_connectivity_state grpc_channel_check_connectivity_state( grpc_channel *channel, int try_to_connect) { diff --git a/src/core/lib/surface/channel_create.c b/src/core/lib/surface/channel_create.c index 123447c8ed..e8777ce816 100644 --- a/src/core/lib/surface/channel_create.c +++ b/src/core/lib/surface/channel_create.c @@ -40,16 +40,16 @@ #include #include -#include "src/core/census/grpc_filter.h" -#include "src/core/channel/channel_args.h" -#include "src/core/channel/client_channel.h" -#include "src/core/channel/compress_filter.h" -#include "src/core/channel/http_client_filter.h" -#include "src/core/client_config/resolver_registry.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/channel.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/census/grpc_filter.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/compress_filter.h" +#include "src/core/lib/channel/http_client_filter.h" +#include "src/core/lib/client_config/resolver_registry.h" +#include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/transport/chttp2_transport.h" typedef struct { grpc_connector base; diff --git a/src/core/lib/surface/channel_init.c b/src/core/lib/surface/channel_init.c index ac962f3972..fc69f61f77 100644 --- a/src/core/lib/surface/channel_init.c +++ b/src/core/lib/surface/channel_init.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/channel_init.h" +#include "src/core/lib/surface/channel_init.h" #include #include diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index ef994b940f..a4d8271ca6 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -34,9 +34,9 @@ #ifndef GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H #define GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H -#include "src/core/channel/channel_stack_builder.h" -#include "src/core/surface/channel_stack_type.h" -#include "src/core/transport/transport.h" +#include "src/core/lib/channel/channel_stack_builder.h" +#include "src/core/lib/surface/channel_stack_type.h" +#include "src/core/lib/transport/transport.h" /// This module provides a way for plugins (and the grpc core library itself) /// to register mutators for channel stacks. diff --git a/src/core/lib/surface/channel_ping.c b/src/core/lib/surface/channel_ping.c index 983f1c8a66..dd862cdadd 100644 --- a/src/core/lib/surface/channel_ping.c +++ b/src/core/lib/surface/channel_ping.c @@ -31,15 +31,15 @@ * */ -#include "src/core/surface/channel.h" +#include "src/core/lib/surface/channel.h" #include #include #include -#include "src/core/surface/api_trace.h" -#include "src/core/surface/completion_queue.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/completion_queue.h" typedef struct { grpc_closure closure; diff --git a/src/core/lib/surface/channel_stack_type.c b/src/core/lib/surface/channel_stack_type.c index 1a6e949ffe..c35d603ca3 100644 --- a/src/core/lib/surface/channel_stack_type.c +++ b/src/core/lib/surface/channel_stack_type.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/channel_stack_type.h" +#include "src/core/lib/surface/channel_stack_type.h" #include #include diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index b22818ea87..a0d7002053 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/completion_queue.h" +#include "src/core/lib/surface/completion_queue.h" #include #include @@ -41,14 +41,14 @@ #include #include -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/timer.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" -#include "src/core/surface/event_string.h" -#include "src/core/surface/surface_trace.h" +#include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/call.h" +#include "src/core/lib/surface/event_string.h" +#include "src/core/lib/surface/surface_trace.h" typedef struct { grpc_pollset_worker **worker; diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index 08c07f3baa..35591cb6f4 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -37,7 +37,7 @@ /* Internal API for completion queues */ #include -#include "src/core/iomgr/pollset.h" +#include "src/core/lib/iomgr/pollset.h" typedef struct grpc_cq_completion { /** user supplied tag */ diff --git a/src/core/lib/surface/event_string.c b/src/core/lib/surface/event_string.c index 85a372b9ad..360c718a17 100644 --- a/src/core/lib/surface/event_string.c +++ b/src/core/lib/surface/event_string.c @@ -31,13 +31,13 @@ * */ -#include "src/core/surface/event_string.h" +#include "src/core/lib/surface/event_string.h" #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" static void addhdr(gpr_strvec *buf, grpc_event *ev) { char *tmp; diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c index 3c4db3e6cc..dcb9c62d36 100644 --- a/src/core/lib/surface/init.c +++ b/src/core/lib/surface/init.c @@ -40,36 +40,36 @@ #include #include /* TODO(ctiller): find another way? - better not to include census here */ -#include "src/core/census/grpc_plugin.h" -#include "src/core/channel/channel_stack.h" -#include "src/core/channel/client_channel.h" -#include "src/core/channel/compress_filter.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_client_filter.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/client_config/lb_policies/pick_first.h" -#include "src/core/client_config/lb_policies/round_robin.h" -#include "src/core/client_config/lb_policy_registry.h" -#include "src/core/client_config/resolver_registry.h" -#include "src/core/client_config/resolvers/dns_resolver.h" -#include "src/core/client_config/resolvers/sockaddr_resolver.h" -#include "src/core/client_config/subchannel.h" -#include "src/core/client_config/subchannel_index.h" -#include "src/core/debug/trace.h" -#include "src/core/iomgr/executor.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/profiling/timers.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" -#include "src/core/surface/channel_init.h" -#include "src/core/surface/completion_queue.h" -#include "src/core/surface/init.h" -#include "src/core/surface/lame_client.h" -#include "src/core/surface/server.h" -#include "src/core/surface/surface_trace.h" -#include "src/core/transport/chttp2_transport.h" -#include "src/core/transport/connectivity_state.h" -#include "src/core/transport/transport_impl.h" +#include "src/core/lib/census/grpc_plugin.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/compress_filter.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_client_filter.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/client_config/lb_policies/pick_first.h" +#include "src/core/lib/client_config/lb_policies/round_robin.h" +#include "src/core/lib/client_config/lb_policy_registry.h" +#include "src/core/lib/client_config/resolver_registry.h" +#include "src/core/lib/client_config/resolvers/dns_resolver.h" +#include "src/core/lib/client_config/resolvers/sockaddr_resolver.h" +#include "src/core/lib/client_config/subchannel.h" +#include "src/core/lib/client_config/subchannel_index.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/call.h" +#include "src/core/lib/surface/channel_init.h" +#include "src/core/lib/surface/completion_queue.h" +#include "src/core/lib/surface/init.h" +#include "src/core/lib/surface/lame_client.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/surface/surface_trace.h" +#include "src/core/lib/transport/chttp2_transport.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/transport_impl.h" #ifndef GRPC_DEFAULT_NAME_PREFIX #define GRPC_DEFAULT_NAME_PREFIX "dns:///" diff --git a/src/core/lib/surface/init_secure.c b/src/core/lib/surface/init_secure.c index e0d66a8d46..d3c2f645a7 100644 --- a/src/core/lib/surface/init_secure.c +++ b/src/core/lib/surface/init_secure.c @@ -31,18 +31,18 @@ * */ -#include "src/core/surface/init.h" +#include "src/core/lib/surface/init.h" #include #include -#include "src/core/debug/trace.h" -#include "src/core/security/auth_filters.h" -#include "src/core/security/credentials.h" -#include "src/core/security/secure_endpoint.h" -#include "src/core/security/security_connector.h" -#include "src/core/surface/channel_init.h" -#include "src/core/tsi/transport_security_interface.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/security/auth_filters.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/security/secure_endpoint.h" +#include "src/core/lib/security/security_connector.h" +#include "src/core/lib/surface/channel_init.h" +#include "src/core/lib/tsi/transport_security_interface.h" void grpc_security_pre_init(void) { grpc_register_tracer("secure_endpoint", &grpc_trace_secure_endpoint); diff --git a/src/core/lib/surface/init_unsecure.c b/src/core/lib/surface/init_unsecure.c index 278fcc83ac..243c005d86 100644 --- a/src/core/lib/surface/init_unsecure.c +++ b/src/core/lib/surface/init_unsecure.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/init.h" +#include "src/core/lib/surface/init.h" void grpc_security_pre_init(void) {} diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c index 25f3a74349..95ec4b06c3 100644 --- a/src/core/lib/surface/lame_client.c +++ b/src/core/lib/surface/lame_client.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/lame_client.h" +#include "src/core/lib/surface/lame_client.h" #include @@ -39,11 +39,11 @@ #include #include -#include "src/core/channel/channel_stack.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" -#include "src/core/surface/channel.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/call.h" +#include "src/core/lib/surface/channel.h" typedef struct { grpc_linked_mdelem status; diff --git a/src/core/lib/surface/lame_client.h b/src/core/lib/surface/lame_client.h index cee9500f3e..5f6ea34d4b 100644 --- a/src/core/lib/surface/lame_client.h +++ b/src/core/lib/surface/lame_client.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_SURFACE_LAME_CLIENT_H #define GRPC_CORE_LIB_SURFACE_LAME_CLIENT_H -#include "src/core/channel/channel_stack.h" +#include "src/core/lib/channel/channel_stack.h" extern const grpc_channel_filter grpc_lame_filter; diff --git a/src/core/lib/surface/metadata_array.c b/src/core/lib/surface/metadata_array.c index 57096326a3..4436f2da87 100644 --- a/src/core/lib/surface/metadata_array.c +++ b/src/core/lib/surface/metadata_array.c @@ -36,7 +36,7 @@ #include -#include "src/core/surface/api_trace.h" +#include "src/core/lib/surface/api_trace.h" void grpc_metadata_array_init(grpc_metadata_array* array) { GRPC_API_TRACE("grpc_metadata_array_init(array=%p)", 1, (array)); diff --git a/src/core/lib/surface/secure_channel_create.c b/src/core/lib/surface/secure_channel_create.c index cc752227ee..dcb367023e 100644 --- a/src/core/lib/surface/secure_channel_create.c +++ b/src/core/lib/surface/secure_channel_create.c @@ -40,17 +40,17 @@ #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/client_channel.h" -#include "src/core/client_config/resolver_registry.h" -#include "src/core/iomgr/tcp_client.h" -#include "src/core/security/auth_filters.h" -#include "src/core/security/credentials.h" -#include "src/core/security/security_context.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/channel.h" -#include "src/core/transport/chttp2_transport.h" -#include "src/core/tsi/transport_security_interface.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/client_config/resolver_registry.h" +#include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/security/auth_filters.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/security/security_context.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/transport/chttp2_transport.h" +#include "src/core/lib/tsi/transport_security_interface.h" typedef struct { grpc_connector base; diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index a92f2b3e38..080734e9d5 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/server.h" +#include "src/core/lib/surface/server.h" #include #include @@ -42,18 +42,18 @@ #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/support/stack_lockfree.h" -#include "src/core/support/string.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/call.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/completion_queue.h" -#include "src/core/surface/init.h" -#include "src/core/transport/metadata.h" -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/support/stack_lockfree.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/call.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/completion_queue.h" +#include "src/core/lib/surface/init.h" +#include "src/core/lib/transport/metadata.h" +#include "src/core/lib/transport/static_metadata.h" typedef struct listener { void *arg; diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index 969d268053..3845eb2981 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -35,8 +35,8 @@ #define GRPC_CORE_LIB_SURFACE_SERVER_H #include -#include "src/core/channel/channel_stack.h" -#include "src/core/transport/transport.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/transport/transport.h" extern const grpc_channel_filter grpc_server_top_filter; diff --git a/src/core/lib/surface/server_chttp2.c b/src/core/lib/surface/server_chttp2.c index 546760ecfa..f0c2ee5153 100644 --- a/src/core/lib/surface/server_chttp2.c +++ b/src/core/lib/surface/server_chttp2.c @@ -36,12 +36,12 @@ #include #include #include -#include "src/core/channel/http_server_filter.h" -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/tcp_server.h" -#include "src/core/surface/api_trace.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/tcp_server.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" static void setup_transport(grpc_exec_ctx *exec_ctx, void *server, grpc_transport *transport) { diff --git a/src/core/lib/surface/surface_trace.h b/src/core/lib/surface/surface_trace.h index 1046eb0c83..6b3f673924 100644 --- a/src/core/lib/surface/surface_trace.h +++ b/src/core/lib/surface/surface_trace.h @@ -35,8 +35,8 @@ #define GRPC_CORE_LIB_SURFACE_SURFACE_TRACE_H #include -#include "src/core/debug/trace.h" -#include "src/core/surface/api_trace.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/surface/api_trace.h" #define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \ if (grpc_api_trace) { \ diff --git a/src/core/lib/transport/byte_stream.c b/src/core/lib/transport/byte_stream.c index cfba878dc4..79981aa154 100644 --- a/src/core/lib/transport/byte_stream.c +++ b/src/core/lib/transport/byte_stream.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/byte_stream.h" +#include "src/core/lib/transport/byte_stream.h" #include diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h index ae01f91295..e7346dafc3 100644 --- a/src/core/lib/transport/byte_stream.h +++ b/src/core/lib/transport/byte_stream.h @@ -35,7 +35,7 @@ #define GRPC_CORE_LIB_TRANSPORT_BYTE_STREAM_H #include -#include "src/core/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/exec_ctx.h" /** Internal bit flag for grpc_begin_message's \a flags signaling the use of * compression for the message */ diff --git a/src/core/lib/transport/chttp2/alpn.c b/src/core/lib/transport/chttp2/alpn.c index 67fff21229..befe319180 100644 --- a/src/core/lib/transport/chttp2/alpn.c +++ b/src/core/lib/transport/chttp2/alpn.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/alpn.h" +#include "src/core/lib/transport/chttp2/alpn.h" #include #include diff --git a/src/core/lib/transport/chttp2/bin_encoder.c b/src/core/lib/transport/chttp2/bin_encoder.c index 3d31162499..79d0aa3d6f 100644 --- a/src/core/lib/transport/chttp2/bin_encoder.c +++ b/src/core/lib/transport/chttp2/bin_encoder.c @@ -31,12 +31,12 @@ * */ -#include "src/core/transport/chttp2/bin_encoder.h" +#include "src/core/lib/transport/chttp2/bin_encoder.h" #include #include -#include "src/core/transport/chttp2/huffsyms.h" +#include "src/core/lib/transport/chttp2/huffsyms.h" static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; diff --git a/src/core/lib/transport/chttp2/frame_data.c b/src/core/lib/transport/chttp2/frame_data.c index 6cc6d4eaf2..cf25c3ccc1 100644 --- a/src/core/lib/transport/chttp2/frame_data.c +++ b/src/core/lib/transport/chttp2/frame_data.c @@ -31,16 +31,16 @@ * */ -#include "src/core/transport/chttp2/frame_data.h" +#include "src/core/lib/transport/chttp2/frame_data.h" #include #include #include #include -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/internal.h" -#include "src/core/transport/transport.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/chttp2/internal.h" +#include "src/core/lib/transport/transport.h" grpc_chttp2_parse_error grpc_chttp2_data_parser_init( grpc_chttp2_data_parser *parser) { diff --git a/src/core/lib/transport/chttp2/frame_data.h b/src/core/lib/transport/chttp2/frame_data.h index 725863bbb7..da404a42c6 100644 --- a/src/core/lib/transport/chttp2/frame_data.h +++ b/src/core/lib/transport/chttp2/frame_data.h @@ -38,9 +38,9 @@ #include #include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/byte_stream.h" -#include "src/core/transport/chttp2/frame.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/byte_stream.h" +#include "src/core/lib/transport/chttp2/frame.h" typedef enum { GRPC_CHTTP2_DATA_FH_0, diff --git a/src/core/lib/transport/chttp2/frame_goaway.c b/src/core/lib/transport/chttp2/frame_goaway.c index 45a8e2e270..bb8c28df90 100644 --- a/src/core/lib/transport/chttp2/frame_goaway.c +++ b/src/core/lib/transport/chttp2/frame_goaway.c @@ -31,8 +31,8 @@ * */ -#include "src/core/transport/chttp2/frame_goaway.h" -#include "src/core/transport/chttp2/internal.h" +#include "src/core/lib/transport/chttp2/frame_goaway.h" +#include "src/core/lib/transport/chttp2/internal.h" #include diff --git a/src/core/lib/transport/chttp2/frame_goaway.h b/src/core/lib/transport/chttp2/frame_goaway.h index 1ed2b62ec6..f64c44f3d9 100644 --- a/src/core/lib/transport/chttp2/frame_goaway.h +++ b/src/core/lib/transport/chttp2/frame_goaway.h @@ -37,8 +37,8 @@ #include #include #include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/chttp2/frame.h" typedef enum { GRPC_CHTTP2_GOAWAY_LSI0, diff --git a/src/core/lib/transport/chttp2/frame_ping.c b/src/core/lib/transport/chttp2/frame_ping.c index d619edb2d6..14ca394264 100644 --- a/src/core/lib/transport/chttp2/frame_ping.c +++ b/src/core/lib/transport/chttp2/frame_ping.c @@ -31,8 +31,8 @@ * */ -#include "src/core/transport/chttp2/frame_ping.h" -#include "src/core/transport/chttp2/internal.h" +#include "src/core/lib/transport/chttp2/frame_ping.h" +#include "src/core/lib/transport/chttp2/internal.h" #include diff --git a/src/core/lib/transport/chttp2/frame_ping.h b/src/core/lib/transport/chttp2/frame_ping.h index 87bf1d3257..7640fc4773 100644 --- a/src/core/lib/transport/chttp2/frame_ping.h +++ b/src/core/lib/transport/chttp2/frame_ping.h @@ -35,8 +35,8 @@ #define GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_PING_H #include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/chttp2/frame.h" typedef struct { uint8_t byte; diff --git a/src/core/lib/transport/chttp2/frame_rst_stream.c b/src/core/lib/transport/chttp2/frame_rst_stream.c index 3b4aa623f2..060912afc4 100644 --- a/src/core/lib/transport/chttp2/frame_rst_stream.c +++ b/src/core/lib/transport/chttp2/frame_rst_stream.c @@ -31,12 +31,12 @@ * */ -#include "src/core/transport/chttp2/frame_rst_stream.h" -#include "src/core/transport/chttp2/internal.h" +#include "src/core/lib/transport/chttp2/frame_rst_stream.h" +#include "src/core/lib/transport/chttp2/internal.h" #include -#include "src/core/transport/chttp2/frame.h" +#include "src/core/lib/transport/chttp2/frame.h" gpr_slice grpc_chttp2_rst_stream_create(uint32_t id, uint32_t code) { gpr_slice slice = gpr_slice_malloc(13); diff --git a/src/core/lib/transport/chttp2/frame_rst_stream.h b/src/core/lib/transport/chttp2/frame_rst_stream.h index 2dd009d3c2..93155fde9d 100644 --- a/src/core/lib/transport/chttp2/frame_rst_stream.h +++ b/src/core/lib/transport/chttp2/frame_rst_stream.h @@ -35,8 +35,8 @@ #define GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H #include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/chttp2/frame.h" typedef struct { uint8_t byte; diff --git a/src/core/lib/transport/chttp2/frame_settings.c b/src/core/lib/transport/chttp2/frame_settings.c index 9c5ad9f30e..48429c2a78 100644 --- a/src/core/lib/transport/chttp2/frame_settings.c +++ b/src/core/lib/transport/chttp2/frame_settings.c @@ -31,18 +31,18 @@ * */ -#include "src/core/transport/chttp2/frame_settings.h" -#include "src/core/transport/chttp2/internal.h" +#include "src/core/lib/transport/chttp2/frame_settings.h" +#include "src/core/lib/transport/chttp2/internal.h" #include #include #include -#include "src/core/debug/trace.h" -#include "src/core/transport/chttp2/frame.h" -#include "src/core/transport/chttp2/http2_errors.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/transport/chttp2/frame.h" +#include "src/core/lib/transport/chttp2/http2_errors.h" +#include "src/core/lib/transport/chttp2_transport.h" #define MAX_MAX_HEADER_LIST_SIZE (1024 * 1024 * 1024) diff --git a/src/core/lib/transport/chttp2/frame_settings.h b/src/core/lib/transport/chttp2/frame_settings.h index fa1db96638..8b294de021 100644 --- a/src/core/lib/transport/chttp2/frame_settings.h +++ b/src/core/lib/transport/chttp2/frame_settings.h @@ -36,8 +36,8 @@ #include #include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/chttp2/frame.h" typedef enum { GRPC_CHTTP2_SPS_ID0, diff --git a/src/core/lib/transport/chttp2/frame_window_update.c b/src/core/lib/transport/chttp2/frame_window_update.c index 03b665c9cb..2ab5003316 100644 --- a/src/core/lib/transport/chttp2/frame_window_update.c +++ b/src/core/lib/transport/chttp2/frame_window_update.c @@ -31,8 +31,8 @@ * */ -#include "src/core/transport/chttp2/frame_window_update.h" -#include "src/core/transport/chttp2/internal.h" +#include "src/core/lib/transport/chttp2/frame_window_update.h" +#include "src/core/lib/transport/chttp2/internal.h" #include diff --git a/src/core/lib/transport/chttp2/frame_window_update.h b/src/core/lib/transport/chttp2/frame_window_update.h index 88e458bbfb..4b1aea294d 100644 --- a/src/core/lib/transport/chttp2/frame_window_update.h +++ b/src/core/lib/transport/chttp2/frame_window_update.h @@ -35,8 +35,8 @@ #define GRPC_CORE_LIB_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H #include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/chttp2/frame.h" typedef struct { uint8_t byte; diff --git a/src/core/lib/transport/chttp2/hpack_encoder.c b/src/core/lib/transport/chttp2/hpack_encoder.c index f30f574d06..6b45929b04 100644 --- a/src/core/lib/transport/chttp2/hpack_encoder.c +++ b/src/core/lib/transport/chttp2/hpack_encoder.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/hpack_encoder.h" +#include "src/core/lib/transport/chttp2/hpack_encoder.h" #include #include @@ -45,11 +45,11 @@ #include #include -#include "src/core/transport/chttp2/bin_encoder.h" -#include "src/core/transport/chttp2/hpack_table.h" -#include "src/core/transport/chttp2/timeout_encoding.h" -#include "src/core/transport/chttp2/varint.h" -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/transport/chttp2/bin_encoder.h" +#include "src/core/lib/transport/chttp2/hpack_table.h" +#include "src/core/lib/transport/chttp2/timeout_encoding.h" +#include "src/core/lib/transport/chttp2/varint.h" +#include "src/core/lib/transport/static_metadata.h" #define HASH_FRAGMENT_1(x) ((x)&255) #define HASH_FRAGMENT_2(x) ((x >> 8) & 255) diff --git a/src/core/lib/transport/chttp2/hpack_encoder.h b/src/core/lib/transport/chttp2/hpack_encoder.h index e842f5719e..de46a8f146 100644 --- a/src/core/lib/transport/chttp2/hpack_encoder.h +++ b/src/core/lib/transport/chttp2/hpack_encoder.h @@ -37,9 +37,9 @@ #include #include #include -#include "src/core/transport/chttp2/frame.h" -#include "src/core/transport/metadata.h" -#include "src/core/transport/metadata_batch.h" +#include "src/core/lib/transport/chttp2/frame.h" +#include "src/core/lib/transport/metadata.h" +#include "src/core/lib/transport/metadata_batch.h" #define GRPC_CHTTP2_HPACKC_NUM_FILTERS 256 #define GRPC_CHTTP2_HPACKC_NUM_VALUES 256 diff --git a/src/core/lib/transport/chttp2/hpack_parser.c b/src/core/lib/transport/chttp2/hpack_parser.c index b6e36923cb..d41ebab147 100644 --- a/src/core/lib/transport/chttp2/hpack_parser.c +++ b/src/core/lib/transport/chttp2/hpack_parser.c @@ -31,8 +31,8 @@ * */ -#include "src/core/transport/chttp2/hpack_parser.h" -#include "src/core/transport/chttp2/internal.h" +#include "src/core/lib/transport/chttp2/hpack_parser.h" +#include "src/core/lib/transport/chttp2/internal.h" #include #include @@ -48,9 +48,9 @@ #include #include -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/bin_encoder.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/chttp2/bin_encoder.h" typedef enum { NOT_BINARY, diff --git a/src/core/lib/transport/chttp2/hpack_parser.h b/src/core/lib/transport/chttp2/hpack_parser.h index 2a47cdf93c..a534fd5cf4 100644 --- a/src/core/lib/transport/chttp2/hpack_parser.h +++ b/src/core/lib/transport/chttp2/hpack_parser.h @@ -37,10 +37,10 @@ #include #include -#include "src/core/iomgr/exec_ctx.h" -#include "src/core/transport/chttp2/frame.h" -#include "src/core/transport/chttp2/hpack_table.h" -#include "src/core/transport/metadata.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/chttp2/frame.h" +#include "src/core/lib/transport/chttp2/hpack_table.h" +#include "src/core/lib/transport/metadata.h" typedef struct grpc_chttp2_hpack_parser grpc_chttp2_hpack_parser; diff --git a/src/core/lib/transport/chttp2/hpack_table.c b/src/core/lib/transport/chttp2/hpack_table.c index bf836e0139..f92bc26585 100644 --- a/src/core/lib/transport/chttp2/hpack_table.c +++ b/src/core/lib/transport/chttp2/hpack_table.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/hpack_table.h" +#include "src/core/lib/transport/chttp2/hpack_table.h" #include #include @@ -39,7 +39,7 @@ #include #include -#include "src/core/support/murmur_hash.h" +#include "src/core/lib/support/murmur_hash.h" static struct { const char *key; diff --git a/src/core/lib/transport/chttp2/hpack_table.h b/src/core/lib/transport/chttp2/hpack_table.h index eddb99ee1c..2cbc02dd9c 100644 --- a/src/core/lib/transport/chttp2/hpack_table.h +++ b/src/core/lib/transport/chttp2/hpack_table.h @@ -36,7 +36,7 @@ #include #include -#include "src/core/transport/metadata.h" +#include "src/core/lib/transport/metadata.h" /* HPACK header table */ diff --git a/src/core/lib/transport/chttp2/huffsyms.c b/src/core/lib/transport/chttp2/huffsyms.c index ebc85d3378..27497e6ae0 100644 --- a/src/core/lib/transport/chttp2/huffsyms.c +++ b/src/core/lib/transport/chttp2/huffsyms.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/huffsyms.h" +#include "src/core/lib/transport/chttp2/huffsyms.h" /* Constants pulled from the HPACK spec, and converted to C using the vim command: diff --git a/src/core/lib/transport/chttp2/incoming_metadata.c b/src/core/lib/transport/chttp2/incoming_metadata.c index 245d6ac15a..a1a8d37562 100644 --- a/src/core/lib/transport/chttp2/incoming_metadata.c +++ b/src/core/lib/transport/chttp2/incoming_metadata.c @@ -31,11 +31,11 @@ * */ -#include "src/core/transport/chttp2/incoming_metadata.h" +#include "src/core/lib/transport/chttp2/incoming_metadata.h" #include -#include "src/core/transport/chttp2/internal.h" +#include "src/core/lib/transport/chttp2/internal.h" #include #include diff --git a/src/core/lib/transport/chttp2/incoming_metadata.h b/src/core/lib/transport/chttp2/incoming_metadata.h index 87f360e1f2..edfa0adf9d 100644 --- a/src/core/lib/transport/chttp2/incoming_metadata.h +++ b/src/core/lib/transport/chttp2/incoming_metadata.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_INCOMING_METADATA_H #define GRPC_CORE_LIB_TRANSPORT_CHTTP2_INCOMING_METADATA_H -#include "src/core/transport/transport.h" +#include "src/core/lib/transport/transport.h" typedef struct { grpc_linked_mdelem *elems; diff --git a/src/core/lib/transport/chttp2/internal.h b/src/core/lib/transport/chttp2/internal.h index 2e7b334426..346e404204 100644 --- a/src/core/lib/transport/chttp2/internal.h +++ b/src/core/lib/transport/chttp2/internal.h @@ -37,20 +37,20 @@ #include #include -#include "src/core/iomgr/endpoint.h" -#include "src/core/transport/chttp2/frame.h" -#include "src/core/transport/chttp2/frame_data.h" -#include "src/core/transport/chttp2/frame_goaway.h" -#include "src/core/transport/chttp2/frame_ping.h" -#include "src/core/transport/chttp2/frame_rst_stream.h" -#include "src/core/transport/chttp2/frame_settings.h" -#include "src/core/transport/chttp2/frame_window_update.h" -#include "src/core/transport/chttp2/hpack_encoder.h" -#include "src/core/transport/chttp2/hpack_parser.h" -#include "src/core/transport/chttp2/incoming_metadata.h" -#include "src/core/transport/chttp2/stream_map.h" -#include "src/core/transport/connectivity_state.h" -#include "src/core/transport/transport_impl.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/transport/chttp2/frame.h" +#include "src/core/lib/transport/chttp2/frame_data.h" +#include "src/core/lib/transport/chttp2/frame_goaway.h" +#include "src/core/lib/transport/chttp2/frame_ping.h" +#include "src/core/lib/transport/chttp2/frame_rst_stream.h" +#include "src/core/lib/transport/chttp2/frame_settings.h" +#include "src/core/lib/transport/chttp2/frame_window_update.h" +#include "src/core/lib/transport/chttp2/hpack_encoder.h" +#include "src/core/lib/transport/chttp2/hpack_parser.h" +#include "src/core/lib/transport/chttp2/incoming_metadata.h" +#include "src/core/lib/transport/chttp2/stream_map.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/transport_impl.h" typedef struct grpc_chttp2_transport grpc_chttp2_transport; typedef struct grpc_chttp2_stream grpc_chttp2_stream; diff --git a/src/core/lib/transport/chttp2/parsing.c b/src/core/lib/transport/chttp2/parsing.c index 0516f39fa9..9ee52f63f2 100644 --- a/src/core/lib/transport/chttp2/parsing.c +++ b/src/core/lib/transport/chttp2/parsing.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/internal.h" +#include "src/core/lib/transport/chttp2/internal.h" #include @@ -39,11 +39,11 @@ #include #include -#include "src/core/profiling/timers.h" -#include "src/core/transport/chttp2/http2_errors.h" -#include "src/core/transport/chttp2/status_conversion.h" -#include "src/core/transport/chttp2/timeout_encoding.h" -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/transport/chttp2/http2_errors.h" +#include "src/core/lib/transport/chttp2/status_conversion.h" +#include "src/core/lib/transport/chttp2/timeout_encoding.h" +#include "src/core/lib/transport/static_metadata.h" static int init_frame_parser(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing); diff --git a/src/core/lib/transport/chttp2/status_conversion.c b/src/core/lib/transport/chttp2/status_conversion.c index cb566230fc..73dd63e720 100644 --- a/src/core/lib/transport/chttp2/status_conversion.c +++ b/src/core/lib/transport/chttp2/status_conversion.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/status_conversion.h" +#include "src/core/lib/transport/chttp2/status_conversion.h" int grpc_chttp2_grpc_status_to_http2_error(grpc_status_code status) { switch (status) { diff --git a/src/core/lib/transport/chttp2/status_conversion.h b/src/core/lib/transport/chttp2/status_conversion.h index 12720c05f9..241417d32e 100644 --- a/src/core/lib/transport/chttp2/status_conversion.h +++ b/src/core/lib/transport/chttp2/status_conversion.h @@ -35,7 +35,7 @@ #define GRPC_CORE_LIB_TRANSPORT_CHTTP2_STATUS_CONVERSION_H #include -#include "src/core/transport/chttp2/http2_errors.h" +#include "src/core/lib/transport/chttp2/http2_errors.h" /* Conversion of grpc status codes to http2 error codes (for RST_STREAM) */ grpc_chttp2_error_code grpc_chttp2_grpc_status_to_http2_error( diff --git a/src/core/lib/transport/chttp2/stream_lists.c b/src/core/lib/transport/chttp2/stream_lists.c index 60fe735cfc..b51a041dc7 100644 --- a/src/core/lib/transport/chttp2/stream_lists.c +++ b/src/core/lib/transport/chttp2/stream_lists.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/internal.h" +#include "src/core/lib/transport/chttp2/internal.h" #include diff --git a/src/core/lib/transport/chttp2/stream_map.c b/src/core/lib/transport/chttp2/stream_map.c index 6c70229e42..dbbbe783bf 100644 --- a/src/core/lib/transport/chttp2/stream_map.c +++ b/src/core/lib/transport/chttp2/stream_map.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/stream_map.h" +#include "src/core/lib/transport/chttp2/stream_map.h" #include diff --git a/src/core/lib/transport/chttp2/timeout_encoding.c b/src/core/lib/transport/chttp2/timeout_encoding.c index c4802e050e..0edacaafd3 100644 --- a/src/core/lib/transport/chttp2/timeout_encoding.c +++ b/src/core/lib/transport/chttp2/timeout_encoding.c @@ -31,13 +31,13 @@ * */ -#include "src/core/transport/chttp2/timeout_encoding.h" +#include "src/core/lib/transport/chttp2/timeout_encoding.h" #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" static int64_t round_up(int64_t x, int64_t divisor) { return (x / divisor + (x % divisor != 0)) * divisor; diff --git a/src/core/lib/transport/chttp2/timeout_encoding.h b/src/core/lib/transport/chttp2/timeout_encoding.h index 9bb3c36d72..731beb5a37 100644 --- a/src/core/lib/transport/chttp2/timeout_encoding.h +++ b/src/core/lib/transport/chttp2/timeout_encoding.h @@ -35,7 +35,7 @@ #define GRPC_CORE_LIB_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #define GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1) diff --git a/src/core/lib/transport/chttp2/varint.c b/src/core/lib/transport/chttp2/varint.c index 1b0cf15eba..6dfef45362 100644 --- a/src/core/lib/transport/chttp2/varint.c +++ b/src/core/lib/transport/chttp2/varint.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/varint.h" +#include "src/core/lib/transport/chttp2/varint.h" uint32_t grpc_chttp2_hpack_varint_length(uint32_t tail_value) { if (tail_value < (1 << 7)) { diff --git a/src/core/lib/transport/chttp2/writing.c b/src/core/lib/transport/chttp2/writing.c index 107725cbc7..daea331d31 100644 --- a/src/core/lib/transport/chttp2/writing.c +++ b/src/core/lib/transport/chttp2/writing.c @@ -31,14 +31,14 @@ * */ -#include "src/core/transport/chttp2/internal.h" +#include "src/core/lib/transport/chttp2/internal.h" #include #include -#include "src/core/profiling/timers.h" -#include "src/core/transport/chttp2/http2_errors.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/transport/chttp2/http2_errors.h" static void finalize_outbuf(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing); diff --git a/src/core/lib/transport/chttp2_transport.c b/src/core/lib/transport/chttp2_transport.c index b45bf31997..7fed3d8b47 100644 --- a/src/core/lib/transport/chttp2_transport.c +++ b/src/core/lib/transport/chttp2_transport.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/transport/chttp2_transport.h" #include #include @@ -43,14 +43,14 @@ #include #include -#include "src/core/profiling/timers.h" -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/http2_errors.h" -#include "src/core/transport/chttp2/internal.h" -#include "src/core/transport/chttp2/status_conversion.h" -#include "src/core/transport/chttp2/timeout_encoding.h" -#include "src/core/transport/static_metadata.h" -#include "src/core/transport/transport_impl.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/chttp2/http2_errors.h" +#include "src/core/lib/transport/chttp2/internal.h" +#include "src/core/lib/transport/chttp2/status_conversion.h" +#include "src/core/lib/transport/chttp2/timeout_encoding.h" +#include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/transport_impl.h" #define DEFAULT_WINDOW 65535 #define DEFAULT_CONNECTION_WINDOW_TARGET (1024 * 1024) diff --git a/src/core/lib/transport/chttp2_transport.h b/src/core/lib/transport/chttp2_transport.h index b188219982..5008cab7f8 100644 --- a/src/core/lib/transport/chttp2_transport.h +++ b/src/core/lib/transport/chttp2_transport.h @@ -34,8 +34,8 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_CHTTP2_TRANSPORT_H #define GRPC_CORE_LIB_TRANSPORT_CHTTP2_TRANSPORT_H -#include "src/core/iomgr/endpoint.h" -#include "src/core/transport/transport.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/transport/transport.h" extern int grpc_http_trace; extern int grpc_flowctl_trace; diff --git a/src/core/lib/transport/connectivity_state.c b/src/core/lib/transport/connectivity_state.c index 87765b9799..123eab8b36 100644 --- a/src/core/lib/transport/connectivity_state.c +++ b/src/core/lib/transport/connectivity_state.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/connectivity_state.h" +#include "src/core/lib/transport/connectivity_state.h" #include diff --git a/src/core/lib/transport/connectivity_state.h b/src/core/lib/transport/connectivity_state.h index dc6623c46c..6f92132438 100644 --- a/src/core/lib/transport/connectivity_state.h +++ b/src/core/lib/transport/connectivity_state.h @@ -35,7 +35,7 @@ #define GRPC_CORE_LIB_TRANSPORT_CONNECTIVITY_STATE_H #include -#include "src/core/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/exec_ctx.h" typedef struct grpc_connectivity_state_watcher { /** we keep watchers in a linked list */ diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c index 7ed28feca8..7605f09991 100644 --- a/src/core/lib/transport/metadata.c +++ b/src/core/lib/transport/metadata.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/metadata.h" +#include "src/core/lib/transport/metadata.h" #include #include @@ -44,12 +44,12 @@ #include #include -#include "src/core/iomgr/iomgr_internal.h" -#include "src/core/profiling/timers.h" -#include "src/core/support/murmur_hash.h" -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/bin_encoder.h" -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/support/murmur_hash.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/chttp2/bin_encoder.h" +#include "src/core/lib/transport/static_metadata.h" /* There are two kinds of mdelem and mdstr instances. * Static instances are declared in static_metadata.{h,c} and diff --git a/src/core/lib/transport/metadata_batch.c b/src/core/lib/transport/metadata_batch.c index 2e27b461c9..bb79b8fa96 100644 --- a/src/core/lib/transport/metadata_batch.c +++ b/src/core/lib/transport/metadata_batch.c @@ -31,14 +31,14 @@ * */ -#include "src/core/transport/metadata_batch.h" +#include "src/core/lib/transport/metadata_batch.h" #include #include #include -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" static void assert_valid_list(grpc_mdelem_list *list) { #ifndef NDEBUG diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index 4c9395e6c0..f1d4726989 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -38,7 +38,7 @@ #include #include #include -#include "src/core/transport/metadata.h" +#include "src/core/lib/transport/metadata.h" typedef struct grpc_linked_mdelem { grpc_mdelem *md; diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c index 30bbb89880..eda277b3dc 100644 --- a/src/core/lib/transport/static_metadata.c +++ b/src/core/lib/transport/static_metadata.c @@ -43,7 +43,7 @@ * explanation of what's going on. */ -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/transport/static_metadata.h" grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index bfcb010387..aff136a6d2 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -46,7 +46,7 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H #define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H -#include "src/core/transport/metadata.h" +#include "src/core/lib/transport/metadata.h" #define GRPC_STATIC_MDSTR_COUNT 89 extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c index 3b555fa933..18256aae5e 100644 --- a/src/core/lib/transport/transport.c +++ b/src/core/lib/transport/transport.c @@ -31,11 +31,11 @@ * */ -#include "src/core/transport/transport.h" +#include "src/core/lib/transport/transport.h" #include #include #include -#include "src/core/transport/transport_impl.h" +#include "src/core/lib/transport/transport_impl.h" #ifdef GRPC_STREAM_REFCOUNT_DEBUG void grpc_stream_ref(grpc_stream_refcount *refcount, const char *reason) { diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 4174f049d5..e98cfe9515 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -36,11 +36,11 @@ #include -#include "src/core/channel/context.h" -#include "src/core/iomgr/pollset.h" -#include "src/core/iomgr/pollset_set.h" -#include "src/core/transport/byte_stream.h" -#include "src/core/transport/metadata_batch.h" +#include "src/core/lib/channel/context.h" +#include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/transport/byte_stream.h" +#include "src/core/lib/transport/metadata_batch.h" /* forward declarations */ typedef struct grpc_transport grpc_transport; diff --git a/src/core/lib/transport/transport_impl.h b/src/core/lib/transport/transport_impl.h index 60fd27a8dc..92fa5d519d 100644 --- a/src/core/lib/transport/transport_impl.h +++ b/src/core/lib/transport/transport_impl.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_TRANSPORT_IMPL_H #define GRPC_CORE_LIB_TRANSPORT_TRANSPORT_IMPL_H -#include "src/core/transport/transport.h" +#include "src/core/lib/transport/transport.h" typedef struct grpc_transport_vtable { /* Memory required for a single stream element - this is allocated by upper diff --git a/src/core/lib/transport/transport_op_string.c b/src/core/lib/transport/transport_op_string.c index 8453412480..1fa8fa5d4f 100644 --- a/src/core/lib/transport/transport_op_string.c +++ b/src/core/lib/transport/transport_op_string.c @@ -31,7 +31,7 @@ * */ -#include "src/core/channel/channel_stack.h" +#include "src/core/lib/channel/channel_stack.h" #include #include @@ -40,7 +40,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" /* These routines are here to facilitate debugging - they produce string representations of various transport data structures */ diff --git a/src/core/lib/tsi/fake_transport_security.c b/src/core/lib/tsi/fake_transport_security.c index c0106f7a33..4b812f4803 100644 --- a/src/core/lib/tsi/fake_transport_security.c +++ b/src/core/lib/tsi/fake_transport_security.c @@ -31,7 +31,7 @@ * */ -#include "src/core/tsi/fake_transport_security.h" +#include "src/core/lib/tsi/fake_transport_security.h" #include #include @@ -39,7 +39,7 @@ #include #include #include -#include "src/core/tsi/transport_security.h" +#include "src/core/lib/tsi/transport_security.h" /* --- Constants. ---*/ #define TSI_FAKE_FRAME_HEADER_SIZE 4 diff --git a/src/core/lib/tsi/fake_transport_security.h b/src/core/lib/tsi/fake_transport_security.h index 718c1a50db..b887dfcb09 100644 --- a/src/core/lib/tsi/fake_transport_security.h +++ b/src/core/lib/tsi/fake_transport_security.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_TSI_FAKE_TRANSPORT_SECURITY_H #define GRPC_CORE_LIB_TSI_FAKE_TRANSPORT_SECURITY_H -#include "src/core/tsi/transport_security_interface.h" +#include "src/core/lib/tsi/transport_security_interface.h" #ifdef __cplusplus extern "C" { diff --git a/src/core/lib/tsi/ssl_transport_security.c b/src/core/lib/tsi/ssl_transport_security.c index 8df582609b..d03201eec6 100644 --- a/src/core/lib/tsi/ssl_transport_security.c +++ b/src/core/lib/tsi/ssl_transport_security.c @@ -31,7 +31,7 @@ * */ -#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/lib/tsi/ssl_transport_security.h" #include @@ -57,8 +57,8 @@ #include #include -#include "src/core/tsi/ssl_types.h" -#include "src/core/tsi/transport_security.h" +#include "src/core/lib/tsi/ssl_types.h" +#include "src/core/lib/tsi/transport_security.h" /* --- Constants. ---*/ diff --git a/src/core/lib/tsi/ssl_transport_security.h b/src/core/lib/tsi/ssl_transport_security.h index 441b010e4e..c9b9e8f54b 100644 --- a/src/core/lib/tsi/ssl_transport_security.h +++ b/src/core/lib/tsi/ssl_transport_security.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_TSI_SSL_TRANSPORT_SECURITY_H #define GRPC_CORE_LIB_TSI_SSL_TRANSPORT_SECURITY_H -#include "src/core/tsi/transport_security_interface.h" +#include "src/core/lib/tsi/transport_security_interface.h" #ifdef __cplusplus extern "C" { diff --git a/src/core/lib/tsi/transport_security.c b/src/core/lib/tsi/transport_security.c index 64aac2c05a..a2c0d46196 100644 --- a/src/core/lib/tsi/transport_security.c +++ b/src/core/lib/tsi/transport_security.c @@ -31,7 +31,7 @@ * */ -#include "src/core/tsi/transport_security.h" +#include "src/core/lib/tsi/transport_security.h" #include #include diff --git a/src/core/lib/tsi/transport_security.h b/src/core/lib/tsi/transport_security.h index 292af7ffb9..349dd0ae9c 100644 --- a/src/core/lib/tsi/transport_security.h +++ b/src/core/lib/tsi/transport_security.h @@ -34,7 +34,7 @@ #ifndef GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H #define GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H -#include "src/core/tsi/transport_security_interface.h" +#include "src/core/lib/tsi/transport_security_interface.h" #ifdef __cplusplus extern "C" { diff --git a/src/cpp/client/channel.cc b/src/cpp/client/channel.cc index ae20392d11..f174676172 100644 --- a/src/cpp/client/channel.cc +++ b/src/cpp/client/channel.cc @@ -49,7 +49,7 @@ #include #include #include -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" namespace grpc { diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc index db636a5456..de8b2db6e3 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -41,7 +41,7 @@ #include #include -#include "src/core/channel/compress_filter.h" +#include "src/core/lib/channel/compress_filter.h" #include "src/cpp/common/create_auth_context.h" namespace grpc { diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index d7faa5e173..3bdb4398ab 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -36,7 +36,7 @@ #include #include -#include "src/core/channel/channel_args.h" +#include "src/core/lib/channel/channel_args.h" namespace grpc { diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc index 45e9e278a0..33a8f755e6 100644 --- a/src/cpp/common/core_codegen.cc +++ b/src/cpp/common/core_codegen.cc @@ -46,7 +46,7 @@ #include #include -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" namespace { diff --git a/src/cpp/common/secure_channel_arguments.cc b/src/cpp/common/secure_channel_arguments.cc index e17d3b58b0..81ec251b92 100644 --- a/src/cpp/common/secure_channel_arguments.cc +++ b/src/cpp/common/secure_channel_arguments.cc @@ -34,7 +34,7 @@ #include #include -#include "src/core/channel/channel_args.h" +#include "src/core/lib/channel/channel_args.h" namespace grpc { diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 6d31a608c8..7e5f557ffa 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -49,7 +49,7 @@ #include #include -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" #include "src/cpp/server/thread_pool_interface.h" namespace grpc { diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index 5d12ce2ecf..0422650953 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -42,8 +42,8 @@ #include #include -#include "src/core/channel/compress_filter.h" -#include "src/core/surface/call.h" +#include "src/core/lib/channel/compress_filter.h" +#include "src/core/lib/surface/call.h" #include "src/cpp/common/create_auth_context.h" namespace grpc { diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 1df74a0993..642dc9ef42 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -31,7 +31,7 @@ * */ -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include #include diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c index c7130f9580..2e9623e5ec 100644 --- a/test/core/bad_client/bad_client.c +++ b/test/core/bad_client/bad_client.c @@ -33,13 +33,13 @@ #include "test/core/bad_client/bad_client.h" -#include "src/core/channel/channel_stack.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/iomgr/endpoint_pair.h" -#include "src/core/support/string.h" -#include "src/core/surface/completion_queue.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/iomgr/endpoint_pair.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/completion_queue.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include #include diff --git a/test/core/bad_client/tests/badreq.c b/test/core/bad_client/tests/badreq.c index 95d46d5731..fd3d13f908 100644 --- a/test/core/bad_client/tests/badreq.c +++ b/test/core/bad_client/tests/badreq.c @@ -35,7 +35,7 @@ #include -#include "src/core/surface/server.h" +#include "src/core/lib/surface/server.h" #include "test/core/end2end/cq_verifier.h" #define PFX_STR \ diff --git a/test/core/bad_client/tests/connection_prefix.c b/test/core/bad_client/tests/connection_prefix.c index 000ecca6c6..87826afa2c 100644 --- a/test/core/bad_client/tests/connection_prefix.c +++ b/test/core/bad_client/tests/connection_prefix.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/server.h" +#include "src/core/lib/surface/server.h" #include "test/core/bad_client/bad_client.h" static void verifier(grpc_server *server, grpc_completion_queue *cq, diff --git a/test/core/bad_client/tests/headers.c b/test/core/bad_client/tests/headers.c index 4ecdb64139..f66f14d8aa 100644 --- a/test/core/bad_client/tests/headers.c +++ b/test/core/bad_client/tests/headers.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/server.h" +#include "src/core/lib/surface/server.h" #include "test/core/bad_client/bad_client.h" #define PFX_STR \ diff --git a/test/core/bad_client/tests/initial_settings_frame.c b/test/core/bad_client/tests/initial_settings_frame.c index 2104892766..b303f033f1 100644 --- a/test/core/bad_client/tests/initial_settings_frame.c +++ b/test/core/bad_client/tests/initial_settings_frame.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/server.h" +#include "src/core/lib/surface/server.h" #include "test/core/bad_client/bad_client.h" #define PFX_STR "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" diff --git a/test/core/bad_client/tests/server_registered_method.c b/test/core/bad_client/tests/server_registered_method.c index d280804687..c35457c3f8 100644 --- a/test/core/bad_client/tests/server_registered_method.c +++ b/test/core/bad_client/tests/server_registered_method.c @@ -35,7 +35,7 @@ #include -#include "src/core/surface/server.h" +#include "src/core/lib/surface/server.h" #include "test/core/end2end/cq_verifier.h" #define PFX_STR \ diff --git a/test/core/bad_client/tests/simple_request.c b/test/core/bad_client/tests/simple_request.c index e535be1527..6cb44ee273 100644 --- a/test/core/bad_client/tests/simple_request.c +++ b/test/core/bad_client/tests/simple_request.c @@ -35,7 +35,7 @@ #include -#include "src/core/surface/server.h" +#include "src/core/lib/surface/server.h" #include "test/core/end2end/cq_verifier.h" #define PFX_STR \ diff --git a/test/core/bad_client/tests/unknown_frame.c b/test/core/bad_client/tests/unknown_frame.c index 729a6d9a75..44d1e35299 100644 --- a/test/core/bad_client/tests/unknown_frame.c +++ b/test/core/bad_client/tests/unknown_frame.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/server.h" +#include "src/core/lib/surface/server.h" #include "test/core/bad_client/bad_client.h" #define PFX_STR \ diff --git a/test/core/bad_client/tests/window_overflow.c b/test/core/bad_client/tests/window_overflow.c index a9117de36a..b6d0101c80 100644 --- a/test/core/bad_client/tests/window_overflow.c +++ b/test/core/bad_client/tests/window_overflow.c @@ -37,7 +37,7 @@ #include -#include "src/core/surface/server.h" +#include "src/core/lib/surface/server.h" #define PFX_STR \ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \ diff --git a/test/core/bad_ssl/bad_ssl_test.c b/test/core/bad_ssl/bad_ssl_test.c index e2babfa114..013b8eaf13 100644 --- a/test/core/bad_ssl/bad_ssl_test.c +++ b/test/core/bad_ssl/bad_ssl_test.c @@ -41,8 +41,8 @@ #include #include #include -#include "src/core/support/env.h" -#include "src/core/support/string.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/bad_ssl/servers/alpn.c b/test/core/bad_ssl/servers/alpn.c index c8cc83b134..98dcd1c0ca 100644 --- a/test/core/bad_ssl/servers/alpn.c +++ b/test/core/bad_ssl/servers/alpn.c @@ -38,7 +38,7 @@ #include #include -#include "src/core/transport/chttp2/alpn.h" +#include "src/core/lib/transport/chttp2/alpn.h" #include "test/core/bad_ssl/server_common.h" #include "test/core/end2end/data/ssl_test_data.h" diff --git a/test/core/bad_ssl/servers/cert.c b/test/core/bad_ssl/servers/cert.c index 4edef50b67..9661347470 100644 --- a/test/core/bad_ssl/servers/cert.c +++ b/test/core/bad_ssl/servers/cert.c @@ -38,7 +38,7 @@ #include #include -#include "src/core/support/load_file.h" +#include "src/core/lib/support/load_file.h" #include "test/core/bad_ssl/server_common.h" #include "test/core/end2end/data/ssl_test_data.h" diff --git a/test/core/census/mlog_test.c b/test/core/census/mlog_test.c index 000ac7335a..a1fadc2290 100644 --- a/test/core/census/mlog_test.c +++ b/test/core/census/mlog_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/census/mlog.h" +#include "src/core/lib/census/mlog.h" #include #include #include diff --git a/test/core/channel/channel_args_test.c b/test/core/channel/channel_args_test.c index 0b74dee41e..c7fc25960c 100644 --- a/test/core/channel/channel_args_test.c +++ b/test/core/channel/channel_args_test.c @@ -36,7 +36,7 @@ #include #include -#include "src/core/channel/channel_args.h" +#include "src/core/lib/channel/channel_args.h" #include "test/core/util/test_config.h" diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index c4c288d736..49e9c7e969 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/channel/channel_stack.h" +#include "src/core/lib/channel/channel_stack.h" #include diff --git a/test/core/client_config/lb_policies_test.c b/test/core/client_config/lb_policies_test.c index 91fa63ea97..bae3e7d18c 100644 --- a/test/core/client_config/lb_policies_test.c +++ b/test/core/client_config/lb_policies_test.c @@ -41,13 +41,13 @@ #include #include -#include "src/core/channel/channel_stack.h" -#include "src/core/channel/client_channel.h" -#include "src/core/client_config/lb_policies/round_robin.h" -#include "src/core/client_config/lb_policy_registry.h" -#include "src/core/support/string.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/client_config/lb_policies/round_robin.h" +#include "src/core/lib/client_config/lb_policy_registry.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/client_config/resolvers/dns_resolver_connectivity_test.c b/test/core/client_config/resolvers/dns_resolver_connectivity_test.c index 75d1eb674f..dc6a614d55 100644 --- a/test/core/client_config/resolvers/dns_resolver_connectivity_test.c +++ b/test/core/client_config/resolvers/dns_resolver_connectivity_test.c @@ -31,15 +31,15 @@ * */ -#include "src/core/client_config/resolvers/dns_resolver.h" +#include "src/core/lib/client_config/resolvers/dns_resolver.h" #include #include #include -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/timer.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/timer.h" #include "test/core/util/test_config.h" static void subchannel_factory_ref(grpc_subchannel_factory *scv) {} diff --git a/test/core/client_config/resolvers/dns_resolver_test.c b/test/core/client_config/resolvers/dns_resolver_test.c index 38e76d5342..043b882184 100644 --- a/test/core/client_config/resolvers/dns_resolver_test.c +++ b/test/core/client_config/resolvers/dns_resolver_test.c @@ -31,13 +31,13 @@ * */ -#include "src/core/client_config/resolvers/dns_resolver.h" +#include "src/core/lib/client_config/resolvers/dns_resolver.h" #include #include -#include "src/core/client_config/resolver.h" +#include "src/core/lib/client_config/resolver.h" #include "test/core/util/test_config.h" static void subchannel_factory_ref(grpc_subchannel_factory *scv) {} diff --git a/test/core/client_config/resolvers/sockaddr_resolver_test.c b/test/core/client_config/resolvers/sockaddr_resolver_test.c index 8856c85449..e23616ca23 100644 --- a/test/core/client_config/resolvers/sockaddr_resolver_test.c +++ b/test/core/client_config/resolvers/sockaddr_resolver_test.c @@ -31,13 +31,13 @@ * */ -#include "src/core/client_config/resolvers/sockaddr_resolver.h" +#include "src/core/lib/client_config/resolvers/sockaddr_resolver.h" #include #include -#include "src/core/client_config/resolver.h" +#include "src/core/lib/client_config/resolver.h" #include "test/core/util/test_config.h" static void subchannel_factory_ref(grpc_subchannel_factory *scv) {} diff --git a/test/core/client_config/set_initial_connect_string_test.c b/test/core/client_config/set_initial_connect_string_test.c index 3cf267fb3b..7fd92a079e 100644 --- a/test/core/client_config/set_initial_connect_string_test.c +++ b/test/core/client_config/set_initial_connect_string_test.c @@ -38,10 +38,10 @@ #include #include -#include "src/core/client_config/initial_connect_string.h" -#include "src/core/iomgr/sockaddr.h" -#include "src/core/security/credentials.h" -#include "src/core/support/string.h" +#include "src/core/lib/client_config/initial_connect_string.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/support/string.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" #include "test/core/util/test_tcp_server.h" diff --git a/test/core/client_config/uri_parser_test.c b/test/core/client_config/uri_parser_test.c index df12d6b4cb..e5d0c378ba 100644 --- a/test/core/client_config/uri_parser_test.c +++ b/test/core/client_config/uri_parser_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/client_config/uri_parser.h" +#include "src/core/lib/client_config/uri_parser.h" #include diff --git a/test/core/compression/algorithm_test.c b/test/core/compression/algorithm_test.c index 7de7e11a94..bdee748ae6 100644 --- a/test/core/compression/algorithm_test.c +++ b/test/core/compression/algorithm_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/compression/algorithm_metadata.h" +#include "src/core/lib/compression/algorithm_metadata.h" #include #include @@ -40,7 +40,7 @@ #include #include -#include "src/core/transport/static_metadata.h" +#include "src/core/lib/transport/static_metadata.h" #include "test/core/util/test_config.h" static void test_algorithm_mesh(void) { diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c index 6d3d16128a..1a93903346 100644 --- a/test/core/compression/message_compress_test.c +++ b/test/core/compression/message_compress_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/compression/message_compress.h" +#include "src/core/lib/compression/message_compress.h" #include #include @@ -40,7 +40,7 @@ #include #include -#include "src/core/support/murmur_hash.h" +#include "src/core/lib/support/murmur_hash.h" #include "test/core/util/slice_splitter.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c index 3687f7caf4..baf8e8ed18 100644 --- a/test/core/end2end/cq_verifier.c +++ b/test/core/end2end/cq_verifier.c @@ -44,8 +44,8 @@ #include #include #include -#include "src/core/support/string.h" -#include "src/core/surface/event_string.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/event_string.h" #define ROOT_EXPECTATION 1000 diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c index 77589a7eee..7501df98dc 100644 --- a/test/core/end2end/dualstack_socket_test.c +++ b/test/core/end2end/dualstack_socket_test.c @@ -39,9 +39,9 @@ #include #include -#include "src/core/iomgr/resolve_address.h" -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/support/string.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" diff --git a/test/core/end2end/fixtures/h2_census.c b/test/core/end2end/fixtures/h2_census.c index 4d89a8f8c3..8d504e4598 100644 --- a/test/core/end2end/fixtures/h2_census.c +++ b/test/core/end2end/fixtures/h2_census.c @@ -41,13 +41,13 @@ #include #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_compress.c b/test/core/end2end/fixtures/h2_compress.c index 19a2495eaf..a45c27af7a 100644 --- a/test/core/end2end/fixtures/h2_compress.c +++ b/test/core/end2end/fixtures/h2_compress.c @@ -41,13 +41,13 @@ #include #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_fakesec.c b/test/core/end2end/fixtures/h2_fakesec.c index 8be8e35b1a..7386691bdc 100644 --- a/test/core/end2end/fixtures/h2_fakesec.c +++ b/test/core/end2end/fixtures/h2_fakesec.c @@ -39,8 +39,8 @@ #include #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/security/credentials.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/security/credentials.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_full+pipe.c b/test/core/end2end/fixtures/h2_full+pipe.c index f2d72f0445..def5efaa42 100644 --- a/test/core/end2end/fixtures/h2_full+pipe.c +++ b/test/core/end2end/fixtures/h2_full+pipe.c @@ -41,13 +41,13 @@ #include #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/iomgr/wakeup_fd_posix.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_full+poll+pipe.c b/test/core/end2end/fixtures/h2_full+poll+pipe.c index 682598fbe2..0584b81448 100644 --- a/test/core/end2end/fixtures/h2_full+poll+pipe.c +++ b/test/core/end2end/fixtures/h2_full+poll+pipe.c @@ -42,14 +42,14 @@ #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/iomgr/wakeup_fd_posix.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_full+poll.c b/test/core/end2end/fixtures/h2_full+poll.c index 5a0b2ef495..8576e3ee90 100644 --- a/test/core/end2end/fixtures/h2_full+poll.c +++ b/test/core/end2end/fixtures/h2_full+poll.c @@ -42,13 +42,13 @@ #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/iomgr/pollset_posix.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_full+trace.c b/test/core/end2end/fixtures/h2_full+trace.c index c84bd72530..0d531565f2 100644 --- a/test/core/end2end/fixtures/h2_full+trace.c +++ b/test/core/end2end/fixtures/h2_full+trace.c @@ -41,13 +41,13 @@ #include #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/support/env.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_full.c b/test/core/end2end/fixtures/h2_full.c index c56d2fc073..4eae620935 100644 --- a/test/core/end2end/fixtures/h2_full.c +++ b/test/core/end2end/fixtures/h2_full.c @@ -41,12 +41,12 @@ #include #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_oauth2.c b/test/core/end2end/fixtures/h2_oauth2.c index 279061b99e..ee188cc174 100644 --- a/test/core/end2end/fixtures/h2_oauth2.c +++ b/test/core/end2end/fixtures/h2_oauth2.c @@ -39,9 +39,9 @@ #include #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/security/credentials.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/security/credentials.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_proxy.c b/test/core/end2end/fixtures/h2_proxy.c index 1e9aa624e3..39ecd89293 100644 --- a/test/core/end2end/fixtures/h2_proxy.c +++ b/test/core/end2end/fixtures/h2_proxy.c @@ -41,12 +41,12 @@ #include #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/end2end/fixtures/proxy.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.c b/test/core/end2end/fixtures/h2_sockpair+trace.c index 33068721fa..374390fb29 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.c +++ b/test/core/end2end/fixtures/h2_sockpair+trace.c @@ -40,17 +40,17 @@ #include #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/compress_filter.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_client_filter.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/iomgr/endpoint_pair.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/support/env.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/compress_filter.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_client_filter.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/iomgr/endpoint_pair.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_sockpair.c b/test/core/end2end/fixtures/h2_sockpair.c index d64c85aea8..c11a528116 100644 --- a/test/core/end2end/fixtures/h2_sockpair.c +++ b/test/core/end2end/fixtures/h2_sockpair.c @@ -40,16 +40,16 @@ #include #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/compress_filter.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_client_filter.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/iomgr/endpoint_pair.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/compress_filter.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_client_filter.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/iomgr/endpoint_pair.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c index 67180a5edb..6a504c6a9c 100644 --- a/test/core/end2end/fixtures/h2_sockpair_1byte.c +++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c @@ -40,16 +40,16 @@ #include #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/compress_filter.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_client_filter.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/iomgr/endpoint_pair.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/compress_filter.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_client_filter.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/iomgr/endpoint_pair.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_ssl+poll.c b/test/core/end2end/fixtures/h2_ssl+poll.c index 4c3bc64197..e93b4361ac 100644 --- a/test/core/end2end/fixtures/h2_ssl+poll.c +++ b/test/core/end2end/fixtures/h2_ssl+poll.c @@ -40,12 +40,12 @@ #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/security/credentials.h" -#include "src/core/support/env.h" -#include "src/core/support/string.h" -#include "src/core/support/tmpfile.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/iomgr/pollset_posix.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/support/tmpfile.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_ssl.c b/test/core/end2end/fixtures/h2_ssl.c index 6a4e8dcb37..fecd03f6a7 100644 --- a/test/core/end2end/fixtures/h2_ssl.c +++ b/test/core/end2end/fixtures/h2_ssl.c @@ -40,11 +40,11 @@ #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/security/credentials.h" -#include "src/core/support/env.h" -#include "src/core/support/string.h" -#include "src/core/support/tmpfile.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/support/tmpfile.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.c b/test/core/end2end/fixtures/h2_ssl_proxy.c index f5fcb91812..bfbc735742 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.c +++ b/test/core/end2end/fixtures/h2_ssl_proxy.c @@ -40,11 +40,11 @@ #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/security/credentials.h" -#include "src/core/support/env.h" -#include "src/core/support/string.h" -#include "src/core/support/tmpfile.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/support/tmpfile.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/end2end/fixtures/proxy.h" #include "test/core/util/port.h" diff --git a/test/core/end2end/fixtures/h2_uds+poll.c b/test/core/end2end/fixtures/h2_uds+poll.c index c3a855ff88..e431ef37ed 100644 --- a/test/core/end2end/fixtures/h2_uds+poll.c +++ b/test/core/end2end/fixtures/h2_uds+poll.c @@ -45,14 +45,14 @@ #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/iomgr/pollset_posix.h" -#include "src/core/support/string.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/iomgr/pollset_posix.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/h2_uds.c b/test/core/end2end/fixtures/h2_uds.c index 3228c055a0..1bdcdef8de 100644 --- a/test/core/end2end/fixtures/h2_uds.c +++ b/test/core/end2end/fixtures/h2_uds.c @@ -44,13 +44,13 @@ #include #include #include -#include "src/core/channel/client_channel.h" -#include "src/core/channel/connected_channel.h" -#include "src/core/channel/http_server_filter.h" -#include "src/core/support/string.h" -#include "src/core/surface/channel.h" -#include "src/core/surface/server.h" -#include "src/core/transport/chttp2_transport.h" +#include "src/core/lib/channel/client_channel.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_server_filter.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/chttp2_transport.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c index fe7a275244..df3f6be431 100644 --- a/test/core/end2end/tests/bad_hostname.c +++ b/test/core/end2end/tests/bad_hostname.c @@ -42,7 +42,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; diff --git a/test/core/end2end/tests/call_creds.c b/test/core/end2end/tests/call_creds.c index 417f7e82bd..f749a60979 100644 --- a/test/core/end2end/tests/call_creds.c +++ b/test/core/end2end/tests/call_creds.c @@ -42,8 +42,8 @@ #include #include #include -#include "src/core/security/credentials.h" -#include "src/core/support/string.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" static const char iam_token[] = "token"; diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c index 135bdf026c..e5a1556019 100644 --- a/test/core/end2end/tests/cancel_with_status.c +++ b/test/core/end2end/tests/cancel_with_status.c @@ -42,7 +42,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c index c9092e3394..9c258858cb 100644 --- a/test/core/end2end/tests/compressed_payload.c +++ b/test/core/end2end/tests/compressed_payload.c @@ -43,9 +43,9 @@ #include #include -#include "src/core/channel/channel_args.h" -#include "src/core/channel/compress_filter.h" -#include "src/core/surface/call_test_only.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/compress_filter.h" +#include "src/core/lib/surface/call_test_only.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; diff --git a/test/core/end2end/tests/default_host.c b/test/core/end2end/tests/default_host.c index 5455428144..576d81e395 100644 --- a/test/core/end2end/tests/default_host.c +++ b/test/core/end2end/tests/default_host.c @@ -42,7 +42,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c index 53b5ca5e6b..7f56313fa0 100644 --- a/test/core/end2end/tests/empty_batch.c +++ b/test/core/end2end/tests/empty_batch.c @@ -42,7 +42,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; diff --git a/test/core/end2end/tests/high_initial_seqno.c b/test/core/end2end/tests/high_initial_seqno.c index 72007821c8..2196fbd343 100644 --- a/test/core/end2end/tests/high_initial_seqno.c +++ b/test/core/end2end/tests/high_initial_seqno.c @@ -44,7 +44,7 @@ #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; diff --git a/test/core/end2end/tests/hpack_size.c b/test/core/end2end/tests/hpack_size.c index 189131870e..2774e50627 100644 --- a/test/core/end2end/tests/hpack_size.c +++ b/test/core/end2end/tests/hpack_size.c @@ -44,7 +44,7 @@ #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" static void *tag(intptr_t t) { return (void *)t; } diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c index 5de82c9795..e5031af59a 100644 --- a/test/core/end2end/tests/negative_deadline.c +++ b/test/core/end2end/tests/negative_deadline.c @@ -42,7 +42,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c index 4051ded1f8..09f452f6e5 100644 --- a/test/core/end2end/tests/registered_call.c +++ b/test/core/end2end/tests/registered_call.c @@ -42,7 +42,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; diff --git a/test/core/end2end/tests/request_with_flags.c b/test/core/end2end/tests/request_with_flags.c index f480009f00..433622e2da 100644 --- a/test/core/end2end/tests/request_with_flags.c +++ b/test/core/end2end/tests/request_with_flags.c @@ -41,7 +41,7 @@ #include #include #include -#include "src/core/transport/byte_stream.h" +#include "src/core/lib/transport/byte_stream.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c index a7d1661f56..d3ac2d5d61 100644 --- a/test/core/end2end/tests/server_finishes_request.c +++ b/test/core/end2end/tests/server_finishes_request.c @@ -42,7 +42,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c index a8ed79330d..bc634ef83a 100644 --- a/test/core/end2end/tests/simple_request.c +++ b/test/core/end2end/tests/simple_request.c @@ -42,7 +42,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; diff --git a/test/core/fling/client.c b/test/core/fling/client.c index b36aef3093..6a4eb1c6e3 100644 --- a/test/core/fling/client.c +++ b/test/core/fling/client.c @@ -41,7 +41,7 @@ #include #include #include -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" #include "test/core/util/grpc_profiler.h" #include "test/core/util/test_config.h" diff --git a/test/core/fling/fling_stream_test.c b/test/core/fling/fling_stream_test.c index ff3d919b05..2807504976 100644 --- a/test/core/fling/fling_stream_test.c +++ b/test/core/fling/fling_stream_test.c @@ -47,7 +47,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/util/port.h" int main(int argc, char **argv) { diff --git a/test/core/fling/fling_test.c b/test/core/fling/fling_test.c index 4e16b7f1b4..46456a2901 100644 --- a/test/core/fling/fling_test.c +++ b/test/core/fling/fling_test.c @@ -38,7 +38,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/util/port.h" int main(int argc, char **argv) { diff --git a/test/core/fling/server.c b/test/core/fling/server.c index 42be20e42d..fd446f1128 100644 --- a/test/core/fling/server.c +++ b/test/core/fling/server.c @@ -49,7 +49,7 @@ #include #include #include -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/grpc_profiler.h" #include "test/core/util/port.h" diff --git a/test/core/http/format_request_test.c b/test/core/http/format_request_test.c index 5e2b709f89..a676420b70 100644 --- a/test/core/http/format_request_test.c +++ b/test/core/http/format_request_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/http/format_request.h" +#include "src/core/lib/http/format_request.h" #include diff --git a/test/core/http/httpcli_test.c b/test/core/http/httpcli_test.c index bdb7a02e9b..1fdbcd0800 100644 --- a/test/core/http/httpcli_test.c +++ b/test/core/http/httpcli_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/http/httpcli.h" +#include "src/core/lib/http/httpcli.h" #include @@ -41,7 +41,7 @@ #include #include #include -#include "src/core/iomgr/iomgr.h" +#include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/http/httpscli_test.c b/test/core/http/httpscli_test.c index 21845b6a8e..71db3e72bf 100644 --- a/test/core/http/httpscli_test.c +++ b/test/core/http/httpscli_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/http/httpcli.h" +#include "src/core/lib/http/httpcli.h" #include @@ -41,7 +41,7 @@ #include #include #include -#include "src/core/iomgr/iomgr.h" +#include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/http/parser_test.c b/test/core/http/parser_test.c index 338a301534..eeb4de7f30 100644 --- a/test/core/http/parser_test.c +++ b/test/core/http/parser_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/http/parser.h" +#include "src/core/lib/http/parser.h" #include #include diff --git a/test/core/iomgr/endpoint_pair_test.c b/test/core/iomgr/endpoint_pair_test.c index c3a91088a5..a91a9a7084 100644 --- a/test/core/iomgr/endpoint_pair_test.c +++ b/test/core/iomgr/endpoint_pair_test.c @@ -31,14 +31,14 @@ * */ -#include "src/core/iomgr/tcp_posix.h" +#include "src/core/lib/iomgr/tcp_posix.h" #include #include #include #include #include -#include "src/core/iomgr/endpoint_pair.h" +#include "src/core/lib/iomgr/endpoint_pair.h" #include "test/core/iomgr/endpoint_tests.h" #include "test/core/util/test_config.h" diff --git a/test/core/iomgr/endpoint_tests.h b/test/core/iomgr/endpoint_tests.h index 8ea47e345c..c7542a03e3 100644 --- a/test/core/iomgr/endpoint_tests.h +++ b/test/core/iomgr/endpoint_tests.h @@ -36,7 +36,7 @@ #include -#include "src/core/iomgr/endpoint.h" +#include "src/core/lib/iomgr/endpoint.h" typedef struct grpc_endpoint_test_config grpc_endpoint_test_config; typedef struct grpc_endpoint_test_fixture grpc_endpoint_test_fixture; diff --git a/test/core/iomgr/fd_conservation_posix_test.c b/test/core/iomgr/fd_conservation_posix_test.c index c38f509b16..aae94e71b2 100644 --- a/test/core/iomgr/fd_conservation_posix_test.c +++ b/test/core/iomgr/fd_conservation_posix_test.c @@ -35,8 +35,8 @@ #include -#include "src/core/iomgr/endpoint_pair.h" -#include "src/core/iomgr/iomgr.h" +#include "src/core/lib/iomgr/endpoint_pair.h" +#include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/test_config.h" int main(int argc, char **argv) { diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c index 99689ebcc3..203e1e3899 100644 --- a/test/core/iomgr/fd_posix_test.c +++ b/test/core/iomgr/fd_posix_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/fd_posix.h" +#include "src/core/lib/iomgr/fd_posix.h" #include #include @@ -50,7 +50,7 @@ #include #include -#include "src/core/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/pollset_posix.h" #include "test/core/util/test_config.h" static gpr_mu *g_mu; diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c index b2a09978e6..7aec91a85e 100644 --- a/test/core/iomgr/resolve_address_test.c +++ b/test/core/iomgr/resolve_address_test.c @@ -31,11 +31,11 @@ * */ -#include "src/core/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/resolve_address.h" #include #include #include -#include "src/core/iomgr/executor.h" +#include "src/core/lib/iomgr/executor.h" #include "test/core/util/test_config.h" static gpr_timespec test_deadline(void) { diff --git a/test/core/iomgr/sockaddr_utils_test.c b/test/core/iomgr/sockaddr_utils_test.c index a7b57c1466..a330314443 100644 --- a/test/core/iomgr/sockaddr_utils_test.c +++ b/test/core/iomgr/sockaddr_utils_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" #include #include diff --git a/test/core/iomgr/socket_utils_test.c b/test/core/iomgr/socket_utils_test.c index 58c3fbc0ae..85c027a978 100644 --- a/test/core/iomgr/socket_utils_test.c +++ b/test/core/iomgr/socket_utils_test.c @@ -32,7 +32,7 @@ */ #include -#include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" #include #include diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c index 746dfd85be..d798bf241d 100644 --- a/test/core/iomgr/tcp_client_posix_test.c +++ b/test/core/iomgr/tcp_client_posix_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/tcp_client.h" +#include "src/core/lib/iomgr/tcp_client.h" #include #include @@ -44,9 +44,9 @@ #include #include -#include "src/core/iomgr/iomgr.h" -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/iomgr/timer.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" +#include "src/core/lib/iomgr/timer.h" #include "test/core/util/test_config.h" static grpc_pollset_set *g_pollset_set; diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c index 4351642ab6..79f18c6d7a 100644 --- a/test/core/iomgr/tcp_posix_test.c +++ b/test/core/iomgr/tcp_posix_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/tcp_posix.h" +#include "src/core/lib/iomgr/tcp_posix.h" #include #include diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c index 7933468355..cde147d30e 100644 --- a/test/core/iomgr/tcp_server_posix_test.c +++ b/test/core/iomgr/tcp_server_posix_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/tcp_server.h" +#include "src/core/lib/iomgr/tcp_server.h" #include #include @@ -45,8 +45,8 @@ #include #include -#include "src/core/iomgr/iomgr.h" -#include "src/core/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/iomgr/time_averaged_stats_test.c b/test/core/iomgr/time_averaged_stats_test.c index cb006d152a..72f8559d66 100644 --- a/test/core/iomgr/time_averaged_stats_test.c +++ b/test/core/iomgr/time_averaged_stats_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/time_averaged_stats.h" +#include "src/core/lib/iomgr/time_averaged_stats.h" #include diff --git a/test/core/iomgr/timer_heap_test.c b/test/core/iomgr/timer_heap_test.c index dd23a99520..d230c831ca 100644 --- a/test/core/iomgr/timer_heap_test.c +++ b/test/core/iomgr/timer_heap_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/timer_heap.h" +#include "src/core/lib/iomgr/timer_heap.h" #include #include diff --git a/test/core/iomgr/timer_list_test.c b/test/core/iomgr/timer_list_test.c index 955bf44bb6..0333a75059 100644 --- a/test/core/iomgr/timer_list_test.c +++ b/test/core/iomgr/timer_list_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/timer.h" +#include "src/core/lib/iomgr/timer.h" #include diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c index 042e936456..0c55ef08b4 100644 --- a/test/core/iomgr/udp_server_test.c +++ b/test/core/iomgr/udp_server_test.c @@ -31,13 +31,13 @@ * */ -#include "src/core/iomgr/udp_server.h" +#include "src/core/lib/iomgr/udp_server.h" #include #include #include #include -#include "src/core/iomgr/iomgr.h" -#include "src/core/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/pollset_posix.h" #include "test/core/util/test_config.h" #include diff --git a/test/core/iomgr/workqueue_test.c b/test/core/iomgr/workqueue_test.c index 8a1faf6303..2d9b5d0d55 100644 --- a/test/core/iomgr/workqueue_test.c +++ b/test/core/iomgr/workqueue_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/iomgr/workqueue.h" +#include "src/core/lib/iomgr/workqueue.h" #include #include diff --git a/test/core/json/json_rewrite.c b/test/core/json/json_rewrite.c index 0c615a9975..c43c6e2589 100644 --- a/test/core/json/json_rewrite.c +++ b/test/core/json/json_rewrite.c @@ -38,8 +38,8 @@ #include #include -#include "src/core/json/json_reader.h" -#include "src/core/json/json_writer.h" +#include "src/core/lib/json/json_reader.h" +#include "src/core/lib/json/json_writer.h" typedef struct json_writer_userdata { FILE *out; } json_writer_userdata; diff --git a/test/core/json/json_rewrite_test.c b/test/core/json/json_rewrite_test.c index 1916d4b86c..33fc98ed74 100644 --- a/test/core/json/json_rewrite_test.c +++ b/test/core/json/json_rewrite_test.c @@ -39,8 +39,8 @@ #include #include "test/core/util/test_config.h" -#include "src/core/json/json_reader.h" -#include "src/core/json/json_writer.h" +#include "src/core/lib/json/json_reader.h" +#include "src/core/lib/json/json_writer.h" typedef struct json_writer_userdata { FILE *cmp; } json_writer_userdata; diff --git a/test/core/json/json_stream_error_test.c b/test/core/json/json_stream_error_test.c index 3b07fcd38e..630e1b03df 100644 --- a/test/core/json/json_stream_error_test.c +++ b/test/core/json/json_stream_error_test.c @@ -39,8 +39,8 @@ #include #include "test/core/util/test_config.h" -#include "src/core/json/json_reader.h" -#include "src/core/json/json_writer.h" +#include "src/core/lib/json/json_reader.h" +#include "src/core/lib/json/json_writer.h" static int g_string_clear_once = 0; diff --git a/test/core/json/json_test.c b/test/core/json/json_test.c index e9b81e2021..2a007627f3 100644 --- a/test/core/json/json_test.c +++ b/test/core/json/json_test.c @@ -37,8 +37,8 @@ #include #include #include -#include "src/core/json/json.h" -#include "src/core/support/string.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/support/string.h" #include "test/core/util/test_config.h" diff --git a/test/core/network_benchmarks/low_level_ping_pong.c b/test/core/network_benchmarks/low_level_ping_pong.c index 7ed3372d5d..b8c6954e38 100644 --- a/test/core/network_benchmarks/low_level_ping_pong.c +++ b/test/core/network_benchmarks/low_level_ping_pong.c @@ -55,7 +55,7 @@ #include #include #include -#include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" typedef struct fd_pair { int read_fd; diff --git a/test/core/profiling/timers_test.c b/test/core/profiling/timers_test.c index 7070fe465f..284589af1e 100644 --- a/test/core/profiling/timers_test.c +++ b/test/core/profiling/timers_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" #include #include "test/core/util/test_config.h" diff --git a/test/core/security/auth_context_test.c b/test/core/security/auth_context_test.c index d091c7e7e6..d1ead16235 100644 --- a/test/core/security/auth_context_test.c +++ b/test/core/security/auth_context_test.c @@ -33,8 +33,8 @@ #include -#include "src/core/security/security_context.h" -#include "src/core/support/string.h" +#include "src/core/lib/security/security_context.h" +#include "src/core/lib/support/string.h" #include "test/core/util/test_config.h" #include diff --git a/test/core/security/b64_test.c b/test/core/security/b64_test.c index 772514e1fd..ab15df2c21 100644 --- a/test/core/security/b64_test.c +++ b/test/core/security/b64_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/security/b64.h" +#include "src/core/lib/security/b64.h" #include diff --git a/test/core/security/create_jwt.c b/test/core/security/create_jwt.c index 4c0cf436ee..3416de7254 100644 --- a/test/core/security/create_jwt.c +++ b/test/core/security/create_jwt.c @@ -34,9 +34,9 @@ #include #include -#include "src/core/security/credentials.h" -#include "src/core/security/json_token.h" -#include "src/core/support/load_file.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/security/json_token.h" +#include "src/core/lib/support/load_file.h" #include #include diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c index 3a6b9696ab..e741e3656f 100644 --- a/test/core/security/credentials_test.c +++ b/test/core/security/credentials_test.c @@ -33,7 +33,7 @@ #include -#include "src/core/security/credentials.h" +#include "src/core/lib/security/credentials.h" #include #include @@ -44,11 +44,11 @@ #include #include -#include "src/core/http/httpcli.h" -#include "src/core/security/json_token.h" -#include "src/core/support/env.h" -#include "src/core/support/string.h" -#include "src/core/support/tmpfile.h" +#include "src/core/lib/http/httpcli.h" +#include "src/core/lib/security/json_token.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/support/tmpfile.h" #include "test/core/util/test_config.h" /* -- Mock channel credentials. -- */ diff --git a/test/core/security/fetch_oauth2.c b/test/core/security/fetch_oauth2.c index 87b54f1a0c..1f4e18005e 100644 --- a/test/core/security/fetch_oauth2.c +++ b/test/core/security/fetch_oauth2.c @@ -42,8 +42,8 @@ #include #include -#include "src/core/security/credentials.h" -#include "src/core/support/load_file.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/support/load_file.h" #include "test/core/security/oauth2_utils.h" static grpc_call_credentials *create_refresh_token_creds( diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c index 4d80c16fb9..460d5299f0 100644 --- a/test/core/security/json_token_test.c +++ b/test/core/security/json_token_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/security/json_token.h" +#include "src/core/lib/security/json_token.h" #include #include @@ -41,8 +41,8 @@ #include #include -#include "src/core/json/json.h" -#include "src/core/security/b64.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/security/b64.h" #include "test/core/util/test_config.h" /* This JSON key was generated with the GCE console and revoked immediately. diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c index d2f8d1d182..c57f4d72ee 100644 --- a/test/core/security/jwt_verifier_test.c +++ b/test/core/security/jwt_verifier_test.c @@ -31,13 +31,13 @@ * */ -#include "src/core/security/jwt_verifier.h" +#include "src/core/lib/security/jwt_verifier.h" #include -#include "src/core/http/httpcli.h" -#include "src/core/security/b64.h" -#include "src/core/security/json_token.h" +#include "src/core/lib/http/httpcli.h" +#include "src/core/lib/security/b64.h" +#include "src/core/lib/security/json_token.h" #include "test/core/util/test_config.h" #include diff --git a/test/core/security/oauth2_utils.c b/test/core/security/oauth2_utils.c index 9b70afffe1..52259e63af 100644 --- a/test/core/security/oauth2_utils.c +++ b/test/core/security/oauth2_utils.c @@ -42,7 +42,7 @@ #include #include -#include "src/core/security/credentials.h" +#include "src/core/lib/security/credentials.h" typedef struct { gpr_mu *mu; diff --git a/test/core/security/oauth2_utils.h b/test/core/security/oauth2_utils.h index b35fe7987f..eff98270c8 100644 --- a/test/core/security/oauth2_utils.h +++ b/test/core/security/oauth2_utils.h @@ -34,7 +34,7 @@ #ifndef GRPC_TEST_CORE_SECURITY_OAUTH2_UTILS_H #define GRPC_TEST_CORE_SECURITY_OAUTH2_UTILS_H -#include "src/core/security/credentials.h" +#include "src/core/lib/security/credentials.h" #ifdef __cplusplus extern "C" { diff --git a/test/core/security/print_google_default_creds_token.c b/test/core/security/print_google_default_creds_token.c index 09673f362c..49812f7f3e 100644 --- a/test/core/security/print_google_default_creds_token.c +++ b/test/core/security/print_google_default_creds_token.c @@ -42,8 +42,8 @@ #include #include -#include "src/core/security/credentials.h" -#include "src/core/support/string.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/support/string.h" typedef struct { gpr_mu *mu; diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c index 0e8c38a53e..f6884ec1ba 100644 --- a/test/core/security/secure_endpoint_test.c +++ b/test/core/security/secure_endpoint_test.c @@ -39,10 +39,10 @@ #include #include #include -#include "src/core/iomgr/endpoint_pair.h" -#include "src/core/iomgr/iomgr.h" -#include "src/core/security/secure_endpoint.h" -#include "src/core/tsi/fake_transport_security.h" +#include "src/core/lib/iomgr/endpoint_pair.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/security/secure_endpoint.h" +#include "src/core/lib/tsi/fake_transport_security.h" #include "test/core/util/test_config.h" static gpr_mu *g_mu; diff --git a/test/core/security/security_connector_test.c b/test/core/security/security_connector_test.c index 31a56ea723..b080343e3f 100644 --- a/test/core/security/security_connector_test.c +++ b/test/core/security/security_connector_test.c @@ -40,13 +40,13 @@ #include #include -#include "src/core/security/security_connector.h" -#include "src/core/security/security_context.h" -#include "src/core/support/env.h" -#include "src/core/support/string.h" -#include "src/core/support/tmpfile.h" -#include "src/core/tsi/ssl_transport_security.h" -#include "src/core/tsi/transport_security.h" +#include "src/core/lib/security/security_connector.h" +#include "src/core/lib/security/security_context.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/support/tmpfile.h" +#include "src/core/lib/tsi/ssl_transport_security.h" +#include "src/core/lib/tsi/transport_security.h" #include "test/core/util/test_config.h" static int check_transport_security_type(const grpc_auth_context *ctx) { diff --git a/test/core/security/verify_jwt.c b/test/core/security/verify_jwt.c index eb86589681..c08e03d9d7 100644 --- a/test/core/security/verify_jwt.c +++ b/test/core/security/verify_jwt.c @@ -42,7 +42,7 @@ #include #include -#include "src/core/security/jwt_verifier.h" +#include "src/core/lib/security/jwt_verifier.h" typedef struct { grpc_pollset *pollset; diff --git a/test/core/statistics/census_log_tests.c b/test/core/statistics/census_log_tests.c index 7cbb0c022b..fef8e9ed48 100644 --- a/test/core/statistics/census_log_tests.c +++ b/test/core/statistics/census_log_tests.c @@ -31,7 +31,7 @@ * */ -#include "src/core/statistics/census_log.h" +#include "src/core/lib/statistics/census_log.h" #include #include #include diff --git a/test/core/statistics/census_stub_test.c b/test/core/statistics/census_stub_test.c index e734a34f55..df5d25b678 100644 --- a/test/core/statistics/census_stub_test.c +++ b/test/core/statistics/census_stub_test.c @@ -36,8 +36,8 @@ #include #include -#include "src/core/statistics/census_interface.h" -#include "src/core/statistics/census_rpc_stats.h" +#include "src/core/lib/statistics/census_interface.h" +#include "src/core/lib/statistics/census_rpc_stats.h" #include "test/core/util/test_config.h" /* Tests census noop stubs in a simulated rpc flow */ diff --git a/test/core/statistics/hash_table_test.c b/test/core/statistics/hash_table_test.c index 7ff5bb77ad..903d297bb8 100644 --- a/test/core/statistics/hash_table_test.c +++ b/test/core/statistics/hash_table_test.c @@ -35,13 +35,13 @@ #include #include -#include "src/core/statistics/hash_table.h" +#include "src/core/lib/statistics/hash_table.h" #include #include #include -#include "src/core/support/murmur_hash.h" -#include "src/core/support/string.h" +#include "src/core/lib/support/murmur_hash.h" +#include "src/core/lib/support/string.h" #include "test/core/util/test_config.h" static uint64_t hash64(const void *k) { diff --git a/test/core/statistics/rpc_stats_test.c b/test/core/statistics/rpc_stats_test.c index 3ece3caaf3..dc2f70bbd4 100644 --- a/test/core/statistics/rpc_stats_test.c +++ b/test/core/statistics/rpc_stats_test.c @@ -39,9 +39,9 @@ #include #include #include -#include "src/core/statistics/census_interface.h" -#include "src/core/statistics/census_rpc_stats.h" -#include "src/core/statistics/census_tracing.h" +#include "src/core/lib/statistics/census_interface.h" +#include "src/core/lib/statistics/census_rpc_stats.h" +#include "src/core/lib/statistics/census_tracing.h" #include "test/core/util/test_config.h" /* Ensure all possible state transitions are called without causing problem */ diff --git a/test/core/statistics/trace_test.c b/test/core/statistics/trace_test.c index 2c64e89ddd..2cc3ddd36c 100644 --- a/test/core/statistics/trace_test.c +++ b/test/core/statistics/trace_test.c @@ -41,9 +41,9 @@ #include #include #include -#include "src/core/statistics/census_interface.h" -#include "src/core/statistics/census_tracing.h" -#include "src/core/statistics/census_tracing.h" +#include "src/core/lib/statistics/census_interface.h" +#include "src/core/lib/statistics/census_tracing.h" +#include "src/core/lib/statistics/census_tracing.h" #include "test/core/util/test_config.h" /* Ensure all possible state transitions are called without causing problem */ diff --git a/test/core/statistics/window_stats_test.c b/test/core/statistics/window_stats_test.c index 9ed7ee1fac..ed0d7bb94a 100644 --- a/test/core/statistics/window_stats_test.c +++ b/test/core/statistics/window_stats_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/statistics/window_stats.h" +#include "src/core/lib/statistics/window_stats.h" #include #include #include diff --git a/test/core/support/backoff_test.c b/test/core/support/backoff_test.c index 870b60b2d5..13cba7d750 100644 --- a/test/core/support/backoff_test.c +++ b/test/core/support/backoff_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/support/backoff.h" +#include "src/core/lib/support/backoff.h" #include diff --git a/test/core/support/env_test.c b/test/core/support/env_test.c index 69aebcc918..bd6a8bdf9d 100644 --- a/test/core/support/env_test.c +++ b/test/core/support/env_test.c @@ -37,8 +37,8 @@ #include #include -#include "src/core/support/env.h" -#include "src/core/support/string.h" +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" #include "test/core/util/test_config.h" #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x) diff --git a/test/core/support/load_file_test.c b/test/core/support/load_file_test.c index a14fdc656e..6bc7b90058 100644 --- a/test/core/support/load_file_test.c +++ b/test/core/support/load_file_test.c @@ -38,9 +38,9 @@ #include #include -#include "src/core/support/load_file.h" -#include "src/core/support/string.h" -#include "src/core/support/tmpfile.h" +#include "src/core/lib/support/load_file.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/support/tmpfile.h" #include "test/core/util/test_config.h" #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x) diff --git a/test/core/support/murmur_hash_test.c b/test/core/support/murmur_hash_test.c index 562b9567e7..ef32719408 100644 --- a/test/core/support/murmur_hash_test.c +++ b/test/core/support/murmur_hash_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/support/murmur_hash.h" +#include "src/core/lib/support/murmur_hash.h" #include #include #include "test/core/util/test_config.h" diff --git a/test/core/support/stack_lockfree_test.c b/test/core/support/stack_lockfree_test.c index 0f49e6fa52..745157f701 100644 --- a/test/core/support/stack_lockfree_test.c +++ b/test/core/support/stack_lockfree_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/support/stack_lockfree.h" +#include "src/core/lib/support/stack_lockfree.h" #include diff --git a/test/core/support/string_test.c b/test/core/support/string_test.c index c1d0f12250..d5f8107f21 100644 --- a/test/core/support/string_test.c +++ b/test/core/support/string_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include #include diff --git a/test/core/surface/byte_buffer_reader_test.c b/test/core/surface/byte_buffer_reader_test.c index c8aacdb017..629bce9107 100644 --- a/test/core/surface/byte_buffer_reader_test.c +++ b/test/core/surface/byte_buffer_reader_test.c @@ -42,7 +42,7 @@ #include #include "test/core/util/test_config.h" -#include "src/core/compression/message_compress.h" +#include "src/core/lib/compression/message_compress.h" #include diff --git a/test/core/surface/channel_create_test.c b/test/core/surface/channel_create_test.c index 044e766473..95b4eaf093 100644 --- a/test/core/surface/channel_create_test.c +++ b/test/core/surface/channel_create_test.c @@ -33,7 +33,7 @@ #include #include -#include "src/core/client_config/resolver_registry.h" +#include "src/core/lib/client_config/resolver_registry.h" #include "test/core/util/test_config.h" void test_unknown_scheme_target(void) { diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c index 4f534de0f6..fa9b363a6f 100644 --- a/test/core/surface/completion_queue_test.c +++ b/test/core/surface/completion_queue_test.c @@ -31,14 +31,14 @@ * */ -#include "src/core/surface/completion_queue.h" +#include "src/core/lib/surface/completion_queue.h" #include #include #include #include #include -#include "src/core/iomgr/iomgr.h" +#include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/test_config.h" #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c index 79e53cb422..310aa00343 100644 --- a/test/core/surface/lame_client_test.c +++ b/test/core/surface/lame_client_test.c @@ -36,10 +36,10 @@ #include #include #include -#include "src/core/channel/channel_stack.h" -#include "src/core/iomgr/closure.h" -#include "src/core/surface/channel.h" -#include "src/core/transport/transport.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/transport/transport.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/test_config.h" diff --git a/test/core/surface/secure_channel_create_test.c b/test/core/surface/secure_channel_create_test.c index f3e5fefaf0..eb710cba38 100644 --- a/test/core/surface/secure_channel_create_test.c +++ b/test/core/surface/secure_channel_create_test.c @@ -36,10 +36,10 @@ #include #include #include -#include "src/core/client_config/resolver_registry.h" -#include "src/core/security/credentials.h" -#include "src/core/security/security_connector.h" -#include "src/core/surface/channel.h" +#include "src/core/lib/client_config/resolver_registry.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/security/security_connector.h" +#include "src/core/lib/surface/channel.h" #include "test/core/util/test_config.h" void test_unknown_scheme_target(void) { diff --git a/test/core/surface/server_chttp2_test.c b/test/core/surface/server_chttp2_test.c index 84b345bb50..14eb1ff9dc 100644 --- a/test/core/surface/server_chttp2_test.c +++ b/test/core/surface/server_chttp2_test.c @@ -37,8 +37,8 @@ #include #include #include -#include "src/core/security/credentials.h" -#include "src/core/tsi/fake_transport_security.h" +#include "src/core/lib/security/credentials.h" +#include "src/core/lib/tsi/fake_transport_security.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/transport/chttp2/alpn_test.c b/test/core/transport/chttp2/alpn_test.c index 9a7d5ef0c3..0792073711 100644 --- a/test/core/transport/chttp2/alpn_test.c +++ b/test/core/transport/chttp2/alpn_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/alpn.h" +#include "src/core/lib/transport/chttp2/alpn.h" #include #include "test/core/util/test_config.h" diff --git a/test/core/transport/chttp2/bin_encoder_test.c b/test/core/transport/chttp2/bin_encoder_test.c index 815b03c535..fd798d88d5 100644 --- a/test/core/transport/chttp2/bin_encoder_test.c +++ b/test/core/transport/chttp2/bin_encoder_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/bin_encoder.h" +#include "src/core/lib/transport/chttp2/bin_encoder.h" #include @@ -41,7 +41,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" static int all_ok = 1; diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c index f5de087bac..b23e999c52 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.c +++ b/test/core/transport/chttp2/hpack_encoder_test.c @@ -31,16 +31,16 @@ * */ -#include "src/core/transport/chttp2/hpack_encoder.h" +#include "src/core/lib/transport/chttp2/hpack_encoder.h" #include #include #include #include -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/hpack_parser.h" -#include "src/core/transport/metadata.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/chttp2/hpack_parser.h" +#include "src/core/lib/transport/metadata.h" #include "test/core/util/parse_hexstring.h" #include "test/core/util/slice_splitter.h" #include "test/core/util/test_config.h" diff --git a/test/core/transport/chttp2/hpack_parser_test.c b/test/core/transport/chttp2/hpack_parser_test.c index 4456e197af..ab82fd4292 100644 --- a/test/core/transport/chttp2/hpack_parser_test.c +++ b/test/core/transport/chttp2/hpack_parser_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/hpack_parser.h" +#include "src/core/lib/transport/chttp2/hpack_parser.h" #include diff --git a/test/core/transport/chttp2/hpack_table_test.c b/test/core/transport/chttp2/hpack_table_test.c index 4c0fa2e2e7..fbacdc3ad6 100644 --- a/test/core/transport/chttp2/hpack_table_test.c +++ b/test/core/transport/chttp2/hpack_table_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/hpack_table.h" +#include "src/core/lib/transport/chttp2/hpack_table.h" #include #include @@ -41,7 +41,7 @@ #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/util/test_config.h" #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) diff --git a/test/core/transport/chttp2/status_conversion_test.c b/test/core/transport/chttp2/status_conversion_test.c index e2729a0a19..f3126cc520 100644 --- a/test/core/transport/chttp2/status_conversion_test.c +++ b/test/core/transport/chttp2/status_conversion_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/status_conversion.h" +#include "src/core/lib/transport/chttp2/status_conversion.h" #include #include "test/core/util/test_config.h" diff --git a/test/core/transport/chttp2/stream_map_test.c b/test/core/transport/chttp2/stream_map_test.c index 527d2fe0ae..971410337d 100644 --- a/test/core/transport/chttp2/stream_map_test.c +++ b/test/core/transport/chttp2/stream_map_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/stream_map.h" +#include "src/core/lib/transport/chttp2/stream_map.h" #include #include "test/core/util/test_config.h" diff --git a/test/core/transport/chttp2/timeout_encoding_test.c b/test/core/transport/chttp2/timeout_encoding_test.c index b7dd60e9b1..9a91a14433 100644 --- a/test/core/transport/chttp2/timeout_encoding_test.c +++ b/test/core/transport/chttp2/timeout_encoding_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/timeout_encoding.h" +#include "src/core/lib/transport/chttp2/timeout_encoding.h" #include #include @@ -40,7 +40,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" #include "test/core/util/test_config.h" #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) diff --git a/test/core/transport/chttp2/varint_test.c b/test/core/transport/chttp2/varint_test.c index f06116a731..f8cc4ab627 100644 --- a/test/core/transport/chttp2/varint_test.c +++ b/test/core/transport/chttp2/varint_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/chttp2/varint.h" +#include "src/core/lib/transport/chttp2/varint.h" #include #include diff --git a/test/core/transport/connectivity_state_test.c b/test/core/transport/connectivity_state_test.c index 4b2d0aa44a..b310d4dc00 100644 --- a/test/core/transport/connectivity_state_test.c +++ b/test/core/transport/connectivity_state_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/connectivity_state.h" +#include "src/core/lib/transport/connectivity_state.h" #include diff --git a/test/core/transport/metadata_test.c b/test/core/transport/metadata_test.c index 928fba7f45..5270d8f4d4 100644 --- a/test/core/transport/metadata_test.c +++ b/test/core/transport/metadata_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/transport/metadata.h" +#include "src/core/lib/transport/metadata.h" #include @@ -40,8 +40,8 @@ #include #include -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/bin_encoder.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/chttp2/bin_encoder.h" #include "test/core/util/test_config.h" #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) diff --git a/test/core/tsi/transport_security_test.c b/test/core/tsi/transport_security_test.c index 667d3f0349..49b5b8b5f2 100644 --- a/test/core/tsi/transport_security_test.c +++ b/test/core/tsi/transport_security_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/tsi/transport_security.h" +#include "src/core/lib/tsi/transport_security.h" #include @@ -42,9 +42,9 @@ #include -#include "src/core/support/string.h" -#include "src/core/tsi/fake_transport_security.h" -#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/tsi/fake_transport_security.h" +#include "src/core/lib/tsi/ssl_transport_security.h" #include "test/core/util/test_config.h" typedef struct { diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c index d211016267..fea7e52b09 100644 --- a/test/core/util/port_posix.c +++ b/test/core/util/port_posix.c @@ -49,8 +49,8 @@ #include #include -#include "src/core/http/httpcli.h" -#include "src/core/support/env.h" +#include "src/core/lib/http/httpcli.h" +#include "src/core/lib/support/env.h" #include "test/core/util/port_server_client.h" #define NUM_RANDOM_PORTS_TO_PICK 100 diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c index c7b9d63109..ea01b46838 100644 --- a/test/core/util/port_server_client.c +++ b/test/core/util/port_server_client.c @@ -47,7 +47,7 @@ #include #include -#include "src/core/http/httpcli.h" +#include "src/core/lib/http/httpcli.h" typedef struct freereq { gpr_mu *mu; diff --git a/test/core/util/port_windows.c b/test/core/util/port_windows.c index 4cbedc0aa6..081782d295 100644 --- a/test/core/util/port_windows.c +++ b/test/core/util/port_windows.c @@ -46,9 +46,9 @@ #include #include -#include "src/core/http/httpcli.h" -#include "src/core/iomgr/sockaddr_utils.h" -#include "src/core/support/env.h" +#include "src/core/lib/http/httpcli.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/support/env.h" #include "test/core/util/port_server_client.h" #define NUM_RANDOM_PORTS_TO_PICK 100 diff --git a/test/core/util/reconnect_server.c b/test/core/util/reconnect_server.c index 57225aa8a3..0e7a486526 100644 --- a/test/core/util/reconnect_server.c +++ b/test/core/util/reconnect_server.c @@ -40,9 +40,9 @@ #include #include #include -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/sockaddr.h" -#include "src/core/iomgr/tcp_server.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/tcp_server.h" #include "test/core/util/port.h" #include "test/core/util/test_tcp_server.h" diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c index f408048fdf..7ffaa6fe27 100644 --- a/test/core/util/test_config.c +++ b/test/core/util/test_config.c @@ -39,7 +39,7 @@ #include #include #include -#include "src/core/support/string.h" +#include "src/core/lib/support/string.h" double g_fixture_slowdown_factor = 1.0; diff --git a/test/core/util/test_tcp_server.c b/test/core/util/test_tcp_server.c index ab379441d8..7703ec0039 100644 --- a/test/core/util/test_tcp_server.c +++ b/test/core/util/test_tcp_server.c @@ -40,9 +40,9 @@ #include #include #include -#include "src/core/iomgr/endpoint.h" -#include "src/core/iomgr/sockaddr.h" -#include "src/core/iomgr/tcp_server.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/tcp_server.h" #include "test/core/util/port.h" static void on_server_destroyed(grpc_exec_ctx *exec_ctx, void *data, diff --git a/test/core/util/test_tcp_server.h b/test/core/util/test_tcp_server.h index 15fcb4fb87..7d1025f17a 100644 --- a/test/core/util/test_tcp_server.h +++ b/test/core/util/test_tcp_server.h @@ -35,7 +35,7 @@ #define GRPC_TEST_CORE_UTIL_TEST_TCP_SERVER_H #include -#include "src/core/iomgr/tcp_server.h" +#include "src/core/lib/iomgr/tcp_server.h" typedef struct test_tcp_server { grpc_tcp_server *tcp_server; diff --git a/test/cpp/common/auth_property_iterator_test.cc b/test/cpp/common/auth_property_iterator_test.cc index 4c6dd6039c..4b5cf02c69 100644 --- a/test/cpp/common/auth_property_iterator_test.cc +++ b/test/cpp/common/auth_property_iterator_test.cc @@ -38,7 +38,7 @@ #include "test/cpp/util/string_ref_helper.h" extern "C" { -#include "src/core/security/security_context.h" +#include "src/core/lib/security/security_context.h" } using ::grpc::testing::ToString; diff --git a/test/cpp/common/secure_auth_context_test.cc b/test/cpp/common/secure_auth_context_test.cc index 123d4947e0..c421910cba 100644 --- a/test/cpp/common/secure_auth_context_test.cc +++ b/test/cpp/common/secure_auth_context_test.cc @@ -38,7 +38,7 @@ #include "test/cpp/util/string_ref_helper.h" extern "C" { -#include "src/core/security/security_context.h" +#include "src/core/lib/security/security_context.h" } using grpc::testing::ToString; diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index dc8c2bb6e5..d8aa4c0137 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -53,7 +53,7 @@ #include "test/cpp/util/string_ref_helper.h" #ifdef GPR_POSIX_SOCKET -#include "src/core/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/pollset_posix.h" #endif using grpc::testing::EchoRequest; diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 4759818322..ff388c0341 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -48,7 +48,7 @@ #include #include -#include "src/core/security/credentials.h" +#include "src/core/lib/security/credentials.h" #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc index dbbda3ac51..62bb6b1b78 100644 --- a/test/cpp/end2end/shutdown_test.cc +++ b/test/cpp/end2end/shutdown_test.cc @@ -43,7 +43,7 @@ #include #include -#include "src/core/support/env.h" +#include "src/core/lib/support/env.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index 114d715baa..8760b8d28e 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -45,7 +45,7 @@ #include #include -#include "src/core/surface/api_trace.h" +#include "src/core/lib/surface/api_trace.h" #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" diff --git a/test/cpp/end2end/zookeeper_test.cc b/test/cpp/end2end/zookeeper_test.cc index bbf1b0edc1..f1b6ac2479 100644 --- a/test/cpp/end2end/zookeeper_test.cc +++ b/test/cpp/end2end/zookeeper_test.cc @@ -42,7 +42,7 @@ #include #include -#include "src/core/support/env.h" +#include "src/core/lib/support/env.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/cpp/grpclb/grpclb_api_test.cc b/test/cpp/grpclb/grpclb_api_test.cc index bd4885fb4c..bc8219c1c7 100644 --- a/test/cpp/grpclb/grpclb_api_test.cc +++ b/test/cpp/grpclb/grpclb_api_test.cc @@ -34,7 +34,7 @@ #include #include -#include "src/core/client_config/lb_policies/load_balancer_api.h" +#include "src/core/lib/client_config/lb_policies/load_balancer_api.h" #include "src/proto/grpc/lb/v0/load_balancer.pb.h" // C++ version namespace grpc { diff --git a/test/cpp/interop/client_helper.h b/test/cpp/interop/client_helper.h index 0f77474139..622b96e4fb 100644 --- a/test/cpp/interop/client_helper.h +++ b/test/cpp/interop/client_helper.h @@ -38,7 +38,7 @@ #include -#include "src/core/surface/call_test_only.h" +#include "src/core/lib/surface/call_test_only.h" namespace grpc { namespace testing { diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 514d4fa861..2fcd9f3951 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -46,7 +46,7 @@ #include #include -#include "src/core/transport/byte_stream.h" +#include "src/core/lib/transport/byte_stream.h" #include "src/proto/grpc/testing/empty.grpc.pb.h" #include "src/proto/grpc/testing/messages.grpc.pb.h" #include "src/proto/grpc/testing/test.grpc.pb.h" diff --git a/test/cpp/interop/interop_test.cc b/test/cpp/interop/interop_test.cc index f0fccf4615..f1fb3c9675 100644 --- a/test/cpp/interop/interop_test.cc +++ b/test/cpp/interop/interop_test.cc @@ -51,8 +51,8 @@ #include "test/core/util/port.h" extern "C" { -#include "src/core/iomgr/socket_utils_posix.h" -#include "src/core/support/string.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" +#include "src/core/lib/support/string.h" } int test_client(const char* root, const char* host, int port) { diff --git a/test/cpp/interop/server_helper.cc b/test/cpp/interop/server_helper.cc index 9a284094f0..c6d891ad71 100644 --- a/test/cpp/interop/server_helper.cc +++ b/test/cpp/interop/server_helper.cc @@ -38,7 +38,7 @@ #include #include -#include "src/core/surface/call_test_only.h" +#include "src/core/lib/surface/call_test_only.h" #include "test/core/end2end/data/ssl_test_data.h" DECLARE_bool(use_tls); diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 4284e07bd4..a1489d88e6 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -53,7 +53,7 @@ #include #include -#include "src/core/profiling/timers.h" +#include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/services.grpc.pb.h" #include "test/cpp/qps/client.h" #include "test/cpp/qps/histogram.h" diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 6c05799d09..6cca7dec2b 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -45,7 +45,7 @@ #include #include -#include "src/core/support/env.h" +#include "src/core/lib/support/env.h" #include "src/proto/grpc/testing/services.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/cpp/qps/qps_test_with_poll.cc b/test/cpp/qps/qps_test_with_poll.cc index 8340a6386a..647aaac4c4 100644 --- a/test/cpp/qps/qps_test_with_poll.cc +++ b/test/cpp/qps/qps_test_with_poll.cc @@ -40,7 +40,7 @@ #include "test/cpp/util/benchmark_config.h" extern "C" { -#include "src/core/iomgr/pollset_posix.h" +#include "src/core/lib/iomgr/pollset_posix.h" } namespace grpc { -- cgit v1.2.3 From b7f3f6eec46d1f16523f5c9f9cf561284c0e2c91 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 25 Mar 2016 17:13:09 -0700 Subject: Fix copyright --- src/cpp/common/secure_channel_arguments.cc | 2 +- test/core/channel/channel_args_test.c | 2 +- test/core/client_config/resolvers/dns_resolver_test.c | 2 +- test/core/client_config/resolvers/sockaddr_resolver_test.c | 2 +- test/core/client_config/uri_parser_test.c | 2 +- test/core/compression/algorithm_test.c | 2 +- test/core/compression/message_compress_test.c | 2 +- test/core/fling/server.c | 2 +- test/core/iomgr/sockaddr_utils_test.c | 2 +- test/core/iomgr/socket_utils_test.c | 2 +- test/core/iomgr/time_averaged_stats_test.c | 2 +- test/core/json/json_rewrite.c | 2 +- test/core/profiling/timers_test.c | 2 +- test/core/security/auth_context_test.c | 2 +- test/core/security/oauth2_utils.h | 2 +- test/core/support/env_test.c | 2 +- test/core/support/murmur_hash_test.c | 2 +- test/core/support/stack_lockfree_test.c | 2 +- test/core/support/string_test.c | 2 +- test/core/surface/channel_create_test.c | 2 +- test/core/surface/secure_channel_create_test.c | 2 +- test/core/transport/chttp2/alpn_test.c | 2 +- test/core/transport/chttp2/hpack_parser_test.c | 2 +- test/core/transport/chttp2/status_conversion_test.c | 2 +- test/core/transport/chttp2/stream_map_test.c | 2 +- test/core/transport/chttp2/varint_test.c | 2 +- test/core/transport/metadata_test.c | 2 +- test/cpp/interop/client_helper.h | 2 +- test/cpp/interop/server_helper.cc | 2 +- 29 files changed, 29 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/cpp/common/secure_channel_arguments.cc b/src/cpp/common/secure_channel_arguments.cc index 81ec251b92..82e02f0238 100644 --- a/src/cpp/common/secure_channel_arguments.cc +++ b/src/cpp/common/secure_channel_arguments.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/channel/channel_args_test.c b/test/core/channel/channel_args_test.c index c7fc25960c..352dfa045e 100644 --- a/test/core/channel/channel_args_test.c +++ b/test/core/channel/channel_args_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/client_config/resolvers/dns_resolver_test.c b/test/core/client_config/resolvers/dns_resolver_test.c index 043b882184..6c7a6b27e4 100644 --- a/test/core/client_config/resolvers/dns_resolver_test.c +++ b/test/core/client_config/resolvers/dns_resolver_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/client_config/resolvers/sockaddr_resolver_test.c b/test/core/client_config/resolvers/sockaddr_resolver_test.c index e23616ca23..fafddfd166 100644 --- a/test/core/client_config/resolvers/sockaddr_resolver_test.c +++ b/test/core/client_config/resolvers/sockaddr_resolver_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/client_config/uri_parser_test.c b/test/core/client_config/uri_parser_test.c index e5d0c378ba..c7f7726380 100644 --- a/test/core/client_config/uri_parser_test.c +++ b/test/core/client_config/uri_parser_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/compression/algorithm_test.c b/test/core/compression/algorithm_test.c index bdee748ae6..937eb66903 100644 --- a/test/core/compression/algorithm_test.c +++ b/test/core/compression/algorithm_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c index 1a93903346..378badca28 100644 --- a/test/core/compression/message_compress_test.c +++ b/test/core/compression/message_compress_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/fling/server.c b/test/core/fling/server.c index fd446f1128..4fef21f51d 100644 --- a/test/core/fling/server.c +++ b/test/core/fling/server.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/iomgr/sockaddr_utils_test.c b/test/core/iomgr/sockaddr_utils_test.c index a330314443..19bee9a399 100644 --- a/test/core/iomgr/sockaddr_utils_test.c +++ b/test/core/iomgr/sockaddr_utils_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/iomgr/socket_utils_test.c b/test/core/iomgr/socket_utils_test.c index 85c027a978..8238a9c33f 100644 --- a/test/core/iomgr/socket_utils_test.c +++ b/test/core/iomgr/socket_utils_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/iomgr/time_averaged_stats_test.c b/test/core/iomgr/time_averaged_stats_test.c index 72f8559d66..a49d899e30 100644 --- a/test/core/iomgr/time_averaged_stats_test.c +++ b/test/core/iomgr/time_averaged_stats_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/json/json_rewrite.c b/test/core/json/json_rewrite.c index c43c6e2589..41090db105 100644 --- a/test/core/json/json_rewrite.c +++ b/test/core/json/json_rewrite.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/profiling/timers_test.c b/test/core/profiling/timers_test.c index 284589af1e..a3831191eb 100644 --- a/test/core/profiling/timers_test.c +++ b/test/core/profiling/timers_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/security/auth_context_test.c b/test/core/security/auth_context_test.c index d1ead16235..84d2afb85b 100644 --- a/test/core/security/auth_context_test.c +++ b/test/core/security/auth_context_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/security/oauth2_utils.h b/test/core/security/oauth2_utils.h index eff98270c8..5930f4729c 100644 --- a/test/core/security/oauth2_utils.h +++ b/test/core/security/oauth2_utils.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/support/env_test.c b/test/core/support/env_test.c index bd6a8bdf9d..1ab86d6991 100644 --- a/test/core/support/env_test.c +++ b/test/core/support/env_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/support/murmur_hash_test.c b/test/core/support/murmur_hash_test.c index ef32719408..c93efb4be4 100644 --- a/test/core/support/murmur_hash_test.c +++ b/test/core/support/murmur_hash_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/support/stack_lockfree_test.c b/test/core/support/stack_lockfree_test.c index 745157f701..13c8f3c925 100644 --- a/test/core/support/stack_lockfree_test.c +++ b/test/core/support/stack_lockfree_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/support/string_test.c b/test/core/support/string_test.c index d5f8107f21..e5e474d43c 100644 --- a/test/core/support/string_test.c +++ b/test/core/support/string_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/surface/channel_create_test.c b/test/core/surface/channel_create_test.c index 95b4eaf093..d5d7d1c311 100644 --- a/test/core/surface/channel_create_test.c +++ b/test/core/surface/channel_create_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/surface/secure_channel_create_test.c b/test/core/surface/secure_channel_create_test.c index eb710cba38..5c95390707 100644 --- a/test/core/surface/secure_channel_create_test.c +++ b/test/core/surface/secure_channel_create_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/transport/chttp2/alpn_test.c b/test/core/transport/chttp2/alpn_test.c index 0792073711..a3c8a9a43c 100644 --- a/test/core/transport/chttp2/alpn_test.c +++ b/test/core/transport/chttp2/alpn_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/transport/chttp2/hpack_parser_test.c b/test/core/transport/chttp2/hpack_parser_test.c index ab82fd4292..e716d38cdb 100644 --- a/test/core/transport/chttp2/hpack_parser_test.c +++ b/test/core/transport/chttp2/hpack_parser_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/transport/chttp2/status_conversion_test.c b/test/core/transport/chttp2/status_conversion_test.c index f3126cc520..f2770e5702 100644 --- a/test/core/transport/chttp2/status_conversion_test.c +++ b/test/core/transport/chttp2/status_conversion_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/transport/chttp2/stream_map_test.c b/test/core/transport/chttp2/stream_map_test.c index 971410337d..baeac175ea 100644 --- a/test/core/transport/chttp2/stream_map_test.c +++ b/test/core/transport/chttp2/stream_map_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/transport/chttp2/varint_test.c b/test/core/transport/chttp2/varint_test.c index f8cc4ab627..960c9536ef 100644 --- a/test/core/transport/chttp2/varint_test.c +++ b/test/core/transport/chttp2/varint_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/transport/metadata_test.c b/test/core/transport/metadata_test.c index 5270d8f4d4..30e3113913 100644 --- a/test/core/transport/metadata_test.c +++ b/test/core/transport/metadata_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cpp/interop/client_helper.h b/test/cpp/interop/client_helper.h index 622b96e4fb..0790464449 100644 --- a/test/cpp/interop/client_helper.h +++ b/test/cpp/interop/client_helper.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cpp/interop/server_helper.cc b/test/cpp/interop/server_helper.cc index c6d891ad71..97c39c4245 100644 --- a/test/cpp/interop/server_helper.cc +++ b/test/cpp/interop/server_helper.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.3 From 0bcca41ddafcda0501bb5594b43e5a958185443a Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 25 Mar 2016 17:14:56 -0700 Subject: Fix --- src/core/lib/support/time_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/lib/support/time_posix.c b/src/core/lib/support/time_posix.c index 6435af6340..fcfab2f2fa 100644 --- a/src/core/lib/support/time_posix.c +++ b/src/core/lib/support/time_posix.c @@ -32,7 +32,7 @@ */ #include -#include +#include "src/core/lib/support/time_precise.h" #ifdef GPR_POSIX_TIME -- cgit v1.2.3 From 5070d8bba53151babab3e3eae24aa3b3518ede47 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 25 Mar 2016 19:44:06 -0700 Subject: Fix another path --- src/core/lib/support/time_win32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/lib/support/time_win32.c b/src/core/lib/support/time_win32.c index 4152f5db21..2f23a7a59c 100644 --- a/src/core/lib/support/time_win32.c +++ b/src/core/lib/support/time_win32.c @@ -41,10 +41,10 @@ #include #include #include -#include #include #include "src/core/lib/support/block_annotate.h" +#include "src/core/support/time_precise.h" static LARGE_INTEGER g_start_time; static double g_time_scale; -- cgit v1.2.3 From 43539fb5398a6b8ed88b4c24ab4f7b2ab1e6d117 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 25 Mar 2016 19:48:22 -0700 Subject: Fix another path --- src/core/lib/support/time_win32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/lib/support/time_win32.c b/src/core/lib/support/time_win32.c index 2f23a7a59c..a6ac003fb8 100644 --- a/src/core/lib/support/time_win32.c +++ b/src/core/lib/support/time_win32.c @@ -44,7 +44,7 @@ #include #include "src/core/lib/support/block_annotate.h" -#include "src/core/support/time_precise.h" +#include "src/core/lib/support/time_precise.h" static LARGE_INTEGER g_start_time; static double g_time_scale; -- cgit v1.2.3 From 8a891eb8ba9b2ed40d62948b589d4db3d381d008 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sat, 26 Mar 2016 13:10:36 -0700 Subject: Regenerate files --- src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h b/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h index 671fb9a60b..3599f881bb 100644 --- a/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h +++ b/src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h @@ -33,8 +33,8 @@ /* Automatically generated nanopb header */ /* Generated by nanopb-0.3.5-dev */ -#ifndef GRPC_CORE_LIB_PROTO_GRPC_LB_V0_LOAD_BALANCER_PB_H0_LOAD_BALANCER_PB_H -#define GRPC_CORE_LIB_PROTO_GRPC_LB_V0_LOAD_BALANCER_PB_H0_LOAD_BALANCER_PB_H +#ifndef PB_LOAD_BALANCER_PB_H_INCLUDED +#define PB_LOAD_BALANCER_PB_H_INCLUDED #include "third_party/nanopb/pb.h" #if PB_PROTO_HEADER_VERSION != 30 #error Regenerate this file with the current version of nanopb generator. @@ -179,4 +179,4 @@ extern const pb_field_t grpc_lb_v0_Server_fields[5]; } /* extern "C" */ #endif -#endif /* GRPC_CORE_LIB_PROTO_GRPC_LB_V0_LOAD_BALANCER_PB_H */ +#endif -- cgit v1.2.3