1 /*
2  *
3  * Copyright 2016 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include "test/core/end2end/end2end_tests.h"
20 
21 #include <limits.h>
22 #include <stdbool.h>
23 #include <stdio.h>
24 #include <string.h>
25 
26 #include <grpc/byte_buffer.h>
27 #include <grpc/support/alloc.h>
28 #include <grpc/support/log.h>
29 #include <grpc/support/time.h>
30 #include "src/core/lib/channel/channel_stack_builder.h"
31 #include "src/core/lib/surface/channel_init.h"
32 #include "test/core/end2end/cq_verifier.h"
33 
34 enum { TIMEOUT = 200000 };
35 
36 static bool g_enable_server_channel_filter = false;
37 static bool g_enable_client_channel_filter = false;
38 static bool g_enable_client_subchannel_filter = false;
39 
tag(intptr_t t)40 static void* tag(intptr_t t) { return (void*)t; }
41 
begin_test(grpc_end2end_test_config config,const char * test_name,grpc_channel_args * client_args,grpc_channel_args * server_args)42 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
43                                             const char* test_name,
44                                             grpc_channel_args* client_args,
45                                             grpc_channel_args* server_args) {
46   grpc_end2end_test_fixture f;
47   gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
48   f = config.create_fixture(client_args, server_args);
49   config.init_server(&f, server_args);
50   config.init_client(&f, client_args);
51   return f;
52 }
53 
n_seconds_from_now(int n)54 static gpr_timespec n_seconds_from_now(int n) {
55   return grpc_timeout_seconds_to_deadline(n);
56 }
57 
five_seconds_from_now(void)58 static gpr_timespec five_seconds_from_now(void) {
59   return n_seconds_from_now(5);
60 }
61 
drain_cq(grpc_completion_queue * cq)62 static void drain_cq(grpc_completion_queue* cq) {
63   grpc_event ev;
64   do {
65     ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
66   } while (ev.type != GRPC_QUEUE_SHUTDOWN);
67 }
68 
shutdown_server(grpc_end2end_test_fixture * f)69 static void shutdown_server(grpc_end2end_test_fixture* f) {
70   if (!f->server) return;
71   grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
72   GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
73                                          grpc_timeout_seconds_to_deadline(5),
74                                          nullptr)
75                  .type == GRPC_OP_COMPLETE);
76   grpc_server_destroy(f->server);
77   f->server = nullptr;
78 }
79 
shutdown_client(grpc_end2end_test_fixture * f)80 static void shutdown_client(grpc_end2end_test_fixture* f) {
81   if (!f->client) return;
82   grpc_channel_destroy(f->client);
83   f->client = nullptr;
84 }
85 
end_test(grpc_end2end_test_fixture * f)86 static void end_test(grpc_end2end_test_fixture* f) {
87   shutdown_server(f);
88   shutdown_client(f);
89 
90   grpc_completion_queue_shutdown(f->cq);
91   drain_cq(f->cq);
92   grpc_completion_queue_destroy(f->cq);
93   grpc_completion_queue_destroy(f->shutdown_cq);
94 }
95 
96 // Simple request via a SERVER_CHANNEL filter that always fails to
97 // initialize the call.
test_server_channel_filter(grpc_end2end_test_config config)98 static void test_server_channel_filter(grpc_end2end_test_config config) {
99   grpc_call* c;
100   grpc_call* s;
101   grpc_slice request_payload_slice =
102       grpc_slice_from_copied_string("hello world");
103   grpc_byte_buffer* request_payload =
104       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
105   grpc_end2end_test_fixture f =
106       begin_test(config, "filter_call_init_fails", nullptr, nullptr);
107   cq_verifier* cqv = cq_verifier_create(f.cq);
108   grpc_op ops[6];
109   grpc_op* op;
110   grpc_metadata_array initial_metadata_recv;
111   grpc_metadata_array trailing_metadata_recv;
112   grpc_metadata_array request_metadata_recv;
113   grpc_byte_buffer* request_payload_recv = nullptr;
114   grpc_call_details call_details;
115   grpc_status_code status;
116   grpc_call_error error;
117   grpc_slice details;
118 
119   gpr_timespec deadline = five_seconds_from_now();
120   c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
121                                grpc_slice_from_static_string("/foo"), nullptr,
122                                deadline, nullptr);
123   GPR_ASSERT(c);
124 
125   grpc_metadata_array_init(&initial_metadata_recv);
126   grpc_metadata_array_init(&trailing_metadata_recv);
127   grpc_metadata_array_init(&request_metadata_recv);
128   grpc_call_details_init(&call_details);
129 
130   memset(ops, 0, sizeof(ops));
131   op = ops;
132   op->op = GRPC_OP_SEND_INITIAL_METADATA;
133   op->data.send_initial_metadata.count = 0;
134   op->data.send_initial_metadata.metadata = nullptr;
135   op->flags = 0;
136   op->reserved = nullptr;
137   op++;
138   op->op = GRPC_OP_SEND_MESSAGE;
139   op->data.send_message.send_message = request_payload;
140   op->flags = 0;
141   op->reserved = nullptr;
142   op++;
143   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
144   op->flags = 0;
145   op->reserved = nullptr;
146   op++;
147   op->op = GRPC_OP_RECV_INITIAL_METADATA;
148   op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
149   op->flags = 0;
150   op->reserved = nullptr;
151   op++;
152   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
153   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
154   op->data.recv_status_on_client.status = &status;
155   op->data.recv_status_on_client.status_details = &details;
156   op->flags = 0;
157   op->reserved = nullptr;
158   op++;
159   error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
160                                 nullptr);
161   GPR_ASSERT(GRPC_CALL_OK == error);
162 
163   error =
164       grpc_server_request_call(f.server, &s, &call_details,
165                                &request_metadata_recv, f.cq, f.cq, tag(101));
166   GPR_ASSERT(GRPC_CALL_OK == error);
167 
168   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
169   cq_verify(cqv);
170 
171   GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
172   GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
173 
174   grpc_slice_unref(details);
175   grpc_metadata_array_destroy(&initial_metadata_recv);
176   grpc_metadata_array_destroy(&trailing_metadata_recv);
177   grpc_metadata_array_destroy(&request_metadata_recv);
178   grpc_call_details_destroy(&call_details);
179 
180   grpc_call_unref(c);
181 
182   cq_verifier_destroy(cqv);
183 
184   grpc_byte_buffer_destroy(request_payload);
185   grpc_byte_buffer_destroy(request_payload_recv);
186 
187   end_test(&f);
188   config.tear_down_data(&f);
189 }
190 
191 // Simple request via a CLIENT_CHANNEL or CLIENT_DIRECT_CHANNEL filter
192 // that always fails to initialize the call.
test_client_channel_filter(grpc_end2end_test_config config)193 static void test_client_channel_filter(grpc_end2end_test_config config) {
194   grpc_call* c;
195   grpc_slice request_payload_slice =
196       grpc_slice_from_copied_string("hello world");
197   grpc_byte_buffer* request_payload =
198       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
199   gpr_timespec deadline = five_seconds_from_now();
200   grpc_end2end_test_fixture f =
201       begin_test(config, "filter_call_init_fails", nullptr, nullptr);
202   cq_verifier* cqv = cq_verifier_create(f.cq);
203   grpc_op ops[6];
204   grpc_op* op;
205   grpc_metadata_array initial_metadata_recv;
206   grpc_metadata_array trailing_metadata_recv;
207   grpc_metadata_array request_metadata_recv;
208   grpc_byte_buffer* request_payload_recv = nullptr;
209   grpc_call_details call_details;
210   grpc_status_code status;
211   grpc_call_error error;
212   grpc_slice details;
213 
214   c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
215                                grpc_slice_from_static_string("/foo"), nullptr,
216                                deadline, nullptr);
217   GPR_ASSERT(c);
218 
219   grpc_metadata_array_init(&initial_metadata_recv);
220   grpc_metadata_array_init(&trailing_metadata_recv);
221   grpc_metadata_array_init(&request_metadata_recv);
222   grpc_call_details_init(&call_details);
223 
224   memset(ops, 0, sizeof(ops));
225   op = ops;
226   op->op = GRPC_OP_SEND_INITIAL_METADATA;
227   op->data.send_initial_metadata.count = 0;
228   op->data.send_initial_metadata.metadata = nullptr;
229   op->flags = 0;
230   op->reserved = nullptr;
231   op++;
232   op->op = GRPC_OP_SEND_MESSAGE;
233   op->data.send_message.send_message = request_payload;
234   op->flags = 0;
235   op->reserved = nullptr;
236   op++;
237   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
238   op->flags = 0;
239   op->reserved = nullptr;
240   op++;
241   op->op = GRPC_OP_RECV_INITIAL_METADATA;
242   op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
243   op->flags = 0;
244   op->reserved = nullptr;
245   op++;
246   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
247   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
248   op->data.recv_status_on_client.status = &status;
249   op->data.recv_status_on_client.status_details = &details;
250   op->flags = 0;
251   op->reserved = nullptr;
252   op++;
253   error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
254                                 nullptr);
255   GPR_ASSERT(GRPC_CALL_OK == error);
256 
257   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
258   cq_verify(cqv);
259 
260   GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
261   GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
262 
263   grpc_slice_unref(details);
264   grpc_metadata_array_destroy(&initial_metadata_recv);
265   grpc_metadata_array_destroy(&trailing_metadata_recv);
266   grpc_metadata_array_destroy(&request_metadata_recv);
267   grpc_call_details_destroy(&call_details);
268 
269   grpc_call_unref(c);
270 
271   cq_verifier_destroy(cqv);
272 
273   grpc_byte_buffer_destroy(request_payload);
274   grpc_byte_buffer_destroy(request_payload_recv);
275 
276   end_test(&f);
277   config.tear_down_data(&f);
278 }
279 
280 // Simple request via a CLIENT_SUBCHANNEL filter that always fails to
281 // initialize the call.
test_client_subchannel_filter(grpc_end2end_test_config config)282 static void test_client_subchannel_filter(grpc_end2end_test_config config) {
283   grpc_call* c;
284   grpc_slice request_payload_slice =
285       grpc_slice_from_copied_string("hello world");
286   grpc_byte_buffer* request_payload =
287       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
288   gpr_timespec deadline = five_seconds_from_now();
289   grpc_end2end_test_fixture f =
290       begin_test(config, "filter_call_init_fails", nullptr, nullptr);
291   cq_verifier* cqv = cq_verifier_create(f.cq);
292   grpc_op ops[6];
293   grpc_op* op;
294   grpc_metadata_array initial_metadata_recv;
295   grpc_metadata_array trailing_metadata_recv;
296   grpc_metadata_array request_metadata_recv;
297   grpc_byte_buffer* request_payload_recv = nullptr;
298   grpc_call_details call_details;
299   grpc_status_code status;
300   grpc_call_error error;
301   grpc_slice details;
302 
303   c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
304                                grpc_slice_from_static_string("/foo"), nullptr,
305                                deadline, nullptr);
306   GPR_ASSERT(c);
307 
308   grpc_metadata_array_init(&initial_metadata_recv);
309   grpc_metadata_array_init(&trailing_metadata_recv);
310   grpc_metadata_array_init(&request_metadata_recv);
311   grpc_call_details_init(&call_details);
312 
313   memset(ops, 0, sizeof(ops));
314   op = ops;
315   op->op = GRPC_OP_SEND_INITIAL_METADATA;
316   op->data.send_initial_metadata.count = 0;
317   op->data.send_initial_metadata.metadata = nullptr;
318   op->flags = 0;
319   op->reserved = nullptr;
320   op++;
321   op->op = GRPC_OP_SEND_MESSAGE;
322   op->data.send_message.send_message = request_payload;
323   op->flags = 0;
324   op->reserved = nullptr;
325   op++;
326   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
327   op->flags = 0;
328   op->reserved = nullptr;
329   op++;
330   op->op = GRPC_OP_RECV_INITIAL_METADATA;
331   op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
332   op->flags = 0;
333   op->reserved = nullptr;
334   op++;
335   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
336   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
337   op->data.recv_status_on_client.status = &status;
338   op->data.recv_status_on_client.status_details = &details;
339   op->flags = 0;
340   op->reserved = nullptr;
341   op++;
342 
343   error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
344                                 nullptr);
345   GPR_ASSERT(GRPC_CALL_OK == error);
346 
347   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
348   cq_verify(cqv);
349 
350   GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
351   GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
352 
353   // Reset and create a new call.  (The first call uses a different code
354   // path in client_channel.c than subsequent calls on the same channel,
355   // and we need to test both.)
356   grpc_call_unref(c);
357   status = GRPC_STATUS_OK;
358   grpc_slice_unref(details);
359   details = grpc_empty_slice();
360 
361   c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
362                                grpc_slice_from_static_string("/foo"), nullptr,
363                                deadline, nullptr);
364   GPR_ASSERT(c);
365 
366   error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2),
367                                 nullptr);
368   GPR_ASSERT(GRPC_CALL_OK == error);
369 
370   CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
371   cq_verify(cqv);
372 
373   GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
374   GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
375 
376   grpc_slice_unref(details);
377   grpc_metadata_array_destroy(&initial_metadata_recv);
378   grpc_metadata_array_destroy(&trailing_metadata_recv);
379   grpc_metadata_array_destroy(&request_metadata_recv);
380   grpc_call_details_destroy(&call_details);
381 
382   grpc_call_unref(c);
383 
384   cq_verifier_destroy(cqv);
385 
386   grpc_byte_buffer_destroy(request_payload);
387   grpc_byte_buffer_destroy(request_payload_recv);
388 
389   end_test(&f);
390   config.tear_down_data(&f);
391 }
392 
393 /*******************************************************************************
394  * Test filter - always fails to initialize a call
395  */
396 
init_call_elem(grpc_call_element *,const grpc_call_element_args *)397 static grpc_error* init_call_elem(grpc_call_element* /*elem*/,
398                                   const grpc_call_element_args* /*args*/) {
399   return grpc_error_set_int(
400       GRPC_ERROR_CREATE_FROM_STATIC_STRING("access denied"),
401       GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_PERMISSION_DENIED);
402 }
403 
destroy_call_elem(grpc_call_element *,const grpc_call_final_info *,grpc_closure *)404 static void destroy_call_elem(grpc_call_element* /*elem*/,
405                               const grpc_call_final_info* /*final_info*/,
406                               grpc_closure* /*ignored*/) {}
407 
init_channel_elem(grpc_channel_element *,grpc_channel_element_args *)408 static grpc_error* init_channel_elem(grpc_channel_element* /*elem*/,
409                                      grpc_channel_element_args* /*args*/) {
410   return GRPC_ERROR_NONE;
411 }
412 
destroy_channel_elem(grpc_channel_element *)413 static void destroy_channel_elem(grpc_channel_element* /*elem*/) {}
414 
415 static const grpc_channel_filter test_filter = {
416     grpc_call_next_op,
417     grpc_channel_next_op,
418     0,
419     init_call_elem,
420     grpc_call_stack_ignore_set_pollset_or_pollset_set,
421     destroy_call_elem,
422     0,
423     init_channel_elem,
424     destroy_channel_elem,
425     grpc_channel_next_get_info,
426     "filter_call_init_fails"};
427 
428 /*******************************************************************************
429  * Registration
430  */
431 
maybe_add_server_channel_filter(grpc_channel_stack_builder * builder,void *)432 static bool maybe_add_server_channel_filter(grpc_channel_stack_builder* builder,
433                                             void* /*arg*/) {
434   if (g_enable_server_channel_filter) {
435     // Want to add the filter as close to the end as possible, to make
436     // sure that all of the filters work well together.  However, we
437     // can't add it at the very end, because the connected channel filter
438     // must be the last one.  So we add it right before the last one.
439     grpc_channel_stack_builder_iterator* it =
440         grpc_channel_stack_builder_create_iterator_at_last(builder);
441     GPR_ASSERT(grpc_channel_stack_builder_move_prev(it));
442     const bool retval = grpc_channel_stack_builder_add_filter_before(
443         it, &test_filter, nullptr, nullptr);
444     grpc_channel_stack_builder_iterator_destroy(it);
445     return retval;
446   } else {
447     return true;
448   }
449 }
450 
maybe_add_client_channel_filter(grpc_channel_stack_builder * builder,void *)451 static bool maybe_add_client_channel_filter(grpc_channel_stack_builder* builder,
452                                             void* /*arg*/) {
453   if (g_enable_client_channel_filter) {
454     // Want to add the filter as close to the end as possible, to make
455     // sure that all of the filters work well together.  However, we
456     // can't add it at the very end, because the connected channel filter
457     // must be the last one.  So we add it right before the last one.
458     grpc_channel_stack_builder_iterator* it =
459         grpc_channel_stack_builder_create_iterator_at_last(builder);
460     GPR_ASSERT(grpc_channel_stack_builder_move_prev(it));
461     const bool retval = grpc_channel_stack_builder_add_filter_before(
462         it, &test_filter, nullptr, nullptr);
463     grpc_channel_stack_builder_iterator_destroy(it);
464     return retval;
465   } else {
466     return true;
467   }
468 }
469 
maybe_add_client_subchannel_filter(grpc_channel_stack_builder * builder,void *)470 static bool maybe_add_client_subchannel_filter(
471     grpc_channel_stack_builder* builder, void* /*arg*/) {
472   if (g_enable_client_subchannel_filter) {
473     // Want to add the filter as close to the end as possible, to make
474     // sure that all of the filters work well together.  However, we
475     // can't add it at the very end, because the client channel filter
476     // must be the last one.  So we add it right before the last one.
477     grpc_channel_stack_builder_iterator* it =
478         grpc_channel_stack_builder_create_iterator_at_last(builder);
479     GPR_ASSERT(grpc_channel_stack_builder_move_prev(it));
480     const bool retval = grpc_channel_stack_builder_add_filter_before(
481         it, &test_filter, nullptr, nullptr);
482     grpc_channel_stack_builder_iterator_destroy(it);
483     return retval;
484   } else {
485     return true;
486   }
487 }
488 
init_plugin(void)489 static void init_plugin(void) {
490   grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
491                                    maybe_add_server_channel_filter, nullptr);
492   grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
493                                    maybe_add_client_channel_filter, nullptr);
494   grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX,
495                                    maybe_add_client_subchannel_filter, nullptr);
496   grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
497                                    maybe_add_client_channel_filter, nullptr);
498 }
499 
destroy_plugin(void)500 static void destroy_plugin(void) {}
501 
filter_call_init_fails(grpc_end2end_test_config config)502 void filter_call_init_fails(grpc_end2end_test_config config) {
503   gpr_log(GPR_INFO, "Testing SERVER_CHANNEL filter.");
504   g_enable_server_channel_filter = true;
505   test_server_channel_filter(config);
506   g_enable_server_channel_filter = false;
507   gpr_log(GPR_INFO, "Testing CLIENT_CHANNEL / CLIENT_DIRECT_CHANNEL filter.");
508   g_enable_client_channel_filter = true;
509   test_client_channel_filter(config);
510   g_enable_client_channel_filter = false;
511   if (config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL) {
512     gpr_log(GPR_INFO, "Testing CLIENT_SUBCHANNEL filter.");
513     g_enable_client_subchannel_filter = true;
514     test_client_subchannel_filter(config);
515     g_enable_client_subchannel_filter = false;
516   }
517 }
518 
filter_call_init_fails_pre_init(void)519 void filter_call_init_fails_pre_init(void) {
520   grpc_register_plugin(init_plugin, destroy_plugin);
521 }
522