Commit fec1f77c authored by Dominik Charousset's avatar Dominik Charousset

Add IPv4 subnet abstraction

parent d23a59db
...@@ -66,6 +66,7 @@ set(LIBCAF_CORE_SRCS ...@@ -66,6 +66,7 @@ set(LIBCAF_CORE_SRCS
src/ini_consumer.cpp src/ini_consumer.cpp
src/invoke_result_visitor.cpp src/invoke_result_visitor.cpp
src/ipv4_address.cpp src/ipv4_address.cpp
src/ipv4_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/ipv4_address.hpp"
namespace caf {
class ipv4_subnet : detail::comparable<ipv4_subnet> {
public:
// -- constructors, destructors, and assignment operators --------------------
ipv4_subnet();
ipv4_subnet(ipv4_address network_address, uint8_t prefix_length);
// -- properties -------------------------------------------------------------
/// Returns the network address for this subnet.
inline ipv4_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(ipv4_address addr) const noexcept;
/// Returns whether this subnet includes `other`.
bool contains(ipv4_subnet other) const noexcept;
// -- comparison -------------------------------------------------------------
int compare(const ipv4_subnet& other) const noexcept;
private:
// -- member variables -------------------------------------------------------
ipv4_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/ipv4_subnet.hpp"
namespace caf {
// -- constructors, destructors, and assignment operators --------------------
ipv4_subnet::ipv4_subnet() {
// nop
}
ipv4_subnet::ipv4_subnet(ipv4_address network_address, uint8_t prefix_length)
: address_(network_address),
prefix_length_(prefix_length) {
// nop
}
// -- properties ---------------------------------------------------------------
bool ipv4_subnet::contains(ipv4_address addr) const noexcept {
return address_ == addr.network_address(prefix_length_);
}
bool ipv4_subnet::contains(ipv4_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_);
}
// -- comparison ---------------------------------------------------------------
int ipv4_subnet::compare(const ipv4_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 ipv4_subnet
#include "caf/test/dsl.hpp"
#include "caf/ipv4_subnet.hpp"
using namespace caf;
namespace {
ipv4_address addr(uint8_t oct1, uint8_t oct2, uint8_t oct3, uint8_t oct4) {
return ipv4_address({oct1, oct2, oct3, oct4});
}
ipv4_subnet operator/(ipv4_address addr, uint8_t prefix) {
return {addr, prefix};
}
} // namespace <anonymous>
CAF_TEST(constructing) {
ipv4_subnet zero{addr(0, 0, 0, 0), 32};
CAF_CHECK_EQUAL(zero.network_address(), addr(0, 0, 0, 0));
CAF_CHECK_EQUAL(zero.prefix_length(), 32u);
ipv4_subnet local{addr(127, 0, 0, 0), 8};
CAF_CHECK_EQUAL(local.network_address(), addr(127, 0, 0, 0));
CAF_CHECK_EQUAL(local.prefix_length(), 8u);
}
CAF_TEST(constains) {
ipv4_subnet local{addr(127, 0, 0, 0), 8};
CAF_CHECK(local.contains(addr(127, 0, 0, 1)));
CAF_CHECK(local.contains(addr(127, 1, 2, 3)));
CAF_CHECK(local.contains(addr(127, 128, 0, 0) / 9));
CAF_CHECK(local.contains(addr(127, 0, 0, 0) / 8));
CAF_CHECK(!local.contains(addr(127, 0, 0, 0) / 7));
}
CAF_TEST(ordering) {
CAF_CHECK_EQUAL(addr(192, 168, 168, 0) / 24, addr(192, 168, 168, 0) / 24);
CAF_CHECK_NOT_EQUAL(addr(192, 168, 168, 0) / 25, addr(192, 168, 168, 0) / 24);
CAF_CHECK_LESS(addr(192, 168, 167, 0) / 24, addr(192, 168, 168, 0) / 24);
CAF_CHECK_LESS(addr(192, 168, 168, 0) / 24, addr(192, 168, 168, 0) / 25);
}
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