accept.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. // Copyright © 2018-2019 Ariadne Devos
  3. /* s2 -- accept HTTP connections */
  4. #include "worker.h"
  5. #include "fd.h"
  6. #include <sHT/accept.h>
  7. #include <sHT/bugs.h>
  8. #include <sHT/compiler.h>
  9. #include <sHT/nospec.h>
  10. #include <sHT/resource.h>
  11. #include <sHT/stream.h>
  12. #include <sHT/test.h>
  13. #include <string.h>
  14. /* TODO: configuration, errno handling in task/accept.c, task/sockrw.c */
  15. static const char test_message[] =
  16. "HTTP/1.1 200 OK\r\n"
  17. "Server: sHTTPd\r\n"
  18. "Connection: Close\r\n"
  19. "Content-Type: text/plain\r\n"
  20. "Content-Language: en\r\n"
  21. "\r\n"
  22. "Hello!";
  23. struct sHT_task_stream *
  24. sHT_accept_subtask(struct sHT_worker *worker, struct sHT_task_accept *task)
  25. {
  26. /* TODO: allow different settings for different TCP ports */
  27. return sHT_alloc(worker->free_streams);
  28. }
  29. void
  30. sHT_accept_abort(struct sHT_worker *worker, struct sHT_task_accept *task, struct sHT_task_stream *subtask)
  31. {
  32. sHT_free(worker->free_streams, subtask);
  33. }
  34. void
  35. sHT_accept_logic(struct sHT_worker *worker, struct sHT_task_accept *task, struct sHT_task_stream *subtask)
  36. {
  37. _Bool oops = sHT_init_stream(worker->papers, &subtask->stream);
  38. if (sHT_nonzero_p(oops)) {
  39. /* XXX Spectre: what if this branch is ignored?
  40. Then a NULL paper might be written to,
  41. might be problematic. */
  42. sHT_close(subtask->stream.fd);
  43. sHT_free(worker->free_streams, subtask);
  44. return;
  45. }
  46. /* TODO: consider patching the kernel to allow 'reservation' of
  47. epoll events. TODO: reconsider this previous TODO. */
  48. oops = sHT_install_edge_trigger(worker->watches, subtask->stream.fd, &subtask->task);
  49. if (sHT_nonzero_p(oops)) {
  50. /* Spectre: a speculatively missing watch isn't problematic.
  51. For a teeny while,
  52. the task won't run although it should be. */
  53. sHT_free_stream(worker->papers, &subtask->stream);
  54. sHT_close(subtask->stream.fd);
  55. sHT_free(worker->free_streams, subtask);
  56. return;
  57. }
  58. sHT_assert(subtask->stream.to_write.offset == 0);
  59. sHT_assert(subtask->stream.to_write.length == 0);
  60. sHT_assert(sizeof(test_message) <= sHT_PAPER_SIZE);
  61. memcpy(subtask->stream.to_write.first, test_message, sizeof(test_message));
  62. sHT_init_task(&subtask->task);
  63. subtask->task.epollflags |= EPOLLIN | EPOLLOUT;
  64. subtask->stream.to_write.length = sizeof(test_message);
  65. }