1 /**
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  * SPDX-License-Identifier: Apache-2.0.
4  */
5 
6 #include <aws/io/channel.h>
7 #include <aws/io/event_loop.h>
8 #include <aws/io/tls_channel_handler.h>
9 #include <aws/testing/aws_test_harness.h>
10 
11 #include <aws/common/clock.h>
12 #include <aws/common/condition_variable.h>
13 
14 struct alpn_channel_setup_test_args {
15     struct aws_condition_variable condition_variable;
16     struct aws_mutex mutex;
17     int error_code;
18     bool shutdown_finished;
19     bool setup_completed;
20 };
21 
s_alpn_channel_setup_test_on_setup_completed(struct aws_channel * channel,int error_code,void * ctx)22 static void s_alpn_channel_setup_test_on_setup_completed(struct aws_channel *channel, int error_code, void *ctx) {
23     (void)channel;
24 
25     struct alpn_channel_setup_test_args *setup_test_args = (struct alpn_channel_setup_test_args *)ctx;
26     aws_mutex_lock(&setup_test_args->mutex);
27     setup_test_args->setup_completed = true;
28     setup_test_args->error_code |= error_code;
29     aws_mutex_unlock(&setup_test_args->mutex);
30     aws_condition_variable_notify_one(&setup_test_args->condition_variable);
31 }
32 
s_alpn_test_setup_completed_predicate(void * arg)33 static bool s_alpn_test_setup_completed_predicate(void *arg) {
34     struct alpn_channel_setup_test_args *setup_test_args = (struct alpn_channel_setup_test_args *)arg;
35     return setup_test_args->setup_completed;
36 }
37 
38 struct alpn_test_on_negotiation_args {
39     struct aws_allocator *allocator;
40     struct aws_channel_slot *new_slot;
41     struct aws_channel_handler *new_handler;
42     struct aws_byte_buf protocol;
43 };
44 
s_alpn_test_shutdown(struct aws_channel_handler * handler,struct aws_channel_slot * slot,enum aws_channel_direction dir,int error_code,bool abort_immediately)45 static int s_alpn_test_shutdown(
46     struct aws_channel_handler *handler,
47     struct aws_channel_slot *slot,
48     enum aws_channel_direction dir,
49     int error_code,
50     bool abort_immediately) {
51     (void)handler;
52 
53     return aws_channel_slot_on_handler_shutdown_complete(slot, dir, error_code, abort_immediately);
54 }
55 
s_alpn_test_message_overhead(struct aws_channel_handler * handler)56 static size_t s_alpn_test_message_overhead(struct aws_channel_handler *handler) {
57     (void)handler;
58 
59     return 0;
60 }
61 
s_alpn_test_initial_window_size(struct aws_channel_handler * handler)62 static size_t s_alpn_test_initial_window_size(struct aws_channel_handler *handler) {
63     (void)handler;
64 
65     return SIZE_MAX;
66 }
67 
s_alpn_test_destroy(struct aws_channel_handler * handler)68 static void s_alpn_test_destroy(struct aws_channel_handler *handler) {
69     aws_mem_release(handler->alloc, (void *)handler);
70 }
71 
72 struct aws_channel_handler_vtable s_alpn_test_vtable = {
73     .destroy = s_alpn_test_destroy,
74     .shutdown = s_alpn_test_shutdown,
75     .initial_window_size = s_alpn_test_initial_window_size,
76     .message_overhead = s_alpn_test_message_overhead,
77 };
78 
s_alpn_tls_successful_negotiation(struct aws_channel_slot * new_slot,struct aws_byte_buf * protocol,void * ctx)79 static struct aws_channel_handler *s_alpn_tls_successful_negotiation(
80     struct aws_channel_slot *new_slot,
81     struct aws_byte_buf *protocol,
82     void *ctx) {
83     struct alpn_test_on_negotiation_args *negotiation_args = (struct alpn_test_on_negotiation_args *)ctx;
84 
85     struct aws_channel_handler *handler =
86         aws_mem_calloc(negotiation_args->allocator, 1, sizeof(struct aws_channel_handler));
87 
88     negotiation_args->new_handler = handler;
89     negotiation_args->protocol = *protocol;
90     negotiation_args->new_slot = new_slot;
91 
92     handler->vtable = &s_alpn_test_vtable;
93     handler->alloc = negotiation_args->allocator;
94 
95     return handler;
96 }
97 
s_alpn_test_shutdown_predicate(void * arg)98 static bool s_alpn_test_shutdown_predicate(void *arg) {
99     struct alpn_channel_setup_test_args *test_args = (struct alpn_channel_setup_test_args *)arg;
100     return test_args->shutdown_finished;
101 }
102 
s_on_server_channel_on_shutdown(struct aws_channel * channel,int error_code,void * user_data)103 static void s_on_server_channel_on_shutdown(struct aws_channel *channel, int error_code, void *user_data) {
104 
105     (void)channel;
106     (void)error_code;
107 
108     struct alpn_channel_setup_test_args *test_args = (struct alpn_channel_setup_test_args *)user_data;
109 
110     aws_mutex_lock(&test_args->mutex);
111     test_args->shutdown_finished = true;
112     aws_mutex_unlock(&test_args->mutex);
113 
114     aws_condition_variable_notify_one(&test_args->condition_variable);
115 }
116 
s_test_alpn_successfully_negotiates(struct aws_allocator * allocator,void * ctx)117 static int s_test_alpn_successfully_negotiates(struct aws_allocator *allocator, void *ctx) {
118 
119     (void)ctx;
120 
121     struct aws_event_loop *event_loop = aws_event_loop_new_default(allocator, aws_high_res_clock_get_ticks);
122 
123     ASSERT_NOT_NULL(event_loop, "Event loop creation failed with error: %s", aws_error_debug_str(aws_last_error()));
124     ASSERT_SUCCESS(aws_event_loop_run(event_loop));
125     struct aws_channel *channel;
126 
127     struct alpn_channel_setup_test_args test_args = {.error_code = 0,
128                                                      .condition_variable = AWS_CONDITION_VARIABLE_INIT,
129                                                      .mutex = AWS_MUTEX_INIT,
130                                                      .setup_completed = false,
131                                                      .shutdown_finished = false};
132 
133     struct aws_channel_options args = {
134         .on_setup_completed = s_alpn_channel_setup_test_on_setup_completed,
135         .setup_user_data = &test_args,
136         .on_shutdown_completed = s_on_server_channel_on_shutdown,
137         .shutdown_user_data = &test_args,
138         .event_loop = event_loop,
139     };
140 
141     channel = aws_channel_new(allocator, &args);
142     ASSERT_NOT_NULL(channel);
143     ASSERT_SUCCESS(aws_mutex_lock(&test_args.mutex));
144     ASSERT_SUCCESS(aws_condition_variable_wait_pred(
145         &test_args.condition_variable, &test_args.mutex, s_alpn_test_setup_completed_predicate, &test_args));
146     ASSERT_SUCCESS(aws_mutex_unlock(&test_args.mutex));
147 
148     struct aws_channel_slot *slot = aws_channel_slot_new(channel);
149     ASSERT_NOT_NULL(slot);
150 
151     struct alpn_test_on_negotiation_args on_negotiation_args = {
152         .new_slot = NULL, .protocol = {0}, .new_handler = NULL, .allocator = allocator};
153 
154     struct aws_channel_handler *handler =
155         aws_tls_alpn_handler_new(allocator, s_alpn_tls_successful_negotiation, &on_negotiation_args);
156     ASSERT_NOT_NULL(handler);
157     ASSERT_SUCCESS(aws_channel_slot_set_handler(slot, handler));
158 
159     struct aws_tls_negotiated_protocol_message protocol_message = {.protocol = aws_byte_buf_from_c_str("h2")};
160 
161     struct aws_io_message message = {
162         .allocator = NULL,
163         .user_data = NULL,
164         .message_tag = AWS_TLS_NEGOTIATED_PROTOCOL_MESSAGE,
165         .message_data = aws_byte_buf_from_array(
166             (const uint8_t *)&protocol_message, sizeof(struct aws_tls_negotiated_protocol_message)),
167         .copy_mark = 0,
168         .on_completion = NULL,
169         .message_type = AWS_IO_MESSAGE_APPLICATION_DATA};
170 
171     ASSERT_SUCCESS(aws_channel_handler_process_read_message(handler, slot, &message));
172     ASSERT_BIN_ARRAYS_EQUALS(
173         protocol_message.protocol.buffer,
174         protocol_message.protocol.len,
175         on_negotiation_args.protocol.buffer,
176         on_negotiation_args.protocol.len);
177 
178     aws_channel_shutdown(channel, AWS_OP_SUCCESS);
179     ASSERT_SUCCESS(aws_mutex_lock(&test_args.mutex));
180     ASSERT_SUCCESS(aws_condition_variable_wait_pred(
181         &test_args.condition_variable, &test_args.mutex, s_alpn_test_shutdown_predicate, &test_args));
182     ASSERT_SUCCESS(aws_mutex_unlock(&test_args.mutex));
183 
184     aws_channel_destroy(channel);
185     aws_event_loop_destroy(event_loop);
186 
187     return AWS_OP_SUCCESS;
188 }
189 
AWS_TEST_CASE(alpn_successfully_negotiates,s_test_alpn_successfully_negotiates)190 AWS_TEST_CASE(alpn_successfully_negotiates, s_test_alpn_successfully_negotiates)
191 
192 static int s_test_alpn_no_protocol_message(struct aws_allocator *allocator, void *ctx) {
193 
194     (void)ctx;
195 
196     struct aws_event_loop *event_loop = aws_event_loop_new_default(allocator, aws_high_res_clock_get_ticks);
197 
198     ASSERT_NOT_NULL(event_loop, "Event loop creation failed with error: %s", aws_error_debug_str(aws_last_error()));
199     ASSERT_SUCCESS(aws_event_loop_run(event_loop));
200     struct aws_channel *channel;
201 
202     struct alpn_channel_setup_test_args test_args = {.error_code = 0,
203                                                      .condition_variable = AWS_CONDITION_VARIABLE_INIT,
204                                                      .mutex = AWS_MUTEX_INIT,
205                                                      .shutdown_finished = false};
206 
207     struct aws_channel_options args = {
208         .on_setup_completed = s_alpn_channel_setup_test_on_setup_completed,
209         .setup_user_data = &test_args,
210         .on_shutdown_completed = s_on_server_channel_on_shutdown,
211         .shutdown_user_data = &test_args,
212         .event_loop = event_loop,
213     };
214 
215     channel = aws_channel_new(allocator, &args);
216     ASSERT_NOT_NULL(channel);
217     ASSERT_SUCCESS(aws_mutex_lock(&test_args.mutex));
218     ASSERT_SUCCESS(aws_condition_variable_wait_pred(
219         &test_args.condition_variable, &test_args.mutex, s_alpn_test_setup_completed_predicate, &test_args));
220     ASSERT_SUCCESS(aws_mutex_unlock(&test_args.mutex));
221 
222     struct aws_channel_slot *slot = aws_channel_slot_new(channel);
223     ASSERT_NOT_NULL(slot);
224 
225     struct alpn_test_on_negotiation_args on_negotiation_args = {
226         .new_slot = NULL, .protocol = {0}, .new_handler = NULL, .allocator = allocator};
227 
228     struct aws_channel_handler *handler =
229         aws_tls_alpn_handler_new(allocator, s_alpn_tls_successful_negotiation, &on_negotiation_args);
230     ASSERT_NOT_NULL(handler);
231     ASSERT_SUCCESS(aws_channel_slot_set_handler(slot, handler));
232 
233     /*this is just for the test since it's the only slot in the channel */
234     handler->vtable->shutdown = s_alpn_test_shutdown;
235 
236     struct aws_io_message message = {
237         .allocator = NULL,
238         .user_data = NULL,
239         .message_tag = 0,
240         .copy_mark = 0,
241         .on_completion = NULL,
242         .message_type = AWS_IO_MESSAGE_APPLICATION_DATA,
243     };
244 
245     ASSERT_ERROR(AWS_IO_MISSING_ALPN_MESSAGE, aws_channel_handler_process_read_message(handler, slot, &message));
246 
247     aws_channel_shutdown(channel, AWS_OP_SUCCESS);
248     ASSERT_SUCCESS(aws_mutex_lock(&test_args.mutex));
249     ASSERT_SUCCESS(aws_condition_variable_wait_pred(
250         &test_args.condition_variable, &test_args.mutex, s_alpn_test_shutdown_predicate, &test_args));
251     ASSERT_SUCCESS(aws_mutex_unlock(&test_args.mutex));
252     aws_channel_destroy(channel);
253     aws_event_loop_destroy(event_loop);
254 
255     return AWS_OP_SUCCESS;
256 }
257 
AWS_TEST_CASE(alpn_no_protocol_message,s_test_alpn_no_protocol_message)258 AWS_TEST_CASE(alpn_no_protocol_message, s_test_alpn_no_protocol_message)
259 
260 static struct aws_channel_handler *s_alpn_tls_failed_negotiation(
261     struct aws_channel_slot *new_slot,
262     struct aws_byte_buf *protocol,
263     void *ctx) {
264 
265     (void)new_slot;
266     (void)protocol;
267     (void)ctx;
268 
269     return NULL;
270 }
271 
s_test_alpn_error_creating_handler(struct aws_allocator * allocator,void * ctx)272 static int s_test_alpn_error_creating_handler(struct aws_allocator *allocator, void *ctx) {
273 
274     (void)ctx;
275 
276     struct aws_event_loop *event_loop = aws_event_loop_new_default(allocator, aws_high_res_clock_get_ticks);
277 
278     ASSERT_NOT_NULL(event_loop, "Event loop creation failed with error: %s", aws_error_debug_str(aws_last_error()));
279     ASSERT_SUCCESS(aws_event_loop_run(event_loop));
280     struct aws_channel *channel;
281 
282     struct alpn_channel_setup_test_args test_args = {.error_code = 0,
283                                                      .condition_variable = AWS_CONDITION_VARIABLE_INIT,
284                                                      .mutex = AWS_MUTEX_INIT,
285                                                      .shutdown_finished = false};
286 
287     struct aws_channel_options args = {
288         .on_setup_completed = s_alpn_channel_setup_test_on_setup_completed,
289         .setup_user_data = &test_args,
290         .on_shutdown_completed = s_on_server_channel_on_shutdown,
291         .shutdown_user_data = &test_args,
292         .event_loop = event_loop,
293     };
294 
295     channel = aws_channel_new(allocator, &args);
296     ASSERT_NOT_NULL(channel);
297     ASSERT_SUCCESS(aws_mutex_lock(&test_args.mutex));
298     ASSERT_SUCCESS(aws_condition_variable_wait_pred(
299         &test_args.condition_variable, &test_args.mutex, s_alpn_test_setup_completed_predicate, &test_args));
300     ASSERT_SUCCESS(aws_mutex_unlock(&test_args.mutex));
301 
302     struct aws_channel_slot *slot = aws_channel_slot_new(channel);
303     ASSERT_NOT_NULL(slot);
304 
305     struct aws_tls_negotiated_protocol_message protocol_message = {.protocol = aws_byte_buf_from_c_str("h2")};
306 
307     struct aws_io_message message = {
308         .allocator = NULL,
309         .user_data = NULL,
310         .message_tag = AWS_TLS_NEGOTIATED_PROTOCOL_MESSAGE,
311         .message_data = aws_byte_buf_from_array(
312             (const uint8_t *)&protocol_message, sizeof(struct aws_tls_negotiated_protocol_message)),
313         .copy_mark = 0,
314         .on_completion = NULL,
315         .message_type = AWS_IO_MESSAGE_APPLICATION_DATA};
316 
317     struct alpn_test_on_negotiation_args on_negotiation_args = {
318         .new_slot = NULL, .protocol = {0}, .new_handler = NULL, .allocator = allocator};
319 
320     struct aws_channel_handler *handler =
321         aws_tls_alpn_handler_new(allocator, s_alpn_tls_failed_negotiation, &on_negotiation_args);
322     ASSERT_NOT_NULL(handler);
323     ASSERT_SUCCESS(aws_channel_slot_set_handler(slot, handler));
324 
325     /*this is just for the test since it's the only slot in the channel */
326     handler->vtable->shutdown = s_alpn_test_shutdown;
327 
328     ASSERT_ERROR(
329         AWS_IO_UNHANDLED_ALPN_PROTOCOL_MESSAGE, aws_channel_handler_process_read_message(handler, slot, &message));
330 
331     aws_channel_shutdown(channel, AWS_OP_SUCCESS);
332     ASSERT_SUCCESS(aws_mutex_lock(&test_args.mutex));
333     ASSERT_SUCCESS(aws_condition_variable_wait_pred(
334         &test_args.condition_variable, &test_args.mutex, s_alpn_test_shutdown_predicate, &test_args));
335     ASSERT_SUCCESS(aws_mutex_unlock(&test_args.mutex));
336     aws_channel_destroy(channel);
337     aws_event_loop_destroy(event_loop);
338 
339     return AWS_OP_SUCCESS;
340 }
341 
342 AWS_TEST_CASE(alpn_error_creating_handler, s_test_alpn_error_creating_handler)
343