Commit aae2e2b9 authored by Dominik Charousset's avatar Dominik Charousset

Merge branch 'topic/ipv6' into develop

parents 20a02150 95a30652
......@@ -31,9 +31,7 @@ namespace network {
* callbacks for incoming connections as well as for error handling.
*/
class acceptor_manager : public manager {
public:
~acceptor_manager();
/**
......@@ -41,7 +39,6 @@ class acceptor_manager : public manager {
* a new connection is awaiting acceptance.
*/
virtual void new_connection() = 0;
};
} // namespace network
......
......@@ -153,12 +153,6 @@ void nonblocking(native_socket fd, bool new_value);
*/
std::pair<native_socket, native_socket> create_pipe();
/**
* Throws network_error with given error message and
* the platform-specific error code if `add_errno` is `true`.
*/
void throw_io_failure(const char* what, bool add_errno = true);
/**
* Returns true if `fd` is configured as nodelay socket.
* @throws network_error
......@@ -222,6 +216,11 @@ class event_handler {
*/
virtual void removed_from_loop(operation op) = 0;
/**
* Returns the native socket handle for this handler.
*/
virtual native_socket fd() const = 0;
/**
* Returns the `multiplexer` this acceptor belongs to.
*/
......@@ -243,11 +242,6 @@ class event_handler {
m_eventbf = value;
}
/**
* Returns the native socket handle for this handler.
*/
virtual native_socket fd() const = 0;
protected:
default_multiplexer& m_backend;
int m_eventbf;
......@@ -294,12 +288,10 @@ class default_socket {
using default_socket_acceptor = default_socket;
class default_multiplexer : public multiplexer {
public:
friend class io::middleman; // disambiguate reference
friend class supervisor;
public:
struct event {
native_socket fd;
int mask;
......@@ -356,7 +348,6 @@ class default_multiplexer : public multiplexer {
void del(operation op, native_socket fd, event_handler* ptr);
private:
// platform-dependent additional initialization code
void init();
......@@ -417,21 +408,18 @@ class default_multiplexer : public multiplexer {
std::vector<event> m_events; // always sorted by .fd
multiplexer_poll_shadow_data m_shadow;
std::pair<native_socket, native_socket> m_pipe;
std::thread::id m_tid;
};
default_multiplexer& get_multiplexer_singleton();
template <class T>
inline connection_handle conn_hdl_from_socket(const T& sock) {
connection_handle conn_hdl_from_socket(const T& sock) {
return connection_handle::from_int(
int64_from_native_socket(sock.native_handle()));
}
template <class T>
inline accept_handle accept_hdl_from_socket(const T& sock) {
accept_handle accept_hdl_from_socket(const T& sock) {
return accept_handle::from_int(
int64_from_native_socket(sock.native_handle()));
}
......@@ -462,17 +450,10 @@ class stream : public event_handler {
configure_read(receive_policy::at_most(1024));
}
/**
* Returns the `multiplexer` this stream belongs to.
*/
inline default_multiplexer& backend() {
return static_cast<default_multiplexer&>(m_sock.backend());
}
/**
* Returns the IO socket.
*/
inline Socket& socket_handle() {
Socket& socket_handle() {
return m_sock;
}
......@@ -502,8 +483,7 @@ class stream : public event_handler {
}
/**
* Configures how much data will be provided
* for the next `consume` callback.
* Configures how much data will be provided for the next `consume` callback.
* @warning Must not be called outside the IO multiplexers event loop
* once the stream has been started.
*/
......@@ -514,7 +494,7 @@ class stream : public event_handler {
/**
* Copies data to the write buffer.
* @note Not thread safe.
* @warning Not thread safe.
*/
void write(const void* buf, size_t num_bytes) {
CAF_LOG_TRACE("num_bytes: " << num_bytes);
......@@ -561,7 +541,7 @@ class stream : public event_handler {
backend().del(operation::read, m_sock.fd(), this);
}
void handle_event(operation op) {
void handle_event(operation op) override {
CAF_LOG_TRACE("op = " << static_cast<int>(op));
switch (op) {
case operation::read: {
......@@ -610,7 +590,6 @@ class stream : public event_handler {
}
}
protected:
native_socket fd() const override {
return m_sock.fd();
}
......@@ -658,20 +637,20 @@ class stream : public event_handler {
}
// reading & writing
Socket m_sock;
Socket m_sock;
// reading
manager_ptr m_reader;
size_t m_threshold;
size_t m_collected;
size_t m_max;
manager_ptr m_reader;
size_t m_threshold;
size_t m_collected;
size_t m_max;
receive_policy_flag m_rd_flag;
buffer_type m_rd_buf;
buffer_type m_rd_buf;
// writing
manager_ptr m_writer;
bool m_writing;
size_t m_written;
buffer_type m_wr_buf;
buffer_type m_wr_offline_buf;
manager_ptr m_writer;
bool m_writing;
size_t m_written;
buffer_type m_wr_buf;
buffer_type m_wr_offline_buf;
};
/**
......@@ -679,9 +658,7 @@ class stream : public event_handler {
*/
template <class SocketAcceptor>
class acceptor : public event_handler {
public:
using socket_type = typename SocketAcceptor::socket_type;
/**
......@@ -704,7 +681,7 @@ class acceptor : public event_handler {
/**
* Returns the IO socket.
*/
inline SocketAcceptor& socket_handle() {
SocketAcceptor& socket_handle() {
return m_accept_sock;
}
......@@ -712,7 +689,7 @@ class acceptor : public event_handler {
* Returns the accepted socket. This member function should
* be called only from the `new_connection` callback.
*/
inline socket_type& accepted_socket() {
socket_type& accepted_socket() {
return m_sock;
}
......@@ -763,48 +740,32 @@ class acceptor : public event_handler {
void removed_from_loop(operation op) override {
CAF_LOG_TRACE("m_accept_sock.fd = " << m_accept_sock.fd()
<< "op = " << static_cast<int>(op));
if (op == operation::read) m_mgr.reset();
if (op == operation::read) {
m_mgr.reset();
}
}
protected:
native_socket fd() const override {
return m_accept_sock.fd();
}
private:
manager_ptr m_mgr;
manager_ptr m_mgr;
SocketAcceptor m_accept_sock;
socket_type m_sock;
socket_type m_sock;
};
native_socket new_ipv4_connection_impl(const std::string&, uint16_t);
default_socket new_ipv4_connection(const std::string& host, uint16_t port);
native_socket new_tcp_connection_impl(const std::string&, uint16_t,
optional<protocol> preferred = none);
template <class Socket>
void ipv4_connect(Socket& sock, const std::string& host, uint16_t port) {
sock = new_ipv4_connection(host, port);
}
default_socket new_tcp_connection(const std::string& host, uint16_t port);
std::pair<native_socket, uint16_t>
new_ipv4_acceptor_impl(uint16_t port, const char* addr, bool reuse_addr);
new_tcp_acceptor_impl(uint16_t port, const char* addr, bool reuse_addr);
std::pair<default_socket_acceptor, uint16_t>
new_ipv4_acceptor(uint16_t port, const char* addr = nullptr,
bool reuse_addr = false);
template <class SocketAcceptor>
uint16_t ipv4_bind(SocketAcceptor& sock,
uint16_t port,
const char* addr = nullptr) {
CAF_LOGF_TRACE(CAF_ARG(port));
auto acceptor = new_ipv4_acceptor(port, addr);
sock = std::move(acceptor.first);
return acceptor.second;
}
new_tcp_acceptor(uint16_t port, const char* addr = nullptr,
bool reuse_addr = false);
} // namespace network
} // namespace io
......
......@@ -17,14 +17,16 @@
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#ifndef CAF_IO_NETWORK_ADDRESSES_HPP
#define CAF_IO_NETWORK_ADDRESSES_HPP
#ifndef CAF_IO_NETWORK_INTERFACES_HPP
#define CAF_IO_NETWORK_INTERFACES_HPP
#include <map>
#include <vector>
#include <string>
#include <utility>
#include "caf/optional.hpp"
#include "caf/io/network/protocol.hpp"
namespace caf {
......@@ -57,10 +59,16 @@ class interfaces {
*/
static std::vector<std::string> list_addresses(protocol proc,
bool include_localhost = true);
/**
* Returns a native IPv4 or IPv6 translation of `host`.
**/
static optional<std::pair<std::string, protocol>>
native_address(const std::string& host, optional<protocol> preferred = none);
};
} // namespace network
} // namespace io
} // namespace caf
#endif // CAF_IO_NETWORK_ADDRESSES_HPP
#endif // CAF_IO_NETWORK_INTERFACES_HPP
......@@ -35,7 +35,7 @@ namespace network {
*/
class manager : public ref_counted {
public:
virtual ~manager();
~manager();
/**
* Causes the manager to stop read operations on its IO device.
......@@ -49,11 +49,6 @@ class manager : public ref_counted {
virtual void io_failure(operation op) = 0;
};
/**
* @relates manager
*/
using manager_ptr = intrusive_ptr<manager>;
} // namespace network
} // namespace io
} // namespace caf
......
......@@ -33,16 +33,13 @@ namespace network {
* for incoming data as well as for error handling.
*/
class stream_manager : public manager {
public:
virtual ~stream_manager();
~stream_manager();
/**
* Called by the underlying IO device whenever it received data.
*/
virtual void consume(const void* data, size_t num_bytes) = 0;
};
} // namespace network
......
This diff is collapsed.
......@@ -19,8 +19,8 @@
#include "caf/io/network/interfaces.hpp"
#include <errno.h>
#include <netdb.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <net/if.h>
......@@ -144,6 +144,39 @@ std::vector<std::string> interfaces::list_addresses(protocol proc,
return result;
}
optional<std::pair<std::string, protocol>>
interfaces::native_address(const std::string& host,
optional<protocol> preferred) {
addrinfo hint;
memset(&hint, 0, sizeof(hint));
hint.ai_socktype = SOCK_STREAM;
if (preferred) {
hint.ai_family = *preferred == protocol::ipv4 ? AF_INET : AF_INET6;
}
addrinfo* tmp = nullptr;
if (getaddrinfo(host.c_str(), nullptr, &hint, &tmp)) {
return none;
}
std::unique_ptr<addrinfo, decltype(freeaddrinfo)*> addrs{tmp, freeaddrinfo};
for (auto i = addrs.get(); i != nullptr; i = i->ai_next) {
auto family = i->ai_family;
if (family == AF_INET || family == AF_INET6) {
char buffer[INET6_ADDRSTRLEN];
auto res = family == AF_INET
? inet_ntop(family,
&reinterpret_cast<sockaddr_in*>(i->ai_addr)->sin_addr,
buffer, sizeof(buffer))
: inet_ntop(family,
&reinterpret_cast<sockaddr_in6*>(i->ai_addr)->sin6_addr,
buffer, sizeof(buffer));
if (res != nullptr) {
return {{res, family == AF_INET ? protocol::ipv4 : protocol::ipv6}};
}
}
}
return none;
}
} // namespace network
} // namespace io
} // namespace caf
......@@ -65,6 +65,7 @@ int main() {
auto port = publish_at_some_port(4242, d);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
io::unpublish(d, port);
CAF_CHECKPOINT();
// must fail now
try {
auto oops = io::remote_actor("127.0.0.1", port);
......
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