aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/ext/client_channel
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2017-03-31 16:59:30 -0700
committerGravatar Craig Tiller <ctiller@google.com>2017-03-31 16:59:30 -0700
commit9eb0fdec004f3f3e8a6ea93e1d8f7c1e0d92ec89 (patch)
tree8e5fba0e0ef071d50976385b7a7f4620079441c0 /src/core/ext/client_channel
parentc7527415e05039113c28a5169b1e48f62deaa29e (diff)
Reorganize ext tree
- filters live under filters - lb_policy, resolver implementations (being part of client_channel) live under client_channel
Diffstat (limited to 'src/core/ext/client_channel')
-rw-r--r--src/core/ext/client_channel/README.md65
-rw-r--r--src/core/ext/client_channel/channel_connectivity.c226
-rw-r--r--src/core/ext/client_channel/client_channel.c1393
-rw-r--r--src/core/ext/client_channel/client_channel.h64
-rw-r--r--src/core/ext/client_channel/client_channel_factory.c87
-rw-r--r--src/core/ext/client_channel/client_channel_factory.h92
-rw-r--r--src/core/ext/client_channel/client_channel_plugin.c104
-rw-r--r--src/core/ext/client_channel/connector.c55
-rw-r--r--src/core/ext/client_channel/connector.h88
-rw-r--r--src/core/ext/client_channel/http_connect_handshaker.c389
-rw-r--r--src/core/ext/client_channel/http_connect_handshaker.h49
-rw-r--r--src/core/ext/client_channel/http_proxy.c125
-rw-r--r--src/core/ext/client_channel/http_proxy.h39
-rw-r--r--src/core/ext/client_channel/lb_policy.c167
-rw-r--r--src/core/ext/client_channel/lb_policy.h209
-rw-r--r--src/core/ext/client_channel/lb_policy_factory.c163
-rw-r--r--src/core/ext/client_channel/lb_policy_factory.h134
-rw-r--r--src/core/ext/client_channel/lb_policy_registry.c85
-rw-r--r--src/core/ext/client_channel/lb_policy_registry.h55
-rw-r--r--src/core/ext/client_channel/parse_address.c170
-rw-r--r--src/core/ext/client_channel/parse_address.h54
-rw-r--r--src/core/ext/client_channel/proxy_mapper.c63
-rw-r--r--src/core/ext/client_channel/proxy_mapper.h89
-rw-r--r--src/core/ext/client_channel/proxy_mapper_registry.c139
-rw-r--r--src/core/ext/client_channel/proxy_mapper_registry.h59
-rw-r--r--src/core/ext/client_channel/resolver.c88
-rw-r--r--src/core/ext/client_channel/resolver.h101
-rw-r--r--src/core/ext/client_channel/resolver_factory.c56
-rw-r--r--src/core/ext/client_channel/resolver_factory.h85
-rw-r--r--src/core/ext/client_channel/resolver_registry.c174
-rw-r--r--src/core/ext/client_channel/resolver_registry.h84
-rw-r--r--src/core/ext/client_channel/retry_throttle.c210
-rw-r--r--src/core/ext/client_channel/retry_throttle.h65
-rw-r--r--src/core/ext/client_channel/subchannel.c839
-rw-r--r--src/core/ext/client_channel/subchannel.h203
-rw-r--r--src/core/ext/client_channel/subchannel_index.c262
-rw-r--r--src/core/ext/client_channel/subchannel_index.h77
-rw-r--r--src/core/ext/client_channel/uri_parser.c315
-rw-r--r--src/core/ext/client_channel/uri_parser.h65
39 files changed, 0 insertions, 6787 deletions
diff --git a/src/core/ext/client_channel/README.md b/src/core/ext/client_channel/README.md
deleted file mode 100644
index 7c209db12e..0000000000
--- a/src/core/ext/client_channel/README.md
+++ /dev/null
@@ -1,65 +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 a set of arguments for the channel. Such arguments
-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_channel_args objects to
-the channel. We represent arguments as a stream so that they can be changed
-by the resolver during execution, by reacting to external events (such as
-new service configuration data being pushed to some store).
-
-
-Load Balancing
---------------
-
-Load balancing configuration is provided by a grpc_lb_policy object.
-
-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_client_channel_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/ext/client_channel/channel_connectivity.c b/src/core/ext/client_channel/channel_connectivity.c
deleted file mode 100644
index f6cb3b9115..0000000000
--- a/src/core/ext/client_channel/channel_connectivity.c
+++ /dev/null
@@ -1,226 +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/lib/surface/channel.h"
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-
-#include "src/core/ext/client_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) {
- /* 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 client channel, but '%s'",
- client_channel_elem->filter->name);
- grpc_exec_ctx_finish(&exec_ctx);
- return GRPC_CHANNEL_SHUTDOWN;
-}
-
-typedef enum {
- WAITING,
- CALLING_BACK,
- CALLING_BACK_AND_FINISHED,
- CALLED_BACK
-} callback_phase;
-
-typedef struct {
- gpr_mu mu;
- callback_phase phase;
- grpc_closure on_complete;
- grpc_closure on_timeout;
- 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,
- bool due_to_completion, grpc_error *error) {
- int delete = 0;
-
- if (due_to_completion) {
- grpc_timer_cancel(exec_ctx, &w->alarm);
- }
-
- gpr_mu_lock(&w->mu);
-
- if (due_to_completion) {
- if (grpc_trace_operation_failures) {
- GRPC_LOG_IF_ERROR("watch_completion_error", GRPC_ERROR_REF(error));
- }
- GRPC_ERROR_UNREF(error);
- error = GRPC_ERROR_NONE;
- } else {
- if (error == GRPC_ERROR_NONE) {
- error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "Timed out waiting for connection state change");
- } else if (error == GRPC_ERROR_CANCELLED) {
- error = GRPC_ERROR_NONE;
- }
- }
- switch (w->phase) {
- case WAITING:
- w->phase = CALLING_BACK;
- grpc_cq_end_op(exec_ctx, w->cq, w->tag, GRPC_ERROR_REF(error),
- 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);
- }
-
- GRPC_ERROR_UNREF(error);
-}
-
-static void watch_complete(grpc_exec_ctx *exec_ctx, void *pw,
- grpc_error *error) {
- partly_done(exec_ctx, pw, true, GRPC_ERROR_REF(error));
-}
-
-static void timeout_complete(grpc_exec_ctx *exec_ctx, void *pw,
- grpc_error *error) {
- partly_done(exec_ctx, pw, false, GRPC_ERROR_REF(error));
-}
-
-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: %" PRId64
- ", tv_nsec: %d, clock_type: %d }, "
- "cq=%p, tag=%p)",
- 7, (channel, (int)last_observed_state, deadline.tv_sec, 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,
- grpc_schedule_on_exec_ctx);
- grpc_closure_init(&w->on_timeout, timeout_complete, w,
- grpc_schedule_on_exec_ctx);
- w->phase = WAITING;
- w->state = last_observed_state;
- w->cq = cq;
- w->tag = tag;
- w->channel = channel;
-
- grpc_timer_init(&exec_ctx, &w->alarm,
- gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
- &w->on_timeout, 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/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
deleted file mode 100644
index 435a3ab0fe..0000000000
--- a/src/core/ext/client_channel/client_channel.c
+++ /dev/null
@@ -1,1393 +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/ext/client_channel/client_channel.h"
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-#include <grpc/support/sync.h>
-#include <grpc/support/useful.h>
-
-#include "src/core/ext/client_channel/http_connect_handshaker.h"
-#include "src/core/ext/client_channel/lb_policy_registry.h"
-#include "src/core/ext/client_channel/proxy_mapper_registry.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
-#include "src/core/ext/client_channel/retry_throttle.h"
-#include "src/core/ext/client_channel/subchannel.h"
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/deadline_filter.h"
-#include "src/core/lib/iomgr/combiner.h"
-#include "src/core/lib/iomgr/iomgr.h"
-#include "src/core/lib/iomgr/polling_entity.h"
-#include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/surface/channel.h"
-#include "src/core/lib/transport/connectivity_state.h"
-#include "src/core/lib/transport/metadata.h"
-#include "src/core/lib/transport/metadata_batch.h"
-#include "src/core/lib/transport/service_config.h"
-#include "src/core/lib/transport/static_metadata.h"
-
-/* Client channel implementation */
-
-/*************************************************************************
- * METHOD-CONFIG TABLE
- */
-
-typedef enum {
- /* zero so it can be default initialized */
- WAIT_FOR_READY_UNSET = 0,
- WAIT_FOR_READY_FALSE,
- WAIT_FOR_READY_TRUE
-} wait_for_ready_value;
-
-typedef struct {
- gpr_refcount refs;
- gpr_timespec timeout;
- wait_for_ready_value wait_for_ready;
-} method_parameters;
-
-static method_parameters *method_parameters_ref(
- method_parameters *method_params) {
- gpr_ref(&method_params->refs);
- return method_params;
-}
-
-static void method_parameters_unref(method_parameters *method_params) {
- if (gpr_unref(&method_params->refs)) {
- gpr_free(method_params);
- }
-}
-
-static void *method_parameters_copy(void *value) {
- return method_parameters_ref(value);
-}
-
-static void method_parameters_free(grpc_exec_ctx *exec_ctx, void *value) {
- method_parameters_unref(value);
-}
-
-static const grpc_slice_hash_table_vtable method_parameters_vtable = {
- method_parameters_free, method_parameters_copy};
-
-static bool parse_wait_for_ready(grpc_json *field,
- wait_for_ready_value *wait_for_ready) {
- if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
- return false;
- }
- *wait_for_ready = field->type == GRPC_JSON_TRUE ? WAIT_FOR_READY_TRUE
- : WAIT_FOR_READY_FALSE;
- return true;
-}
-
-static bool parse_timeout(grpc_json *field, gpr_timespec *timeout) {
- if (field->type != GRPC_JSON_STRING) return false;
- size_t len = strlen(field->value);
- if (field->value[len - 1] != 's') return false;
- char *buf = gpr_strdup(field->value);
- buf[len - 1] = '\0'; // Remove trailing 's'.
- char *decimal_point = strchr(buf, '.');
- if (decimal_point != NULL) {
- *decimal_point = '\0';
- timeout->tv_nsec = gpr_parse_nonnegative_int(decimal_point + 1);
- if (timeout->tv_nsec == -1) {
- gpr_free(buf);
- return false;
- }
- // There should always be exactly 3, 6, or 9 fractional digits.
- int multiplier = 1;
- switch (strlen(decimal_point + 1)) {
- case 9:
- break;
- case 6:
- multiplier *= 1000;
- break;
- case 3:
- multiplier *= 1000000;
- break;
- default: // Unsupported number of digits.
- gpr_free(buf);
- return false;
- }
- timeout->tv_nsec *= multiplier;
- }
- timeout->tv_sec = gpr_parse_nonnegative_int(buf);
- gpr_free(buf);
- if (timeout->tv_sec == -1) return false;
- return true;
-}
-
-static void *method_parameters_create_from_json(const grpc_json *json) {
- wait_for_ready_value wait_for_ready = WAIT_FOR_READY_UNSET;
- gpr_timespec timeout = {0, 0, GPR_TIMESPAN};
- for (grpc_json *field = json->child; field != NULL; field = field->next) {
- if (field->key == NULL) continue;
- if (strcmp(field->key, "waitForReady") == 0) {
- if (wait_for_ready != WAIT_FOR_READY_UNSET) return NULL; // Duplicate.
- if (!parse_wait_for_ready(field, &wait_for_ready)) return NULL;
- } else if (strcmp(field->key, "timeout") == 0) {
- if (timeout.tv_sec > 0 || timeout.tv_nsec > 0) return NULL; // Duplicate.
- if (!parse_timeout(field, &timeout)) return NULL;
- }
- }
- method_parameters *value = gpr_malloc(sizeof(method_parameters));
- gpr_ref_init(&value->refs, 1);
- value->timeout = timeout;
- value->wait_for_ready = wait_for_ready;
- return value;
-}
-
-/*************************************************************************
- * CHANNEL-WIDE FUNCTIONS
- */
-
-typedef struct client_channel_channel_data {
- /** resolver for this channel */
- grpc_resolver *resolver;
- /** have we started resolving this channel */
- bool started_resolving;
- /** client channel factory */
- grpc_client_channel_factory *client_channel_factory;
-
- /** combiner protecting all variables below in this data structure */
- grpc_combiner *combiner;
- /** currently active load balancer */
- grpc_lb_policy *lb_policy;
- /** retry throttle data */
- grpc_server_retry_throttle_data *retry_throttle_data;
- /** maps method names to method_parameters structs */
- grpc_slice_hash_table *method_params_table;
- /** incoming resolver result - set by resolver.next() */
- grpc_channel_args *resolver_result;
- /** 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_resolver_result_changed;
- /** connectivity state being tracked */
- grpc_connectivity_state_tracker state_tracker;
- /** when an lb_policy arrives, should we try to exit idle */
- bool exit_idle_when_lb_policy_arrives;
- /** owning stack */
- grpc_channel_stack *owning_stack;
- /** interested parties (owned) */
- grpc_pollset_set *interested_parties;
-
- /* the following properties are guarded by a mutex since API's require them
- to be instantaneously available */
- gpr_mu info_mu;
- char *info_lb_policy_name;
- /** service config in JSON form */
- char *info_service_config_json;
-} 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;
-
-static void watch_lb_policy_locked(grpc_exec_ctx *exec_ctx, channel_data *chand,
- grpc_lb_policy *lb_policy,
- grpc_connectivity_state current_state);
-
-static void set_channel_connectivity_state_locked(grpc_exec_ctx *exec_ctx,
- channel_data *chand,
- grpc_connectivity_state state,
- grpc_error *error,
- const char *reason) {
- if ((state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
- state == GRPC_CHANNEL_SHUTDOWN) &&
- chand->lb_policy != NULL) {
- /* cancel picks with wait_for_ready=false */
- grpc_lb_policy_cancel_picks_locked(
- exec_ctx, chand->lb_policy,
- /* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY,
- /* check= */ 0, GRPC_ERROR_REF(error));
- }
- grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, state, error,
- reason);
-}
-
-static void on_lb_policy_state_changed_locked(grpc_exec_ctx *exec_ctx,
- void *arg, grpc_error *error) {
- lb_policy_connectivity_watcher *w = arg;
- grpc_connectivity_state publish_state = w->state;
- /* check if the notification is for the latest policy */
- if (w->lb_policy == w->chand->lb_policy) {
- if (publish_state == GRPC_CHANNEL_SHUTDOWN && w->chand->resolver != NULL) {
- publish_state = GRPC_CHANNEL_TRANSIENT_FAILURE;
- grpc_resolver_channel_saw_error_locked(exec_ctx, w->chand->resolver);
- GRPC_LB_POLICY_UNREF(exec_ctx, w->chand->lb_policy, "channel");
- w->chand->lb_policy = NULL;
- }
- set_channel_connectivity_state_locked(exec_ctx, w->chand, publish_state,
- GRPC_ERROR_REF(error), "lb_changed");
- if (w->state != GRPC_CHANNEL_SHUTDOWN) {
- watch_lb_policy_locked(exec_ctx, w->chand, w->lb_policy, w->state);
- }
- }
-
- GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack, "watch_lb_policy");
- gpr_free(w);
-}
-
-static void watch_lb_policy_locked(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_locked, w,
- grpc_combiner_scheduler(chand->combiner, false));
- w->state = current_state;
- w->lb_policy = lb_policy;
- grpc_lb_policy_notify_on_state_change_locked(exec_ctx, lb_policy, &w->state,
- &w->on_changed);
-}
-
-typedef struct {
- char *server_name;
- grpc_server_retry_throttle_data *retry_throttle_data;
-} service_config_parsing_state;
-
-static void parse_retry_throttle_params(const grpc_json *field, void *arg) {
- service_config_parsing_state *parsing_state = arg;
- if (strcmp(field->key, "retryThrottling") == 0) {
- if (parsing_state->retry_throttle_data != NULL) return; // Duplicate.
- if (field->type != GRPC_JSON_OBJECT) return;
- int max_milli_tokens = 0;
- int milli_token_ratio = 0;
- for (grpc_json *sub_field = field->child; sub_field != NULL;
- sub_field = sub_field->next) {
- if (sub_field->key == NULL) return;
- if (strcmp(sub_field->key, "maxTokens") == 0) {
- if (max_milli_tokens != 0) return; // Duplicate.
- if (sub_field->type != GRPC_JSON_NUMBER) return;
- max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value);
- if (max_milli_tokens == -1) return;
- max_milli_tokens *= 1000;
- } else if (strcmp(sub_field->key, "tokenRatio") == 0) {
- if (milli_token_ratio != 0) return; // Duplicate.
- if (sub_field->type != GRPC_JSON_NUMBER) return;
- // We support up to 3 decimal digits.
- size_t whole_len = strlen(sub_field->value);
- uint32_t multiplier = 1;
- uint32_t decimal_value = 0;
- const char *decimal_point = strchr(sub_field->value, '.');
- if (decimal_point != NULL) {
- whole_len = (size_t)(decimal_point - sub_field->value);
- multiplier = 1000;
- size_t decimal_len = strlen(decimal_point + 1);
- if (decimal_len > 3) decimal_len = 3;
- if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
- &decimal_value)) {
- return;
- }
- uint32_t decimal_multiplier = 1;
- for (size_t i = 0; i < (3 - decimal_len); ++i) {
- decimal_multiplier *= 10;
- }
- decimal_value *= decimal_multiplier;
- }
- uint32_t whole_value;
- if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
- &whole_value)) {
- return;
- }
- milli_token_ratio = (int)((whole_value * multiplier) + decimal_value);
- if (milli_token_ratio <= 0) return;
- }
- }
- parsing_state->retry_throttle_data =
- grpc_retry_throttle_map_get_data_for_server(
- parsing_state->server_name, max_milli_tokens, milli_token_ratio);
- }
-}
-
-static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
- void *arg, grpc_error *error) {
- channel_data *chand = arg;
- char *lb_policy_name = NULL;
- grpc_lb_policy *lb_policy = NULL;
- grpc_lb_policy *old_lb_policy;
- grpc_slice_hash_table *method_params_table = NULL;
- grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE;
- bool exit_idle = false;
- grpc_error *state_error =
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy");
- char *service_config_json = NULL;
- service_config_parsing_state parsing_state;
- memset(&parsing_state, 0, sizeof(parsing_state));
-
- if (chand->resolver_result != NULL) {
- // Find LB policy name.
- const grpc_arg *channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_POLICY_NAME);
- if (channel_arg != NULL) {
- GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
- lb_policy_name = channel_arg->value.string;
- }
- // Special case: If all of the addresses are balancer addresses,
- // assume that we should use the grpclb policy, regardless of what the
- // resolver actually specified.
- channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES);
- if (channel_arg != NULL) {
- GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER);
- grpc_lb_addresses *addresses = channel_arg->value.pointer.p;
- bool found_backend_address = false;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (!addresses->addresses[i].is_balancer) {
- found_backend_address = true;
- break;
- }
- }
- if (!found_backend_address) {
- if (lb_policy_name != NULL && strcmp(lb_policy_name, "grpclb") != 0) {
- gpr_log(GPR_INFO,
- "resolver requested LB policy %s but provided only balancer "
- "addresses, no backend addresses -- forcing use of grpclb LB "
- "policy",
- lb_policy_name);
- }
- lb_policy_name = "grpclb";
- }
- }
- // Use pick_first if nothing was specified and we didn't select grpclb
- // above.
- if (lb_policy_name == NULL) lb_policy_name = "pick_first";
- // Instantiate LB policy.
- grpc_lb_policy_args lb_policy_args;
- lb_policy_args.args = chand->resolver_result;
- lb_policy_args.client_channel_factory = chand->client_channel_factory;
- lb_policy_args.combiner = chand->combiner;
- lb_policy =
- grpc_lb_policy_create(exec_ctx, lb_policy_name, &lb_policy_args);
- if (lb_policy != NULL) {
- GRPC_LB_POLICY_REF(lb_policy, "config_change");
- GRPC_ERROR_UNREF(state_error);
- state = grpc_lb_policy_check_connectivity_locked(exec_ctx, lb_policy,
- &state_error);
- }
- // Find service config.
- channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_SERVICE_CONFIG);
- if (channel_arg != NULL) {
- GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
- service_config_json = gpr_strdup(channel_arg->value.string);
- grpc_service_config *service_config =
- grpc_service_config_create(service_config_json);
- if (service_config != NULL) {
- channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_SERVER_URI);
- GPR_ASSERT(channel_arg != NULL);
- GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
- grpc_uri *uri =
- grpc_uri_parse(exec_ctx, channel_arg->value.string, true);
- GPR_ASSERT(uri->path[0] != '\0');
- parsing_state.server_name =
- uri->path[0] == '/' ? uri->path + 1 : uri->path;
- grpc_service_config_parse_global_params(
- service_config, parse_retry_throttle_params, &parsing_state);
- parsing_state.server_name = NULL;
- grpc_uri_destroy(uri);
- method_params_table = grpc_service_config_create_method_config_table(
- exec_ctx, service_config, method_parameters_create_from_json,
- &method_parameters_vtable);
- grpc_service_config_destroy(service_config);
- }
- }
- // Before we clean up, save a copy of lb_policy_name, since it might
- // be pointing to data inside chand->resolver_result.
- // The copy will be saved in chand->lb_policy_name below.
- lb_policy_name = gpr_strdup(lb_policy_name);
- grpc_channel_args_destroy(exec_ctx, chand->resolver_result);
- chand->resolver_result = NULL;
- }
-
- if (lb_policy != NULL) {
- grpc_pollset_set_add_pollset_set(exec_ctx, lb_policy->interested_parties,
- chand->interested_parties);
- }
-
- gpr_mu_lock(&chand->info_mu);
- if (lb_policy_name != NULL) {
- gpr_free(chand->info_lb_policy_name);
- chand->info_lb_policy_name = lb_policy_name;
- }
- old_lb_policy = chand->lb_policy;
- chand->lb_policy = lb_policy;
- if (service_config_json != NULL) {
- gpr_free(chand->info_service_config_json);
- chand->info_service_config_json = service_config_json;
- }
- gpr_mu_unlock(&chand->info_mu);
-
- if (chand->retry_throttle_data != NULL) {
- grpc_server_retry_throttle_data_unref(chand->retry_throttle_data);
- }
- chand->retry_throttle_data = parsing_state.retry_throttle_data;
- if (chand->method_params_table != NULL) {
- grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table);
- }
- chand->method_params_table = method_params_table;
- if (lb_policy != NULL) {
- grpc_closure_list_sched(exec_ctx, &chand->waiting_for_config_closures);
- } else if (chand->resolver == NULL /* disconnected */) {
- grpc_closure_list_fail_all(&chand->waiting_for_config_closures,
- GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Channel disconnected", &error, 1));
- grpc_closure_list_sched(exec_ctx, &chand->waiting_for_config_closures);
- }
- if (lb_policy != NULL && chand->exit_idle_when_lb_policy_arrives) {
- GRPC_LB_POLICY_REF(lb_policy, "exit_idle");
- exit_idle = true;
- chand->exit_idle_when_lb_policy_arrives = false;
- }
-
- if (error == GRPC_ERROR_NONE && chand->resolver) {
- set_channel_connectivity_state_locked(
- exec_ctx, chand, state, GRPC_ERROR_REF(state_error), "new_lb+resolver");
- if (lb_policy != NULL) {
- watch_lb_policy_locked(exec_ctx, chand, lb_policy, state);
- }
- GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
- grpc_resolver_next_locked(exec_ctx, chand->resolver,
- &chand->resolver_result,
- &chand->on_resolver_result_changed);
- } else {
- if (chand->resolver != NULL) {
- grpc_resolver_shutdown_locked(exec_ctx, chand->resolver);
- GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel");
- chand->resolver = NULL;
- }
- grpc_error *refs[] = {error, state_error};
- set_channel_connectivity_state_locked(
- exec_ctx, chand, GRPC_CHANNEL_SHUTDOWN,
- GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Got config after disconnection", refs, GPR_ARRAY_SIZE(refs)),
- "resolver_gone");
- }
-
- if (exit_idle) {
- grpc_lb_policy_exit_idle_locked(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");
- GRPC_ERROR_UNREF(state_error);
-}
-
-static void start_transport_op_locked(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error_ignored) {
- grpc_transport_op *op = arg;
- grpc_channel_element *elem = op->transport_private.args[0];
- channel_data *chand = elem->channel_data;
-
- 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_closure_sched(
- exec_ctx, op->send_ping,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"));
- } else {
- grpc_lb_policy_ping_one_locked(exec_ctx, chand->lb_policy, op->send_ping);
- op->bind_pollset = NULL;
- }
- op->send_ping = NULL;
- }
-
- if (op->disconnect_with_error != GRPC_ERROR_NONE) {
- if (chand->resolver != NULL) {
- set_channel_connectivity_state_locked(
- exec_ctx, chand, GRPC_CHANNEL_SHUTDOWN,
- GRPC_ERROR_REF(op->disconnect_with_error), "disconnect");
- grpc_resolver_shutdown_locked(exec_ctx, chand->resolver);
- GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel");
- chand->resolver = NULL;
- if (!chand->started_resolving) {
- grpc_closure_list_fail_all(&chand->waiting_for_config_closures,
- GRPC_ERROR_REF(op->disconnect_with_error));
- grpc_closure_list_sched(exec_ctx, &chand->waiting_for_config_closures);
- }
- 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;
- }
- }
- GRPC_ERROR_UNREF(op->disconnect_with_error);
- }
- GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->owning_stack, "start_transport_op");
-
- grpc_closure_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE);
-}
-
-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;
-
- 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);
- }
-
- op->transport_private.args[0] = elem;
- GRPC_CHANNEL_STACK_REF(chand->owning_stack, "start_transport_op");
- grpc_closure_sched(
- exec_ctx, grpc_closure_init(
- &op->transport_private.closure, start_transport_op_locked,
- op, grpc_combiner_scheduler(chand->combiner, false)),
- GRPC_ERROR_NONE);
-}
-
-static void cc_get_channel_info(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- const grpc_channel_info *info) {
- channel_data *chand = elem->channel_data;
- gpr_mu_lock(&chand->info_mu);
- if (info->lb_policy_name != NULL) {
- *info->lb_policy_name = chand->info_lb_policy_name == NULL
- ? NULL
- : gpr_strdup(chand->info_lb_policy_name);
- }
- if (info->service_config_json != NULL) {
- *info->service_config_json =
- chand->info_service_config_json == NULL
- ? NULL
- : gpr_strdup(chand->info_service_config_json);
- }
- gpr_mu_unlock(&chand->info_mu);
-}
-
-/* Constructor for channel_data */
-static grpc_error *cc_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);
- GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
- // Initialize data members.
- chand->combiner = grpc_combiner_create(NULL);
- gpr_mu_init(&chand->info_mu);
- chand->owning_stack = args->channel_stack;
- grpc_closure_init(&chand->on_resolver_result_changed,
- on_resolver_result_changed_locked, chand,
- grpc_combiner_scheduler(chand->combiner, false));
- chand->interested_parties = grpc_pollset_set_create();
- grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
- "client_channel");
- // Record client channel factory.
- const grpc_arg *arg = grpc_channel_args_find(args->channel_args,
- GRPC_ARG_CLIENT_CHANNEL_FACTORY);
- GPR_ASSERT(arg != NULL);
- GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
- grpc_client_channel_factory_ref(arg->value.pointer.p);
- chand->client_channel_factory = arg->value.pointer.p;
- // Get server name to resolve, using proxy mapper if needed.
- arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI);
- GPR_ASSERT(arg != NULL);
- GPR_ASSERT(arg->type == GRPC_ARG_STRING);
- char *proxy_name = NULL;
- grpc_channel_args *new_args = NULL;
- grpc_proxy_mappers_map_name(exec_ctx, arg->value.string, args->channel_args,
- &proxy_name, &new_args);
- // Instantiate resolver.
- chand->resolver = grpc_resolver_create(
- exec_ctx, proxy_name != NULL ? proxy_name : arg->value.string,
- new_args != NULL ? new_args : args->channel_args,
- chand->interested_parties, chand->combiner);
- if (proxy_name != NULL) gpr_free(proxy_name);
- if (new_args != NULL) grpc_channel_args_destroy(exec_ctx, new_args);
- if (chand->resolver == NULL) {
- return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed");
- }
- return GRPC_ERROR_NONE;
-}
-
-static void shutdown_resolver_locked(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error) {
- grpc_resolver *resolver = arg;
- grpc_resolver_shutdown_locked(exec_ctx, resolver);
- GRPC_RESOLVER_UNREF(exec_ctx, resolver, "channel");
-}
-
-/* Destructor for channel_data */
-static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem) {
- channel_data *chand = elem->channel_data;
- if (chand->resolver != NULL) {
- grpc_closure_sched(
- exec_ctx,
- grpc_closure_create(shutdown_resolver_locked, chand->resolver,
- grpc_combiner_scheduler(chand->combiner, false)),
- GRPC_ERROR_NONE);
- }
- if (chand->client_channel_factory != NULL) {
- grpc_client_channel_factory_unref(exec_ctx, chand->client_channel_factory);
- }
- 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");
- }
- gpr_free(chand->info_lb_policy_name);
- gpr_free(chand->info_service_config_json);
- if (chand->retry_throttle_data != NULL) {
- grpc_server_retry_throttle_data_unref(chand->retry_throttle_data);
- }
- if (chand->method_params_table != NULL) {
- grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table);
- }
- grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker);
- grpc_pollset_set_destroy(exec_ctx, chand->interested_parties);
- GRPC_COMBINER_UNREF(exec_ctx, chand->combiner, "client_channel");
- gpr_mu_destroy(&chand->info_mu);
-}
-
-/*************************************************************************
- * PER-CALL FUNCTIONS
- */
-
-#define GET_CALL(call_data) \
- ((grpc_subchannel_call *)(gpr_atm_acq_load(&(call_data)->subchannel_call)))
-
-#define CANCELLED_CALL ((grpc_subchannel_call *)1)
-
-typedef enum {
- /* zero so that it can be default-initialized */
- GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING = 0,
- GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL
-} subchannel_creation_phase;
-
-/** Call data. Holds 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. */
-typedef struct client_channel_call_data {
- // State for handling deadlines.
- // The code in deadline_filter.c requires this to be the first field.
- // TODO(roth): This is slightly sub-optimal in that grpc_deadline_state
- // and this struct both independently store a pointer to the call
- // stack and each has its own mutex. If/when we have time, find a way
- // to avoid this without breaking the grpc_deadline_state abstraction.
- grpc_deadline_state deadline_state;
-
- grpc_slice path; // Request path.
- gpr_timespec call_start_time;
- gpr_timespec deadline;
- grpc_server_retry_throttle_data *retry_throttle_data;
- method_parameters *method_params;
-
- grpc_error *cancel_error;
-
- /** either 0 for no call, 1 for cancelled, or a pointer to a
- grpc_subchannel_call */
- gpr_atm subchannel_call;
- gpr_arena *arena;
-
- subchannel_creation_phase creation_phase;
- grpc_connected_subchannel *connected_subchannel;
- grpc_polling_entity *pollent;
-
- 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_linked_mdelem lb_token_mdelem;
-
- grpc_closure on_complete;
- grpc_closure *original_on_complete;
-} call_data;
-
-grpc_subchannel_call *grpc_client_channel_get_subchannel_call(
- grpc_call_element *call_elem) {
- grpc_subchannel_call *scc = GET_CALL((call_data *)call_elem->call_data);
- return scc == CANCELLED_CALL ? NULL : scc;
-}
-
-static void add_waiting_locked(call_data *calld, grpc_transport_stream_op *op) {
- GPR_TIMER_BEGIN("add_waiting_locked", 0);
- if (calld->waiting_ops_count == calld->waiting_ops_capacity) {
- calld->waiting_ops_capacity = GPR_MAX(3, 2 * calld->waiting_ops_capacity);
- calld->waiting_ops =
- gpr_realloc(calld->waiting_ops,
- calld->waiting_ops_capacity * sizeof(*calld->waiting_ops));
- }
- calld->waiting_ops[calld->waiting_ops_count++] = op;
- GPR_TIMER_END("add_waiting_locked", 0);
-}
-
-static void fail_locked(grpc_exec_ctx *exec_ctx, call_data *calld,
- grpc_error *error) {
- size_t i;
- for (i = 0; i < calld->waiting_ops_count; i++) {
- grpc_transport_stream_op_finish_with_failure(
- exec_ctx, calld->waiting_ops[i], GRPC_ERROR_REF(error));
- }
- calld->waiting_ops_count = 0;
- GRPC_ERROR_UNREF(error);
-}
-
-static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) {
- if (calld->waiting_ops_count == 0) {
- return;
- }
-
- grpc_subchannel_call *call = GET_CALL(calld);
- grpc_transport_stream_op **ops = calld->waiting_ops;
- size_t nops = calld->waiting_ops_count;
- if (call == CANCELLED_CALL) {
- fail_locked(exec_ctx, calld, GRPC_ERROR_CANCELLED);
- return;
- }
- calld->waiting_ops = NULL;
- calld->waiting_ops_count = 0;
- calld->waiting_ops_capacity = 0;
- for (size_t i = 0; i < nops; i++) {
- grpc_subchannel_call_process_op(exec_ctx, call, ops[i]);
- }
- gpr_free(ops);
-}
-
-// Sets calld->method_params and calld->retry_throttle_data.
-// If the method params specify a timeout, populates
-// *per_method_deadline and returns true.
-static bool set_call_method_params_from_service_config_locked(
- grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
- gpr_timespec *per_method_deadline) {
- channel_data *chand = elem->channel_data;
- call_data *calld = elem->call_data;
- if (chand->retry_throttle_data != NULL) {
- calld->retry_throttle_data =
- grpc_server_retry_throttle_data_ref(chand->retry_throttle_data);
- }
- if (chand->method_params_table != NULL) {
- calld->method_params = grpc_method_config_table_get(
- exec_ctx, chand->method_params_table, calld->path);
- if (calld->method_params != NULL) {
- method_parameters_ref(calld->method_params);
- if (gpr_time_cmp(calld->method_params->timeout,
- gpr_time_0(GPR_TIMESPAN)) != 0) {
- *per_method_deadline =
- gpr_time_add(calld->call_start_time, calld->method_params->timeout);
- return true;
- }
- }
- }
- return false;
-}
-
-static void apply_final_configuration_locked(grpc_exec_ctx *exec_ctx,
- grpc_call_element *elem) {
- /* apply service-config level configuration to the call (now that we're
- * certain it exists) */
- call_data *calld = elem->call_data;
- gpr_timespec per_method_deadline;
- if (set_call_method_params_from_service_config_locked(exec_ctx, elem,
- &per_method_deadline)) {
- // If the deadline from the service config is shorter than the one
- // from the client API, reset the deadline timer.
- if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) {
- calld->deadline = per_method_deadline;
- grpc_deadline_state_reset(exec_ctx, elem, calld->deadline);
- }
- }
-}
-
-static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error) {
- grpc_call_element *elem = arg;
- call_data *calld = elem->call_data;
- channel_data *chand = elem->channel_data;
- GPR_ASSERT(calld->creation_phase ==
- GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL);
- grpc_polling_entity_del_from_pollset_set(exec_ctx, calld->pollent,
- chand->interested_parties);
- calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
- if (calld->connected_subchannel == NULL) {
- gpr_atm_no_barrier_store(&calld->subchannel_call, 1);
- fail_locked(exec_ctx, calld,
- GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Failed to create subchannel", &error, 1));
- } else if (GET_CALL(calld) == CANCELLED_CALL) {
- /* already cancelled before subchannel became ready */
- grpc_error *cancellation_error =
- GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Cancelled before creating subchannel", &error, 1);
- /* if due to deadline, attach the deadline exceeded status to the error */
- if (gpr_time_cmp(calld->deadline, gpr_now(GPR_CLOCK_MONOTONIC)) < 0) {
- cancellation_error =
- grpc_error_set_int(cancellation_error, GRPC_ERROR_INT_GRPC_STATUS,
- GRPC_STATUS_DEADLINE_EXCEEDED);
- }
- fail_locked(exec_ctx, calld, cancellation_error);
- } else {
- /* Create call on subchannel. */
- grpc_subchannel_call *subchannel_call = NULL;
- const grpc_connected_subchannel_call_args call_args = {
- .pollent = calld->pollent,
- .path = calld->path,
- .start_time = calld->call_start_time,
- .deadline = calld->deadline,
- .arena = calld->arena};
- grpc_error *new_error = grpc_connected_subchannel_create_call(
- exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call);
- if (new_error != GRPC_ERROR_NONE) {
- new_error = grpc_error_add_child(new_error, error);
- subchannel_call = CANCELLED_CALL;
- fail_locked(exec_ctx, calld, new_error);
- }
- gpr_atm_rel_store(&calld->subchannel_call,
- (gpr_atm)(uintptr_t)subchannel_call);
- retry_waiting_locked(exec_ctx, calld);
- }
- GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
-}
-
-static char *cc_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
- call_data *calld = elem->call_data;
- grpc_subchannel_call *subchannel_call = GET_CALL(calld);
- if (subchannel_call == NULL || subchannel_call == CANCELLED_CALL) {
- return NULL;
- } else {
- return grpc_subchannel_call_get_peer(exec_ctx, subchannel_call);
- }
-}
-
-typedef struct {
- grpc_metadata_batch *initial_metadata;
- uint32_t initial_metadata_flags;
- grpc_connected_subchannel **connected_subchannel;
- grpc_closure *on_ready;
- grpc_call_element *elem;
- grpc_closure closure;
-} continue_picking_args;
-
-/** Return true if subchannel is available immediately (in which case on_ready
- should not be called), or false otherwise (in which case on_ready should be
- called when the subchannel is available). */
-static bool pick_subchannel_locked(
- grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
- grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags,
- grpc_connected_subchannel **connected_subchannel, grpc_closure *on_ready,
- grpc_error *error);
-
-static void continue_picking_locked(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error) {
- continue_picking_args *cpa = arg;
- if (cpa->connected_subchannel == NULL) {
- /* cancelled, do nothing */
- } else if (error != GRPC_ERROR_NONE) {
- grpc_closure_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_REF(error));
- } else {
- if (pick_subchannel_locked(exec_ctx, cpa->elem, cpa->initial_metadata,
- cpa->initial_metadata_flags,
- cpa->connected_subchannel, cpa->on_ready,
- GRPC_ERROR_NONE)) {
- grpc_closure_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_NONE);
- }
- }
- gpr_free(cpa);
-}
-
-static bool pick_subchannel_locked(
- grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
- grpc_metadata_batch *initial_metadata, uint32_t initial_metadata_flags,
- grpc_connected_subchannel **connected_subchannel, grpc_closure *on_ready,
- grpc_error *error) {
- GPR_TIMER_BEGIN("pick_subchannel", 0);
-
- channel_data *chand = elem->channel_data;
- call_data *calld = elem->call_data;
- continue_picking_args *cpa;
- grpc_closure *closure;
-
- GPR_ASSERT(connected_subchannel);
-
- if (initial_metadata == NULL) {
- if (chand->lb_policy != NULL) {
- grpc_lb_policy_cancel_pick_locked(exec_ctx, chand->lb_policy,
- connected_subchannel,
- GRPC_ERROR_REF(error));
- }
- for (closure = chand->waiting_for_config_closures.head; closure != NULL;
- closure = closure->next_data.next) {
- cpa = closure->cb_arg;
- if (cpa->connected_subchannel == connected_subchannel) {
- cpa->connected_subchannel = NULL;
- grpc_closure_sched(exec_ctx, cpa->on_ready,
- GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Pick cancelled", &error, 1));
- }
- }
- GPR_TIMER_END("pick_subchannel", 0);
- GRPC_ERROR_UNREF(error);
- return true;
- }
- GPR_ASSERT(error == GRPC_ERROR_NONE);
- if (chand->lb_policy != NULL) {
- apply_final_configuration_locked(exec_ctx, elem);
- grpc_lb_policy *lb_policy = chand->lb_policy;
- GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel");
- // If the application explicitly set wait_for_ready, use that.
- // Otherwise, if the service config specified a value for this
- // method, use that.
- const bool wait_for_ready_set_from_api =
- initial_metadata_flags &
- GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET;
- const bool wait_for_ready_set_from_service_config =
- calld->method_params != NULL &&
- calld->method_params->wait_for_ready != WAIT_FOR_READY_UNSET;
- if (!wait_for_ready_set_from_api &&
- wait_for_ready_set_from_service_config) {
- if (calld->method_params->wait_for_ready == WAIT_FOR_READY_TRUE) {
- initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY;
- } else {
- initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY;
- }
- }
- const grpc_lb_policy_pick_args inputs = {
- initial_metadata, initial_metadata_flags, &calld->lb_token_mdelem,
- gpr_inf_future(GPR_CLOCK_MONOTONIC)};
- const bool result = grpc_lb_policy_pick_locked(
- exec_ctx, lb_policy, &inputs, connected_subchannel, NULL, on_ready);
- GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "pick_subchannel");
- GPR_TIMER_END("pick_subchannel", 0);
- return result;
- }
- if (chand->resolver != NULL && !chand->started_resolving) {
- chand->started_resolving = true;
- GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
- grpc_resolver_next_locked(exec_ctx, chand->resolver,
- &chand->resolver_result,
- &chand->on_resolver_result_changed);
- }
- if (chand->resolver != NULL) {
- cpa = gpr_malloc(sizeof(*cpa));
- cpa->initial_metadata = initial_metadata;
- cpa->initial_metadata_flags = initial_metadata_flags;
- cpa->connected_subchannel = connected_subchannel;
- cpa->on_ready = on_ready;
- cpa->elem = elem;
- grpc_closure_init(&cpa->closure, continue_picking_locked, cpa,
- grpc_combiner_scheduler(chand->combiner, true));
- grpc_closure_list_append(&chand->waiting_for_config_closures, &cpa->closure,
- GRPC_ERROR_NONE);
- } else {
- grpc_closure_sched(exec_ctx, on_ready,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected"));
- }
-
- GPR_TIMER_END("pick_subchannel", 0);
- return false;
-}
-
-static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
- grpc_transport_stream_op *op,
- grpc_call_element *elem) {
- channel_data *chand = elem->channel_data;
- call_data *calld = elem->call_data;
- grpc_subchannel_call *call;
-
- /* need to recheck that another thread hasn't set the call */
- call = GET_CALL(calld);
- if (call == CANCELLED_CALL) {
- grpc_transport_stream_op_finish_with_failure(
- exec_ctx, op, GRPC_ERROR_REF(calld->cancel_error));
- /* early out */
- return;
- }
- if (call != NULL) {
- grpc_subchannel_call_process_op(exec_ctx, call, op);
- /* early out */
- return;
- }
- /* if this is a cancellation, then we can raise our cancelled flag */
- if (op->cancel_error != GRPC_ERROR_NONE) {
- if (!gpr_atm_rel_cas(&calld->subchannel_call, 0,
- (gpr_atm)(uintptr_t)CANCELLED_CALL)) {
- /* recurse to retry */
- start_transport_stream_op_locked_inner(exec_ctx, op, elem);
- /* early out */
- return;
- } else {
- /* Stash a copy of cancel_error in our call data, so that we can use
- it for subsequent operations. This ensures that if the call is
- cancelled before any ops are passed down (e.g., if the deadline
- is in the past when the call starts), we can return the right
- error to the caller when the first op does get passed down. */
- calld->cancel_error = GRPC_ERROR_REF(op->cancel_error);
- switch (calld->creation_phase) {
- case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING:
- fail_locked(exec_ctx, calld, GRPC_ERROR_REF(op->cancel_error));
- break;
- case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL:
- pick_subchannel_locked(exec_ctx, elem, NULL, 0,
- &calld->connected_subchannel, NULL,
- GRPC_ERROR_REF(op->cancel_error));
- break;
- }
- grpc_transport_stream_op_finish_with_failure(
- exec_ctx, op, GRPC_ERROR_REF(op->cancel_error));
- /* early out */
- return;
- }
- }
- /* if we don't have a subchannel, try to get one */
- if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
- calld->connected_subchannel == NULL &&
- op->send_initial_metadata != NULL) {
- calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL;
- grpc_closure_init(&calld->next_step, subchannel_ready_locked, elem,
- grpc_combiner_scheduler(chand->combiner, true));
- GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel");
- /* If a subchannel is not available immediately, the polling entity from
- call_data should be provided to channel_data's interested_parties, so
- that IO of the lb_policy and resolver could be done under it. */
- if (pick_subchannel_locked(exec_ctx, elem, op->send_initial_metadata,
- op->send_initial_metadata_flags,
- &calld->connected_subchannel, &calld->next_step,
- GRPC_ERROR_NONE)) {
- calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
- GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
- } else {
- grpc_polling_entity_add_to_pollset_set(exec_ctx, calld->pollent,
- chand->interested_parties);
- }
- }
- /* if we've got a subchannel, then let's ask it to create a call */
- if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
- calld->connected_subchannel != NULL) {
- grpc_subchannel_call *subchannel_call = NULL;
- const grpc_connected_subchannel_call_args call_args = {
- .pollent = calld->pollent,
- .path = calld->path,
- .start_time = calld->call_start_time,
- .deadline = calld->deadline,
- .arena = calld->arena};
- grpc_error *error = grpc_connected_subchannel_create_call(
- exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call);
- if (error != GRPC_ERROR_NONE) {
- subchannel_call = CANCELLED_CALL;
- fail_locked(exec_ctx, calld, GRPC_ERROR_REF(error));
- grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
- }
- gpr_atm_rel_store(&calld->subchannel_call,
- (gpr_atm)(uintptr_t)subchannel_call);
- retry_waiting_locked(exec_ctx, calld);
- /* recurse to retry */
- start_transport_stream_op_locked_inner(exec_ctx, op, elem);
- /* early out */
- return;
- }
- /* nothing to be done but wait */
- add_waiting_locked(calld, op);
-}
-
-static void on_complete(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
- grpc_call_element *elem = arg;
- call_data *calld = elem->call_data;
- if (calld->retry_throttle_data != NULL) {
- if (error == GRPC_ERROR_NONE) {
- grpc_server_retry_throttle_data_record_success(
- calld->retry_throttle_data);
- } else {
- // TODO(roth): In a subsequent PR, check the return value here and
- // decide whether or not to retry. Note that we should only
- // record failures whose statuses match the configured retryable
- // or non-fatal status codes.
- grpc_server_retry_throttle_data_record_failure(
- calld->retry_throttle_data);
- }
- }
- grpc_closure_run(exec_ctx, calld->original_on_complete,
- GRPC_ERROR_REF(error));
-}
-
-static void start_transport_stream_op_locked(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error_ignored) {
- GPR_TIMER_BEGIN("start_transport_stream_op_locked", 0);
-
- grpc_transport_stream_op *op = arg;
- grpc_call_element *elem = op->handler_private.args[0];
- call_data *calld = elem->call_data;
-
- if (op->recv_trailing_metadata != NULL) {
- GPR_ASSERT(op->on_complete != NULL);
- calld->original_on_complete = op->on_complete;
- grpc_closure_init(&calld->on_complete, on_complete, elem,
- grpc_schedule_on_exec_ctx);
- op->on_complete = &calld->on_complete;
- }
-
- start_transport_stream_op_locked_inner(exec_ctx, op, elem);
-
- GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call,
- "start_transport_stream_op");
- GPR_TIMER_END("start_transport_stream_op_locked", 0);
-}
-
-/* The logic here is fairly complicated, due to (a) the fact that we
- need to handle the case where we receive the send op before the
- initial metadata op, and (b) the need for efficiency, especially in
- the streaming case.
-
- We use double-checked locking to initially see if initialization has been
- performed. If it has not, we acquire the combiner and perform initialization.
- If it has, we proceed on the fast path. */
-static void cc_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_deadline_state_client_start_transport_stream_op(exec_ctx, elem, op);
- /* try to (atomically) get the call */
- grpc_subchannel_call *call = GET_CALL(calld);
- GPR_TIMER_BEGIN("cc_start_transport_stream_op", 0);
- if (call == CANCELLED_CALL) {
- grpc_transport_stream_op_finish_with_failure(
- exec_ctx, op, GRPC_ERROR_REF(calld->cancel_error));
- GPR_TIMER_END("cc_start_transport_stream_op", 0);
- /* early out */
- return;
- }
- if (call != NULL) {
- grpc_subchannel_call_process_op(exec_ctx, call, op);
- GPR_TIMER_END("cc_start_transport_stream_op", 0);
- /* early out */
- return;
- }
- /* we failed; lock and figure out what to do */
- GRPC_CALL_STACK_REF(calld->owning_call, "start_transport_stream_op");
- op->handler_private.args[0] = elem;
- grpc_closure_sched(
- exec_ctx,
- grpc_closure_init(&op->handler_private.closure,
- start_transport_stream_op_locked, op,
- grpc_combiner_scheduler(chand->combiner, false)),
- GRPC_ERROR_NONE);
- GPR_TIMER_END("cc_start_transport_stream_op", 0);
-}
-
-/* Constructor for call_data */
-static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
- grpc_call_element *elem,
- const grpc_call_element_args *args) {
- call_data *calld = elem->call_data;
- // Initialize data members.
- grpc_deadline_state_init(exec_ctx, elem, args->call_stack);
- calld->path = grpc_slice_ref_internal(args->path);
- calld->call_start_time = args->start_time;
- calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC);
- calld->owning_call = args->call_stack;
- calld->arena = args->arena;
- grpc_deadline_state_start(exec_ctx, elem, calld->deadline);
- return GRPC_ERROR_NONE;
-}
-
-/* Destructor for call_data */
-static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
- grpc_call_element *elem,
- const grpc_call_final_info *final_info,
- grpc_closure *then_schedule_closure) {
- call_data *calld = elem->call_data;
- grpc_deadline_state_destroy(exec_ctx, elem);
- grpc_slice_unref_internal(exec_ctx, calld->path);
- if (calld->method_params != NULL) {
- method_parameters_unref(calld->method_params);
- }
- GRPC_ERROR_UNREF(calld->cancel_error);
- grpc_subchannel_call *call = GET_CALL(calld);
- if (call != NULL && call != CANCELLED_CALL) {
- grpc_subchannel_call_set_cleanup_closure(call, then_schedule_closure);
- then_schedule_closure = NULL;
- GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call");
- }
- GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING);
- GPR_ASSERT(calld->waiting_ops_count == 0);
- if (calld->connected_subchannel != NULL) {
- GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, calld->connected_subchannel,
- "picked");
- }
- gpr_free(calld->waiting_ops);
- grpc_closure_sched(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE);
-}
-
-static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
- grpc_call_element *elem,
- grpc_polling_entity *pollent) {
- call_data *calld = elem->call_data;
- calld->pollent = pollent;
-}
-
-/*************************************************************************
- * EXPORTED SYMBOLS
- */
-
-const grpc_channel_filter grpc_client_channel_filter = {
- cc_start_transport_stream_op,
- cc_start_transport_op,
- sizeof(call_data),
- cc_init_call_elem,
- cc_set_pollset_or_pollset_set,
- cc_destroy_call_elem,
- sizeof(channel_data),
- cc_init_channel_elem,
- cc_destroy_channel_elem,
- cc_get_peer,
- cc_get_channel_info,
- "client-channel",
-};
-
-static void try_to_connect_locked(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error_ignored) {
- channel_data *chand = arg;
- if (chand->lb_policy != NULL) {
- grpc_lb_policy_exit_idle_locked(exec_ctx, chand->lb_policy);
- } else {
- chand->exit_idle_when_lb_policy_arrives = true;
- if (!chand->started_resolving && chand->resolver != NULL) {
- GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
- chand->started_resolving = true;
- grpc_resolver_next_locked(exec_ctx, chand->resolver,
- &chand->resolver_result,
- &chand->on_resolver_result_changed);
- }
- }
- GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->owning_stack, "try_to_connect");
-}
-
-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 =
- grpc_connectivity_state_check(&chand->state_tracker);
- if (out == GRPC_CHANNEL_IDLE && try_to_connect) {
- GRPC_CHANNEL_STACK_REF(chand->owning_stack, "try_to_connect");
- grpc_closure_sched(
- exec_ctx,
- grpc_closure_create(try_to_connect_locked, chand,
- grpc_combiner_scheduler(chand->combiner, false)),
- GRPC_ERROR_NONE);
- }
- return out;
-}
-
-typedef struct {
- channel_data *chand;
- grpc_pollset *pollset;
- grpc_closure *on_complete;
- grpc_connectivity_state *state;
- grpc_closure my_closure;
-} external_connectivity_watcher;
-
-static void on_external_watch_complete(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error) {
- 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);
- grpc_closure_run(exec_ctx, follow_up, GRPC_ERROR_REF(error));
-}
-
-static void watch_connectivity_state_locked(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error_ignored) {
- external_connectivity_watcher *w = arg;
- grpc_closure_init(&w->my_closure, on_external_watch_complete, w,
- grpc_schedule_on_exec_ctx);
- grpc_connectivity_state_notify_on_state_change(
- exec_ctx, &w->chand->state_tracker, w->state, &w->my_closure);
-}
-
-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;
- w->state = state;
- grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, pollset);
- GRPC_CHANNEL_STACK_REF(w->chand->owning_stack,
- "external_connectivity_watcher");
- grpc_closure_sched(
- exec_ctx,
- grpc_closure_init(&w->my_closure, watch_connectivity_state_locked, w,
- grpc_combiner_scheduler(chand->combiner, true)),
- GRPC_ERROR_NONE);
-}
diff --git a/src/core/ext/client_channel/client_channel.h b/src/core/ext/client_channel/client_channel.h
deleted file mode 100644
index 5e6e64e58b..0000000000
--- a/src/core/ext/client_channel/client_channel.h
+++ /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.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_H
-
-#include "src/core/ext/client_channel/client_channel_factory.h"
-#include "src/core/ext/client_channel/resolver.h"
-#include "src/core/lib/channel/channel_stack.h"
-
-// Channel arg key for server URI string.
-#define GRPC_ARG_SERVER_URI "grpc.server_uri"
-
-/* 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;
-
-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);
-
-/* Debug helper: pull the subchannel call from a call stack element */
-grpc_subchannel_call *grpc_client_channel_get_subchannel_call(
- grpc_call_element *elem);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_H */
diff --git a/src/core/ext/client_channel/client_channel_factory.c b/src/core/ext/client_channel/client_channel_factory.c
deleted file mode 100644
index d2707a1556..0000000000
--- a/src/core/ext/client_channel/client_channel_factory.c
+++ /dev/null
@@ -1,87 +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/ext/client_channel/client_channel_factory.h"
-
-void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory) {
- factory->vtable->ref(factory);
-}
-
-void grpc_client_channel_factory_unref(grpc_exec_ctx* exec_ctx,
- grpc_client_channel_factory* factory) {
- factory->vtable->unref(exec_ctx, factory);
-}
-
-grpc_subchannel* grpc_client_channel_factory_create_subchannel(
- grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* factory,
- const grpc_subchannel_args* args) {
- return factory->vtable->create_subchannel(exec_ctx, factory, args);
-}
-
-grpc_channel* grpc_client_channel_factory_create_channel(
- grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* factory,
- const char* target, grpc_client_channel_type type,
- const grpc_channel_args* args) {
- return factory->vtable->create_client_channel(exec_ctx, factory, target, type,
- args);
-}
-
-static void* factory_arg_copy(void* factory) {
- grpc_client_channel_factory_ref(factory);
- return factory;
-}
-
-static void factory_arg_destroy(grpc_exec_ctx* exec_ctx, void* factory) {
- // TODO(roth): Remove local exec_ctx when
- // https://github.com/grpc/grpc/pull/8705 is merged.
- grpc_client_channel_factory_unref(exec_ctx, factory);
-}
-
-static int factory_arg_cmp(void* factory1, void* factory2) {
- if (factory1 < factory2) return -1;
- if (factory1 > factory2) return 1;
- return 0;
-}
-
-static const grpc_arg_pointer_vtable factory_arg_vtable = {
- factory_arg_copy, factory_arg_destroy, factory_arg_cmp};
-
-grpc_arg grpc_client_channel_factory_create_channel_arg(
- grpc_client_channel_factory* factory) {
- grpc_arg arg;
- arg.type = GRPC_ARG_POINTER;
- arg.key = GRPC_ARG_CLIENT_CHANNEL_FACTORY;
- arg.value.pointer.p = factory;
- arg.value.pointer.vtable = &factory_arg_vtable;
- return arg;
-}
diff --git a/src/core/ext/client_channel/client_channel_factory.h b/src/core/ext/client_channel/client_channel_factory.h
deleted file mode 100644
index bf2764b537..0000000000
--- a/src/core/ext/client_channel/client_channel_factory.h
+++ /dev/null
@@ -1,92 +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_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H
-
-#include <grpc/impl/codegen/grpc_types.h>
-
-#include "src/core/ext/client_channel/subchannel.h"
-#include "src/core/lib/channel/channel_stack.h"
-
-// Channel arg key for client channel factory.
-#define GRPC_ARG_CLIENT_CHANNEL_FACTORY "grpc.client_channel_factory"
-
-typedef struct grpc_client_channel_factory grpc_client_channel_factory;
-typedef struct grpc_client_channel_factory_vtable
- grpc_client_channel_factory_vtable;
-
-typedef enum {
- GRPC_CLIENT_CHANNEL_TYPE_REGULAR, /** for the user-level regular calls */
- GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, /** for communication with a load
- balancing service */
-} grpc_client_channel_type;
-
-/** Constructor for new configured channels.
- Creating decorators around this type is encouraged to adapt behavior. */
-struct grpc_client_channel_factory {
- const grpc_client_channel_factory_vtable *vtable;
-};
-
-struct grpc_client_channel_factory_vtable {
- void (*ref)(grpc_client_channel_factory *factory);
- void (*unref)(grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory);
- grpc_subchannel *(*create_subchannel)(grpc_exec_ctx *exec_ctx,
- grpc_client_channel_factory *factory,
- const grpc_subchannel_args *args);
- grpc_channel *(*create_client_channel)(grpc_exec_ctx *exec_ctx,
- grpc_client_channel_factory *factory,
- const char *target,
- grpc_client_channel_type type,
- const grpc_channel_args *args);
-};
-
-void grpc_client_channel_factory_ref(grpc_client_channel_factory *factory);
-void grpc_client_channel_factory_unref(grpc_exec_ctx *exec_ctx,
- grpc_client_channel_factory *factory);
-
-/** Create a new grpc_subchannel */
-grpc_subchannel *grpc_client_channel_factory_create_subchannel(
- grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory,
- const grpc_subchannel_args *args);
-
-/** Create a new grpc_channel */
-grpc_channel *grpc_client_channel_factory_create_channel(
- grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory,
- const char *target, grpc_client_channel_type type,
- const grpc_channel_args *args);
-
-grpc_arg grpc_client_channel_factory_create_channel_arg(
- grpc_client_channel_factory *factory);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H */
diff --git a/src/core/ext/client_channel/client_channel_plugin.c b/src/core/ext/client_channel/client_channel_plugin.c
deleted file mode 100644
index f51277d0b2..0000000000
--- a/src/core/ext/client_channel/client_channel_plugin.c
+++ /dev/null
@@ -1,104 +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 <limits.h>
-#include <stdbool.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/http_connect_handshaker.h"
-#include "src/core/ext/client_channel/http_proxy.h"
-#include "src/core/ext/client_channel/lb_policy_registry.h"
-#include "src/core/ext/client_channel/proxy_mapper_registry.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
-#include "src/core/ext/client_channel/retry_throttle.h"
-#include "src/core/ext/client_channel/subchannel_index.h"
-#include "src/core/lib/surface/channel_init.h"
-
-static bool append_filter(grpc_exec_ctx *exec_ctx,
- grpc_channel_stack_builder *builder, void *arg) {
- return grpc_channel_stack_builder_append_filter(
- builder, (const grpc_channel_filter *)arg, NULL, NULL);
-}
-
-static bool set_default_host_if_unset(grpc_exec_ctx *exec_ctx,
- grpc_channel_stack_builder *builder,
- void *unused) {
- const grpc_channel_args *args =
- grpc_channel_stack_builder_get_channel_arguments(builder);
- for (size_t i = 0; i < args->num_args; i++) {
- if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY) ||
- 0 == strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
- return true;
- }
- }
- char *default_authority = grpc_get_default_authority(
- exec_ctx, grpc_channel_stack_builder_get_target(builder));
- if (default_authority != NULL) {
- grpc_arg arg;
- arg.type = GRPC_ARG_STRING;
- arg.key = GRPC_ARG_DEFAULT_AUTHORITY;
- arg.value.string = default_authority;
- grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
- grpc_channel_stack_builder_set_channel_arguments(exec_ctx, builder,
- new_args);
- gpr_free(default_authority);
- grpc_channel_args_destroy(exec_ctx, new_args);
- }
- return true;
-}
-
-void grpc_client_channel_init(void) {
- grpc_lb_policy_registry_init();
- grpc_resolver_registry_init();
- grpc_retry_throttle_map_init();
- grpc_proxy_mapper_registry_init();
- grpc_register_http_proxy_mapper();
- grpc_subchannel_index_init();
- grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MIN,
- set_default_host_if_unset, NULL);
- grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, append_filter,
- (void *)&grpc_client_channel_filter);
- grpc_http_connect_register_handshaker_factory();
-}
-
-void grpc_client_channel_shutdown(void) {
- grpc_subchannel_index_shutdown();
- grpc_channel_init_shutdown();
- grpc_proxy_mapper_registry_shutdown();
- grpc_retry_throttle_map_shutdown();
- grpc_resolver_registry_shutdown();
- grpc_lb_policy_registry_shutdown();
-}
diff --git a/src/core/ext/client_channel/connector.c b/src/core/ext/client_channel/connector.c
deleted file mode 100644
index 7a720fd1bd..0000000000
--- a/src/core/ext/client_channel/connector.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/ext/client_channel/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,
- grpc_error* why) {
- connector->vtable->shutdown(exec_ctx, connector, why);
-}
diff --git a/src/core/ext/client_channel/connector.h b/src/core/ext/client_channel/connector.h
deleted file mode 100644
index 94b5fb5c9e..0000000000
--- a/src/core/ext/client_channel/connector.h
+++ /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.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_CONNECTOR_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_CONNECTOR_H
-
-#include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/iomgr/resolve_address.h"
-#include "src/core/lib/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;
- /** 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) */
- 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,
- grpc_error *why);
- /** 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,
- grpc_error *why);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_CONNECTOR_H */
diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
deleted file mode 100644
index 778d76c39f..0000000000
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ /dev/null
@@ -1,389 +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/ext/client_channel/http_connect_handshaker.h"
-
-#include <string.h>
-
-#include <grpc/slice_buffer.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
-#include "src/core/ext/client_channel/uri_parser.h"
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/handshaker_registry.h"
-#include "src/core/lib/http/format_request.h"
-#include "src/core/lib/http/parser.h"
-#include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
-
-typedef struct http_connect_handshaker {
- // Base class. Must be first.
- grpc_handshaker base;
-
- gpr_refcount refcount;
- gpr_mu mu;
-
- bool shutdown;
- // Endpoint and read buffer to destroy after a shutdown.
- grpc_endpoint* endpoint_to_destroy;
- grpc_slice_buffer* read_buffer_to_destroy;
-
- // State saved while performing the handshake.
- grpc_handshaker_args* args;
- grpc_closure* on_handshake_done;
-
- // Objects for processing the HTTP CONNECT request and response.
- grpc_slice_buffer write_buffer;
- grpc_closure request_done_closure;
- grpc_closure response_read_closure;
- grpc_http_parser http_parser;
- grpc_http_response http_response;
-} http_connect_handshaker;
-
-// Unref and clean up handshaker.
-static void http_connect_handshaker_unref(grpc_exec_ctx* exec_ctx,
- http_connect_handshaker* handshaker) {
- if (gpr_unref(&handshaker->refcount)) {
- gpr_mu_destroy(&handshaker->mu);
- if (handshaker->endpoint_to_destroy != NULL) {
- grpc_endpoint_destroy(exec_ctx, handshaker->endpoint_to_destroy);
- }
- if (handshaker->read_buffer_to_destroy != NULL) {
- grpc_slice_buffer_destroy_internal(exec_ctx,
- handshaker->read_buffer_to_destroy);
- gpr_free(handshaker->read_buffer_to_destroy);
- }
- grpc_slice_buffer_destroy_internal(exec_ctx, &handshaker->write_buffer);
- grpc_http_parser_destroy(&handshaker->http_parser);
- grpc_http_response_destroy(&handshaker->http_response);
- gpr_free(handshaker);
- }
-}
-
-// Set args fields to NULL, saving the endpoint and read buffer for
-// later destruction.
-static void cleanup_args_for_failure_locked(
- grpc_exec_ctx* exec_ctx, http_connect_handshaker* handshaker) {
- handshaker->endpoint_to_destroy = handshaker->args->endpoint;
- handshaker->args->endpoint = NULL;
- handshaker->read_buffer_to_destroy = handshaker->args->read_buffer;
- handshaker->args->read_buffer = NULL;
- grpc_channel_args_destroy(exec_ctx, handshaker->args->args);
- handshaker->args->args = NULL;
-}
-
-// If the handshake failed or we're shutting down, clean up and invoke the
-// callback with the error.
-static void handshake_failed_locked(grpc_exec_ctx* exec_ctx,
- http_connect_handshaker* handshaker,
- grpc_error* error) {
- if (error == GRPC_ERROR_NONE) {
- // If we were shut down after an endpoint operation succeeded but
- // before the endpoint callback was invoked, we need to generate our
- // own error.
- error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshaker shutdown");
- }
- if (!handshaker->shutdown) {
- // TODO(ctiller): It is currently necessary to shutdown endpoints
- // before destroying them, even if we know that there are no
- // pending read/write callbacks. This should be fixed, at which
- // point this can be removed.
- grpc_endpoint_shutdown(exec_ctx, handshaker->args->endpoint,
- GRPC_ERROR_REF(error));
- // Not shutting down, so the handshake failed. Clean up before
- // invoking the callback.
- cleanup_args_for_failure_locked(exec_ctx, handshaker);
- // Set shutdown to true so that subsequent calls to
- // http_connect_handshaker_shutdown() do nothing.
- handshaker->shutdown = true;
- }
- // Invoke callback.
- grpc_closure_sched(exec_ctx, handshaker->on_handshake_done, error);
-}
-
-// Callback invoked when finished writing HTTP CONNECT request.
-static void on_write_done(grpc_exec_ctx* exec_ctx, void* arg,
- grpc_error* error) {
- http_connect_handshaker* handshaker = arg;
- gpr_mu_lock(&handshaker->mu);
- if (error != GRPC_ERROR_NONE || handshaker->shutdown) {
- // If the write failed or we're shutting down, clean up and invoke the
- // callback with the error.
- handshake_failed_locked(exec_ctx, handshaker, GRPC_ERROR_REF(error));
- gpr_mu_unlock(&handshaker->mu);
- http_connect_handshaker_unref(exec_ctx, handshaker);
- } else {
- // Otherwise, read the response.
- // The read callback inherits our ref to the handshaker.
- grpc_endpoint_read(exec_ctx, handshaker->args->endpoint,
- handshaker->args->read_buffer,
- &handshaker->response_read_closure);
- gpr_mu_unlock(&handshaker->mu);
- }
-}
-
-// Callback invoked for reading HTTP CONNECT response.
-static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
- grpc_error* error) {
- http_connect_handshaker* handshaker = arg;
- gpr_mu_lock(&handshaker->mu);
- if (error != GRPC_ERROR_NONE || handshaker->shutdown) {
- // If the read failed or we're shutting down, clean up and invoke the
- // callback with the error.
- handshake_failed_locked(exec_ctx, handshaker, GRPC_ERROR_REF(error));
- goto done;
- }
- // Add buffer to parser.
- for (size_t i = 0; i < handshaker->args->read_buffer->count; ++i) {
- if (GRPC_SLICE_LENGTH(handshaker->args->read_buffer->slices[i]) > 0) {
- size_t body_start_offset = 0;
- error = grpc_http_parser_parse(&handshaker->http_parser,
- handshaker->args->read_buffer->slices[i],
- &body_start_offset);
- if (error != GRPC_ERROR_NONE) {
- handshake_failed_locked(exec_ctx, handshaker, error);
- goto done;
- }
- if (handshaker->http_parser.state == GRPC_HTTP_BODY) {
- // Remove the data we've already read from the read buffer,
- // leaving only the leftover bytes (if any).
- grpc_slice_buffer tmp_buffer;
- grpc_slice_buffer_init(&tmp_buffer);
- if (body_start_offset <
- GRPC_SLICE_LENGTH(handshaker->args->read_buffer->slices[i])) {
- grpc_slice_buffer_add(
- &tmp_buffer,
- grpc_slice_split_tail(&handshaker->args->read_buffer->slices[i],
- body_start_offset));
- }
- grpc_slice_buffer_addn(&tmp_buffer,
- &handshaker->args->read_buffer->slices[i + 1],
- handshaker->args->read_buffer->count - i - 1);
- grpc_slice_buffer_swap(handshaker->args->read_buffer, &tmp_buffer);
- grpc_slice_buffer_destroy_internal(exec_ctx, &tmp_buffer);
- break;
- }
- }
- }
- // If we're not done reading the response, read more data.
- // TODO(roth): In practice, I suspect that the response to a CONNECT
- // request will never include a body, in which case this check is
- // sufficient. However, the language of RFC-2817 doesn't explicitly
- // forbid the response from including a body. If there is a body,
- // it's possible that we might have parsed part but not all of the
- // body, in which case this check will cause us to fail to parse the
- // remainder of the body. If that ever becomes an issue, we may
- // need to fix the HTTP parser to understand when the body is
- // complete (e.g., handling chunked transfer encoding or looking
- // at the Content-Length: header).
- if (handshaker->http_parser.state != GRPC_HTTP_BODY) {
- grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
- handshaker->args->read_buffer);
- grpc_endpoint_read(exec_ctx, handshaker->args->endpoint,
- handshaker->args->read_buffer,
- &handshaker->response_read_closure);
- gpr_mu_unlock(&handshaker->mu);
- return;
- }
- // Make sure we got a 2xx response.
- if (handshaker->http_response.status < 200 ||
- handshaker->http_response.status >= 300) {
- char* msg;
- gpr_asprintf(&msg, "HTTP proxy returned response code %d",
- handshaker->http_response.status);
- error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
- gpr_free(msg);
- handshake_failed_locked(exec_ctx, handshaker, error);
- goto done;
- }
- // Success. Invoke handshake-done callback.
- grpc_closure_sched(exec_ctx, handshaker->on_handshake_done, error);
-done:
- // Set shutdown to true so that subsequent calls to
- // http_connect_handshaker_shutdown() do nothing.
- handshaker->shutdown = true;
- gpr_mu_unlock(&handshaker->mu);
- http_connect_handshaker_unref(exec_ctx, handshaker);
-}
-
-//
-// Public handshaker methods
-//
-
-static void http_connect_handshaker_destroy(grpc_exec_ctx* exec_ctx,
- grpc_handshaker* handshaker_in) {
- http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
- http_connect_handshaker_unref(exec_ctx, handshaker);
-}
-
-static void http_connect_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
- grpc_handshaker* handshaker_in,
- grpc_error* why) {
- http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
- gpr_mu_lock(&handshaker->mu);
- if (!handshaker->shutdown) {
- handshaker->shutdown = true;
- grpc_endpoint_shutdown(exec_ctx, handshaker->args->endpoint,
- GRPC_ERROR_REF(why));
- cleanup_args_for_failure_locked(exec_ctx, handshaker);
- }
- gpr_mu_unlock(&handshaker->mu);
- GRPC_ERROR_UNREF(why);
-}
-
-static void http_connect_handshaker_do_handshake(
- grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker_in,
- grpc_tcp_server_acceptor* acceptor, grpc_closure* on_handshake_done,
- grpc_handshaker_args* args) {
- http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
- // Check for HTTP CONNECT channel arg.
- // If not found, invoke on_handshake_done without doing anything.
- const grpc_arg* arg =
- grpc_channel_args_find(args->args, GRPC_ARG_HTTP_CONNECT_SERVER);
- if (arg == NULL) {
- // Set shutdown to true so that subsequent calls to
- // http_connect_handshaker_shutdown() do nothing.
- gpr_mu_lock(&handshaker->mu);
- handshaker->shutdown = true;
- gpr_mu_unlock(&handshaker->mu);
- grpc_closure_sched(exec_ctx, on_handshake_done, GRPC_ERROR_NONE);
- return;
- }
- GPR_ASSERT(arg->type == GRPC_ARG_STRING);
- char* server_name = arg->value.string;
- // Get headers from channel args.
- arg = grpc_channel_args_find(args->args, GRPC_ARG_HTTP_CONNECT_HEADERS);
- grpc_http_header* headers = NULL;
- size_t num_headers = 0;
- char** header_strings = NULL;
- size_t num_header_strings = 0;
- if (arg != NULL) {
- GPR_ASSERT(arg->type == GRPC_ARG_STRING);
- gpr_string_split(arg->value.string, "\n", &header_strings,
- &num_header_strings);
- headers = gpr_malloc(sizeof(grpc_http_header) * num_header_strings);
- for (size_t i = 0; i < num_header_strings; ++i) {
- char* sep = strchr(header_strings[i], ':');
- if (sep == NULL) {
- gpr_log(GPR_ERROR, "skipping unparseable HTTP CONNECT header: %s",
- header_strings[i]);
- continue;
- }
- *sep = '\0';
- headers[num_headers].key = header_strings[i];
- headers[num_headers].value = sep + 1;
- ++num_headers;
- }
- }
- // Save state in the handshaker object.
- gpr_mu_lock(&handshaker->mu);
- handshaker->args = args;
- handshaker->on_handshake_done = on_handshake_done;
- // Log connection via proxy.
- char* proxy_name = grpc_endpoint_get_peer(args->endpoint);
- gpr_log(GPR_INFO, "Connecting to server %s via HTTP proxy %s", server_name,
- proxy_name);
- gpr_free(proxy_name);
- // Construct HTTP CONNECT request.
- grpc_httpcli_request request;
- memset(&request, 0, sizeof(request));
- request.host = server_name;
- request.http.method = "CONNECT";
- request.http.path = server_name;
- request.http.hdrs = headers;
- request.http.hdr_count = num_headers;
- request.handshaker = &grpc_httpcli_plaintext;
- grpc_slice request_slice = grpc_httpcli_format_connect_request(&request);
- grpc_slice_buffer_add(&handshaker->write_buffer, request_slice);
- // Clean up.
- gpr_free(headers);
- for (size_t i = 0; i < num_header_strings; ++i) {
- gpr_free(header_strings[i]);
- }
- gpr_free(header_strings);
- // Take a new ref to be held by the write callback.
- gpr_ref(&handshaker->refcount);
- grpc_endpoint_write(exec_ctx, args->endpoint, &handshaker->write_buffer,
- &handshaker->request_done_closure);
- gpr_mu_unlock(&handshaker->mu);
-}
-
-static const grpc_handshaker_vtable http_connect_handshaker_vtable = {
- http_connect_handshaker_destroy, http_connect_handshaker_shutdown,
- http_connect_handshaker_do_handshake};
-
-static grpc_handshaker* grpc_http_connect_handshaker_create() {
- http_connect_handshaker* handshaker = gpr_malloc(sizeof(*handshaker));
- memset(handshaker, 0, sizeof(*handshaker));
- grpc_handshaker_init(&http_connect_handshaker_vtable, &handshaker->base);
- gpr_mu_init(&handshaker->mu);
- gpr_ref_init(&handshaker->refcount, 1);
- grpc_slice_buffer_init(&handshaker->write_buffer);
- grpc_closure_init(&handshaker->request_done_closure, on_write_done,
- handshaker, grpc_schedule_on_exec_ctx);
- grpc_closure_init(&handshaker->response_read_closure, on_read_done,
- handshaker, grpc_schedule_on_exec_ctx);
- grpc_http_parser_init(&handshaker->http_parser, GRPC_HTTP_RESPONSE,
- &handshaker->http_response);
- return &handshaker->base;
-}
-
-//
-// handshaker factory
-//
-
-static void handshaker_factory_add_handshakers(
- grpc_exec_ctx* exec_ctx, grpc_handshaker_factory* factory,
- const grpc_channel_args* args, grpc_handshake_manager* handshake_mgr) {
- grpc_handshake_manager_add(handshake_mgr,
- grpc_http_connect_handshaker_create());
-}
-
-static void handshaker_factory_destroy(grpc_exec_ctx* exec_ctx,
- grpc_handshaker_factory* factory) {}
-
-static const grpc_handshaker_factory_vtable handshaker_factory_vtable = {
- handshaker_factory_add_handshakers, handshaker_factory_destroy};
-
-static grpc_handshaker_factory handshaker_factory = {
- &handshaker_factory_vtable};
-
-void grpc_http_connect_register_handshaker_factory() {
- grpc_handshaker_factory_register(true /* at_start */, HANDSHAKER_CLIENT,
- &handshaker_factory);
-}
diff --git a/src/core/ext/client_channel/http_connect_handshaker.h b/src/core/ext/client_channel/http_connect_handshaker.h
deleted file mode 100644
index 3059d551e3..0000000000
--- a/src/core/ext/client_channel/http_connect_handshaker.h
+++ /dev/null
@@ -1,49 +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_EXT_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H
-
-/// Channel arg indicating the server in HTTP CONNECT request (string).
-/// The presence of this arg triggers the use of HTTP CONNECT.
-#define GRPC_ARG_HTTP_CONNECT_SERVER "grpc.http_connect_server"
-
-/// Channel arg indicating HTTP CONNECT headers (string).
-/// Multiple headers are separated by newlines. Key/value pairs are
-/// seperated by colons.
-#define GRPC_ARG_HTTP_CONNECT_HEADERS "grpc.http_connect_headers"
-
-/// Registers handshaker factory.
-void grpc_http_connect_register_handshaker_factory();
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H */
diff --git a/src/core/ext/client_channel/http_proxy.c b/src/core/ext/client_channel/http_proxy.c
deleted file mode 100644
index e280cef101..0000000000
--- a/src/core/ext/client_channel/http_proxy.c
+++ /dev/null
@@ -1,125 +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/ext/client_channel/http_proxy.h"
-
-#include <stdbool.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-
-#include "src/core/ext/client_channel/http_connect_handshaker.h"
-#include "src/core/ext/client_channel/proxy_mapper_registry.h"
-#include "src/core/ext/client_channel/uri_parser.h"
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/support/env.h"
-
-static char* grpc_get_http_proxy_server(grpc_exec_ctx* exec_ctx) {
- char* uri_str = gpr_getenv("http_proxy");
- if (uri_str == NULL) return NULL;
- grpc_uri* uri =
- grpc_uri_parse(exec_ctx, uri_str, false /* suppress_errors */);
- char* proxy_name = NULL;
- if (uri == NULL || uri->authority == NULL) {
- gpr_log(GPR_ERROR, "cannot parse value of 'http_proxy' env var");
- goto done;
- }
- if (strcmp(uri->scheme, "http") != 0) {
- gpr_log(GPR_ERROR, "'%s' scheme not supported in proxy URI", uri->scheme);
- goto done;
- }
- if (strchr(uri->authority, '@') != NULL) {
- gpr_log(GPR_ERROR, "userinfo not supported in proxy URI");
- goto done;
- }
- proxy_name = gpr_strdup(uri->authority);
-done:
- gpr_free(uri_str);
- grpc_uri_destroy(uri);
- return proxy_name;
-}
-
-static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
- grpc_proxy_mapper* mapper,
- const char* server_uri,
- const grpc_channel_args* args,
- char** name_to_resolve,
- grpc_channel_args** new_args) {
- *name_to_resolve = grpc_get_http_proxy_server(exec_ctx);
- if (*name_to_resolve == NULL) return false;
- grpc_uri* uri =
- grpc_uri_parse(exec_ctx, server_uri, false /* suppress_errors */);
- if (uri == NULL || uri->path[0] == '\0') {
- gpr_log(GPR_ERROR,
- "'http_proxy' environment variable set, but cannot "
- "parse server URI '%s' -- not using proxy",
- server_uri);
- if (uri != NULL) grpc_uri_destroy(uri);
- return false;
- }
- if (strcmp(uri->scheme, "unix") == 0) {
- gpr_log(GPR_INFO, "not using proxy for Unix domain socket '%s'",
- server_uri);
- grpc_uri_destroy(uri);
- return false;
- }
- grpc_arg new_arg;
- new_arg.key = GRPC_ARG_HTTP_CONNECT_SERVER;
- new_arg.type = GRPC_ARG_STRING;
- new_arg.value.string = uri->path[0] == '/' ? uri->path + 1 : uri->path;
- *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
- grpc_uri_destroy(uri);
- return true;
-}
-
-static bool proxy_mapper_map_address(grpc_exec_ctx* exec_ctx,
- grpc_proxy_mapper* mapper,
- const grpc_resolved_address* address,
- const grpc_channel_args* args,
- grpc_resolved_address** new_address,
- grpc_channel_args** new_args) {
- return false;
-}
-
-static void proxy_mapper_destroy(grpc_proxy_mapper* mapper) {}
-
-static const grpc_proxy_mapper_vtable proxy_mapper_vtable = {
- proxy_mapper_map_name, proxy_mapper_map_address, proxy_mapper_destroy};
-
-static grpc_proxy_mapper proxy_mapper = {&proxy_mapper_vtable};
-
-void grpc_register_http_proxy_mapper() {
- grpc_proxy_mapper_register(true /* at_start */, &proxy_mapper);
-}
diff --git a/src/core/ext/client_channel/http_proxy.h b/src/core/ext/client_channel/http_proxy.h
deleted file mode 100644
index c8882b1ef1..0000000000
--- a/src/core/ext/client_channel/http_proxy.h
+++ /dev/null
@@ -1,39 +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_EXT_CLIENT_CHANNEL_HTTP_PROXY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_PROXY_H
-
-void grpc_register_http_proxy_mapper();
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_PROXY_H */
diff --git a/src/core/ext/client_channel/lb_policy.c b/src/core/ext/client_channel/lb_policy.c
deleted file mode 100644
index aba51add53..0000000000
--- a/src/core/ext/client_channel/lb_policy.c
+++ /dev/null
@@ -1,167 +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/ext/client_channel/lb_policy.h"
-#include "src/core/lib/iomgr/combiner.h"
-
-#define WEAK_REF_BITS 16
-
-void grpc_lb_policy_init(grpc_lb_policy *policy,
- const grpc_lb_policy_vtable *vtable,
- grpc_combiner *combiner) {
- policy->vtable = vtable;
- gpr_atm_no_barrier_store(&policy->ref_pair, 1 << WEAK_REF_BITS);
- policy->interested_parties = grpc_pollset_set_create();
- policy->combiner = GRPC_COMBINER_REF(combiner, "lb_policy");
-}
-
-#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: 0x%" PRIxPTR " %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR
- " [%s]",
- (intptr_t)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"));
-}
-
-static void shutdown_locked(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error) {
- grpc_lb_policy *policy = arg;
- policy->vtable->shutdown_locked(exec_ctx, policy);
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, policy, "strong-unref");
-}
-
-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) {
- grpc_closure_sched(
- exec_ctx,
- grpc_closure_create(shutdown_locked, policy,
- grpc_combiner_scheduler(policy->combiner, false)),
- GRPC_ERROR_NONE);
- } else {
- 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(exec_ctx, policy->interested_parties);
- grpc_combiner *combiner = policy->combiner;
- policy->vtable->destroy(exec_ctx, policy);
- GRPC_COMBINER_UNREF(exec_ctx, combiner, "lb_policy");
- }
-}
-
-int grpc_lb_policy_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
- const grpc_lb_policy_pick_args *pick_args,
- grpc_connected_subchannel **target,
- void **user_data, grpc_closure *on_complete) {
- return policy->vtable->pick_locked(exec_ctx, policy, pick_args, target,
- user_data, on_complete);
-}
-
-void grpc_lb_policy_cancel_pick_locked(grpc_exec_ctx *exec_ctx,
- grpc_lb_policy *policy,
- grpc_connected_subchannel **target,
- grpc_error *error) {
- policy->vtable->cancel_pick_locked(exec_ctx, policy, target, error);
-}
-
-void grpc_lb_policy_cancel_picks_locked(grpc_exec_ctx *exec_ctx,
- grpc_lb_policy *policy,
- uint32_t initial_metadata_flags_mask,
- uint32_t initial_metadata_flags_eq,
- grpc_error *error) {
- policy->vtable->cancel_picks_locked(exec_ctx, policy,
- initial_metadata_flags_mask,
- initial_metadata_flags_eq, error);
-}
-
-void grpc_lb_policy_exit_idle_locked(grpc_exec_ctx *exec_ctx,
- grpc_lb_policy *policy) {
- policy->vtable->exit_idle_locked(exec_ctx, policy);
-}
-
-void grpc_lb_policy_ping_one_locked(grpc_exec_ctx *exec_ctx,
- grpc_lb_policy *policy,
- grpc_closure *closure) {
- policy->vtable->ping_one_locked(exec_ctx, policy, closure);
-}
-
-void grpc_lb_policy_notify_on_state_change_locked(
- grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
- grpc_connectivity_state *state, grpc_closure *closure) {
- policy->vtable->notify_on_state_change_locked(exec_ctx, policy, state,
- closure);
-}
-
-grpc_connectivity_state grpc_lb_policy_check_connectivity_locked(
- grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
- grpc_error **connectivity_error) {
- return policy->vtable->check_connectivity_locked(exec_ctx, policy,
- connectivity_error);
-}
diff --git a/src/core/ext/client_channel/lb_policy.h b/src/core/ext/client_channel/lb_policy.h
deleted file mode 100644
index 3405709c2c..0000000000
--- a/src/core/ext/client_channel/lb_policy.h
+++ /dev/null
@@ -1,209 +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_EXT_CLIENT_CHANNEL_LB_POLICY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_H
-
-#include "src/core/ext/client_channel/subchannel.h"
-#include "src/core/lib/iomgr/polling_entity.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) */
-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;
- /* combiner under which lb_policy actions take place */
- grpc_combiner *combiner;
-};
-
-/** Extra arguments for an LB pick */
-typedef struct grpc_lb_policy_pick_args {
- /** Initial metadata associated with the picking call. */
- grpc_metadata_batch *initial_metadata;
- /** Bitmask used for selective cancelling. See \a
- * grpc_lb_policy_cancel_picks() and \a GRPC_INITIAL_METADATA_* in
- * grpc_types.h */
- uint32_t initial_metadata_flags;
- /** Storage for LB token in \a initial_metadata, or NULL if not used */
- grpc_linked_mdelem *lb_token_mdelem_storage;
- /** Deadline for the call to the LB server */
- gpr_timespec deadline;
-} grpc_lb_policy_pick_args;
-
-struct grpc_lb_policy_vtable {
- void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy);
- void (*shutdown_locked)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy);
-
- /** \see grpc_lb_policy_pick */
- int (*pick_locked)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
- const grpc_lb_policy_pick_args *pick_args,
- grpc_connected_subchannel **target, void **user_data,
- grpc_closure *on_complete);
-
- /** \see grpc_lb_policy_cancel_pick */
- void (*cancel_pick_locked)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
- grpc_connected_subchannel **target,
- grpc_error *error);
-
- /** \see grpc_lb_policy_cancel_picks */
- void (*cancel_picks_locked)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
- uint32_t initial_metadata_flags_mask,
- uint32_t initial_metadata_flags_eq,
- grpc_error *error);
-
- /** \see grpc_lb_policy_ping_one */
- void (*ping_one_locked)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
- grpc_closure *closure);
-
- /** Try to enter a READY connectivity state */
- void (*exit_idle_locked)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy);
-
- /** check the current connectivity of the lb_policy */
- grpc_connectivity_state (*check_connectivity_locked)(
- grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
- grpc_error **connectivity_error);
-
- /** call notify when the connectivity state of a channel changes from *state.
- Updates *state with the new state of the policy. Calling with a NULL \a
- state cancels the subscription. */
- void (*notify_on_state_change_locked)(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
-
-/* Strong references: the policy will shutdown when they reach zero */
-#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))
-
-/* Weak references: they don't prevent the shutdown of the LB policy. When no
- * strong references are left but there are still weak ones, shutdown is called.
- * Once the weak reference also reaches zero, the LB policy is destroyed. */
-#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,
- grpc_combiner *combiner);
-
-/** Finds an appropriate subchannel for a call, based on \a pick_args.
-
- \a target will be set to the selected subchannel, or NULL on failure.
- Upon success, \a user_data will be set to whatever opaque information
- may need to be propagated from the LB policy, or NULL if not needed.
-
- If the pick succeeds and a result is known immediately, a non-zero
- value will be returned. Otherwise, \a on_complete will be invoked
- once the pick is complete with its error argument set to indicate
- success or failure.
-
- Any IO should be done under the \a interested_parties \a grpc_pollset_set
- in the \a grpc_lb_policy struct. */
-int grpc_lb_policy_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
- const grpc_lb_policy_pick_args *pick_args,
- grpc_connected_subchannel **target,
- void **user_data, grpc_closure *on_complete);
-
-/** Perform a connected subchannel ping (see \a grpc_connected_subchannel_ping)
- against one of the connected subchannels managed by \a policy. */
-void grpc_lb_policy_ping_one_locked(grpc_exec_ctx *exec_ctx,
- grpc_lb_policy *policy,
- grpc_closure *closure);
-
-/** Cancel picks for \a target.
- The \a on_complete callback of the pending picks will be invoked with \a
- *target set to NULL. */
-void grpc_lb_policy_cancel_pick_locked(grpc_exec_ctx *exec_ctx,
- grpc_lb_policy *policy,
- grpc_connected_subchannel **target,
- grpc_error *error);
-
-/** Cancel all pending picks for which their \a initial_metadata_flags (as given
- in the call to \a grpc_lb_policy_pick) matches \a initial_metadata_flags_eq
- when AND'd with \a initial_metadata_flags_mask */
-void grpc_lb_policy_cancel_picks_locked(grpc_exec_ctx *exec_ctx,
- grpc_lb_policy *policy,
- uint32_t initial_metadata_flags_mask,
- uint32_t initial_metadata_flags_eq,
- grpc_error *error);
-
-/** Try to enter a READY connectivity state */
-void grpc_lb_policy_exit_idle_locked(grpc_exec_ctx *exec_ctx,
- grpc_lb_policy *policy);
-
-/* Call notify when the connectivity state of a channel changes from \a *state.
- * Updates \a *state with the new state of the policy */
-void grpc_lb_policy_notify_on_state_change_locked(
- grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
- grpc_connectivity_state *state, grpc_closure *closure);
-
-grpc_connectivity_state grpc_lb_policy_check_connectivity_locked(
- grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
- grpc_error **connectivity_error);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_H */
diff --git a/src/core/ext/client_channel/lb_policy_factory.c b/src/core/ext/client_channel/lb_policy_factory.c
deleted file mode 100644
index 7af9bb0411..0000000000
--- a/src/core/ext/client_channel/lb_policy_factory.c
+++ /dev/null
@@ -1,163 +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 <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/string_util.h>
-
-#include "src/core/ext/client_channel/lb_policy_factory.h"
-
-grpc_lb_addresses* grpc_lb_addresses_create(
- size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable) {
- grpc_lb_addresses* addresses = gpr_malloc(sizeof(grpc_lb_addresses));
- addresses->num_addresses = num_addresses;
- addresses->user_data_vtable = user_data_vtable;
- const size_t addresses_size = sizeof(grpc_lb_address) * num_addresses;
- addresses->addresses = gpr_malloc(addresses_size);
- memset(addresses->addresses, 0, addresses_size);
- return addresses;
-}
-
-grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses) {
- grpc_lb_addresses* new_addresses = grpc_lb_addresses_create(
- addresses->num_addresses, addresses->user_data_vtable);
- memcpy(new_addresses->addresses, addresses->addresses,
- sizeof(grpc_lb_address) * addresses->num_addresses);
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (new_addresses->addresses[i].balancer_name != NULL) {
- new_addresses->addresses[i].balancer_name =
- gpr_strdup(new_addresses->addresses[i].balancer_name);
- }
- if (new_addresses->addresses[i].user_data != NULL) {
- new_addresses->addresses[i].user_data = addresses->user_data_vtable->copy(
- new_addresses->addresses[i].user_data);
- }
- }
- return new_addresses;
-}
-
-void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index,
- void* address, size_t address_len,
- bool is_balancer, char* balancer_name,
- void* user_data) {
- GPR_ASSERT(index < addresses->num_addresses);
- if (user_data != NULL) GPR_ASSERT(addresses->user_data_vtable != NULL);
- grpc_lb_address* target = &addresses->addresses[index];
- memcpy(target->address.addr, address, address_len);
- target->address.len = address_len;
- target->is_balancer = is_balancer;
- target->balancer_name = balancer_name;
- target->user_data = user_data;
-}
-
-int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1,
- const grpc_lb_addresses* addresses2) {
- if (addresses1->num_addresses > addresses2->num_addresses) return 1;
- if (addresses1->num_addresses < addresses2->num_addresses) return -1;
- if (addresses1->user_data_vtable > addresses2->user_data_vtable) return 1;
- if (addresses1->user_data_vtable < addresses2->user_data_vtable) return -1;
- for (size_t i = 0; i < addresses1->num_addresses; ++i) {
- const grpc_lb_address* target1 = &addresses1->addresses[i];
- const grpc_lb_address* target2 = &addresses2->addresses[i];
- if (target1->address.len > target2->address.len) return 1;
- if (target1->address.len < target2->address.len) return -1;
- int retval = memcmp(target1->address.addr, target2->address.addr,
- target1->address.len);
- if (retval != 0) return retval;
- if (target1->is_balancer > target2->is_balancer) return 1;
- if (target1->is_balancer < target2->is_balancer) return -1;
- const char* balancer_name1 =
- target1->balancer_name != NULL ? target1->balancer_name : "";
- const char* balancer_name2 =
- target2->balancer_name != NULL ? target2->balancer_name : "";
- retval = strcmp(balancer_name1, balancer_name2);
- if (retval != 0) return retval;
- if (addresses1->user_data_vtable != NULL) {
- retval = addresses1->user_data_vtable->cmp(target1->user_data,
- target2->user_data);
- if (retval != 0) return retval;
- }
- }
- return 0;
-}
-
-void grpc_lb_addresses_destroy(grpc_exec_ctx* exec_ctx,
- grpc_lb_addresses* addresses) {
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- gpr_free(addresses->addresses[i].balancer_name);
- if (addresses->addresses[i].user_data != NULL) {
- addresses->user_data_vtable->destroy(exec_ctx,
- addresses->addresses[i].user_data);
- }
- }
- gpr_free(addresses->addresses);
- gpr_free(addresses);
-}
-
-static void* lb_addresses_copy(void* addresses) {
- return grpc_lb_addresses_copy(addresses);
-}
-static void lb_addresses_destroy(grpc_exec_ctx* exec_ctx, void* addresses) {
- grpc_lb_addresses_destroy(exec_ctx, addresses);
-}
-static int lb_addresses_cmp(void* addresses1, void* addresses2) {
- return grpc_lb_addresses_cmp(addresses1, addresses2);
-}
-static const grpc_arg_pointer_vtable lb_addresses_arg_vtable = {
- lb_addresses_copy, lb_addresses_destroy, lb_addresses_cmp};
-
-grpc_arg grpc_lb_addresses_create_channel_arg(
- const grpc_lb_addresses* addresses) {
- grpc_arg arg;
- arg.type = GRPC_ARG_POINTER;
- arg.key = GRPC_ARG_LB_ADDRESSES;
- arg.value.pointer.p = (void*)addresses;
- arg.value.pointer.vtable = &lb_addresses_arg_vtable;
- return arg;
-}
-
-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_exec_ctx* exec_ctx, grpc_lb_policy_factory* factory,
- grpc_lb_policy_args* args) {
- if (factory == NULL) return NULL;
- return factory->vtable->create_lb_policy(exec_ctx, factory, args);
-}
diff --git a/src/core/ext/client_channel/lb_policy_factory.h b/src/core/ext/client_channel/lb_policy_factory.h
deleted file mode 100644
index 27c12c0d73..0000000000
--- a/src/core/ext/client_channel/lb_policy_factory.h
+++ /dev/null
@@ -1,134 +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_EXT_CLIENT_CHANNEL_LB_POLICY_FACTORY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_FACTORY_H
-
-#include "src/core/ext/client_channel/client_channel_factory.h"
-#include "src/core/ext/client_channel/lb_policy.h"
-
-#include "src/core/lib/iomgr/exec_ctx.h"
-#include "src/core/lib/iomgr/resolve_address.h"
-
-// Channel arg key for grpc_lb_addresses.
-#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses"
-
-typedef struct grpc_lb_policy_factory grpc_lb_policy_factory;
-typedef struct grpc_lb_policy_factory_vtable grpc_lb_policy_factory_vtable;
-
-struct grpc_lb_policy_factory {
- const grpc_lb_policy_factory_vtable *vtable;
-};
-
-/** A resolved address alongside any LB related information associated with it.
- * \a user_data, if not NULL, contains opaque data meant to be consumed by the
- * gRPC LB policy. Note that no all LB policies support \a user_data as input.
- * Those who don't will simply ignore it and will correspondingly return NULL in
- * their namesake pick() output argument. */
-typedef struct grpc_lb_address {
- grpc_resolved_address address;
- bool is_balancer;
- char *balancer_name; /* For secure naming. */
- void *user_data;
-} grpc_lb_address;
-
-typedef struct grpc_lb_user_data_vtable {
- void *(*copy)(void *);
- void (*destroy)(grpc_exec_ctx *exec_ctx, void *);
- int (*cmp)(void *, void *);
-} grpc_lb_user_data_vtable;
-
-typedef struct grpc_lb_addresses {
- size_t num_addresses;
- grpc_lb_address *addresses;
- const grpc_lb_user_data_vtable *user_data_vtable;
-} grpc_lb_addresses;
-
-/** Returns a grpc_addresses struct with enough space for
- \a num_addresses addresses. The \a user_data_vtable argument may be
- NULL if no user data will be added. */
-grpc_lb_addresses *grpc_lb_addresses_create(
- size_t num_addresses, const grpc_lb_user_data_vtable *user_data_vtable);
-
-/** Creates a copy of \a addresses. */
-grpc_lb_addresses *grpc_lb_addresses_copy(const grpc_lb_addresses *addresses);
-
-/** Sets the value of the address at index \a index of \a addresses.
- * \a address is a socket address of length \a address_len.
- * Takes ownership of \a balancer_name. */
-void grpc_lb_addresses_set_address(grpc_lb_addresses *addresses, size_t index,
- void *address, size_t address_len,
- bool is_balancer, char *balancer_name,
- void *user_data);
-
-/** Compares \a addresses1 and \a addresses2. */
-int grpc_lb_addresses_cmp(const grpc_lb_addresses *addresses1,
- const grpc_lb_addresses *addresses2);
-
-/** Destroys \a addresses. */
-void grpc_lb_addresses_destroy(grpc_exec_ctx *exec_ctx,
- grpc_lb_addresses *addresses);
-
-/** Returns a channel arg containing \a addresses. */
-grpc_arg grpc_lb_addresses_create_channel_arg(
- const grpc_lb_addresses *addresses);
-
-/** Arguments passed to LB policies. */
-typedef struct grpc_lb_policy_args {
- grpc_client_channel_factory *client_channel_factory;
- grpc_channel_args *args;
- grpc_combiner *combiner;
-} 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_exec_ctx *exec_ctx,
- 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_exec_ctx *exec_ctx, grpc_lb_policy_factory *factory,
- grpc_lb_policy_args *args);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_FACTORY_H */
diff --git a/src/core/ext/client_channel/lb_policy_registry.c b/src/core/ext/client_channel/lb_policy_registry.c
deleted file mode 100644
index 90c149d947..0000000000
--- a/src/core/ext/client_channel/lb_policy_registry.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 "src/core/ext/client_channel/lb_policy_registry.h"
-
-#include <string.h>
-
-#include "src/core/lib/support/string.h"
-
-#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;
-
-void grpc_lb_policy_registry_init(void) { g_number_of_lb_policies = 0; }
-
-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 != gpr_stricmp(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 == gpr_stricmp(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(grpc_exec_ctx *exec_ctx, 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(exec_ctx, factory, args);
- return lb_policy;
-}
diff --git a/src/core/ext/client_channel/lb_policy_registry.h b/src/core/ext/client_channel/lb_policy_registry.h
deleted file mode 100644
index 21c468e021..0000000000
--- a/src/core/ext/client_channel/lb_policy_registry.h
+++ /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.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H
-
-#include "src/core/ext/client_channel/lb_policy_factory.h"
-#include "src/core/lib/iomgr/exec_ctx.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(void);
-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(grpc_exec_ctx *exec_ctx, const char *name,
- grpc_lb_policy_args *args);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H */
diff --git a/src/core/ext/client_channel/parse_address.c b/src/core/ext/client_channel/parse_address.c
deleted file mode 100644
index cd1b2cd80c..0000000000
--- a/src/core/ext/client_channel/parse_address.c
+++ /dev/null
@@ -1,170 +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/ext/client_channel/parse_address.h"
-#include "src/core/lib/iomgr/sockaddr.h"
-
-#include <stdio.h>
-#include <string.h>
-#ifdef GRPC_HAVE_UNIX_SOCKET
-#include <sys/un.h>
-#endif
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/host_port.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-#include "src/core/lib/support/string.h"
-
-#ifdef GRPC_HAVE_UNIX_SOCKET
-
-int parse_unix(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
- struct sockaddr_un *un = (struct sockaddr_un *)resolved_addr->addr;
- const size_t maxlen = sizeof(un->sun_path);
- const size_t path_len = strnlen(uri->path, maxlen);
- if (path_len == maxlen) return 0;
- un->sun_family = AF_UNIX;
- strcpy(un->sun_path, uri->path);
- resolved_addr->len = sizeof(*un);
- return 1;
-}
-
-#else /* GRPC_HAVE_UNIX_SOCKET */
-
-int parse_unix(grpc_uri *uri, grpc_resolved_address *resolved_addr) { abort(); }
-
-#endif /* GRPC_HAVE_UNIX_SOCKET */
-
-int parse_ipv4(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
- const char *host_port = uri->path;
- char *host;
- char *port;
- int port_num;
- int result = 0;
- struct sockaddr_in *in = (struct sockaddr_in *)resolved_addr->addr;
-
- if (*host_port == '/') ++host_port;
- if (!gpr_split_host_port(host_port, &host, &port)) {
- return 0;
- }
-
- memset(resolved_addr, 0, sizeof(grpc_resolved_address));
- resolved_addr->len = sizeof(struct sockaddr_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;
-}
-
-int parse_ipv6(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
- const char *host_port = uri->path;
- char *host;
- char *port;
- int port_num;
- int result = 0;
- struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)resolved_addr->addr;
-
- if (*host_port == '/') ++host_port;
- if (!gpr_split_host_port(host_port, &host, &port)) {
- return 0;
- }
-
- memset(in6, 0, sizeof(*in6));
- resolved_addr->len = sizeof(*in6);
- in6->sin6_family = AF_INET6;
-
- /* Handle the RFC6874 syntax for IPv6 zone identifiers. */
- char *host_end = (char *)gpr_memrchr(host, '%', strlen(host));
- if (host_end != NULL) {
- GPR_ASSERT(host_end >= host);
- char host_without_scope[INET6_ADDRSTRLEN];
- size_t host_without_scope_len = (size_t)(host_end - host);
- uint32_t sin6_scope_id = 0;
- strncpy(host_without_scope, host, host_without_scope_len);
- host_without_scope[host_without_scope_len] = '\0';
- if (inet_pton(AF_INET6, host_without_scope, &in6->sin6_addr) == 0) {
- gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host_without_scope);
- goto done;
- }
- if (gpr_parse_bytes_to_uint32(host_end + 1,
- strlen(host) - host_without_scope_len - 1,
- &sin6_scope_id) == 0) {
- gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1);
- goto done;
- }
- // Handle "sin6_scope_id" being type "u_long". See grpc issue ##10027.
- in6->sin6_scope_id = sin6_scope_id;
- } else {
- 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;
-}
diff --git a/src/core/ext/client_channel/parse_address.h b/src/core/ext/client_channel/parse_address.h
deleted file mode 100644
index bf99c5298a..0000000000
--- a/src/core/ext/client_channel/parse_address.h
+++ /dev/null
@@ -1,54 +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_EXT_CLIENT_CHANNEL_PARSE_ADDRESS_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_PARSE_ADDRESS_H
-
-#include <stddef.h>
-
-#include "src/core/ext/client_channel/uri_parser.h"
-#include "src/core/lib/iomgr/resolve_address.h"
-
-/** Populate \a addr and \a len from \a uri, whose path is expected to contain a
- * unix socket path. Returns true upon success. */
-int parse_unix(grpc_uri *uri, grpc_resolved_address *resolved_addr);
-
-/** Populate /a addr and \a len from \a uri, whose path is expected to contain a
- * host:port pair. Returns true upon success. */
-int parse_ipv4(grpc_uri *uri, grpc_resolved_address *resolved_addr);
-
-/** Populate /a addr and \a len from \a uri, whose path is expected to contain a
- * host:port pair. Returns true upon success. */
-int parse_ipv6(grpc_uri *uri, grpc_resolved_address *resolved_addr);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_PARSE_ADDRESS_H */
diff --git a/src/core/ext/client_channel/proxy_mapper.c b/src/core/ext/client_channel/proxy_mapper.c
deleted file mode 100644
index f92afe847b..0000000000
--- a/src/core/ext/client_channel/proxy_mapper.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *
- * Copyright 2017, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING 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/ext/client_channel/proxy_mapper.h"
-
-void grpc_proxy_mapper_init(const grpc_proxy_mapper_vtable* vtable,
- grpc_proxy_mapper* mapper) {
- mapper->vtable = vtable;
-}
-
-bool grpc_proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
- grpc_proxy_mapper* mapper,
- const char* server_uri,
- const grpc_channel_args* args,
- char** name_to_resolve,
- grpc_channel_args** new_args) {
- return mapper->vtable->map_name(exec_ctx, mapper, server_uri, args,
- name_to_resolve, new_args);
-}
-
-bool grpc_proxy_mapper_map_address(grpc_exec_ctx* exec_ctx,
- grpc_proxy_mapper* mapper,
- const grpc_resolved_address* address,
- const grpc_channel_args* args,
- grpc_resolved_address** new_address,
- grpc_channel_args** new_args) {
- return mapper->vtable->map_address(exec_ctx, mapper, address, args,
- new_address, new_args);
-}
-
-void grpc_proxy_mapper_destroy(grpc_proxy_mapper* mapper) {
- mapper->vtable->destroy(mapper);
-}
diff --git a/src/core/ext/client_channel/proxy_mapper.h b/src/core/ext/client_channel/proxy_mapper.h
deleted file mode 100644
index 6e4607fe4d..0000000000
--- a/src/core/ext/client_channel/proxy_mapper.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *
- * Copyright 2017, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_H
-
-#include <stdbool.h>
-
-#include <grpc/impl/codegen/grpc_types.h>
-
-#include "src/core/lib/iomgr/resolve_address.h"
-
-typedef struct grpc_proxy_mapper grpc_proxy_mapper;
-
-typedef struct {
- /// Determines the proxy name to resolve for \a server_uri.
- /// If no proxy is needed, returns false.
- /// Otherwise, sets \a name_to_resolve, optionally sets \a new_args,
- /// and returns true.
- bool (*map_name)(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper,
- const char* server_uri, const grpc_channel_args* args,
- char** name_to_resolve, grpc_channel_args** new_args);
- /// Determines the proxy address to use to contact \a address.
- /// If no proxy is needed, returns false.
- /// Otherwise, sets \a new_address, optionally sets \a new_args, and
- /// returns true.
- bool (*map_address)(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper,
- const grpc_resolved_address* address,
- const grpc_channel_args* args,
- grpc_resolved_address** new_address,
- grpc_channel_args** new_args);
- /// Destroys \a mapper.
- void (*destroy)(grpc_proxy_mapper* mapper);
-} grpc_proxy_mapper_vtable;
-
-struct grpc_proxy_mapper {
- const grpc_proxy_mapper_vtable* vtable;
-};
-
-void grpc_proxy_mapper_init(const grpc_proxy_mapper_vtable* vtable,
- grpc_proxy_mapper* mapper);
-
-bool grpc_proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
- grpc_proxy_mapper* mapper,
- const char* server_uri,
- const grpc_channel_args* args,
- char** name_to_resolve,
- grpc_channel_args** new_args);
-
-bool grpc_proxy_mapper_map_address(grpc_exec_ctx* exec_ctx,
- grpc_proxy_mapper* mapper,
- const grpc_resolved_address* address,
- const grpc_channel_args* args,
- grpc_resolved_address** new_address,
- grpc_channel_args** new_args);
-
-void grpc_proxy_mapper_destroy(grpc_proxy_mapper* mapper);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_H */
diff --git a/src/core/ext/client_channel/proxy_mapper_registry.c b/src/core/ext/client_channel/proxy_mapper_registry.c
deleted file mode 100644
index 0935ddbdbd..0000000000
--- a/src/core/ext/client_channel/proxy_mapper_registry.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- *
- * Copyright 2017, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING 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/ext/client_channel/proxy_mapper_registry.h"
-
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-
-//
-// grpc_proxy_mapper_list
-//
-
-typedef struct {
- grpc_proxy_mapper** list;
- size_t num_mappers;
-} grpc_proxy_mapper_list;
-
-static void grpc_proxy_mapper_list_register(grpc_proxy_mapper_list* list,
- bool at_start,
- grpc_proxy_mapper* mapper) {
- list->list = gpr_realloc(
- list->list, (list->num_mappers + 1) * sizeof(grpc_proxy_mapper*));
- if (at_start) {
- memmove(list->list + 1, list->list,
- sizeof(grpc_proxy_mapper*) * list->num_mappers);
- list->list[0] = mapper;
- } else {
- list->list[list->num_mappers] = mapper;
- }
- ++list->num_mappers;
-}
-
-static bool grpc_proxy_mapper_list_map_name(grpc_exec_ctx* exec_ctx,
- grpc_proxy_mapper_list* list,
- const char* server_uri,
- const grpc_channel_args* args,
- char** name_to_resolve,
- grpc_channel_args** new_args) {
- for (size_t i = 0; i < list->num_mappers; ++i) {
- if (grpc_proxy_mapper_map_name(exec_ctx, list->list[i], server_uri, args,
- name_to_resolve, new_args)) {
- return true;
- }
- }
- return false;
-}
-
-static bool grpc_proxy_mapper_list_map_address(
- grpc_exec_ctx* exec_ctx, grpc_proxy_mapper_list* list,
- const grpc_resolved_address* address, const grpc_channel_args* args,
- grpc_resolved_address** new_address, grpc_channel_args** new_args) {
- for (size_t i = 0; i < list->num_mappers; ++i) {
- if (grpc_proxy_mapper_map_address(exec_ctx, list->list[i], address, args,
- new_address, new_args)) {
- return true;
- }
- }
- return false;
-}
-
-static void grpc_proxy_mapper_list_destroy(grpc_proxy_mapper_list* list) {
- for (size_t i = 0; i < list->num_mappers; ++i) {
- grpc_proxy_mapper_destroy(list->list[i]);
- }
- gpr_free(list->list);
- // Clean up in case we re-initialze later.
- // TODO(ctiller): This should ideally live in
- // grpc_proxy_mapper_registry_init(). However, if we did this there,
- // then we would do it AFTER we start registering proxy mappers from
- // third-party plugins, so they'd never show up (and would leak memory).
- // We probably need some sort of dependency system for plugins to fix
- // this.
- memset(list, 0, sizeof(*list));
-}
-
-//
-// plugin
-//
-
-static grpc_proxy_mapper_list g_proxy_mapper_list;
-
-void grpc_proxy_mapper_registry_init() {}
-
-void grpc_proxy_mapper_registry_shutdown() {
- grpc_proxy_mapper_list_destroy(&g_proxy_mapper_list);
-}
-
-void grpc_proxy_mapper_register(bool at_start, grpc_proxy_mapper* mapper) {
- grpc_proxy_mapper_list_register(&g_proxy_mapper_list, at_start, mapper);
-}
-
-bool grpc_proxy_mappers_map_name(grpc_exec_ctx* exec_ctx,
- const char* server_uri,
- const grpc_channel_args* args,
- char** name_to_resolve,
- grpc_channel_args** new_args) {
- return grpc_proxy_mapper_list_map_name(exec_ctx, &g_proxy_mapper_list,
- server_uri, args, name_to_resolve,
- new_args);
-}
-bool grpc_proxy_mappers_map_address(grpc_exec_ctx* exec_ctx,
- const grpc_resolved_address* address,
- const grpc_channel_args* args,
- grpc_resolved_address** new_address,
- grpc_channel_args** new_args) {
- return grpc_proxy_mapper_list_map_address(
- exec_ctx, &g_proxy_mapper_list, address, args, new_address, new_args);
-}
diff --git a/src/core/ext/client_channel/proxy_mapper_registry.h b/src/core/ext/client_channel/proxy_mapper_registry.h
deleted file mode 100644
index 742b57a2d4..0000000000
--- a/src/core/ext/client_channel/proxy_mapper_registry.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *
- * Copyright 2017, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H
-
-#include "src/core/ext/client_channel/proxy_mapper.h"
-
-void grpc_proxy_mapper_registry_init();
-void grpc_proxy_mapper_registry_shutdown();
-
-/// Registers a new proxy mapper. Takes ownership.
-/// If \a at_start is true, the new mapper will be at the beginning of
-/// the list. Otherwise, it will be added to the end.
-void grpc_proxy_mapper_register(bool at_start, grpc_proxy_mapper* mapper);
-
-bool grpc_proxy_mappers_map_name(grpc_exec_ctx* exec_ctx,
- const char* server_uri,
- const grpc_channel_args* args,
- char** name_to_resolve,
- grpc_channel_args** new_args);
-
-bool grpc_proxy_mappers_map_address(grpc_exec_ctx* exec_ctx,
- const grpc_resolved_address* address,
- const grpc_channel_args* args,
- grpc_resolved_address** new_address,
- grpc_channel_args** new_args);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H */
diff --git a/src/core/ext/client_channel/resolver.c b/src/core/ext/client_channel/resolver.c
deleted file mode 100644
index b1a1faa6c9..0000000000
--- a/src/core/ext/client_channel/resolver.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/ext/client_channel/resolver.h"
-#include "src/core/lib/iomgr/combiner.h"
-
-void grpc_resolver_init(grpc_resolver *resolver,
- const grpc_resolver_vtable *vtable,
- grpc_combiner *combiner) {
- resolver->vtable = vtable;
- resolver->combiner = GRPC_COMBINER_REF(combiner, "resolver");
- 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)) {
- grpc_combiner *combiner = resolver->combiner;
- resolver->vtable->destroy(exec_ctx, resolver);
- GRPC_COMBINER_UNREF(exec_ctx, combiner, "resolver");
- }
-}
-
-void grpc_resolver_shutdown_locked(grpc_exec_ctx *exec_ctx,
- grpc_resolver *resolver) {
- resolver->vtable->shutdown_locked(exec_ctx, resolver);
-}
-
-void grpc_resolver_channel_saw_error_locked(grpc_exec_ctx *exec_ctx,
- grpc_resolver *resolver) {
- resolver->vtable->channel_saw_error_locked(exec_ctx, resolver);
-}
-
-void grpc_resolver_next_locked(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
- grpc_channel_args **result,
- grpc_closure *on_complete) {
- resolver->vtable->next_locked(exec_ctx, resolver, result, on_complete);
-}
diff --git a/src/core/ext/client_channel/resolver.h b/src/core/ext/client_channel/resolver.h
deleted file mode 100644
index bbba424ca5..0000000000
--- a/src/core/ext/client_channel/resolver.h
+++ /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.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_H
-
-#include "src/core/ext/client_channel/subchannel.h"
-#include "src/core/lib/iomgr/iomgr.h"
-
-typedef struct grpc_resolver grpc_resolver;
-typedef struct grpc_resolver_vtable grpc_resolver_vtable;
-
-/** \a grpc_resolver provides \a grpc_channel_args objects to its caller */
-struct grpc_resolver {
- const grpc_resolver_vtable *vtable;
- gpr_refcount refs;
- grpc_combiner *combiner;
-};
-
-struct grpc_resolver_vtable {
- void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver);
- void (*shutdown_locked)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver);
- void (*channel_saw_error_locked)(grpc_exec_ctx *exec_ctx,
- grpc_resolver *resolver);
- void (*next_locked)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
- grpc_channel_args **result, 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,
- grpc_combiner *combiner);
-
-void grpc_resolver_shutdown_locked(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.
-
- Must be called from the combiner passed as a resolver_arg at construction
- time.*/
-void grpc_resolver_channel_saw_error_locked(grpc_exec_ctx *exec_ctx,
- grpc_resolver *resolver);
-
-/** Get the next result from the resolver. Expected to set \a *result with
- new channel args and then schedule \a on_complete for execution.
-
- If resolution is fatally broken, set \a *result to NULL and
- schedule \a on_complete.
-
- Must be called from the combiner passed as a resolver_arg at construction
- time.*/
-void grpc_resolver_next_locked(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
- grpc_channel_args **result,
- grpc_closure *on_complete);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_H */
diff --git a/src/core/ext/client_channel/resolver_factory.c b/src/core/ext/client_channel/resolver_factory.c
deleted file mode 100644
index 00bbb92dd0..0000000000
--- a/src/core/ext/client_channel/resolver_factory.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/ext/client_channel/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_exec_ctx* exec_ctx, grpc_resolver_factory* factory,
- grpc_resolver_args* args) {
- if (factory == NULL) return NULL;
- return factory->vtable->create_resolver(exec_ctx, 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/ext/client_channel/resolver_factory.h b/src/core/ext/client_channel/resolver_factory.h
deleted file mode 100644
index e3cd99ec5a..0000000000
--- a/src/core/ext/client_channel/resolver_factory.h
+++ /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.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_FACTORY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_FACTORY_H
-
-#include "src/core/ext/client_channel/client_channel_factory.h"
-#include "src/core/ext/client_channel/resolver.h"
-#include "src/core/ext/client_channel/uri_parser.h"
-#include "src/core/lib/iomgr/pollset_set.h"
-
-typedef struct grpc_resolver_factory grpc_resolver_factory;
-typedef struct grpc_resolver_factory_vtable grpc_resolver_factory_vtable;
-
-struct grpc_resolver_factory {
- const grpc_resolver_factory_vtable *vtable;
-};
-
-typedef struct grpc_resolver_args {
- grpc_uri *uri;
- const grpc_channel_args *args;
- grpc_pollset_set *pollset_set;
- grpc_combiner *combiner;
-} 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_exec_ctx *exec_ctx,
- 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_exec_ctx *exec_ctx, 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_EXT_CLIENT_CHANNEL_RESOLVER_FACTORY_H */
diff --git a/src/core/ext/client_channel/resolver_registry.c b/src/core/ext/client_channel/resolver_registry.c
deleted file mode 100644
index 0f074a3386..0000000000
--- a/src/core/ext/client_channel/resolver_registry.c
+++ /dev/null
@@ -1,174 +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/ext/client_channel/resolver_registry.h"
-
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-
-#define MAX_RESOLVERS 10
-#define DEFAULT_RESOLVER_PREFIX_MAX_LENGTH 32
-
-static grpc_resolver_factory *g_all_of_the_resolvers[MAX_RESOLVERS];
-static int g_number_of_resolvers = 0;
-
-static char g_default_resolver_prefix[DEFAULT_RESOLVER_PREFIX_MAX_LENGTH] =
- "dns:///";
-
-void grpc_resolver_registry_init() {}
-
-void grpc_resolver_registry_shutdown(void) {
- for (int i = 0; i < g_number_of_resolvers; i++) {
- grpc_resolver_factory_unref(g_all_of_the_resolvers[i]);
- }
- // FIXME(ctiller): this should live in grpc_resolver_registry_init,
- // however that would have the client_channel plugin call this AFTER we start
- // registering resolvers from third party plugins, and so they'd never show
- // up.
- // We likely need some kind of dependency system for plugins.... what form
- // that takes is TBD.
- g_number_of_resolvers = 0;
-}
-
-void grpc_resolver_registry_set_default_prefix(
- const char *default_resolver_prefix) {
- const size_t len = strlen(default_resolver_prefix);
- GPR_ASSERT(len < DEFAULT_RESOLVER_PREFIX_MAX_LENGTH &&
- "default resolver prefix too long");
- GPR_ASSERT(len > 0 && "default resolver prefix can't be empty");
- // By the previous assert, default_resolver_prefix is safe to be copied with a
- // plain strcpy.
- strcpy(g_default_resolver_prefix, 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(const char *name) {
- int i;
-
- for (i = 0; i < g_number_of_resolvers; i++) {
- if (0 == strcmp(name, g_all_of_the_resolvers[i]->vtable->scheme)) {
- return g_all_of_the_resolvers[i];
- }
- }
- return NULL;
-}
-
-grpc_resolver_factory *grpc_resolver_factory_lookup(const char *name) {
- grpc_resolver_factory *f = lookup_factory(name);
- if (f) grpc_resolver_factory_ref(f);
- return f;
-}
-
-static grpc_resolver_factory *lookup_factory_by_uri(grpc_uri *uri) {
- if (!uri) return NULL;
- return lookup_factory(uri->scheme);
-}
-
-static grpc_resolver_factory *resolve_factory(grpc_exec_ctx *exec_ctx,
- const char *target,
- grpc_uri **uri,
- char **canonical_target) {
- grpc_resolver_factory *factory = NULL;
-
- GPR_ASSERT(uri != NULL);
- *uri = grpc_uri_parse(exec_ctx, target, 1);
- factory = lookup_factory_by_uri(*uri);
- if (factory == NULL) {
- grpc_uri_destroy(*uri);
- gpr_asprintf(canonical_target, "%s%s", g_default_resolver_prefix, target);
- *uri = grpc_uri_parse(exec_ctx, *canonical_target, 1);
- factory = lookup_factory_by_uri(*uri);
- if (factory == NULL) {
- grpc_uri_destroy(grpc_uri_parse(exec_ctx, target, 0));
- grpc_uri_destroy(grpc_uri_parse(exec_ctx, *canonical_target, 0));
- gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target,
- *canonical_target);
- }
- }
- return factory;
-}
-
-grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
- const grpc_channel_args *args,
- grpc_pollset_set *pollset_set,
- grpc_combiner *combiner) {
- grpc_uri *uri = NULL;
- char *canonical_target = NULL;
- grpc_resolver_factory *factory =
- resolve_factory(exec_ctx, target, &uri, &canonical_target);
- grpc_resolver *resolver;
- grpc_resolver_args resolver_args;
- memset(&resolver_args, 0, sizeof(resolver_args));
- resolver_args.uri = uri;
- resolver_args.args = args;
- resolver_args.pollset_set = pollset_set;
- resolver_args.combiner = combiner;
- resolver =
- grpc_resolver_factory_create_resolver(exec_ctx, factory, &resolver_args);
- grpc_uri_destroy(uri);
- gpr_free(canonical_target);
- return resolver;
-}
-
-char *grpc_get_default_authority(grpc_exec_ctx *exec_ctx, const char *target) {
- grpc_uri *uri = NULL;
- char *canonical_target = NULL;
- grpc_resolver_factory *factory =
- resolve_factory(exec_ctx, target, &uri, &canonical_target);
- char *authority = grpc_resolver_factory_get_default_authority(factory, uri);
- grpc_uri_destroy(uri);
- gpr_free(canonical_target);
- return authority;
-}
-
-char *grpc_resolver_factory_add_default_prefix_if_needed(
- grpc_exec_ctx *exec_ctx, const char *target) {
- grpc_uri *uri = NULL;
- char *canonical_target = NULL;
- resolve_factory(exec_ctx, target, &uri, &canonical_target);
- grpc_uri_destroy(uri);
- return canonical_target == NULL ? gpr_strdup(target) : canonical_target;
-}
diff --git a/src/core/ext/client_channel/resolver_registry.h b/src/core/ext/client_channel/resolver_registry.h
deleted file mode 100644
index 1a3ebee25a..0000000000
--- a/src/core/ext/client_channel/resolver_registry.h
+++ /dev/null
@@ -1,84 +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_EXT_CLIENT_CHANNEL_RESOLVER_REGISTRY_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_REGISTRY_H
-
-#include "src/core/ext/client_channel/resolver_factory.h"
-#include "src/core/lib/iomgr/pollset_set.h"
-
-void grpc_resolver_registry_init();
-void grpc_resolver_registry_shutdown(void);
-
-/** Set the default URI prefix to \a default_prefix. */
-void grpc_resolver_registry_set_default_prefix(const char *default_prefix);
-
-/** 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.
- \a args is a set of channel arguments to be included in the result
- (typically the set of arguments passed in from the client API).
- \a pollset_set is used to drive IO in the name resolution process, it
- should not be NULL. */
-grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
- const grpc_channel_args *args,
- grpc_pollset_set *pollset_set,
- grpc_combiner *combiner);
-
-/** Find a resolver factory given a name and return an (owned-by-the-caller)
- * reference to it */
-grpc_resolver_factory *grpc_resolver_factory_lookup(const char *name);
-
-/** Given a target, return a (freshly allocated with gpr_malloc) string
- representing the default authority to pass from a client. */
-char *grpc_get_default_authority(grpc_exec_ctx *exec_ctx, const char *target);
-
-/** Returns a newly allocated string containing \a target, adding the
- default prefix if needed. */
-char *grpc_resolver_factory_add_default_prefix_if_needed(
- grpc_exec_ctx *exec_ctx, const char *target);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_REGISTRY_H */
diff --git a/src/core/ext/client_channel/retry_throttle.c b/src/core/ext/client_channel/retry_throttle.c
deleted file mode 100644
index 8926c3d782..0000000000
--- a/src/core/ext/client_channel/retry_throttle.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- *
- * Copyright 2017, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING 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/ext/client_channel/retry_throttle.h"
-
-#include <limits.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/atm.h>
-#include <grpc/support/avl.h>
-#include <grpc/support/string_util.h>
-#include <grpc/support/sync.h>
-
-//
-// server_retry_throttle_data
-//
-
-struct grpc_server_retry_throttle_data {
- gpr_refcount refs;
- int max_milli_tokens;
- int milli_token_ratio;
- gpr_atm milli_tokens;
- // A pointer to the replacement for this grpc_server_retry_throttle_data
- // entry. If non-NULL, then this entry is stale and must not be used.
- // We hold a reference to the replacement.
- gpr_atm replacement;
-};
-
-static void get_replacement_throttle_data_if_needed(
- grpc_server_retry_throttle_data** throttle_data) {
- while (true) {
- grpc_server_retry_throttle_data* new_throttle_data =
- (grpc_server_retry_throttle_data*)gpr_atm_acq_load(
- &(*throttle_data)->replacement);
- if (new_throttle_data == NULL) return;
- *throttle_data = new_throttle_data;
- }
-}
-
-bool grpc_server_retry_throttle_data_record_failure(
- grpc_server_retry_throttle_data* throttle_data) {
- // First, check if we are stale and need to be replaced.
- get_replacement_throttle_data_if_needed(&throttle_data);
- // We decrement milli_tokens by 1000 (1 token) for each failure.
- const int new_value = (int)gpr_atm_no_barrier_clamped_add(
- &throttle_data->milli_tokens, (gpr_atm)-1000, (gpr_atm)0,
- (gpr_atm)throttle_data->max_milli_tokens);
- // Retries are allowed as long as the new value is above the threshold
- // (max_milli_tokens / 2).
- return new_value > throttle_data->max_milli_tokens / 2;
-}
-
-void grpc_server_retry_throttle_data_record_success(
- grpc_server_retry_throttle_data* throttle_data) {
- // First, check if we are stale and need to be replaced.
- get_replacement_throttle_data_if_needed(&throttle_data);
- // We increment milli_tokens by milli_token_ratio for each success.
- gpr_atm_no_barrier_clamped_add(
- &throttle_data->milli_tokens, (gpr_atm)throttle_data->milli_token_ratio,
- (gpr_atm)0, (gpr_atm)throttle_data->max_milli_tokens);
-}
-
-grpc_server_retry_throttle_data* grpc_server_retry_throttle_data_ref(
- grpc_server_retry_throttle_data* throttle_data) {
- gpr_ref(&throttle_data->refs);
- return throttle_data;
-}
-
-void grpc_server_retry_throttle_data_unref(
- grpc_server_retry_throttle_data* throttle_data) {
- if (gpr_unref(&throttle_data->refs)) {
- grpc_server_retry_throttle_data* replacement =
- (grpc_server_retry_throttle_data*)gpr_atm_acq_load(
- &throttle_data->replacement);
- if (replacement != NULL) {
- grpc_server_retry_throttle_data_unref(replacement);
- }
- gpr_free(throttle_data);
- }
-}
-
-static grpc_server_retry_throttle_data* grpc_server_retry_throttle_data_create(
- int max_milli_tokens, int milli_token_ratio,
- grpc_server_retry_throttle_data* old_throttle_data) {
- grpc_server_retry_throttle_data* throttle_data =
- gpr_malloc(sizeof(*throttle_data));
- memset(throttle_data, 0, sizeof(*throttle_data));
- gpr_ref_init(&throttle_data->refs, 1);
- throttle_data->max_milli_tokens = max_milli_tokens;
- throttle_data->milli_token_ratio = milli_token_ratio;
- int initial_milli_tokens = max_milli_tokens;
- // If there was a pre-existing entry for this server name, initialize
- // the token count by scaling proportionately to the old data. This
- // ensures that if we're already throttling retries on the old scale,
- // we will start out doing the same thing on the new one.
- if (old_throttle_data != NULL) {
- double token_fraction =
- (int)gpr_atm_acq_load(&old_throttle_data->milli_tokens) /
- (double)old_throttle_data->max_milli_tokens;
- initial_milli_tokens = (int)(token_fraction * max_milli_tokens);
- }
- gpr_atm_rel_store(&throttle_data->milli_tokens,
- (gpr_atm)initial_milli_tokens);
- // If there was a pre-existing entry, mark it as stale and give it a
- // pointer to the new entry, which is its replacement.
- if (old_throttle_data != NULL) {
- grpc_server_retry_throttle_data_ref(throttle_data);
- gpr_atm_rel_store(&old_throttle_data->replacement, (gpr_atm)throttle_data);
- }
- return throttle_data;
-}
-
-//
-// avl vtable for string -> server_retry_throttle_data map
-//
-
-static void* copy_server_name(void* key) { return gpr_strdup(key); }
-
-static long compare_server_name(void* key1, void* key2) {
- return strcmp(key1, key2);
-}
-
-static void destroy_server_retry_throttle_data(void* value) {
- grpc_server_retry_throttle_data* throttle_data = value;
- grpc_server_retry_throttle_data_unref(throttle_data);
-}
-
-static void* copy_server_retry_throttle_data(void* value) {
- grpc_server_retry_throttle_data* throttle_data = value;
- return grpc_server_retry_throttle_data_ref(throttle_data);
-}
-
-static const gpr_avl_vtable avl_vtable = {
- gpr_free /* destroy_key */, copy_server_name, compare_server_name,
- destroy_server_retry_throttle_data, copy_server_retry_throttle_data};
-
-//
-// server_retry_throttle_map
-//
-
-static gpr_mu g_mu;
-static gpr_avl g_avl;
-
-void grpc_retry_throttle_map_init() {
- gpr_mu_init(&g_mu);
- g_avl = gpr_avl_create(&avl_vtable);
-}
-
-void grpc_retry_throttle_map_shutdown() {
- gpr_mu_destroy(&g_mu);
- gpr_avl_unref(g_avl);
-}
-
-grpc_server_retry_throttle_data* grpc_retry_throttle_map_get_data_for_server(
- const char* server_name, int max_milli_tokens, int milli_token_ratio) {
- gpr_mu_lock(&g_mu);
- grpc_server_retry_throttle_data* throttle_data =
- gpr_avl_get(g_avl, (char*)server_name);
- if (throttle_data == NULL) {
- // Entry not found. Create a new one.
- throttle_data = grpc_server_retry_throttle_data_create(
- max_milli_tokens, milli_token_ratio, NULL);
- g_avl = gpr_avl_add(g_avl, (char*)server_name, throttle_data);
- } else {
- if (throttle_data->max_milli_tokens != max_milli_tokens ||
- throttle_data->milli_token_ratio != milli_token_ratio) {
- // Entry found but with old parameters. Create a new one based on
- // the original one.
- throttle_data = grpc_server_retry_throttle_data_create(
- max_milli_tokens, milli_token_ratio, throttle_data);
- g_avl = gpr_avl_add(g_avl, (char*)server_name, throttle_data);
- } else {
- // Entry found. Increase refcount.
- grpc_server_retry_throttle_data_ref(throttle_data);
- }
- }
- gpr_mu_unlock(&g_mu);
- return throttle_data;
-}
diff --git a/src/core/ext/client_channel/retry_throttle.h b/src/core/ext/client_channel/retry_throttle.h
deleted file mode 100644
index f9971faf65..0000000000
--- a/src/core/ext/client_channel/retry_throttle.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *
- * Copyright 2017, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_RETRY_THROTTLE_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_RETRY_THROTTLE_H
-
-#include <stdbool.h>
-
-/// Tracks retry throttling data for an individual server name.
-typedef struct grpc_server_retry_throttle_data grpc_server_retry_throttle_data;
-
-/// Records a failure. Returns true if it's okay to send a retry.
-bool grpc_server_retry_throttle_data_record_failure(
- grpc_server_retry_throttle_data* throttle_data);
-/// Records a success.
-void grpc_server_retry_throttle_data_record_success(
- grpc_server_retry_throttle_data* throttle_data);
-
-grpc_server_retry_throttle_data* grpc_server_retry_throttle_data_ref(
- grpc_server_retry_throttle_data* throttle_data);
-void grpc_server_retry_throttle_data_unref(
- grpc_server_retry_throttle_data* throttle_data);
-
-/// Initializes global map of failure data for each server name.
-void grpc_retry_throttle_map_init();
-/// Shuts down global map of failure data for each server name.
-void grpc_retry_throttle_map_shutdown();
-
-/// Returns a reference to the failure data for \a server_name, creating
-/// a new entry if needed.
-/// Caller must eventually unref via \a grpc_server_retry_throttle_data_unref().
-grpc_server_retry_throttle_data* grpc_retry_throttle_map_get_data_for_server(
- const char* server_name, int max_milli_tokens, int milli_token_ratio);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_RETRY_THROTTLE_H */
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
deleted file mode 100644
index 063c0badff..0000000000
--- a/src/core/ext/client_channel/subchannel.c
+++ /dev/null
@@ -1,839 +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/ext/client_channel/subchannel.h"
-
-#include <limits.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/avl.h>
-#include <grpc/support/string_util.h>
-
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/parse_address.h"
-#include "src/core/ext/client_channel/proxy_mapper_registry.h"
-#include "src/core/ext/client_channel/subchannel_index.h"
-#include "src/core/ext/client_channel/uri_parser.h"
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/iomgr/timer.h"
-#include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/slice/slice_internal.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))
-
-#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;
-
- grpc_subchannel_key *key;
-
- /** set during connection */
- grpc_connect_out_args connecting_result;
-
- /** callback for connection finishing */
- grpc_closure connected;
-
- /** callback for our alarm */
- grpc_closure on_alarm;
-
- /** 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? */
- bool disconnected;
- /** are we connecting */
- bool 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? */
- bool have_alarm;
- /** have we started the backoff loop */
- bool backoff_begun;
- /** our alarm */
- grpc_timer alarm;
-};
-
-struct grpc_subchannel_call {
- grpc_connected_subchannel *connection;
- grpc_closure *schedule_closure_after_destroy;
-};
-
-#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,
- grpc_error *error);
-
-#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,
- grpc_error *error) {
- grpc_connected_subchannel *c = arg;
- grpc_channel_stack_destroy(exec_ctx, CHANNEL_STACK_FROM_CONNECTION(c));
- gpr_free(c);
-}
-
-grpc_connected_subchannel *grpc_connected_subchannel_ref(
- grpc_connected_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
- GRPC_CHANNEL_STACK_REF(CHANNEL_STACK_FROM_CONNECTION(c), REF_REASON);
- return c;
-}
-
-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,
- grpc_error *error) {
- grpc_subchannel *c = arg;
- gpr_free((void *)c->filters);
- grpc_channel_args_destroy(exec_ctx, c->args);
- grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
- grpc_connector_unref(exec_ctx, c->connector);
- grpc_pollset_set_destroy(exec_ctx, 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 %s 0x%08" PRIxPTR " -> 0x%08" PRIxPTR " [%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 = true;
- grpc_connector_shutdown(
- exec_ctx, c->connector,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Subchannel disconnected"));
- 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, (gpr_atm)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_closure_sched(exec_ctx, grpc_closure_create(subchannel_destroy, c,
- grpc_schedule_on_exec_ctx),
- GRPC_ERROR_NONE);
- }
-}
-
-grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
- grpc_connector *connector,
- const 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_zalloc(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->pollset_set = grpc_pollset_set_create();
- grpc_resolved_address *addr = gpr_malloc(sizeof(*addr));
- grpc_get_subchannel_address_arg(exec_ctx, args->args, addr);
- grpc_resolved_address *new_address = NULL;
- grpc_channel_args *new_args = NULL;
- if (grpc_proxy_mappers_map_address(exec_ctx, addr, args->args, &new_address,
- &new_args)) {
- GPR_ASSERT(new_address != NULL);
- gpr_free(addr);
- addr = new_address;
- }
- static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS};
- grpc_arg new_arg = grpc_create_subchannel_address_arg(addr);
- gpr_free(addr);
- c->args = grpc_channel_args_copy_and_add_and_remove(
- new_args != NULL ? new_args : args->args, keys_to_remove,
- GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1);
- gpr_free(new_arg.value.string);
- if (new_args != NULL) grpc_channel_args_destroy(exec_ctx, new_args);
- 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_schedule_on_exec_ctx);
- grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE,
- "subchannel");
- int initial_backoff_ms =
- GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000;
- int max_backoff_ms = GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS * 1000;
- int min_backoff_ms = GRPC_SUBCHANNEL_MIN_CONNECT_TIMEOUT_SECONDS * 1000;
- bool fixed_reconnect_backoff = false;
- 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_ms")) {
- GPR_ASSERT(c->args->args[i].type == GRPC_ARG_INTEGER);
- fixed_reconnect_backoff = true;
- initial_backoff_ms = min_backoff_ms = max_backoff_ms =
- grpc_channel_arg_get_integer(
- &c->args->args[i],
- (grpc_integer_options){initial_backoff_ms, 100, INT_MAX});
- } else if (0 == strcmp(c->args->args[i].key,
- GRPC_ARG_MAX_RECONNECT_BACKOFF_MS)) {
- fixed_reconnect_backoff = false;
- max_backoff_ms = grpc_channel_arg_get_integer(
- &c->args->args[i],
- (grpc_integer_options){max_backoff_ms, 100, INT_MAX});
- } else if (0 == strcmp(c->args->args[i].key,
- GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS)) {
- fixed_reconnect_backoff = false;
- initial_backoff_ms = grpc_channel_arg_get_integer(
- &c->args->args[i],
- (grpc_integer_options){initial_backoff_ms, 100, INT_MAX});
- }
- }
- }
- gpr_backoff_init(
- &c->backoff_state, initial_backoff_ms,
- fixed_reconnect_backoff ? 1.0
- : GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER,
- fixed_reconnect_backoff ? 0.0 : GRPC_SUBCHANNEL_RECONNECT_JITTER,
- min_backoff_ms, max_backoff_ms);
- gpr_mu_init(&c->mu);
-
- return grpc_subchannel_index_register(exec_ctx, key, c);
-}
-
-static void continue_connect_locked(grpc_exec_ctx *exec_ctx,
- grpc_subchannel *c) {
- grpc_connect_in_args args;
-
- args.interested_parties = c->pollset_set;
- args.deadline = c->next_attempt;
- args.channel_args = c->args;
-
- grpc_connectivity_state_set(exec_ctx, &c->state_tracker,
- GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
- "state_change");
- grpc_connector_connect(exec_ctx, c->connector, &args, &c->connecting_result,
- &c->connected);
-}
-
-grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel *c,
- grpc_error **error) {
- grpc_connectivity_state state;
- gpr_mu_lock(&c->mu);
- state = grpc_connectivity_state_get(&c->state_tracker, error);
- gpr_mu_unlock(&c->mu);
- return state;
-}
-
-static void on_external_state_watcher_done(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error) {
- 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);
- grpc_closure_run(exec_ctx, follow_up, GRPC_ERROR_REF(error));
-}
-
-static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
- grpc_subchannel *c = arg;
- gpr_mu_lock(&c->mu);
- c->have_alarm = false;
- if (c->disconnected) {
- error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected",
- &error, 1);
- } else {
- GRPC_ERROR_REF(error);
- }
- if (error == GRPC_ERROR_NONE) {
- gpr_log(GPR_INFO, "Failed to connect to channel, retrying");
- c->next_attempt =
- gpr_backoff_step(&c->backoff_state, gpr_now(GPR_CLOCK_MONOTONIC));
- continue_connect_locked(exec_ctx, c);
- gpr_mu_unlock(&c->mu);
- } else {
- gpr_mu_unlock(&c->mu);
- GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
- }
- GRPC_ERROR_UNREF(error);
-}
-
-static void maybe_start_connecting_locked(grpc_exec_ctx *exec_ctx,
- grpc_subchannel *c) {
- if (c->disconnected) {
- /* Don't try to connect if we're already disconnected */
- return;
- }
-
- if (c->connecting) {
- /* Already connecting: don't restart */
- return;
- }
-
- if (GET_CONNECTED_SUBCHANNEL(c, no_barrier) != NULL) {
- /* Already connected: don't restart */
- return;
- }
-
- if (!grpc_connectivity_state_has_watchers(&c->state_tracker)) {
- /* Nobody is interested in connecting: so don't just yet */
- return;
- }
-
- c->connecting = true;
- GRPC_SUBCHANNEL_WEAK_REF(c, "connecting");
-
- gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
- if (!c->backoff_begun) {
- c->backoff_begun = true;
- c->next_attempt = gpr_backoff_begin(&c->backoff_state, now);
- continue_connect_locked(exec_ctx, c);
- } else {
- GPR_ASSERT(!c->have_alarm);
- c->have_alarm = true;
- gpr_timespec time_til_next = gpr_time_sub(c->next_attempt, now);
- if (gpr_time_cmp(time_til_next, gpr_time_0(time_til_next.clock_type)) <=
- 0) {
- gpr_log(GPR_INFO, "Retry immediately");
- } else {
- gpr_log(GPR_INFO, "Retry in %" PRId64 ".%09d seconds",
- time_til_next.tv_sec, time_til_next.tv_nsec);
- }
- grpc_closure_init(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx);
- grpc_timer_init(exec_ctx, &c->alarm, c->next_attempt, &c->on_alarm, now);
- }
-}
-
-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,
- grpc_schedule_on_exec_ctx);
- 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;
- grpc_connectivity_state_notify_on_state_change(exec_ctx, &c->state_tracker,
- state, &w->closure);
- maybe_start_connecting_locked(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,
- grpc_error *error) {
- 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 (sw->connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
- /* any errors on a subchannel ==> we're done, create a new one */
- sw->connectivity_state = GRPC_CHANNEL_SHUTDOWN;
- }
- grpc_connectivity_state_set(exec_ctx, &c->state_tracker,
- sw->connectivity_state, GRPC_ERROR_REF(error),
- "reflect_child");
- if (sw->connectivity_state != GRPC_CHANNEL_SHUTDOWN) {
- 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_make_transport_op(NULL);
- grpc_channel_element *elem;
- 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_make_transport_op(NULL);
- grpc_channel_element *elem;
- 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 */
- grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
- grpc_channel_stack_builder_set_channel_arguments(
- exec_ctx, builder, c->connecting_result.channel_args);
- grpc_channel_stack_builder_set_transport(builder,
- c->connecting_result.transport);
-
- if (!grpc_channel_init_create_stack(exec_ctx, builder,
- GRPC_CLIENT_SUBCHANNEL)) {
- grpc_channel_stack_builder_destroy(exec_ctx, builder);
- abort(); /* TODO(ctiller): what to do here (previously we just crashed) */
- }
- grpc_error *error = grpc_channel_stack_builder_finish(
- exec_ctx, builder, 0, 1, connection_destroy, NULL, (void **)&con);
- if (error != GRPC_ERROR_NONE) {
- gpr_log(GPR_ERROR, "error initializing subchannel stack: %s",
- grpc_error_string(error));
- GRPC_ERROR_UNREF(error);
- abort(); /* TODO(ctiller): what to do here? */
- }
- 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, grpc_schedule_on_exec_ctx);
-
- 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));
-
- /* 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,
- GRPC_ERROR_NONE, "connected");
-}
-
-static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error) {
- grpc_subchannel *c = arg;
- grpc_channel_args *delete_channel_args = c->connecting_result.channel_args;
-
- GRPC_SUBCHANNEL_WEAK_REF(c, "connected");
- gpr_mu_lock(&c->mu);
- c->connecting = false;
- 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 {
- grpc_connectivity_state_set(
- exec_ctx, &c->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
- grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Connect Failed", &error, 1),
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
- "connect_failed");
-
- const char *errmsg = grpc_error_string(error);
- gpr_log(GPR_INFO, "Connect failed: %s", errmsg);
-
- maybe_start_connecting_locked(exec_ctx, c);
- GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
- }
- gpr_mu_unlock(&c->mu);
- GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connected");
- grpc_channel_args_destroy(exec_ctx, delete_channel_args);
-}
-
-/*
- * grpc_subchannel_call implementation
- */
-
-static void subchannel_call_destroy(grpc_exec_ctx *exec_ctx, void *call,
- grpc_error *error) {
- grpc_subchannel_call *c = call;
- GPR_ASSERT(c->schedule_closure_after_destroy != NULL);
- GPR_TIMER_BEGIN("grpc_subchannel_call_unref.destroy", 0);
- grpc_connected_subchannel *connection = c->connection;
- grpc_call_stack_destroy(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c), NULL,
- c->schedule_closure_after_destroy);
- GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, connection, "subchannel_call");
- GPR_TIMER_END("grpc_subchannel_call_unref.destroy", 0);
-}
-
-void grpc_subchannel_call_set_cleanup_closure(grpc_subchannel_call *call,
- grpc_closure *closure) {
- GPR_ASSERT(call->schedule_closure_after_destroy == NULL);
- GPR_ASSERT(closure != NULL);
- call->schedule_closure_after_destroy = closure;
-}
-
-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) {
- GPR_TIMER_BEGIN("grpc_subchannel_call_process_op", 0);
- 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);
- GPR_TIMER_END("grpc_subchannel_call_process_op", 0);
-}
-
-grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel(
- grpc_subchannel *c) {
- return GET_CONNECTED_SUBCHANNEL(c, acq);
-}
-
-grpc_error *grpc_connected_subchannel_create_call(
- grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con,
- const grpc_connected_subchannel_call_args *args,
- grpc_subchannel_call **call) {
- grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
- *call = gpr_arena_alloc(
- args->arena, sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
- grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
- (*call)->connection = con; // Ref is added below.
- const grpc_call_element_args call_args = {.call_stack = callstk,
- .server_transport_data = NULL,
- .context = NULL,
- .path = args->path,
- .start_time = args->start_time,
- .deadline = args->deadline,
- .arena = args->arena};
- grpc_error *error = grpc_call_stack_init(
- exec_ctx, chanstk, 1, subchannel_call_destroy, *call, &call_args);
- if (error != GRPC_ERROR_NONE) {
- const char *error_string = grpc_error_string(error);
- gpr_log(GPR_ERROR, "error: %s", error_string);
-
- gpr_free(*call);
- return error;
- }
- GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call");
- grpc_call_stack_set_pollset_or_pollset_set(exec_ctx, callstk, args->pollent);
- return GRPC_ERROR_NONE;
-}
-
-grpc_call_stack *grpc_subchannel_call_get_call_stack(
- grpc_subchannel_call *subchannel_call) {
- return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
-}
-
-static void grpc_uri_to_sockaddr(grpc_exec_ctx *exec_ctx, const char *uri_str,
- grpc_resolved_address *addr) {
- grpc_uri *uri = grpc_uri_parse(exec_ctx, uri_str, 0 /* suppress_errors */);
- GPR_ASSERT(uri != NULL);
- if (strcmp(uri->scheme, "ipv4") == 0) {
- GPR_ASSERT(parse_ipv4(uri, addr));
- } else if (strcmp(uri->scheme, "ipv6") == 0) {
- GPR_ASSERT(parse_ipv6(uri, addr));
- } else {
- GPR_ASSERT(parse_unix(uri, addr));
- }
- grpc_uri_destroy(uri);
-}
-
-void grpc_get_subchannel_address_arg(grpc_exec_ctx *exec_ctx,
- const grpc_channel_args *args,
- grpc_resolved_address *addr) {
- const char *addr_uri_str = grpc_get_subchannel_address_uri_arg(args);
- memset(addr, 0, sizeof(*addr));
- if (*addr_uri_str != '\0') {
- grpc_uri_to_sockaddr(exec_ctx, addr_uri_str, addr);
- }
-}
-
-const char *grpc_get_subchannel_address_uri_arg(const grpc_channel_args *args) {
- const grpc_arg *addr_arg =
- grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS);
- GPR_ASSERT(addr_arg != NULL); // Should have been set by LB policy.
- GPR_ASSERT(addr_arg->type == GRPC_ARG_STRING);
- return addr_arg->value.string;
-}
-
-grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr) {
- grpc_arg new_arg;
- new_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
- new_arg.type = GRPC_ARG_STRING;
- new_arg.value.string =
- addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("");
- return new_arg;
-}
diff --git a/src/core/ext/client_channel/subchannel.h b/src/core/ext/client_channel/subchannel.h
deleted file mode 100644
index 3e64a2507c..0000000000
--- a/src/core/ext/client_channel/subchannel.h
+++ /dev/null
@@ -1,203 +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_EXT_CLIENT_CHANNEL_SUBCHANNEL_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_H
-
-#include "src/core/ext/client_channel/connector.h"
-#include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/iomgr/polling_entity.h"
-#include "src/core/lib/support/arena.h"
-#include "src/core/lib/transport/connectivity_state.h"
-#include "src/core/lib/transport/metadata.h"
-
-// Channel arg containing a grpc_resolved_address to connect to.
-#define GRPC_ARG_SUBCHANNEL_ADDRESS "grpc.subchannel_address"
-
-/** 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);
-grpc_connected_subchannel *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 */
-typedef struct {
- grpc_polling_entity *pollent;
- grpc_slice path;
- gpr_timespec start_time;
- gpr_timespec deadline;
- gpr_arena *arena;
-} grpc_connected_subchannel_call_args;
-
-grpc_error *grpc_connected_subchannel_create_call(
- grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel,
- const grpc_connected_subchannel_call_args *args,
- grpc_subchannel_call **subchannel_call);
-
-/** 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, grpc_error **error);
-
-/** 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);
-
-/** Must be called once per call. Sets the 'then_schedule_closure' argument for
- call stack destruction. */
-void grpc_subchannel_call_set_cleanup_closure(
- grpc_subchannel_call *subchannel_call, grpc_closure *closure);
-
-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;
-};
-
-/** create a subchannel given a connector */
-grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
- grpc_connector *connector,
- const grpc_subchannel_args *args);
-
-/// Sets \a addr from \a args.
-void grpc_get_subchannel_address_arg(grpc_exec_ctx *exec_ctx,
- const grpc_channel_args *args,
- grpc_resolved_address *addr);
-
-/// Returns the URI string for the address to connect to.
-const char *grpc_get_subchannel_address_uri_arg(const grpc_channel_args *args);
-
-/// Returns a new channel arg encoding the subchannel address as a string.
-/// Caller is responsible for freeing the string.
-grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_H */
diff --git a/src/core/ext/client_channel/subchannel_index.c b/src/core/ext/client_channel/subchannel_index.c
deleted file mode 100644
index 11889300a2..0000000000
--- a/src/core/ext/client_channel/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/ext/client_channel/subchannel_index.h"
-
-#include <stdbool.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/avl.h>
-#include <grpc/support/string_util.h>
-#include <grpc/support/tls.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
-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, const 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;
- if (k->args.filter_count > 0) {
- 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);
- } else {
- k->args.filters = NULL;
- }
- k->args.args = copy_channel_args(args->args);
- return k;
-}
-
-grpc_subchannel_key *grpc_subchannel_key_create(
- grpc_connector *connector, const 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.filter_count, b->args.filter_count);
- if (c != 0) return c;
- if (a->args.filter_count > 0) {
- 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((grpc_channel_args *)k->args.filters);
- grpc_channel_args_destroy(exec_ctx, (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/ext/client_channel/subchannel_index.h b/src/core/ext/client_channel/subchannel_index.h
deleted file mode 100644
index a67bd5e219..0000000000
--- a/src/core/ext/client_channel/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_EXT_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H
-
-#include "src/core/ext/client_channel/connector.h"
-#include "src/core/ext/client_channel/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, const 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_EXT_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H */
diff --git a/src/core/ext/client_channel/uri_parser.c b/src/core/ext/client_channel/uri_parser.c
deleted file mode 100644
index d385db0801..0000000000
--- a/src/core/ext/client_channel/uri_parser.c
+++ /dev/null
@@ -1,315 +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/ext/client_channel/uri_parser.h"
-
-#include <string.h>
-
-#include <grpc/slice_buffer.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
-#include <grpc/support/string_util.h>
-
-#include "src/core/lib/slice/percent_encoding.h"
-#include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
-
-/** a size_t default value... maps to all 1's */
-#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 percent decoded \a src[begin, end) */
-static char *decode_and_copy_component(grpc_exec_ctx *exec_ctx, const char *src,
- size_t begin, size_t end) {
- grpc_slice component =
- grpc_slice_from_copied_buffer(src + begin, end - begin);
- grpc_slice decoded_component =
- grpc_permissive_percent_decode_slice(component);
- char *out = grpc_dump_slice(decoded_component, GPR_DUMP_ASCII);
- grpc_slice_unref_internal(exec_ctx, component);
- grpc_slice_unref_internal(exec_ctx, decoded_component);
- 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;
-}
-
-static void parse_query_parts(grpc_uri *uri) {
- static const char *QUERY_PARTS_SEPARATOR = "&";
- static const char *QUERY_PARTS_VALUE_SEPARATOR = "=";
- GPR_ASSERT(uri->query != NULL);
- if (uri->query[0] == '\0') {
- uri->query_parts = NULL;
- uri->query_parts_values = NULL;
- uri->num_query_parts = 0;
- return;
- }
-
- gpr_string_split(uri->query, QUERY_PARTS_SEPARATOR, &uri->query_parts,
- &uri->num_query_parts);
- uri->query_parts_values = gpr_malloc(uri->num_query_parts * sizeof(char **));
- for (size_t i = 0; i < uri->num_query_parts; i++) {
- char **query_param_parts;
- size_t num_query_param_parts;
- char *full = uri->query_parts[i];
- gpr_string_split(full, QUERY_PARTS_VALUE_SEPARATOR, &query_param_parts,
- &num_query_param_parts);
- GPR_ASSERT(num_query_param_parts > 0);
- uri->query_parts[i] = query_param_parts[0];
- if (num_query_param_parts > 1) {
- /* TODO(dgq): only the first value after the separator is considered.
- * Perhaps all chars after the first separator for the query part should
- * be included, even if they include the separator. */
- uri->query_parts_values[i] = query_param_parts[1];
- } else {
- uri->query_parts_values[i] = NULL;
- }
- for (size_t j = 2; j < num_query_param_parts; j++) {
- gpr_free(query_param_parts[j]);
- }
- gpr_free(query_param_parts);
- gpr_free(full);
- }
-}
-
-grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text,
- int suppress_errors) {
- grpc_uri *uri;
- size_t scheme_begin = 0;
- size_t scheme_end = NOT_SET;
- 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_zalloc(sizeof(*uri));
- uri->scheme =
- decode_and_copy_component(exec_ctx, uri_text, scheme_begin, scheme_end);
- uri->authority = decode_and_copy_component(exec_ctx, uri_text,
- authority_begin, authority_end);
- uri->path =
- decode_and_copy_component(exec_ctx, uri_text, path_begin, path_end);
- uri->query =
- decode_and_copy_component(exec_ctx, uri_text, query_begin, query_end);
- uri->fragment = decode_and_copy_component(exec_ctx, uri_text, fragment_begin,
- fragment_end);
- parse_query_parts(uri);
-
- return uri;
-}
-
-const char *grpc_uri_get_query_arg(const grpc_uri *uri, const char *key) {
- GPR_ASSERT(key != NULL);
- if (key[0] == '\0') return NULL;
-
- for (size_t i = 0; i < uri->num_query_parts; ++i) {
- if (0 == strcmp(key, uri->query_parts[i])) {
- return uri->query_parts_values[i];
- }
- }
- return NULL;
-}
-
-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);
- for (size_t i = 0; i < uri->num_query_parts; ++i) {
- gpr_free(uri->query_parts[i]);
- gpr_free(uri->query_parts_values[i]);
- }
- gpr_free(uri->query_parts);
- gpr_free(uri->query_parts_values);
- gpr_free(uri->fragment);
- gpr_free(uri);
-}
diff --git a/src/core/ext/client_channel/uri_parser.h b/src/core/ext/client_channel/uri_parser.h
deleted file mode 100644
index efd4302c1c..0000000000
--- a/src/core/ext/client_channel/uri_parser.h
+++ /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.
- *
- */
-
-#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_URI_PARSER_H
-#define GRPC_CORE_EXT_CLIENT_CHANNEL_URI_PARSER_H
-
-#include <stddef.h>
-#include "src/core/lib/iomgr/exec_ctx.h"
-
-typedef struct {
- char *scheme;
- char *authority;
- char *path;
- char *query;
- /** Query substrings separated by '&' */
- char **query_parts;
- /** Number of elements in \a query_parts and \a query_parts_values */
- size_t num_query_parts;
- /** Split each query part by '='. NULL if not present. */
- char **query_parts_values;
- char *fragment;
-} grpc_uri;
-
-/** parse a uri, return NULL on failure */
-grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text,
- int suppress_errors);
-
-/** return the part of a query string after the '=' in "?key=xxx&...", or NULL
- * if key is not present */
-const char *grpc_uri_get_query_arg(const grpc_uri *uri, const char *key);
-
-/** destroy a uri */
-void grpc_uri_destroy(grpc_uri *uri);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_URI_PARSER_H */