Commit f20e612b authored by Dominik Charousset's avatar Dominik Charousset

Add IPv6 subnet abstraction

parent 0304cdf9
...@@ -68,6 +68,7 @@ set(LIBCAF_CORE_SRCS ...@@ -68,6 +68,7 @@ set(LIBCAF_CORE_SRCS
src/ipv4_address.cpp src/ipv4_address.cpp
src/ipv4_subnet.cpp src/ipv4_subnet.cpp
src/ipv6_address.cpp src/ipv6_address.cpp
src/ipv6_subnet.cpp
src/local_actor.cpp src/local_actor.cpp
src/logger.cpp src/logger.cpp
src/mailbox_element.cpp src/mailbox_element.cpp
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 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 <cstdint>
#include "caf/detail/comparable.hpp"
#include "caf/fwd.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/ipv4_subnet.hpp"
#include "caf/ipv6_address.hpp"
namespace caf {
class ipv6_subnet : detail::comparable<ipv6_subnet> {
public:
// -- constants --------------------------------------------------------------
/// Stores the offset of an embedded IPv4 subnet in bits.
static constexpr uint8_t v4_offset =
static_cast<uint8_t>(ipv6_address::num_bytes - ipv4_address::num_bytes) * 8;
// -- constructors, destructors, and assignment operators --------------------
ipv6_subnet();
explicit ipv6_subnet(ipv4_subnet subnet);
ipv6_subnet(ipv4_address network_address, uint8_t prefix_length);
ipv6_subnet(ipv6_address network_address, uint8_t prefix_length);
// -- properties -------------------------------------------------------------
/// Returns whether this subnet embeds an IPv4 subnet.
bool embeds_v4() const noexcept;
/// Returns an embedded IPv4 subnet.
/// @pre `embeds_v4()`
ipv4_subnet embedded_v4() const noexcept;
/// Returns the network address for this subnet.
inline ipv6_address network_address() const noexcept {
return address_;
}
/// Returns the prefix length of the netmask.
inline uint8_t prefix_length() const noexcept {
return prefix_length_;
}
/// Returns whether `addr` belongs to this subnet.
bool contains(ipv6_address addr) const noexcept;
/// Returns whether this subnet includes `other`.
bool contains(ipv6_subnet other) const noexcept;
/// Returns whether `addr` belongs to this subnet.
bool contains(ipv4_address addr) const noexcept;
/// Returns whether this subnet includes `other`.
bool contains(ipv4_subnet other) const noexcept;
// -- comparison -------------------------------------------------------------
int compare(const ipv6_subnet& other) const noexcept;
private:
// -- member variables -------------------------------------------------------
ipv6_address address_;
uint8_t prefix_length_;
};
} // namespace caf
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 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. *
******************************************************************************/
#include "caf/ipv6_subnet.hpp"
namespace caf {
// -- constructors, destructors, and assignment operators --------------------
ipv6_subnet::ipv6_subnet() {
// nop
}
ipv6_subnet::ipv6_subnet(ipv4_subnet subnet)
: address_(ipv6_address{subnet.network_address()}),
prefix_length_(v4_offset + subnet.prefix_length()){
// nop
}
ipv6_subnet::ipv6_subnet(ipv4_address network_address, uint8_t prefix_length)
: address_(network_address),
prefix_length_(prefix_length + v4_offset) {
// nop
}
ipv6_subnet::ipv6_subnet(ipv6_address network_address, uint8_t prefix_length)
: address_(network_address),
prefix_length_(prefix_length) {
// nop
}
// -- properties ---------------------------------------------------------------
bool ipv6_subnet::embeds_v4() const noexcept {
return prefix_length_ >= v4_offset && address_.embeds_v4();
}
ipv4_subnet ipv6_subnet::embedded_v4() const noexcept {
return {address_.embedded_v4(),
static_cast<uint8_t>(prefix_length_ - v4_offset)};
}
bool ipv6_subnet::contains(ipv6_address addr) const noexcept {
return address_ == addr.network_address(prefix_length_);
}
bool ipv6_subnet::contains(ipv6_subnet other) const noexcept {
// We can only contain a subnet if it's prefix is greater or equal.
if (prefix_length_ > other.prefix_length_)
return false;
return prefix_length_ == other.prefix_length_
? address_ == other.address_
: address_ == other.address_.network_address(prefix_length_);
}
bool ipv6_subnet::contains(ipv4_address addr) const noexcept {
return embeds_v4() ? embedded_v4().contains(addr) : false;
}
bool ipv6_subnet::contains(ipv4_subnet other) const noexcept {
return embeds_v4() ? embedded_v4().contains(other) : false;
}
// -- comparison ---------------------------------------------------------------
int ipv6_subnet::compare(const ipv6_subnet& other) const noexcept {
auto sub_res = address_.compare(other.address_);
return sub_res != 0 ? sub_res
: static_cast<int>(prefix_length_) - other.prefix_length_;
}
} // namespace caf
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 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. *
******************************************************************************/
#include "caf/config.hpp"
#define CAF_SUITE ipv6_subnet
#include "caf/test/dsl.hpp"
#include "caf/ipv6_subnet.hpp"
using namespace caf;
namespace {
ipv6_subnet operator/(ipv6_address addr, uint8_t prefix) {
return {addr, prefix};
}
} // namespace <anonymous>
CAF_TEST(constructing) {
auto zero = ipv6_address() / 128;
CAF_CHECK_EQUAL(zero.network_address(), ipv6_address());
CAF_CHECK_EQUAL(zero.prefix_length(), 128u);
}
CAF_TEST(constains) {
auto local = ipv6_address{{0xbebe, 0xbebe}, {}} / 32;
CAF_CHECK(local.contains(ipv6_address({0xbebe, 0xbebe, 0xbebe}, {})));
CAF_CHECK(!local.contains(ipv6_address({0xbebe, 0xbebf}, {})));
}
CAF_TEST(embedding) {
ipv4_subnet v4_local{ipv4_address({127, 0, 0, 1}), 8};
ipv6_subnet local{v4_local};
CAF_CHECK(local.embeds_v4());
CAF_CHECK_EQUAL(local.prefix_length(), 104u);
}
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