poll_immediate.c 4.4 KB

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