Commit 3c747ee3 authored by Dominik Charousset's avatar Dominik Charousset

Simplify socket design

parent c08a983d
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <cstddef>
#include <limits>
#include "caf/net/socket_id.hpp"
namespace caf {
namespace net {
template <class Derived>
struct abstract_socket {
socket_id id;
constexpr abstract_socket() : id(invalid_socket_id) {
// nop
}
constexpr abstract_socket(socket_id id) : id(id) {
// nop
}
constexpr abstract_socket(const Derived& other) : id(other.id) {
// nop
}
abstract_socket& operator=(const Derived& other) {
id = other.id;
return *this;
}
template <class Inspector>
friend typename Inspector::result_type inspect(Inspector& f, Derived& x) {
return f(x.id);
}
friend constexpr bool operator==(Derived x, Derived y) {
return x.id == y.id;
}
friend constexpr bool operator!=(Derived x, Derived y) {
return x.id != y.id;
}
friend constexpr bool operator<(Derived x, Derived y) {
return x.id < y.id;
}
};
} // namespace net
} // namespace caf
...@@ -25,18 +25,10 @@ namespace caf { ...@@ -25,18 +25,10 @@ namespace caf {
namespace net { namespace net {
/// A datagram-oriented network communication endpoint. /// A datagram-oriented network communication endpoint.
struct datagram_socket : abstract_socket<datagram_socket> { struct datagram_socket : network_socket {
using super = abstract_socket<datagram_socket>; using super = network_socket;
using super::super; using super::super;
constexpr operator socket() const noexcept {
return socket{id};
}
constexpr operator network_socket() const noexcept {
return network_socket{id};
}
}; };
/// Enables or disables `SIO_UDP_CONNRESET` error on `x`. /// Enables or disables `SIO_UDP_CONNRESET` error on `x`.
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include "caf/config.hpp" #include "caf/config.hpp"
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
#include "caf/net/abstract_socket.hpp"
#include "caf/net/socket.hpp" #include "caf/net/socket.hpp"
#include "caf/net/socket_id.hpp" #include "caf/net/socket_id.hpp"
...@@ -33,14 +32,10 @@ namespace caf { ...@@ -33,14 +32,10 @@ namespace caf {
namespace net { namespace net {
/// A bidirectional network communication endpoint. /// A bidirectional network communication endpoint.
struct network_socket : abstract_socket<network_socket> { struct network_socket : socket {
using super = abstract_socket<network_socket>; using super = socket;
using super::super; using super::super;
constexpr operator socket() const noexcept {
return socket{id};
}
}; };
/// Enables or disables `SIGPIPE` events from `x`. /// Enables or disables `SIGPIPE` events from `x`.
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <utility> #include <utility>
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
#include "caf/net/abstract_socket.hpp"
#include "caf/net/socket.hpp" #include "caf/net/socket.hpp"
#include "caf/net/socket_id.hpp" #include "caf/net/socket_id.hpp"
...@@ -31,14 +30,10 @@ namespace caf { ...@@ -31,14 +30,10 @@ namespace caf {
namespace net { namespace net {
/// A unidirectional communication endpoint for inter-process communication. /// A unidirectional communication endpoint for inter-process communication.
struct pipe_socket : abstract_socket<pipe_socket> { struct pipe_socket : socket {
using super = abstract_socket<pipe_socket>; using super = socket;
using super::super; using super::super;
constexpr operator socket() const noexcept {
return socket{id};
}
}; };
/// Creates two connected sockets. The first socket is the read handle and the /// Creates two connected sockets. The first socket is the read handle and the
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include "caf/config.hpp" #include "caf/config.hpp"
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
#include "caf/net/abstract_socket.hpp"
#include "caf/net/socket_id.hpp" #include "caf/net/socket_id.hpp"
namespace caf { namespace caf {
...@@ -32,12 +31,48 @@ namespace net { ...@@ -32,12 +31,48 @@ namespace net {
/// An internal endpoint for sending or receiving data. Can be either a /// An internal endpoint for sending or receiving data. Can be either a
/// ::network_socket, ::pipe_socket, ::stream_socket, or ::datagram_socket. /// ::network_socket, ::pipe_socket, ::stream_socket, or ::datagram_socket.
struct socket : abstract_socket<socket> { struct socket {
using super = abstract_socket<socket>; socket_id id;
using super::super; constexpr socket() : id(invalid_socket_id) {
// nop
}
constexpr explicit socket(socket_id id) : id(id) {
// nop
}
constexpr socket(const socket& other) : id(other.id) {
// nop
}
socket& operator=(const socket& other) {
id = other.id;
return *this;
}
}; };
/// @relates socket
template <class Inspector>
typename Inspector::result_type inspect(Inspector& f, socket& x) {
return f(x.id);
}
/// @relates socket
constexpr bool operator==(socket x, socket y) {
return x.id == y.id;
}
/// @relates socket
constexpr bool operator!=(socket x, socket y) {
return x.id != y.id;
}
/// @relates socket
constexpr bool operator<(socket x, socket y) {
return x.id < y.id;
}
/// Denotes the invalid socket. /// Denotes the invalid socket.
constexpr auto invalid_socket = socket{invalid_socket_id}; constexpr auto invalid_socket = socket{invalid_socket_id};
......
...@@ -26,18 +26,10 @@ namespace net { ...@@ -26,18 +26,10 @@ namespace net {
/// A connection-oriented network communication endpoint for bidirectional byte /// A connection-oriented network communication endpoint for bidirectional byte
/// streams. /// streams.
struct stream_socket : abstract_socket<stream_socket> { struct stream_socket : network_socket {
using super = abstract_socket<stream_socket>; using super = network_socket;
using super::super; using super::super;
constexpr operator socket() const noexcept {
return socket{id};
}
constexpr operator network_socket() const noexcept {
return network_socket{id};
}
}; };
/// Creates two connected sockets to mimic network communication (usually for /// Creates two connected sockets to mimic network communication (usually for
......
...@@ -19,28 +19,18 @@ ...@@ -19,28 +19,18 @@
#pragma once #pragma once
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
#include "caf/net/abstract_socket.hpp"
#include "caf/net/fwd.hpp" #include "caf/net/fwd.hpp"
#include "caf/net/network_socket.hpp" #include "caf/net/network_socket.hpp"
#include "caf/net/socket.hpp"
#include "caf/uri.hpp" #include "caf/uri.hpp"
namespace caf { namespace caf {
namespace net { namespace net {
/// Represents a TCP acceptor in listening mode. /// Represents a TCP acceptor in listening mode.
struct tcp_accept_socket : abstract_socket<tcp_accept_socket> { struct tcp_accept_socket : network_socket {
using super = abstract_socket<tcp_accept_socket>; using super = network_socket;
using super::super; using super::super;
constexpr operator socket() const noexcept {
return socket{id};
}
constexpr operator network_socket() const noexcept {
return network_socket{id};
}
}; };
/// Creates a new TCP socket to accept connections on a given port. /// Creates a new TCP socket to accept connections on a given port.
......
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
#pragma once #pragma once
#include "caf/ip_endpoint.hpp" #include "caf/ip_endpoint.hpp"
#include "caf/net/abstract_socket.hpp"
#include "caf/net/network_socket.hpp"
#include "caf/net/socket.hpp" #include "caf/net/socket.hpp"
#include "caf/net/stream_socket.hpp" #include "caf/net/stream_socket.hpp"
#include "caf/uri.hpp" #include "caf/uri.hpp"
...@@ -29,22 +27,10 @@ namespace caf { ...@@ -29,22 +27,10 @@ namespace caf {
namespace net { namespace net {
/// Represents a TCP connection. /// Represents a TCP connection.
struct tcp_stream_socket : abstract_socket<tcp_stream_socket> { struct tcp_stream_socket : stream_socket {
using super = abstract_socket<tcp_stream_socket>; using super = stream_socket;
using super::super; using super::super;
constexpr operator socket() const noexcept {
return socket{id};
}
constexpr operator network_socket() const noexcept {
return network_socket{id};
}
constexpr operator stream_socket() const noexcept {
return stream_socket{id};
}
}; };
/// Creates a `tcp_stream_socket` connected to given remote node. /// Creates a `tcp_stream_socket` connected to given remote node.
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#pragma once #pragma once
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
#include "caf/ip_endpoint.hpp"
#include "caf/net/network_socket.hpp" #include "caf/net/network_socket.hpp"
namespace caf { namespace caf {
...@@ -27,18 +26,10 @@ namespace net { ...@@ -27,18 +26,10 @@ namespace net {
/// A datagram-oriented network communication endpoint for bidirectional /// A datagram-oriented network communication endpoint for bidirectional
/// byte transmission. /// byte transmission.
struct udp_datagram_socket : abstract_socket<udp_datagram_socket> { struct udp_datagram_socket : network_socket {
using super = abstract_socket<udp_datagram_socket>; using super = network_socket;
using super::super; using super::super;
constexpr operator socket() const noexcept {
return socket{id};
}
constexpr operator network_socket() const noexcept {
return network_socket{id};
}
}; };
/// Creates a `udp_datagram_socket` bound to given port. /// Creates a `udp_datagram_socket` bound to given port.
......
...@@ -63,9 +63,10 @@ expected<tcp_accept_socket> new_tcp_acceptor_impl(uint16_t port, ...@@ -63,9 +63,10 @@ expected<tcp_accept_socket> new_tcp_acceptor_impl(uint16_t port,
socktype |= SOCK_CLOEXEC; socktype |= SOCK_CLOEXEC;
#endif #endif
CAF_NET_SYSCALL("socket", fd, ==, -1, ::socket(Family, socktype, 0)); CAF_NET_SYSCALL("socket", fd, ==, -1, ::socket(Family, socktype, 0));
child_process_inherit(fd, false); tcp_accept_socket sock{fd};
// sguard closes the socket in case of exception // sguard closes the socket in case of exception
auto sguard = make_socket_guard(tcp_accept_socket{fd}); auto sguard = make_socket_guard(tcp_accept_socket{fd});
child_process_inherit(sock, false);
if (reuse_addr) { if (reuse_addr) {
int on = 1; int on = 1;
CAF_NET_SYSCALL("setsockopt", tmp1, !=, 0, CAF_NET_SYSCALL("setsockopt", tmp1, !=, 0,
...@@ -79,7 +80,7 @@ expected<tcp_accept_socket> new_tcp_acceptor_impl(uint16_t port, ...@@ -79,7 +80,7 @@ expected<tcp_accept_socket> new_tcp_acceptor_impl(uint16_t port,
memset(&sa, 0, sizeof(sockaddr_type)); memset(&sa, 0, sizeof(sockaddr_type));
detail::family_of(sa) = Family; detail::family_of(sa) = Family;
if (any) if (any)
if (auto err = set_inaddr_any(fd, sa)) if (auto err = set_inaddr_any(sock, sa))
return err; return err;
CAF_NET_SYSCALL("inet_pton", tmp, !=, 1, CAF_NET_SYSCALL("inet_pton", tmp, !=, 1,
inet_pton(Family, addr, &detail::addr_of(sa))); inet_pton(Family, addr, &detail::addr_of(sa)));
...@@ -141,7 +142,7 @@ expected<tcp_stream_socket> accept(tcp_accept_socket x) { ...@@ -141,7 +142,7 @@ expected<tcp_stream_socket> accept(tcp_accept_socket x) {
} }
return caf::make_error(sec::socket_operation_failed, "tcp accept failed"); return caf::make_error(sec::socket_operation_failed, "tcp accept failed");
} }
return {sock}; return tcp_stream_socket{sock};
} }
} // namespace net } // namespace net
......
...@@ -60,14 +60,15 @@ expected<tcp_stream_socket> make_connected_tcp_stream_socket(ip_endpoint node) { ...@@ -60,14 +60,15 @@ expected<tcp_stream_socket> make_connected_tcp_stream_socket(ip_endpoint node) {
socktype |= SOCK_CLOEXEC; socktype |= SOCK_CLOEXEC;
#endif #endif
CAF_NET_SYSCALL("socket", fd, ==, -1, ::socket(proto, socktype, 0)); CAF_NET_SYSCALL("socket", fd, ==, -1, ::socket(proto, socktype, 0));
child_process_inherit(fd, false); tcp_stream_socket sock{fd};
auto sguard = make_socket_guard(tcp_stream_socket{fd}); child_process_inherit(sock, false);
auto sguard = make_socket_guard(sock);
if (proto == AF_INET6) { if (proto == AF_INET6) {
if (ip_connect<AF_INET6>(fd, to_string(node.address()), node.port())) { if (ip_connect<AF_INET6>(sock, to_string(node.address()), node.port())) {
CAF_LOG_INFO("successfully connected to (IPv6):" << to_string(node)); CAF_LOG_INFO("successfully connected to (IPv6):" << to_string(node));
return sguard.release(); return sguard.release();
} }
} else if (ip_connect<AF_INET>(fd, to_string(node.address().embedded_v4()), } else if (ip_connect<AF_INET>(sock, to_string(node.address().embedded_v4()),
node.port())) { node.port())) {
CAF_LOG_INFO("successfully connected to (IPv4):" << to_string(node)); CAF_LOG_INFO("successfully connected to (IPv4):" << to_string(node));
return sguard.release(); return sguard.release();
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include "caf/test/dsl.hpp" #include "caf/test/dsl.hpp"
#include "caf/net/abstract_socket.hpp"
#include "caf/net/socket_id.hpp" #include "caf/net/socket_id.hpp"
using namespace caf; using namespace caf;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "caf/detail/net_syscall.hpp" #include "caf/detail/net_syscall.hpp"
#include "caf/detail/socket_sys_includes.hpp" #include "caf/detail/socket_sys_includes.hpp"
#include "caf/ip_address.hpp" #include "caf/ip_address.hpp"
#include "caf/ip_endpoint.hpp"
#include "caf/ipv4_address.hpp" #include "caf/ipv4_address.hpp"
#include "caf/net/ip.hpp" #include "caf/net/ip.hpp"
#include "caf/net/socket_guard.hpp" #include "caf/net/socket_guard.hpp"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment