Commit 9e362be0 authored by Thomas Markwalder's avatar Thomas Markwalder

[5535] dhcpsrv now supports multiple relay addresses in RelayInfo

src/lib/dhcpsrv/network.*
    Network::RelayInfo
    - modified to support a list of IP addresses
    - added methods:
        addAddress(const asiolink::IOAddress& addr)
        bool hasAddresses()
        bool containsAddress(const asiolink::IOAddress& addr)
        +const IOAddressList& getAddresses()

    Network
    - added wrapper methods for convenience:
        addRelayAddress(const asiolink::IOAddress& addr)
        bool hasRelays()
        bool hasRelayAddress(const asiolink::IOAddress& addr)
        const IOAddressList& getRelayAddresses()

    - toElement() - modified to output ip-addresses list

    Updated the following accordingly:
        src/lib/dhcpsrv/cfg_subnets4.cc
        src/lib/dhcpsrv/cfg_subnets6.cc
        src/lib/dhcpsrv/parsers/dhcp_parsers.cc
        src/lib/dhcpsrv/subnet.cc
        src/lib/dhcpsrv/tests/cfg_shared_networks4_unittest.cc
        src/lib/dhcpsrv/tests/cfg_shared_networks6_unittest.cc
        src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc
        src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc
        src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc
        src/lib/dhcpsrv/tests/shared_network_unittest.cc
        src/lib/dhcpsrv/tests/subnet_unittest.cc
parent c494c28c
......@@ -137,17 +137,16 @@ CfgSubnets4::selectSubnet(const SubnetSelector& selector) const {
// If relay information is specified for this subnet, it must match.
// Otherwise, we ignore this subnet.
if (!(*subnet)->getRelayInfo().addr_.isV4Zero()) {
if (selector.giaddr_ != (*subnet)->getRelayInfo().addr_) {
if ((*subnet)->hasRelays()) {
if (!(*subnet)->hasRelayAddress(selector.giaddr_)) {
continue;
}
} else {
// Relay information is not specified on the subnet level,
// so let's try matching on the shared network level.
SharedNetwork4Ptr network;
(*subnet)->getSharedNetwork(network);
if (!network || (selector.giaddr_ != network->getRelayInfo().addr_)) {
if (!network || !(network->hasRelayAddress(selector.giaddr_))) {
continue;
}
}
......
......@@ -116,16 +116,17 @@ CfgSubnets6::selectSubnet(const asiolink::IOAddress& address,
for (Subnet6Collection::const_iterator subnet = subnets_.begin();
subnet != subnets_.end(); ++subnet) {
// If the specified address matches the relay address, return this
// If the specified address matches a relay address, return this
// subnet.
if (is_relay_address &&
((*subnet)->getRelayInfo().addr_ == address) &&
((*subnet)->hasRelayAddress(address)) &&
(*subnet)->clientSupported(client_classes)) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
DHCPSRV_CFGMGR_SUBNET6_RELAY)
.arg((*subnet)->toText()).arg(address.toText());
return (*subnet);
}
}
}
......
......@@ -16,8 +16,56 @@ using namespace isc::data;
namespace isc {
namespace dhcp {
Network::RelayInfo::RelayInfo(const isc::asiolink::IOAddress& addr)
:addr_(addr) {
void
Network::RelayInfo::addAddress(const asiolink::IOAddress& addr) {
if (containsAddress(addr)) {
isc_throw (BadValue, "RelayInfo already contains address: "
<< addr.toText());
}
addresses_.push_back(addr);
}
bool
Network::RelayInfo::hasAddresses() const {
return (addresses_.size() > 0);
}
bool
Network::RelayInfo::containsAddress(const asiolink::IOAddress& addr) const {
for (auto address = addresses_.begin(); address != addresses_.end();
++address) {
if ((*address) == addr) {
return (true);
}
}
return (false);
}
const IOAddressList&
Network::RelayInfo::getAddresses() const {
return (addresses_);
}
void
Network::addRelayAddress(const asiolink::IOAddress& addr) {
relay_.addAddress(addr);
}
bool
Network::hasRelays() const {
return (relay_.hasAddresses());
}
bool
Network::hasRelayAddress(const asiolink::IOAddress& addr) const {
return (relay_.containsAddress(addr));
}
const IOAddressList&
Network::getRelayAddresses() const {
return (relay_.getAddresses());
}
bool
......@@ -61,11 +109,15 @@ Network::toElement() const {
map->set("interface", Element::create(iface));
}
// Set relay info
const RelayInfo& relay_info = getRelayInfo();
ElementPtr relay = Element::createMap();
relay->set("ip-address", Element::create(relay_info.addr_.toText()));
map->set("relay", relay);
ElementPtr relay_map = Element::createMap();
ElementPtr address_list = Element::createList();
const IOAddressList addresses = getRelayAddresses();
for (auto address = addresses.begin(); address != addresses.end(); ++address) {
address_list->add(Element::create((*address).toText()));
}
relay_map->set("ip-addresses", address_list);
map->set("relay", relay_map);
// Set client-class
const ClientClass& cclass = getClientClass();
......
......@@ -24,6 +24,9 @@
namespace isc {
namespace dhcp {
/// List of IOAddresses
typedef std::vector<isc::asiolink::IOAddress> IOAddressList;
/// @brief Common interface representing a network to which the DHCP clients
/// are connected.
///
......@@ -44,24 +47,42 @@ namespace dhcp {
/// derived classes.
class Network : public virtual UserContext, public data::CfgToElement {
public:
/// @brief Holds optional information about relay.
///
/// In some cases it is beneficial to have additional information about
/// a relay configured in the subnet. For now, the structure holds only
/// IP address, but there may potentially be additional parameters added
/// IP addresses, but there may potentially be additional parameters added
/// later, e.g. relay interface-id or relay-id.
struct RelayInfo {
class RelayInfo {
public:
/// @brief default and the only constructor
/// @brief Adds an address to the list of addresses
///
/// @param addr an IP address of the relay (may be :: or 0.0.0.0)
RelayInfo(const isc::asiolink::IOAddress& addr);
/// @param addr address to add
/// @throw BadValue if the address is already in the list
void addAddress(const asiolink::IOAddress& addr);
/// @brief IP address of the relay
isc::asiolink::IOAddress addr_;
/// @brief Returns const reference to the list of addresses
///
/// @return const reference to the list of addresses
const IOAddressList& getAddresses() const;
/// @brief Indicates whether or not the address list has entries
///
/// @return True if the address list is not empty
bool hasAddresses() const;
/// @brief Checks the address list for the given address
///
/// @return True if the address is found in the address list
bool containsAddress(const asiolink::IOAddress& addr) const;
private:
/// @brief List of relay IP addresses
IOAddressList addresses_;
};
/// @brief Specifies allowed host reservation mode.
///
typedef enum {
......@@ -88,8 +109,7 @@ public:
/// @brief Constructor.
Network()
: iface_name_(), relay_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
client_class_(""), t1_(0), t2_(0), valid_(0),
: iface_name_(), client_class_(""), t1_(0), t2_(0), valid_(0),
host_reservation_mode_(HR_ALL), cfg_option_(new CfgOption()) {
}
......@@ -151,6 +171,28 @@ public:
return (relay_);
}
/// @brief Adds an address to the list addresses in the network's relay info
///
/// @param addr address of the relay
/// @throw BadValue if the address is already in the list
void addRelayAddress(const asiolink::IOAddress& addr);
/// @brief Returns the list of relay addresses from the network's relay info
///
/// @return const reference to the list of addresses
const IOAddressList& getRelayAddresses() const;
/// @brief Indicates if network's relay info has relay addresses
///
/// @return True the relay list is not empty, false otherwise
bool hasRelays() const;
/// @brief Tests if the network's relay info contains the given address
///
/// @param address address to search for in the relay list
/// @return True if a relay with the given address is found, false otherwise
bool hasRelayAddress(const asiolink::IOAddress& address) const;
/// @brief Checks whether this network supports client that belongs to
/// specified classes.
///
......@@ -363,7 +405,6 @@ public:
/// @brief Constructor.
Network6()
: Network(), preferred_(0), interface_id_(), rapid_commit_(false) {
setRelayInfo(asiolink::IOAddress::IPV6_ZERO_ADDRESS());
}
/// @brief Returns preferred lifetime (in seconds)
......
......@@ -249,7 +249,8 @@ RelayInfoParser::parse(const isc::dhcp::Network::RelayInfoPtr& cfg,
// Ok, we're done with parsing. Let's store the result in the structure
// we were given as configuration storage.
*cfg = isc::dhcp::Network::RelayInfo(ip);
*cfg = isc::dhcp::Network::RelayInfo();
cfg->addAddress(ip);
}
//****************************** PoolParser ********************************
......@@ -431,8 +432,7 @@ SubnetConfigParser::SubnetConfigParser(uint16_t family)
: pools_(new PoolStorage()),
address_family_(family),
options_(new CfgOption()) {
string addr = family == AF_INET ? "0.0.0.0" : "::";
relay_info_.reset(new isc::dhcp::Network::RelayInfo(IOAddress(addr)));
relay_info_.reset(new isc::dhcp::Network::RelayInfo());
}
SubnetPtr
......@@ -991,7 +991,6 @@ Subnet6ConfigParser::parse(ConstElementPtr subnet) {
sn6ptr->setRelayInfo(*relay_info_);
}
// Parse Host Reservations for this subnet if any.
ConstElementPtr reservations = subnet->get("reservations");
if (reservations) {
......
......@@ -231,8 +231,7 @@ Subnet4::Subnet4(const isc::asiolink::IOAddress& prefix, uint8_t length,
isc_throw(BadValue, "Non IPv4 prefix " << prefix.toText()
<< " specified in subnet4");
}
// Relay info.
setRelayInfo(IOAddress::IPV4_ZERO_ADDRESS());
// Timers.
setT1(t1);
setT2(t2);
......@@ -602,8 +601,6 @@ Subnet6::Subnet6(const isc::asiolink::IOAddress& prefix, uint8_t length,
<< " specified in subnet6");
}
// Relay info.
setRelayInfo(RelayInfo(IOAddress::IPV6_ZERO_ADDRESS()));
// Timers.
setT1(t1);
setT2(t2);
......
......@@ -111,6 +111,9 @@ TEST(CfgSharedNetworks4Test, unparse) {
SharedNetwork4Ptr network2(new SharedNetwork4("dog"));
network1->setIface("eth0");
network1->addRelayAddress(IOAddress("198.16.1.1"));
network1->addRelayAddress(IOAddress("198.16.1.2"));
network2->setIface("eth1");
CfgSharedNetworks4 cfg;
......@@ -125,9 +128,7 @@ TEST(CfgSharedNetworks4Test, unparse) {
" \"name\": \"dog\",\n"
" \"option-data\": [ ],\n"
" \"rebind-timer\": 0,\n"
" \"relay\": {\n"
" \"ip-address\": \"0.0.0.0\"\n"
" },\n"
" \"relay\": { \"ip-addresses\": [ ] },\n"
" \"renew-timer\": 0,\n"
" \"reservation-mode\": \"all\","
" \"subnet4\": [ ],\n"
......@@ -139,9 +140,7 @@ TEST(CfgSharedNetworks4Test, unparse) {
" \"name\": \"frog\",\n"
" \"option-data\": [ ],\n"
" \"rebind-timer\": 0,\n"
" \"relay\": {\n"
" \"ip-address\": \"0.0.0.0\"\n"
" },\n"
" \"relay\": { \"ip-addresses\": [ \"198.16.1.1\", \"198.16.1.2\" ] },\n"
" \"renew-timer\": 0,\n"
" \"reservation-mode\": \"all\","
" \"subnet4\": [ ],\n"
......
......@@ -111,6 +111,8 @@ TEST(CfgSharedNetworks6Test, unparse) {
SharedNetwork6Ptr network2(new SharedNetwork6("dog"));
network1->setIface("eth0");
network1->addRelayAddress(IOAddress("2001:db8:1::1"));
network1->addRelayAddress(IOAddress("2001:db8:1::2"));
network2->setIface("eth1");
CfgSharedNetworks6 cfg;
......@@ -126,9 +128,7 @@ TEST(CfgSharedNetworks6Test, unparse) {
" \"preferred-lifetime\": 0,\n"
" \"rapid-commit\": false,\n"
" \"rebind-timer\": 0,\n"
" \"relay\": {\n"
" \"ip-address\": \"::\"\n"
" },\n"
" \"relay\": { \"ip-addresses\": [ ] },\n"
" \"renew-timer\": 0,\n"
" \"reservation-mode\": \"all\","
" \"subnet6\": [ ],\n"
......@@ -141,9 +141,7 @@ TEST(CfgSharedNetworks6Test, unparse) {
" \"preferred-lifetime\": 0,\n"
" \"rapid-commit\": false,\n"
" \"rebind-timer\": 0,\n"
" \"relay\": {\n"
" \"ip-address\": \"::\"\n"
" },\n"
" \"relay\": { \"ip-addresses\": [ \"2001:db8:1::1\", \"2001:db8:1::2\" ] },\n"
" \"renew-timer\": 0,\n"
" \"reservation-mode\": \"all\","
" \"subnet6\": [ ],\n"
......
......@@ -414,7 +414,7 @@ TEST(CfgSubnets4Test, selectSubnetByOptionSelect) {
// Over relay-info too
selector.giaddr_ = IOAddress("10.0.0.1");
subnet2->setRelayInfo(IOAddress("10.0.0.1"));
subnet2->addRelayAddress(IOAddress("10.0.0.1"));
EXPECT_EQ(subnet3, cfg.selectSubnet(selector));
selector.option_select_ = IOAddress("0.0.0.0");
EXPECT_EQ(subnet2, cfg.selectSubnet(selector));
......@@ -450,9 +450,9 @@ TEST(CfgSubnets4Test, selectSubnetByRelayAddress) {
EXPECT_FALSE(cfg.selectSubnet(selector));
// Now specify relay info
subnet1->setRelayInfo(IOAddress("10.0.0.1"));
subnet2->setRelayInfo(IOAddress("10.0.0.2"));
subnet3->setRelayInfo(IOAddress("10.0.0.3"));
subnet1->addRelayAddress(IOAddress("10.0.0.1"));
subnet2->addRelayAddress(IOAddress("10.0.0.2"));
subnet3->addRelayAddress(IOAddress("10.0.0.3"));
// And try again. This time relay-info is there and should match.
selector.giaddr_ = IOAddress("10.0.0.1");
......@@ -485,9 +485,9 @@ TEST(CfgSubnets4Test, selectSharedNetworkByRelayAddressNetworkLevel) {
// Now specify relay info. Note that for the second subnet we specify
// relay info on the network level.
subnet1->setRelayInfo(IOAddress("10.0.0.1"));
network->setRelayInfo(IOAddress("10.0.0.2"));
subnet3->setRelayInfo(IOAddress("10.0.0.3"));
subnet1->addRelayAddress(IOAddress("10.0.0.1"));
network->addRelayAddress(IOAddress("10.0.0.2"));
subnet3->addRelayAddress(IOAddress("10.0.0.3"));
// And try again. This time relay-info is there and should match.
selector.giaddr_ = IOAddress("10.0.0.1");
......@@ -524,9 +524,9 @@ TEST(CfgSubnets4Test, selectSharedNetworkByRelayAddressSubnetLevel) {
// Now specify relay info. Note that for the second subnet we specify
// relay info on the network level.
subnet1->setRelayInfo(IOAddress("10.0.0.1"));
subnet2->setRelayInfo(IOAddress("10.0.0.2"));
subnet3->setRelayInfo(IOAddress("10.0.0.3"));
subnet1->addRelayAddress(IOAddress("10.0.0.1"));
subnet2->addRelayAddress(IOAddress("10.0.0.2"));
subnet3->addRelayAddress(IOAddress("10.0.0.3"));
// And try again. This time relay-info is there and should match.
selector.giaddr_ = IOAddress("10.0.0.1");
......@@ -737,7 +737,7 @@ TEST(CfgSubnets4Test, unparseSubnet) {
Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.2.128"), 26, 1, 2, 3, 125));
subnet1->allowClientClass("foo");
subnet2->setIface("lo");
subnet2->setRelayInfo(IOAddress("10.0.0.1"));
subnet2->addRelayAddress(IOAddress("10.0.0.1"));
subnet3->setIface("eth1");
subnet3->requireClientClass("foo");
subnet3->requireClientClass("bar");
......@@ -757,13 +757,13 @@ TEST(CfgSubnets4Test, unparseSubnet) {
" \"comment\": \"foo\",\n"
" \"id\": 123,\n"
" \"subnet\": \"192.0.2.0/26\",\n"
" \"relay\": { \"ip-address\": \"0.0.0.0\" },\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
" \"server-hostname\": \"\",\n"
" \"boot-file-name\": \"\",\n"
" \"renew-timer\": 1,\n"
" \"rebind-timer\": 2,\n"
" \"relay\": { \"ip-addresses\": [ ] },\n"
" \"valid-lifetime\": 3,\n"
" \"client-class\": \"foo\",\n"
" \"4o6-interface\": \"\",\n"
......@@ -775,7 +775,6 @@ TEST(CfgSubnets4Test, unparseSubnet) {
"},{\n"
" \"id\": 124,\n"
" \"subnet\": \"192.0.2.64/26\",\n"
" \"relay\": { \"ip-address\": \"10.0.0.1\" },\n"
" \"interface\": \"lo\",\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
......@@ -783,6 +782,7 @@ TEST(CfgSubnets4Test, unparseSubnet) {
" \"boot-file-name\": \"\",\n"
" \"renew-timer\": 1,\n"
" \"rebind-timer\": 2,\n"
" \"relay\": { \"ip-addresses\": [ \"10.0.0.1\" ] },\n"
" \"valid-lifetime\": 3,\n"
" \"4o6-interface\": \"\",\n"
" \"4o6-interface-id\": \"\",\n"
......@@ -794,7 +794,6 @@ TEST(CfgSubnets4Test, unparseSubnet) {
"},{\n"
" \"id\": 125,\n"
" \"subnet\": \"192.0.2.128/26\",\n"
" \"relay\": { \"ip-address\": \"0.0.0.0\" },\n"
" \"interface\": \"eth1\",\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
......@@ -802,6 +801,7 @@ TEST(CfgSubnets4Test, unparseSubnet) {
" \"boot-file-name\": \"\",\n"
" \"renew-timer\": 1,\n"
" \"rebind-timer\": 2,\n"
" \"relay\": { \"ip-addresses\": [ ] },\n"
" \"valid-lifetime\": 3,\n"
" \"4o6-interface\": \"\",\n"
" \"4o6-interface-id\": \"\",\n"
......@@ -840,13 +840,13 @@ TEST(CfgSubnets4Test, unparsePool) {
"{\n"
" \"id\": 123,\n"
" \"subnet\": \"192.0.2.0/24\",\n"
" \"relay\": { \"ip-address\": \"0.0.0.0\" },\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
" \"server-hostname\": \"\",\n"
" \"boot-file-name\": \"\",\n"
" \"renew-timer\": 1,\n"
" \"rebind-timer\": 2,\n"
" \"relay\": { \"ip-addresses\": [ ] },\n"
" \"valid-lifetime\": 3,\n"
" \"4o6-interface\": \"\",\n"
" \"4o6-interface-id\": \"\",\n"
......
......@@ -132,9 +132,9 @@ TEST(CfgSubnets6Test, selectSubnetByRelayAddress) {
EXPECT_FALSE(cfg.selectSubnet(selector));
// Now specify relay information.
subnet1->setRelayInfo(IOAddress("2001:db8:ff::1"));
subnet2->setRelayInfo(IOAddress("2001:db8:ff::2"));
subnet3->setRelayInfo(IOAddress("2001:db8:ff::3"));
subnet1->addRelayAddress(IOAddress("2001:db8:ff::1"));
subnet2->addRelayAddress(IOAddress("2001:db8:ff::2"));
subnet3->addRelayAddress(IOAddress("2001:db8:ff::3"));
// And try again. This time relay-info is there and should match.
selector.first_relay_linkaddr_ = IOAddress("2001:db8:ff::1");
......@@ -436,7 +436,7 @@ TEST(CfgSubnets6Test, unparseSubnet) {
subnet1->setInterfaceId(ifaceid);
subnet1->allowClientClass("foo");
subnet2->setIface("lo");
subnet2->setRelayInfo(IOAddress("2001:db8:ff::2"));
subnet2->addRelayAddress(IOAddress("2001:db8:ff::2"));
subnet3->setIface("eth1");
subnet3->requireClientClass("foo");
subnet3->requireClientClass("bar");
......@@ -456,10 +456,10 @@ TEST(CfgSubnets6Test, unparseSubnet) {
" \"comment\": \"foo\",\n"
" \"id\": 123,\n"
" \"subnet\": \"2001:db8:1::/48\",\n"
" \"relay\": { \"ip-address\": \"::\" },\n"
" \"interface-id\": \"relay.eth0\",\n"
" \"renew-timer\": 1,\n"
" \"rebind-timer\": 2,\n"
" \"relay\": { \"ip-addresses\": [ ] },\n"
" \"preferred-lifetime\": 3,\n"
" \"valid-lifetime\": 4,\n"
" \"rapid-commit\": false,\n"
......@@ -471,10 +471,10 @@ TEST(CfgSubnets6Test, unparseSubnet) {
"},{\n"
" \"id\": 124,\n"
" \"subnet\": \"2001:db8:2::/48\",\n"
" \"relay\": { \"ip-address\": \"2001:db8:ff::2\" },\n"
" \"interface\": \"lo\",\n"
" \"renew-timer\": 1,\n"
" \"rebind-timer\": 2,\n"
" \"relay\": { \"ip-addresses\": [ \"2001:db8:ff::2\" ] },\n"
" \"preferred-lifetime\": 3,\n"
" \"valid-lifetime\": 4,\n"
" \"rapid-commit\": false,\n"
......@@ -486,10 +486,10 @@ TEST(CfgSubnets6Test, unparseSubnet) {
"},{\n"
" \"id\": 125,\n"
" \"subnet\": \"2001:db8:3::/48\",\n"
" \"relay\": { \"ip-address\": \"::\" },\n"
" \"interface\": \"eth1\",\n"
" \"renew-timer\": 1,\n"
" \"rebind-timer\": 2,\n"
" \"relay\": { \"ip-addresses\": [ ] },\n"
" \"preferred-lifetime\": 3,\n"
" \"valid-lifetime\": 4,\n"
" \"rapid-commit\": false,\n"
......@@ -531,9 +531,9 @@ TEST(CfgSubnets6Test, unparsePool) {
"{\n"
" \"id\": 123,\n"
" \"subnet\": \"2001:db8:1::/48\",\n"
" \"relay\": { \"ip-address\": \"::\" },\n"
" \"renew-timer\": 1,\n"
" \"rebind-timer\": 2,\n"
" \"relay\": { \"ip-addresses\": [ ] },\n"
" \"preferred-lifetime\": 3,\n"
" \"valid-lifetime\": 4,\n"
" \"rapid-commit\": false,\n"
......@@ -586,9 +586,9 @@ TEST(CfgSubnets6Test, unparsePdPool) {
"{\n"
" \"id\": 123,\n"
" \"subnet\": \"2001:db8:1::/48\",\n"
" \"relay\": { \"ip-address\": \"::\" },\n"
" \"renew-timer\": 1,\n"
" \"rebind-timer\": 2,\n"
" \"relay\": { \"ip-addresses\": [ ] },\n"
" \"preferred-lifetime\": 3,\n"
" \"valid-lifetime\": 4,\n"
" \"rapid-commit\": false,\n"
......
......@@ -2220,14 +2220,13 @@ TEST_F(ParseConfigTest, validRelayInfo4) {
" }";
ElementPtr json = Element::fromJSON(config_str);
// We need to set the default ip-address to something.
Network::RelayInfoPtr result(new Network::RelayInfo(asiolink::IOAddress("0.0.0.0")));
// Create an "empty" RelayInfo to hold the parsed result.
Network::RelayInfoPtr result(new Network::RelayInfo());
RelayInfoParser parser(Option::V4);
// Subnet4 parser will pass 0.0.0.0 to the RelayInfoParser
EXPECT_NO_THROW(parser.parse(result, json));
EXPECT_EQ("192.0.2.1", result->addr_.toText());
EXPECT_TRUE(result->containsAddress(IOAddress("192.0.2.1")));
}
/// @brief Checks that a bogus relay info structure for IPv4 is rejected.
......@@ -2253,8 +2252,8 @@ TEST_F(ParseConfigTest, bogusRelayInfo4) {
" }";
ElementPtr json_bogus3 = Element::fromJSON(config_str_bogus3);
// We need to set the default ip-address to something.
Network::RelayInfoPtr result(new Network::RelayInfo(IOAddress::IPV4_ZERO_ADDRESS()));
// Create an "empty" RelayInfo to hold the parsed result.
Network::RelayInfoPtr result(new Network::RelayInfo());
RelayInfoParser parser(Option::V4);
......@@ -2278,13 +2277,13 @@ TEST_F(ParseConfigTest, validRelayInfo6) {
" }";
ElementPtr json = Element::fromJSON(config_str);
// We need to set the default ip-address to something.
Network::RelayInfoPtr result(new Network::RelayInfo(asiolink::IOAddress("::")));
// Create an "empty" RelayInfo to hold the parsed result.
Network::RelayInfoPtr result(new Network::RelayInfo());
RelayInfoParser parser(Option::V6);
// Subnet4 parser will pass :: to the RelayInfoParser
EXPECT_NO_THROW(parser.parse(result, json));
EXPECT_EQ("2001:db8::1", result->addr_.toText());
EXPECT_TRUE(result->containsAddress(IOAddress("2001:db8::1")));
}
/// @brief Checks that a valid relay info structure for IPv6 can be handled
......@@ -2310,8 +2309,8 @@ TEST_F(ParseConfigTest, bogusRelayInfo6) {
" }";
ElementPtr json_bogus3 = Element::fromJSON(config_str_bogus3);
// We need to set the default ip-address to something.
Network::RelayInfoPtr result(new Network::RelayInfo(asiolink::IOAddress("::")));
// Create an "empty" RelayInfo to hold the parsed result.
Network::RelayInfoPtr result(new Network::RelayInfo());
RelayInfoParser parser(Option::V6);
......
......@@ -265,6 +265,26 @@ TEST(SharedNetwork4Test, getPreferredSubnet) {
EXPECT_EQ(subnet3->getID(), preferred->getID());
}
// This test verifies operations on the network's relay list
TEST(SharedNetwork4Test, relayInfoList) {
SharedNetwork4Ptr network(new SharedNetwork4("frog"));
EXPECT_FALSE(network->hasRelays());
EXPECT_FALSE(network->hasRelayAddress(IOAddress("192.168.2.1")));
// Add relay addresses to the network.
network->addRelayAddress(IOAddress("192.168.2.1"));
network->addRelayAddress(IOAddress("192.168.2.2"));
network->addRelayAddress(IOAddress("192.168.2.3"));
// Verify we believe we have relays and we can match them accordingly.
EXPECT_TRUE(network->hasRelays());
EXPECT_TRUE(network->hasRelayAddress(IOAddress("192.168.2.1")));
EXPECT_TRUE(network->hasRelayAddress(IOAddress("192.168.2.2")));
EXPECT_TRUE(network->hasRelayAddress(IOAddress("192.168.2.3")));
EXPECT_FALSE(network->hasRelayAddress(IOAddress("192.168.2.4")));
}
// This test verifies that unparsing shared network returns valid structure.
TEST(SharedNetwork4Test, unparse) {
SharedNetwork4Ptr network(new SharedNetwork4("frog"));
......@@ -281,10 +301,14 @@ TEST(SharedNetwork4Test, unparse) {
data::ElementPtr ctx = data::Element::fromJSON(uc);
network->setContext(ctx);
network->requireClientClass("foo");
network->addRelayAddress(IOAddress("192.168.2.1"));
// Add several subnets.
Subnet4Ptr subnet1(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
SubnetID(1)));