socket.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. //
  2. // Copyright (c) 2024 Klemens Morgenstern (klemens.morgenstern@gmx.net)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. #ifndef BOOST_COBALT_IOSOCKET_HPP
  8. #define BOOST_COBALT_IOSOCKET_HPP
  9. #include <boost/cobalt/io/detail/config.hpp>
  10. #include <boost/cobalt/io/endpoint.hpp>
  11. #include <boost/cobalt/io/ops.hpp>
  12. #include <boost/asio/socket_base.hpp>
  13. #include <boost/asio/basic_socket.hpp>
  14. namespace boost::cobalt::io
  15. {
  16. struct BOOST_SYMBOL_VISIBLE socket
  17. {
  18. [[nodiscard]] system::result<void> open(protocol_type prot = protocol_type {});
  19. [[nodiscard]] system::result<void> close();
  20. [[nodiscard]] system::result<void> cancel();
  21. [[nodiscard]] bool is_open() const;
  22. // asio acceptor compatibility
  23. template<typename T>
  24. struct rebind_executor {using other = socket;};
  25. using shutdown_type = asio::socket_base::shutdown_type;
  26. using wait_type = asio::socket_base::wait_type;
  27. using message_flags = asio::socket_base::message_flags;
  28. constexpr static int message_peek = asio::socket_base::message_peek;
  29. constexpr static int message_out_of_band = asio::socket_base::message_out_of_band;
  30. constexpr static int message_do_not_route = asio::socket_base::message_do_not_route;
  31. constexpr static int message_end_of_record = asio::socket_base::message_end_of_record;
  32. using native_handle_type = asio::basic_socket<protocol_type, executor>::native_handle_type;
  33. BOOST_COBALT_IO_DECL native_handle_type native_handle();
  34. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> shutdown(shutdown_type = shutdown_type::shutdown_both);
  35. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<endpoint> local_endpoint() const;
  36. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<endpoint> remote_endpoint() const;
  37. BOOST_COBALT_IO_DECL system::result<void> assign(protocol_type protocol, native_handle_type native_handle);
  38. BOOST_COBALT_IO_DECL system::result<native_handle_type> release();
  39. /// copied from what asio does
  40. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<std::size_t> bytes_readable();
  41. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_debug(bool debug);
  42. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<bool> get_debug() const;
  43. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_do_not_route(bool do_not_route);
  44. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<bool> get_do_not_route() const;
  45. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_enable_connection_aborted(bool enable_connection_aborted);
  46. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<bool> get_enable_connection_aborted() const;
  47. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_keep_alive(bool keep_alive);
  48. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<bool> get_keep_alive() const;
  49. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_linger(bool linger, int timeout);
  50. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<std::pair<bool, int>> get_linger() const;
  51. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_receive_buffer_size(int receive_buffer_size);
  52. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<int> get_receive_buffer_size() const;
  53. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_send_buffer_size(int send_buffer_size);
  54. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<int> get_send_buffer_size() const;
  55. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_receive_low_watermark(int receive_low_watermark);
  56. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<int> get_receive_low_watermark() const;
  57. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_send_low_watermark(int send_low_watermark);
  58. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<int> get_send_low_watermark() const;
  59. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_reuse_address(bool reuse_address);
  60. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<bool> get_reuse_address() const;
  61. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_no_delay(bool reuse_address);
  62. [[nodiscard]] BOOST_COBALT_IO_DECL system::result<bool> get_no_delay() const;
  63. struct BOOST_COBALT_IO_DECL wait_op final : op<system::error_code>
  64. {
  65. wait_type wt;
  66. void ready(boost::cobalt::handler<system::error_code>) final;
  67. void initiate(boost::cobalt::completion_handler<system::error_code>) final;
  68. wait_op(wait_type wt, socket & sock) :
  69. wt(wt), sock_(sock) {}
  70. ~wait_op() = default;
  71. private:
  72. socket & sock_;
  73. };
  74. [[nodiscard]] wait_op wait(wait_type wt = wait_type::wait_read)
  75. {
  76. return {wt, *this};
  77. }
  78. struct BOOST_COBALT_IO_DECL connect_op final : op<system::error_code>
  79. {
  80. struct endpoint endpoint;
  81. void initiate(boost::cobalt::completion_handler<system::error_code>) final;
  82. connect_op(struct endpoint endpoint, socket & socket) :
  83. endpoint(endpoint), sock_(socket) {}
  84. ~connect_op() = default;
  85. private:
  86. socket & sock_;
  87. };
  88. [[nodiscard]] connect_op connect(endpoint ep)
  89. {
  90. return {ep, *this};
  91. }
  92. struct BOOST_COBALT_IO_DECL ranged_connect_op final : op<system::error_code, endpoint>
  93. {
  94. endpoint_sequence endpoints;
  95. void initiate(boost::cobalt::completion_handler<system::error_code, endpoint>) final;
  96. ranged_connect_op(endpoint_sequence eps, socket & socket) :
  97. endpoints(eps), sock_(socket) {}
  98. ~ranged_connect_op() = default;
  99. private:
  100. socket & sock_;
  101. };
  102. [[nodiscard]] ranged_connect_op connect(endpoint_sequence ep)
  103. {
  104. return {std::move(ep), *this};
  105. }
  106. protected:
  107. virtual void adopt_endpoint_(endpoint & ) {}
  108. socket(asio::basic_socket<protocol_type, executor> & socket) : socket_(socket) {}
  109. private:
  110. friend struct acceptor;
  111. asio::basic_socket<protocol_type, executor> & socket_;
  112. };
  113. BOOST_COBALT_IO_DECL system::result<void> connect_pair(protocol_type protocol, socket & socket1, socket & socket2);
  114. }
  115. #endif //BOOST_COBALT_IOSOCKET_HPP