Browse Source

[5032] Duplicate mac-sources are no longer accepted.

Tomek Mrugalski 8 years ago
parent
commit
bc73056982

+ 11 - 1
src/lib/dhcpsrv/cfg_mac_source.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2015,2017 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -47,6 +47,16 @@ uint32_t CfgMACSource::MACSourceFromText(const std::string& name) {
     isc_throw(BadValue, "Can't convert '" << name << "' to any known MAC source.");
 }
 
+void CfgMACSource::add(uint32_t source) {
+    for (CfgMACSources::const_iterator it = mac_sources_.begin();
+         it != mac_sources_.end(); ++it) {
+        if (*it == source) {
+            isc_throw(InvalidParameter, "mac-source paramter " << source
+                      << "' specified twice.");
+        }
+    }
+    mac_sources_.push_back(source);
+}
 
 };
 };

+ 3 - 5
src/lib/dhcpsrv/cfg_mac_source.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2015,2017 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -52,10 +52,8 @@ class CfgMACSource {
     /// @param source MAC source (see constants in Pkt::HWADDR_SOURCE_*)
     ///
     /// Specified source is being added to the mac_sources_ array.
-    /// @todo implement add(string) version of this method.
-    void add(uint32_t source) {
-        mac_sources_.push_back(source);
-    }
+    /// @throw InvalidParameter if such a source is already defined.
+    void add(uint32_t source);
 
     /// @brief Provides access to the configure MAC/Hardware address sources.
     ///

+ 3 - 0
src/lib/dhcpsrv/parsers/dhcp_parsers.cc

@@ -193,6 +193,9 @@ MACSourcesListConfigParser::parse(CfgMACSource& mac_sources, ConstElementPtr val
             source = CfgMACSource::MACSourceFromText(source_str);
             mac_sources.add(source);
             ++cnt;
+        } catch (const InvalidParameter& ex) {
+            isc_throw(DhcpConfigError, "The mac-sources value '" << source_str
+                      << "' was specified twice (" << value->getPosition() << ")");
         } catch (const std::exception& ex) {
             isc_throw(DhcpConfigError, "Failed to convert '"
                       << source_str << "' to any recognized MAC source:"

+ 23 - 0
src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc

@@ -292,6 +292,29 @@ TEST_F(DhcpParserTest, MacSourcesBogus) {
     EXPECT_THROW(parser.parse(sources, values), DhcpConfigError);
 }
 
+/// Verifies the code that properly catches duplicate entries
+/// in mac-sources definition.
+TEST_F(DhcpParserTest, MacSourcesDuplicate) {
+
+    // That's an equivalent of the following snippet:
+    // "mac-sources: [ \"duid\", \"ipv6\" ]";
+    ElementPtr values = Element::createList();
+    values->add(Element::create("ipv6-link-local"));
+    values->add(Element::create("duid"));
+    values->add(Element::create("duid"));
+    values->add(Element::create("duid"));
+
+    // Let's grab server configuration from CfgMgr
+    SrvConfigPtr cfg = CfgMgr::instance().getStagingCfg();
+    ASSERT_TRUE(cfg);
+    CfgMACSource& sources = cfg->getMACSources();
+
+    // This should parse the configuration and check that it throws.
+    MACSourcesListConfigParser parser;
+    EXPECT_THROW(parser.parse(sources, values), DhcpConfigError);
+}
+
+
 /// @brief Test Fixture class which provides basic structure for testing
 /// configuration parsing.  This is essentially the same structure provided
 /// by dhcp servers.