Commit c1d3b4db authored by Dominik Charousset's avatar Dominik Charousset

Distinct between network and transport protocol

parent 85483265
......@@ -7,22 +7,23 @@ file(GLOB_RECURSE LIBCAF_IO_HDRS "caf/*.hpp")
# list cpp files excluding platform-dependent files
set (LIBCAF_IO_SRCS
src/basp_broker.cpp
src/abstract_broker.cpp
src/acceptor_manager.cpp
src/basp_broker.cpp
src/broker.cpp
src/default_multiplexer.cpp
src/doorman.cpp
src/middleman.cpp
src/middleman_actor.cpp
src/middleman_actor_impl.cpp
src/hook.cpp
src/interfaces.cpp
src/manager.cpp
src/middleman.cpp
src/middleman_actor.cpp
src/middleman_actor_impl.cpp
src/multiplexer.cpp
src/protocol.cpp
src/scribe.cpp
src/stream_manager.cpp
src/test_multiplexer.cpp
src/acceptor_manager.cpp
src/multiplexer.cpp
# BASP files
src/header.cpp
src/message_type.cpp
......
......@@ -676,9 +676,9 @@ private:
ProtocolPolicy policy_;
};
expected<native_socket> new_tcp_connection(const std::string& host,
uint16_t port,
optional<protocol> preferred = none);
expected<native_socket>
new_tcp_connection(const std::string& host, uint16_t port,
optional<protocol::network> preferred = none);
expected<native_socket> new_tcp_acceptor_impl(uint16_t port, const char* addr,
bool reuse_addr);
......
......@@ -36,7 +36,7 @@ namespace io {
namespace network {
// {protocol => address}
using address_listing = std::map<protocol, std::vector<std::string>>;
using address_listing = std::map<protocol::network, std::vector<std::string>>;
// {interface_name => {protocol => address}}
using interfaces_map = std::map<std::string, address_listing>;
......@@ -45,11 +45,11 @@ using interfaces_map = std::map<std::string, address_listing>;
class interfaces {
public:
/// Consumes `{interface_name, protocol_type, is_localhost, address}` entries.
using consumer = std::function<void (const char*, protocol,
using consumer = std::function<void (const char*, protocol::network,
bool, const char*)>;
/// Traverses all network interfaces for given protocols using `f`.
static void traverse(std::initializer_list<protocol> ps, consumer f);
static void traverse(std::initializer_list<protocol::network> ps, consumer f);
/// Traverses all network interfaces using `f`.
static void traverse(consumer f);
......@@ -62,21 +62,22 @@ public:
/// Returns all addresses for all devices for given protocols.
static std::vector<std::string>
list_addresses(std::initializer_list<protocol> procs,
list_addresses(std::initializer_list<protocol::network> procs,
bool include_localhost = true);
/// Returns all addresses for all devices for given protocol.
static std::vector<std::string> list_addresses(protocol proc,
static std::vector<std::string> list_addresses(protocol::network 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);
static optional<std::pair<std::string, protocol::network>>
native_address(const std::string& host,
optional<protocol::network> preferred = none);
/// Returns the host and protocol available for a local server socket
static std::vector<std::pair<std::string, protocol>>
static std::vector<std::pair<std::string, protocol::network>>
server_address(uint16_t port, const char* host,
optional<protocol> preferred = none);
optional<protocol::network> preferred = none);
};
} // namespace network
......
......@@ -21,25 +21,51 @@
#define CAF_IO_NETWORK_PROTOCOL_HPP
#include <cstddef>
#include <string>
#include "caf/meta/type_name.hpp"
namespace caf {
namespace io {
namespace network {
/// Denotes a network protocol, e.g., Ethernet or IP4/6.
enum class protocol : uint32_t {
ethernet,
/// Bundles protocol information for network and transport layer communication.
struct protocol {
/// Denotes a network protocol, i.e., IPv4 or IPv6.
enum network {
ipv4,
ipv6
};
/// Denotes a transport protocol, i.e., TCP or UDP.
enum transport {
tcp,
udp
};
transport trans;
network net;
};
/// @relates protocol::transport
inline std::string to_string(protocol::transport x) {
return x == protocol::tcp ? "TCP" : "UDP";
}
/// @relates protocol::network
inline std::string to_string(protocol::network x) {
return x == protocol::ipv4 ? "IPv4" : "IPv6";
}
/// @relates protocol
inline std::string to_string(protocol value) {
return value == protocol::ethernet ? "ethernet"
: (value == protocol::ipv4 ? "ipv4"
: "ipv6");
template <class Inspector>
typename Inspector::result_type inspect(Inspector& f, protocol& x) {
return f(meta::type_name("protocol"), x.trans, x.net);
}
/// Converts a protocol into a transport/network string representation, e.g.,
/// "TCP/IPv4".
/// @relates protocol
std::string to_string(const protocol& x);
} // namespace network
} // namespace io
} // namespace caf
......
......@@ -401,7 +401,6 @@ void basp_broker_state::learned_new_node_indirectly(const node_id& nid) {
[&](uint16_t port, network::address_listing& addresses) {
auto& mx = system().middleman().backend();
for (auto& kvp : addresses)
if (kvp.first != network::protocol::ethernet)
for (auto& addr : kvp.second) {
auto hdl = mx.new_tcp_scribe(addr, port);
if (hdl) {
......@@ -411,7 +410,6 @@ void basp_broker_state::learned_new_node_indirectly(const node_id& nid) {
helper->send(s, connect_atom::value, *hdl, port);
return;
}
// else: simply try next address
}
CAF_LOG_INFO("could not connect to node directly:" << CAF_ARG(nid));
}
......
......@@ -1153,9 +1153,9 @@ bool ip_connect(native_socket fd, const std::string& host, uint16_t port) {
return connect(fd, reinterpret_cast<const sockaddr*>(&sa), sizeof(sa)) == 0;
}
expected<native_socket> new_tcp_connection(const std::string& host,
uint16_t port,
optional<protocol> preferred) {
expected<native_socket>
new_tcp_connection(const std::string& host, uint16_t port,
optional<protocol::network> preferred) {
CAF_LOG_TRACE(CAF_ARG(host) << CAF_ARG(port) << CAF_ARG(preferred));
CAF_LOG_INFO("try to connect to:" << CAF_ARG(host) << CAF_ARG(port));
auto res = interfaces::native_address(host, std::move(preferred));
......
......@@ -56,7 +56,7 @@ namespace network {
// {interface_name => {protocol => address}}
using interfaces_map = std::map<std::string,
std::map<protocol,
std::map<protocol::network,
std::vector<std::string>>>;
template <class T>
......@@ -161,10 +161,7 @@ void for_each_address(bool get_ipv4, bool get_ipv6, F fun) {
namespace {
template <class F>
void traverse_impl(std::initializer_list<protocol> ps, F f) {
if (std::find(ps.begin(), ps.end(), protocol::ethernet) != ps.end())
for (auto& pair : detail::get_mac_addresses())
f(pair.first.c_str(), protocol::ethernet, false, pair.second.c_str());
void traverse_impl(std::initializer_list<protocol::network> ps, F f) {
auto get_ipv4 = std::find(ps.begin(), ps.end(), protocol::ipv4) != ps.end();
auto get_ipv6 = std::find(ps.begin(), ps.end(), protocol::ipv6) != ps.end();
for_each_address(get_ipv4, get_ipv6, f);
......@@ -172,29 +169,32 @@ void traverse_impl(std::initializer_list<protocol> ps, F f) {
} // namespace <anonymous>
void interfaces::traverse(std::initializer_list<protocol> ps, consumer f) {
void interfaces::traverse(std::initializer_list<protocol::network> ps,
consumer f) {
traverse_impl(ps, std::move(f));
}
void interfaces::traverse(consumer f) {
traverse_impl({protocol::ethernet, protocol::ipv4, protocol::ipv6}, std::move(f));
traverse_impl({protocol::ipv4, protocol::ipv6}, std::move(f));
}
interfaces_map interfaces::list_all(bool include_localhost) {
interfaces_map result;
traverse_impl({protocol::ethernet, protocol::ipv4, protocol::ipv6},
[&](const char* name, protocol p, bool lo, const char* addr) {
traverse_impl(
{protocol::ipv4, protocol::ipv6},
[&](const char* name, protocol::network p, bool lo, const char* addr) {
if (include_localhost || !lo)
result[name][p].emplace_back(addr);
});
return result;
}
std::map<protocol, std::vector<std::string>>
std::map<protocol::network, std::vector<std::string>>
interfaces::list_addresses(bool include_localhost) {
std::map<protocol, std::vector<std::string>> result;
traverse_impl({protocol::ethernet, protocol::ipv4, protocol::ipv6},
[&](const char*, protocol p, bool lo, const char* addr) {
std::map<protocol::network, std::vector<std::string>> result;
traverse_impl(
{protocol::ipv4, protocol::ipv6},
[&](const char*, protocol::network p, bool lo, const char* addr) {
if (include_localhost || !lo)
result[p].emplace_back(addr);
});
......@@ -202,24 +202,25 @@ interfaces::list_addresses(bool include_localhost) {
}
std::vector<std::string>
interfaces::list_addresses(std::initializer_list<protocol> procs,
interfaces::list_addresses(std::initializer_list<protocol::network> procs,
bool include_localhost) {
std::vector<std::string> result;
traverse_impl(procs, [&](const char*, protocol, bool lo, const char* addr) {
traverse_impl(procs,
[&](const char*, protocol::network, bool lo, const char* addr) {
if (include_localhost || !lo)
result.emplace_back(addr);
});
return result;
}
std::vector<std::string> interfaces::list_addresses(protocol proc,
std::vector<std::string> interfaces::list_addresses(protocol::network proc,
bool include_localhost) {
return list_addresses({proc}, include_localhost);
}
optional<std::pair<std::string, protocol>>
optional<std::pair<std::string, protocol::network>>
interfaces::native_address(const std::string& host,
optional<protocol> preferred) {
optional<protocol::network> preferred) {
addrinfo hint;
memset(&hint, 0, sizeof(hint));
hint.ai_socktype = SOCK_STREAM;
......@@ -239,10 +240,10 @@ interfaces::native_address(const std::string& host,
return none;
}
std::vector<std::pair<std::string, protocol>>
std::vector<std::pair<std::string, protocol::network>>
interfaces::server_address(uint16_t port, const char* host,
optional<protocol> preferred) {
using addr_pair = std::pair<std::string, protocol>;
optional<protocol::network> preferred) {
using addr_pair = std::pair<std::string, protocol::network>;
addrinfo hint;
memset(&hint, 0, sizeof(hint));
hint.ai_socktype = SOCK_STREAM;
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2017 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* 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. *
******************************************************************************/
#include "caf/io/network/protocol.hpp"
namespace caf {
namespace io {
namespace network {
std::string to_string(const protocol& x) {
std::string result;
result += to_string(x.trans);
result += "/";
result += to_string(x.net);
return result;
}
} // namespace network
} // namespace io
} // namespace caf
......@@ -201,8 +201,9 @@ void bootstrap(actor_system& system,
<< " --caf#slave-name=" << slave.host
<< " --caf#bootstrap-node=";
bool is_first = true;
interfaces::traverse({protocol::ipv4, protocol::ipv6},
[&](const char*, protocol, bool lo, const char* x) {
interfaces::traverse(
{protocol::ipv4, protocol::ipv6},
[&](const char*, protocol::network, bool lo, const char* x) {
if (lo)
return;
if (!is_first)
......
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