alpn_handler.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/io/channel.h>
  6. #include <aws/io/tls_channel_handler.h>
  7. struct alpn_handler {
  8. aws_tls_on_protocol_negotiated on_protocol_negotiated;
  9. void *user_data;
  10. };
  11. static int s_alpn_process_read_message(
  12. struct aws_channel_handler *handler,
  13. struct aws_channel_slot *slot,
  14. struct aws_io_message *message) {
  15. if (message->message_tag != AWS_TLS_NEGOTIATED_PROTOCOL_MESSAGE) {
  16. return aws_raise_error(AWS_IO_MISSING_ALPN_MESSAGE);
  17. }
  18. struct aws_tls_negotiated_protocol_message *protocol_message =
  19. (struct aws_tls_negotiated_protocol_message *)message->message_data.buffer;
  20. struct aws_channel_slot *new_slot = aws_channel_slot_new(slot->channel);
  21. struct alpn_handler *alpn_handler = (struct alpn_handler *)handler->impl;
  22. if (!new_slot) {
  23. return AWS_OP_ERR;
  24. }
  25. struct aws_channel_handler *new_handler =
  26. alpn_handler->on_protocol_negotiated(new_slot, &protocol_message->protocol, alpn_handler->user_data);
  27. if (!new_handler) {
  28. aws_mem_release(handler->alloc, (void *)new_slot);
  29. return aws_raise_error(AWS_IO_UNHANDLED_ALPN_PROTOCOL_MESSAGE);
  30. }
  31. aws_channel_slot_replace(slot, new_slot);
  32. aws_channel_slot_set_handler(new_slot, new_handler);
  33. return AWS_OP_SUCCESS;
  34. }
  35. static int s_alpn_shutdown(
  36. struct aws_channel_handler *handler,
  37. struct aws_channel_slot *slot,
  38. enum aws_channel_direction dir,
  39. int error_code,
  40. bool abort_immediately) {
  41. (void)handler;
  42. return aws_channel_slot_on_handler_shutdown_complete(slot, dir, error_code, abort_immediately);
  43. }
  44. static size_t s_alpn_get_initial_window_size(struct aws_channel_handler *handler) {
  45. (void)handler;
  46. return sizeof(struct aws_tls_negotiated_protocol_message);
  47. }
  48. static void s_alpn_destroy(struct aws_channel_handler *handler) {
  49. struct alpn_handler *alpn_handler = (struct alpn_handler *)handler->impl;
  50. aws_mem_release(handler->alloc, alpn_handler);
  51. aws_mem_release(handler->alloc, handler);
  52. }
  53. static size_t s_alpn_message_overhead(struct aws_channel_handler *handler) {
  54. (void)handler;
  55. return 0;
  56. }
  57. static struct aws_channel_handler_vtable s_alpn_handler_vtable = {
  58. .initial_window_size = s_alpn_get_initial_window_size,
  59. .increment_read_window = NULL,
  60. .shutdown = s_alpn_shutdown,
  61. .process_write_message = NULL,
  62. .process_read_message = s_alpn_process_read_message,
  63. .destroy = s_alpn_destroy,
  64. .message_overhead = s_alpn_message_overhead,
  65. };
  66. struct aws_channel_handler *aws_tls_alpn_handler_new(
  67. struct aws_allocator *allocator,
  68. aws_tls_on_protocol_negotiated on_protocol_negotiated,
  69. void *user_data) {
  70. struct aws_channel_handler *channel_handler =
  71. (struct aws_channel_handler *)aws_mem_calloc(allocator, 1, sizeof(struct aws_channel_handler));
  72. if (!channel_handler) {
  73. return NULL;
  74. }
  75. struct alpn_handler *alpn_handler =
  76. (struct alpn_handler *)aws_mem_calloc(allocator, 1, sizeof(struct alpn_handler));
  77. if (!alpn_handler) {
  78. aws_mem_release(allocator, (void *)channel_handler);
  79. return NULL;
  80. }
  81. alpn_handler->on_protocol_negotiated = on_protocol_negotiated;
  82. alpn_handler->user_data = user_data;
  83. channel_handler->impl = alpn_handler;
  84. channel_handler->alloc = allocator;
  85. channel_handler->vtable = &s_alpn_handler_vtable;
  86. return channel_handler;
  87. }