poll_immediate.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include "internal/common.h"
  10. #include "internal/quic_ssl.h"
  11. #include <openssl/ssl.h>
  12. #include <openssl/err.h>
  13. #include "../ssl_local.h"
  14. #define ITEM_N(items, stride, n) \
  15. (*(SSL_POLL_ITEM *)((char *)(items) + (n)*(stride)))
  16. #define FAIL_FROM(n) \
  17. do { \
  18. size_t j; \
  19. \
  20. for (j = (n); j < num_items; ++j) \
  21. ITEM_N(items, stride, j).revents = 0; \
  22. \
  23. ok = 0; \
  24. goto out; \
  25. } while (0)
  26. #define FAIL_ITEM(i) \
  27. do { \
  28. ITEM_N(items, stride, i).revents = SSL_POLL_EVENT_F; \
  29. ++result_count; \
  30. FAIL_FROM(i + 1); \
  31. } while (0)
  32. int SSL_poll(SSL_POLL_ITEM *items,
  33. size_t num_items,
  34. size_t stride,
  35. const struct timeval *timeout,
  36. uint64_t flags,
  37. size_t *p_result_count)
  38. {
  39. int ok = 1;
  40. size_t i, result_count = 0;
  41. SSL_POLL_ITEM *item;
  42. SSL *ssl;
  43. uint64_t revents;
  44. ossl_unused uint64_t events;
  45. ossl_unused int do_tick = ((flags & SSL_POLL_FLAG_NO_HANDLE_EVENTS) == 0);
  46. int is_immediate
  47. = (timeout != NULL
  48. && timeout->tv_sec == 0 && timeout->tv_usec == 0);
  49. /*
  50. * Prevent calls which use SSL_poll functionality which is not currently
  51. * supported.
  52. */
  53. if (!is_immediate) {
  54. ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
  55. "SSL_poll does not currently support blocking "
  56. "operation");
  57. FAIL_FROM(0);
  58. }
  59. /* Trivial case. */
  60. if (num_items == 0)
  61. goto out;
  62. /* Poll current state of each item. */
  63. for (i = 0; i < num_items; ++i) {
  64. item = &ITEM_N(items, stride, i);
  65. events = item->events;
  66. revents = 0;
  67. switch (item->desc.type) {
  68. case BIO_POLL_DESCRIPTOR_TYPE_SSL:
  69. ssl = item->desc.value.ssl;
  70. if (ssl == NULL)
  71. /* NULL items are no-ops and have revents reported as 0 */
  72. break;
  73. switch (ssl->type) {
  74. #ifndef OPENSSL_NO_QUIC
  75. case SSL_TYPE_QUIC_CONNECTION:
  76. case SSL_TYPE_QUIC_XSO:
  77. if (!ossl_quic_conn_poll_events(ssl, events, do_tick, &revents))
  78. /* above call raises ERR */
  79. FAIL_ITEM(i);
  80. if (revents != 0)
  81. ++result_count;
  82. break;
  83. #endif
  84. default:
  85. ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
  86. "SSL_poll currently only supports QUIC SSL "
  87. "objects");
  88. FAIL_ITEM(i);
  89. }
  90. break;
  91. case BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD:
  92. ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
  93. "SSL_poll currently does not support polling "
  94. "sockets");
  95. FAIL_ITEM(i);
  96. default:
  97. ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
  98. "SSL_poll does not support unknown poll descriptor "
  99. "type %d", item->desc.type);
  100. FAIL_ITEM(i);
  101. }
  102. item->revents = revents;
  103. }
  104. /* TODO(QUIC POLLING): Blocking mode */
  105. /* TODO(QUIC POLLING): Support for polling FDs */
  106. out:
  107. if (p_result_count != NULL)
  108. *p_result_count = result_count;
  109. return ok;
  110. }