Unverified Commit 47b45d8e authored by Dominik Charousset's avatar Dominik Charousset Committed by GitHub

Merge pull request #25

Simplify socket design
parents 7fb9bd97 240bb073
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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 {
namespace net {
/// A datagram-oriented network communication endpoint.
struct datagram_socket : abstract_socket<datagram_socket> {
using super = abstract_socket<datagram_socket>;
struct datagram_socket : network_socket {
using super = network_socket;
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`.
......
......@@ -25,7 +25,6 @@
#include "caf/config.hpp"
#include "caf/fwd.hpp"
#include "caf/net/abstract_socket.hpp"
#include "caf/net/socket.hpp"
#include "caf/net/socket_id.hpp"
......@@ -33,14 +32,10 @@ namespace caf {
namespace net {
/// A bidirectional network communication endpoint.
struct network_socket : abstract_socket<network_socket> {
using super = abstract_socket<network_socket>;
struct network_socket : socket {
using super = socket;
using super::super;
constexpr operator socket() const noexcept {
return socket{id};
}
};
/// Enables or disables `SIGPIPE` events from `x`.
......
......@@ -23,7 +23,6 @@
#include <utility>
#include "caf/fwd.hpp"
#include "caf/net/abstract_socket.hpp"
#include "caf/net/socket.hpp"
#include "caf/net/socket_id.hpp"
......@@ -31,14 +30,10 @@ namespace caf {
namespace net {
/// A unidirectional communication endpoint for inter-process communication.
struct pipe_socket : abstract_socket<pipe_socket> {
using super = abstract_socket<pipe_socket>;
struct pipe_socket : socket {
using super = socket;
using super::super;
constexpr operator socket() const noexcept {
return socket{id};
}
};
/// Creates two connected sockets. The first socket is the read handle and the
......
......@@ -23,8 +23,8 @@
#include <type_traits>
#include "caf/config.hpp"
#include "caf/detail/comparable.hpp"
#include "caf/fwd.hpp"
#include "caf/net/abstract_socket.hpp"
#include "caf/net/socket_id.hpp"
namespace caf {
......@@ -32,12 +32,33 @@ namespace net {
/// An internal endpoint for sending or receiving data. Can be either a
/// ::network_socket, ::pipe_socket, ::stream_socket, or ::datagram_socket.
struct socket : abstract_socket<socket> {
using super = abstract_socket<socket>;
struct socket : detail::comparable<socket> {
socket_id id;
using super::super;
constexpr socket() noexcept : id(invalid_socket_id) {
// nop
}
constexpr explicit socket(socket_id id) noexcept : id(id) {
// nop
}
constexpr socket(const socket& other) noexcept = default;
socket& operator=(const socket& other) noexcept = default;
constexpr signed_socket_id compare(socket other) const noexcept {
return static_cast<signed_socket_id>(id)
- static_cast<signed_socket_id>(other.id);
}
};
/// @relates socket
template <class Inspector>
typename Inspector::result_type inspect(Inspector& f, socket& x) {
return f(x.id);
}
/// Denotes the invalid socket.
constexpr auto invalid_socket = socket{invalid_socket_id};
......
......@@ -20,6 +20,7 @@
#include <cstddef>
#include <limits>
#include <type_traits>
#include "caf/config.hpp"
......@@ -46,5 +47,9 @@ constexpr socket_id invalid_socket_id = -1;
#endif // CAF_WINDOWS
/// Signed counterpart of `socket_id`.
/// @relates socket
using signed_socket_id = std::make_signed<socket_id>::type;
} // namespace net
} // namespace caf
......@@ -26,18 +26,10 @@ namespace net {
/// A connection-oriented network communication endpoint for bidirectional byte
/// streams.
struct stream_socket : abstract_socket<stream_socket> {
using super = abstract_socket<stream_socket>;
struct stream_socket : network_socket {
using super = network_socket;
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
......
......@@ -19,28 +19,18 @@
#pragma once
#include "caf/fwd.hpp"
#include "caf/net/abstract_socket.hpp"
#include "caf/net/fwd.hpp"
#include "caf/net/network_socket.hpp"
#include "caf/net/socket.hpp"
#include "caf/uri.hpp"
namespace caf {
namespace net {
/// Represents a TCP acceptor in listening mode.
struct tcp_accept_socket : abstract_socket<tcp_accept_socket> {
using super = abstract_socket<tcp_accept_socket>;
struct tcp_accept_socket : network_socket {
using super = network_socket;
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.
......
......@@ -19,8 +19,6 @@
#pragma once
#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/stream_socket.hpp"
#include "caf/uri.hpp"
......@@ -29,22 +27,10 @@ namespace caf {
namespace net {
/// Represents a TCP connection.
struct tcp_stream_socket : abstract_socket<tcp_stream_socket> {
using super = abstract_socket<tcp_stream_socket>;
struct tcp_stream_socket : stream_socket {
using super = stream_socket;
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.
......
......@@ -19,7 +19,6 @@
#pragma once
#include "caf/fwd.hpp"
#include "caf/ip_endpoint.hpp"
#include "caf/net/network_socket.hpp"
namespace caf {
......@@ -27,18 +26,10 @@ namespace net {
/// A datagram-oriented network communication endpoint for bidirectional
/// byte transmission.
struct udp_datagram_socket : abstract_socket<udp_datagram_socket> {
using super = abstract_socket<udp_datagram_socket>;
struct udp_datagram_socket : network_socket {
using super = network_socket;
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.
......
......@@ -115,7 +115,7 @@ expected<std::pair<stream_socket, stream_socket>> make_stream_socket_pair() {
accept(listener, nullptr, nullptr));
close(socket{listener});
guard.disable();
return std::make_pair(read_fd, write_fd);
return std::make_pair(stream_socket{read_fd}, stream_socket{write_fd});
}
error keepalive(stream_socket x, bool new_value) {
......
......@@ -63,9 +63,10 @@ expected<tcp_accept_socket> new_tcp_acceptor_impl(uint16_t port,
socktype |= SOCK_CLOEXEC;
#endif
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
auto sguard = make_socket_guard(tcp_accept_socket{fd});
child_process_inherit(sock, false);
if (reuse_addr) {
int on = 1;
CAF_NET_SYSCALL("setsockopt", tmp1, !=, 0,
......@@ -79,7 +80,7 @@ expected<tcp_accept_socket> new_tcp_acceptor_impl(uint16_t port,
memset(&sa, 0, sizeof(sockaddr_type));
detail::family_of(sa) = Family;
if (any)
if (auto err = set_inaddr_any(fd, sa))
if (auto err = set_inaddr_any(sock, sa))
return err;
CAF_NET_SYSCALL("inet_pton", tmp, !=, 1,
inet_pton(Family, addr, &detail::addr_of(sa)));
......@@ -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 {sock};
return tcp_stream_socket{sock};
}
} // namespace net
......
......@@ -60,14 +60,15 @@ expected<tcp_stream_socket> make_connected_tcp_stream_socket(ip_endpoint node) {
socktype |= SOCK_CLOEXEC;
#endif
CAF_NET_SYSCALL("socket", fd, ==, -1, ::socket(proto, socktype, 0));
child_process_inherit(fd, false);
auto sguard = make_socket_guard(tcp_stream_socket{fd});
tcp_stream_socket sock{fd};
child_process_inherit(sock, false);
auto sguard = make_socket_guard(sock);
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));
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())) {
CAF_LOG_INFO("successfully connected to (IPv4):" << to_string(node));
return sguard.release();
......
......@@ -22,7 +22,6 @@
#include "caf/test/dsl.hpp"
#include "caf/net/abstract_socket.hpp"
#include "caf/net/socket_id.hpp"
using namespace caf;
......
......@@ -27,6 +27,7 @@
#include "caf/detail/net_syscall.hpp"
#include "caf/detail/socket_sys_includes.hpp"
#include "caf/ip_address.hpp"
#include "caf/ip_endpoint.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/net/ip.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