3 #include <ossia/network/sockets/configuration.hpp>
5 #include <boost/asio/io_context.hpp>
6 #include <boost/asio/ip/udp.hpp>
7 #include <boost/asio/local/datagram_protocol.hpp>
8 #include <boost/asio/local/stream_protocol.hpp>
9 #include <boost/asio/placeholders.hpp>
10 #include <boost/asio/strand.hpp>
11 #include <boost/asio/write.hpp>
13 #include <nano_signal_slot.hpp>
17 #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
18 class unix_datagram_socket
20 using proto = boost::asio::local::datagram_protocol;
23 unix_datagram_socket(
const fd_configuration& conf, boost::asio::io_context& ctx)
26 , m_socket{boost::asio::make_strand(ctx)}
32 ::unlink(m_endpoint.path().data());
34 m_socket.bind(m_endpoint);
45 if(m_socket.is_open())
47 m_context.post([
this] {
57 m_socket.async_receive_from(
58 boost::asio::mutable_buffer(&m_data[0], std::size(m_data)), m_endpoint,
59 [
this, f](boost::system::error_code ec, std::size_t sz) {
60 if(ec == boost::asio::error::operation_aborted)
76 void write(
const char* data, std::size_t sz)
78 m_socket.send_to(boost::asio::buffer(data, sz), m_endpoint);
81 Nano::Signal<void()> on_close;
83 boost::asio::io_context& m_context;
84 proto::endpoint m_endpoint;
85 proto::socket m_socket;
86 alignas(16)
char m_data[65535];
89 class unix_stream_listener
92 using proto = boost::asio::local::stream_protocol;
93 unix_stream_listener() =
delete;
94 unix_stream_listener(
const unix_stream_listener&) =
delete;
95 unix_stream_listener& operator=(
const unix_stream_listener&) =
delete;
96 unix_stream_listener(unix_stream_listener&&) =
default;
97 unix_stream_listener& operator=(unix_stream_listener&&) =
default;
98 explicit unix_stream_listener(proto::socket sock)
99 : m_socket{std::move(sock)}
103 void close() { m_socket.close(); }
105 void write(
const boost::asio::const_buffer& buf) { boost::asio::write(m_socket, buf); }
111 proto::socket m_socket;
114 class unix_stream_server
117 using proto = boost::asio::local::stream_protocol;
118 using listener = unix_stream_listener;
119 [[no_unique_address]]
struct ensure_reuse
121 explicit ensure_reuse(
const proto::endpoint& endpoint)
123 ::unlink(endpoint.path().data());
127 unix_stream_server(
const fd_configuration& conf, boost::asio::io_context& ctx)
128 : m_ensure_reuse{conf.fd}
130 , m_acceptor{boost::asio::make_strand(ctx), conf.fd}
134 boost::asio::io_context& m_context;
135 proto::acceptor m_acceptor;
138 class unix_stream_client
141 using proto = boost::asio::local::stream_protocol;
142 using socket =
typename proto::socket;
144 unix_stream_client(
const fd_configuration& conf, boost::asio::io_context& ctx)
146 , m_endpoint{conf.fd}
147 , m_socket{boost::asio::make_strand(ctx)}
153 m_socket.connect(m_endpoint);
157 bool connected()
const {
return m_connected; }
161 m_context.post([
this] {
167 void write(
const char* data, std::size_t sz)
169 boost::asio::write(m_socket, boost::asio::buffer(data, sz));
172 Nano::Signal<void()> on_open;
173 Nano::Signal<void()> on_close;
174 Nano::Signal<void()> on_fail;
176 boost::asio::io_context& m_context;
177 proto::endpoint m_endpoint;
178 proto::socket m_socket;
179 bool m_connected{
false};