aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/channel/client_authority_filter.cc
diff options
context:
space:
mode:
authorGravatar David Garcia Quintas <dgq@google.com>2018-03-10 17:27:15 -0800
committerGravatar David Garcia Quintas <dgq@google.com>2018-03-10 21:32:57 -0800
commitc7c0d69d8b411f1c5102bfd186aa2f6992c2e59c (patch)
tree4fda7b9d59a6c8e39b0bff4632072840d5bf4945 /src/core/lib/channel/client_authority_filter.cc
parent12136821220a671bb9d6443b69817babf2f5c254 (diff)
Secure channels: use the right authority
Diffstat (limited to 'src/core/lib/channel/client_authority_filter.cc')
-rw-r--r--src/core/lib/channel/client_authority_filter.cc117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/core/lib/channel/client_authority_filter.cc b/src/core/lib/channel/client_authority_filter.cc
new file mode 100644
index 0000000000..57c5d29a93
--- /dev/null
+++ b/src/core/lib/channel/client_authority_filter.cc
@@ -0,0 +1,117 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/channel/client_authority_filter.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
+#include "src/core/lib/surface/call.h"
+#include "src/core/lib/surface/channel_init.h"
+#include "src/core/lib/surface/channel_stack_type.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+namespace {
+
+struct call_data {
+ grpc_linked_mdelem authority_storage;
+ grpc_call_combiner* call_combiner;
+};
+
+struct channel_data {
+ grpc_slice default_authority;
+};
+
+void authority_start_transport_stream_op_batch(
+ grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ // Handle send_initial_metadata.
+ auto* initial_metadata =
+ batch->payload->send_initial_metadata.send_initial_metadata;
+ // If the initial metadata doesn't already contain :authority, add it.
+ if (batch->send_initial_metadata &&
+ initial_metadata->idx.named.authority == nullptr) {
+ grpc_error* error = grpc_metadata_batch_add_head(
+ initial_metadata, &calld->authority_storage,
+ grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY,
+ grpc_slice_ref(chand->default_authority)));
+ if (error != GRPC_ERROR_NONE) {
+ grpc_transport_stream_op_batch_finish_with_failure(batch, error,
+ calld->call_combiner);
+ return;
+ }
+ }
+ // Pass control down the stack.
+ grpc_call_next_op(elem, batch);
+}
+
+/* Constructor for call_data */
+grpc_error* init_call_elem(grpc_call_element* elem,
+ const grpc_call_element_args* args) {
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ calld->call_combiner = args->call_combiner;
+ return GRPC_ERROR_NONE;
+}
+
+/* Destructor for call_data */
+void destroy_call_elem(grpc_call_element* elem,
+ const grpc_call_final_info* final_info,
+ grpc_closure* ignored) {}
+
+/* Constructor for channel_data */
+grpc_error* init_channel_elem(grpc_channel_element* elem,
+ grpc_channel_element_args* args) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ const grpc_arg* default_authority_arg =
+ grpc_channel_args_find(args->channel_args, GRPC_ARG_DEFAULT_AUTHORITY);
+ GPR_ASSERT(default_authority_arg != nullptr);
+ chand->default_authority = grpc_slice_from_copied_string(
+ grpc_channel_arg_get_string(default_authority_arg));
+ GPR_ASSERT(!args->is_last);
+ return GRPC_ERROR_NONE;
+}
+
+/* Destructor for channel data */
+void destroy_channel_elem(grpc_channel_element* elem) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ grpc_slice_unref(chand->default_authority);
+}
+} // namespace
+
+const grpc_channel_filter grpc_client_authority_filter = {
+ authority_start_transport_stream_op_batch,
+ grpc_channel_next_op,
+ sizeof(call_data),
+ init_call_elem,
+ grpc_call_stack_ignore_set_pollset_or_pollset_set,
+ destroy_call_elem,
+ sizeof(channel_data),
+ init_channel_elem,
+ destroy_channel_elem,
+ grpc_channel_next_get_info,
+ "authority"};