Browse Source

[master] Merge branch 'trac2549'

Marcin Siodelski 12 years ago
parent
commit
d2cc8db8c1

+ 15 - 16
src/lib/dhcp/iface_mgr.cc

@@ -212,8 +212,8 @@ bool IfaceMgr::openSockets4(const uint16_t port) {
              addr != addrs.end();
              ++addr) {
 
-            // Skip IPv6 addresses
-            if (addr->getFamily() != AF_INET) {
+            // Skip all but V4 addresses.
+            if (!addr->isV4()) {
                 continue;
             }
 
@@ -247,8 +247,8 @@ bool IfaceMgr::openSockets6(const uint16_t port) {
              addr != addrs.end();
              ++addr) {
 
-            // skip IPv4 addresses
-            if (addr->getFamily() != AF_INET6) {
+            // Skip all but V6 addresses.
+            if (!addr->isV6()) {
                 continue;
             }
 
@@ -356,12 +356,13 @@ int IfaceMgr::openSocket(const std::string& ifname, const IOAddress& addr,
     if (!iface) {
         isc_throw(BadValue, "There is no " << ifname << " interface present.");
     }
-    switch (addr.getFamily()) {
-    case AF_INET:
+    if (addr.isV4()) {
         return openSocket4(*iface, addr, port);
-    case AF_INET6:
+
+    } else if (addr.isV6()) {
         return openSocket6(*iface, addr, port);
-    default:
+
+    } else {
         isc_throw(BadValue, "Failed to detect family of address: "
                   << addr.toText());
     }
@@ -469,7 +470,7 @@ IfaceMgr::getLocalAddress(const IOAddress& remote_addr, const uint16_t port) {
     asio::error_code err_code;
     // If remote address is broadcast address we have to
     // allow this on the socket.
-    if (remote_addr.getAddress().is_v4() &&
+    if (remote_addr.isV4() &&
         (remote_addr == IOAddress(DHCP_IPV4_BROADCAST_ADDRESS))) {
         // Socket has to be open prior to setting the broadcast
         // option. Otherwise set_option will complain about
@@ -556,9 +557,7 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
         addr6.sin6_scope_id = if_nametoindex(iface.getName().c_str());
     }
 
-    memcpy(&addr6.sin6_addr,
-           addr.getAddress().to_v6().to_bytes().data(),
-           sizeof(addr6.sin6_addr));
+    memcpy(&addr6.sin6_addr, &addr.toBytes()[0], sizeof(addr6.sin6_addr));
 #ifdef HAVE_SA_LEN
     addr6.sin6_len = sizeof(addr6);
 #endif
@@ -660,7 +659,7 @@ IfaceMgr::send(const Pkt6Ptr& pkt) {
     to.sin6_family = AF_INET6;
     to.sin6_port = htons(pkt->getRemotePort());
     memcpy(&to.sin6_addr,
-           pkt->getRemoteAddr().getAddress().to_v6().to_bytes().data(),
+           &pkt->getRemoteAddr().toBytes()[0],
            16);
     to.sin6_scope_id = pkt->getIndex();
 
@@ -798,7 +797,7 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
              s != socket_collection.end(); ++s) {
 
             // Only deal with IPv4 addresses.
-            if (s->addr_.getFamily() == AF_INET) {
+            if (s->addr_.isV4()) {
                 names << s->sockfd_ << "(" << iface->getName() << ") ";
 
                 // Add this socket to listening set
@@ -950,8 +949,8 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
         for (SocketCollection::const_iterator s = socket_collection.begin();
              s != socket_collection.end(); ++s) {
 
-            // Only deal with IPv4 addresses.
-            if (s->addr_.getFamily() == AF_INET6) {
+            // Only deal with IPv6 addresses.
+            if (s->addr_.isV6()) {
                 names << s->sockfd_ << "(" << iface->getName() << ") ";
 
                 // Add this socket to listening set

+ 2 - 2
src/lib/dhcp/option4_addrlst.cc

@@ -86,7 +86,7 @@ Option4AddrLst::pack4(isc::util::OutputBuffer& buf) {
 }
 
 void Option4AddrLst::setAddress(const isc::asiolink::IOAddress& addr) {
-    if (addr.getFamily() != AF_INET) {
+    if (!addr.isV4()) {
         isc_throw(BadValue, "Can't store non-IPv4 address in "
                   << "Option4AddrLst option");
     }
@@ -107,7 +107,7 @@ void Option4AddrLst::setAddresses(const AddressContainer& addrs) {
 
 
 void Option4AddrLst::addAddress(const isc::asiolink::IOAddress& addr) {
-    if (addr.getFamily() != AF_INET) {
+    if (!addr.isV4()) {
         isc_throw(BadValue, "Can't store non-IPv4 address in "
                   << "Option4AddrLst option");
     }

+ 9 - 4
src/lib/dhcp/option6_addrlst.cc

@@ -49,7 +49,7 @@ Option6AddrLst::Option6AddrLst(uint16_t type, OptionBufferConstIter begin,
 
 void
 Option6AddrLst::setAddress(const isc::asiolink::IOAddress& addr) {
-    if (addr.getFamily() != AF_INET6) {
+    if (!addr.isV6()) {
         isc_throw(BadValue, "Can't store non-IPv6 address in Option6AddrLst option");
     }
 
@@ -72,7 +72,13 @@ void Option6AddrLst::pack(isc::util::OutputBuffer& buf) {
 
     for (AddressContainer::const_iterator addr=addrs_.begin();
          addr!=addrs_.end(); ++addr) {
-        buf.writeData(addr->getAddress().to_v6().to_bytes().data(), V6ADDRESS_LEN);
+        if (!addr->isV6()) {
+            isc_throw(isc::BadValue, addr->toText()
+                      << " is not an IPv6 address");
+        }
+        // If an address is IPv6 address it should have assumed
+        // length of V6ADDRESS_LEN.
+        buf.writeData(&addr->toBytes()[0], V6ADDRESS_LEN);
     }
 }
 
@@ -104,8 +110,7 @@ std::string Option6AddrLst::toText(int indent /* =0 */) {
 }
 
 uint16_t Option6AddrLst::len() {
-
-    return (OPTION6_HDR_LEN + addrs_.size()*V6ADDRESS_LEN);
+    return (OPTION6_HDR_LEN + addrs_.size() * V6ADDRESS_LEN);
 }
 
 } // end of namespace isc::dhcp

+ 5 - 3
src/lib/dhcp/option6_iaaddr.cc

@@ -51,9 +51,11 @@ void Option6IAAddr::pack(isc::util::OutputBuffer& buf) {
     // length without 4-byte option header
     buf.writeUint16(len() - getHeaderLen());
 
-
-    buf.writeData(addr_.getAddress().to_v6().to_bytes().data(),
-                  isc::asiolink::V6ADDRESS_LEN);
+    if (!addr_.isV6()) {
+        isc_throw(isc::BadValue, addr_.toText()
+                  << " is not an IPv6 address");
+    }
+    buf.writeData(&addr_.toBytes()[0], isc::asiolink::V6ADDRESS_LEN);
 
     buf.writeUint32(preferred_);
     buf.writeUint32(valid_);

+ 6 - 10
src/lib/dhcp/option_custom.cc

@@ -58,14 +58,12 @@ void
 OptionCustom::addArrayDataField(const asiolink::IOAddress& address) {
     checkArrayType();
 
-    if ((address.getFamily() == AF_INET &&
-         definition_.getType() != OPT_IPV4_ADDRESS_TYPE) ||
-        (address.getFamily() == AF_INET6 &&
-         definition_.getType() != OPT_IPV6_ADDRESS_TYPE)) {
+    if ((address.isV4() && definition_.getType() != OPT_IPV4_ADDRESS_TYPE) ||
+        (address.isV6() && definition_.getType() != OPT_IPV6_ADDRESS_TYPE)) {
         isc_throw(BadDataTypeCast, "invalid address specified "
                   << address.toText() << ". Expected a valid IPv"
-                  << (definition_.getType() == OPT_IPV4_ADDRESS_TYPE ? "4" : "6")
-                  << " address.");
+                  << (definition_.getType() == OPT_IPV4_ADDRESS_TYPE ?
+                      "4" : "6") << " address.");
     }
 
     OptionBuffer buf;
@@ -454,10 +452,8 @@ OptionCustom::writeAddress(const asiolink::IOAddress& address,
 
     checkIndex(index);
 
-    if ((address.getFamily() == AF_INET &&
-         buffers_[index].size() != V4ADDRESS_LEN) ||
-        (address.getFamily() == AF_INET6 &&
-         buffers_[index].size() != V6ADDRESS_LEN)) {
+    if ((address.isV4() && buffers_[index].size() != V4ADDRESS_LEN) ||
+        (address.isV6() && buffers_[index].size() != V6ADDRESS_LEN)) {
         isc_throw(BadDataTypeCast, "invalid address specified "
                   << address.toText() << ". Expected a valid IPv"
                   << (buffers_[index].size() == V4ADDRESS_LEN ? "4" : "6")

+ 2 - 21
src/lib/dhcp/option_data_types.cc

@@ -146,27 +146,8 @@ OptionDataTypeUtil::readAddress(const std::vector<uint8_t>& buf,
 void
 OptionDataTypeUtil::writeAddress(const asiolink::IOAddress& address,
                                  std::vector<uint8_t>& buf) {
-    // @todo There is a ticket 2396 submitted, which adds the
-    // functionality to return a buffer representation of
-    // IOAddress. If so, this function can be simplified.
-    if (address.getAddress().is_v4()) {
-        asio::ip::address_v4::bytes_type addr_bytes =
-            address.getAddress().to_v4().to_bytes();
-        // Increase the buffer size by the size of IPv4 address.
-        buf.resize(buf.size() + addr_bytes.size());
-        std::copy_backward(addr_bytes.begin(), addr_bytes.end(),
-                           buf.end());
-    } else if (address.getAddress().is_v6()) {
-        asio::ip::address_v6::bytes_type addr_bytes =
-            address.getAddress().to_v6().to_bytes();
-        // Incresase the buffer size by the size of IPv6 address.
-        buf.resize(buf.size() + addr_bytes.size());
-        std::copy_backward(addr_bytes.begin(), addr_bytes.end(),
-                           buf.end());
-    } else {
-        isc_throw(BadDataTypeCast, "the address " << address.toText()
-                  << " is neither valid IPv4 not IPv6 address.");
-    }
+    const std::vector<uint8_t>& vec = address.toBytes();
+    buf.insert(buf.end(), vec.begin(), vec.end());
 }
 
 void

+ 2 - 5
src/lib/dhcp/option_definition.cc

@@ -379,12 +379,9 @@ OptionDefinition::writeToBuffer(const std::string& value,
     case OPT_IPV6_ADDRESS_TYPE:
         {
             asiolink::IOAddress address(value);
-            if (address.getFamily() != AF_INET &&
-                address.getFamily() != AF_INET6) {
+            if (!address.isV4() && !address.isV6()) {
                 isc_throw(BadDataTypeCast, "provided address " << address.toText()
-                          << " is not a valid "
-                          << (address.getAddress().is_v4() ? "IPv4" : "IPv6")
-                          << " address");
+                          << " is not a valid IPv4 or IPv6 address.");
             }
             OptionDataTypeUtil::writeAddress(address, buf);
             return;

+ 2 - 10
src/lib/dhcp/tests/option_custom_unittest.cc

@@ -38,16 +38,8 @@ public:
     /// @param [out] buf output buffer.
     void writeAddress(const asiolink::IOAddress& address,
                       std::vector<uint8_t>& buf) {
-        short family = address.getFamily();
-        if (family == AF_INET) {
-            asio::ip::address_v4::bytes_type buf_addr =
-                address.getAddress().to_v4().to_bytes();
-            buf.insert(buf.end(), buf_addr.begin(), buf_addr.end());
-        } else if (family == AF_INET6) {
-            asio::ip::address_v6::bytes_type buf_addr =
-                address.getAddress().to_v6().to_bytes();
-            buf.insert(buf.end(), buf_addr.begin(), buf_addr.end());
-        }
+        const std::vector<uint8_t>& vec = address.toBytes();
+        buf.insert(buf.end(), vec.begin(), vec.end());
     }
 
     /// @brief Write integer (signed or unsigned) into a buffer.

+ 2 - 10
src/lib/dhcp/tests/option_data_types_unittest.cc

@@ -34,16 +34,8 @@ public:
     /// @param [out] buf output buffer.
     void writeAddress(const asiolink::IOAddress& address,
                       std::vector<uint8_t>& buf) {
-        short family = address.getFamily();
-        if (family == AF_INET) {
-            asio::ip::address_v4::bytes_type buf_addr =
-                address.getAddress().to_v4().to_bytes();
-            buf.insert(buf.end(), buf_addr.begin(), buf_addr.end());
-        } else if (family == AF_INET6) {
-            asio::ip::address_v6::bytes_type buf_addr =
-                address.getAddress().to_v6().to_bytes();
-            buf.insert(buf.end(), buf_addr.begin(), buf_addr.end());
-        }
+        const std::vector<uint8_t>& vec = address.toBytes();
+        buf.insert(buf.end(), vec.begin(), vec.end());
     }
 
     /// @brief Write integer (signed or unsigned) into a buffer.

+ 10 - 13
src/lib/dhcp/tests/option_definition_unittest.cc

@@ -207,10 +207,9 @@ TEST_F(OptionDefinitionTest, ipv6AddressArray) {
     // Write addresses to the buffer.
     OptionBuffer buf(addrs.size() * asiolink::V6ADDRESS_LEN);
     for (int i = 0; i < addrs.size(); ++i) {
-        asio::ip::address_v6::bytes_type addr_bytes =
-            addrs[i].getAddress().to_v6().to_bytes();
-        ASSERT_EQ(asiolink::V6ADDRESS_LEN, addr_bytes.size());
-        std::copy(addr_bytes.begin(), addr_bytes.end(),
+        const std::vector<uint8_t>& vec = addrs[i].toBytes();
+        ASSERT_EQ(asiolink::V6ADDRESS_LEN, vec.size());
+        std::copy(vec.begin(), vec.end(),
                   buf.begin() + i * asiolink::V6ADDRESS_LEN);
     }
     // Create DHCPv6 option from this buffer. Once option is created it is
@@ -306,10 +305,9 @@ TEST_F(OptionDefinitionTest, ipv4AddressArray) {
     // Write addresses to the buffer.
     OptionBuffer buf(addrs.size() * asiolink::V4ADDRESS_LEN);
     for (int i = 0; i < addrs.size(); ++i) {
-        asio::ip::address_v4::bytes_type addr_bytes =
-            addrs[i].getAddress().to_v4().to_bytes();
-        ASSERT_EQ(asiolink::V4ADDRESS_LEN, addr_bytes.size());
-        std::copy(addr_bytes.begin(), addr_bytes.end(),
+        const std::vector<uint8_t> vec = addrs[i].toBytes();
+        ASSERT_EQ(asiolink::V4ADDRESS_LEN, vec.size());
+        std::copy(vec.begin(), vec.end(),
                   buf.begin() + i * asiolink::V4ADDRESS_LEN);
     }
     // Create DHCPv6 option from this buffer. Once option is created it is
@@ -512,11 +510,10 @@ TEST_F(OptionDefinitionTest, recordIAAddr6) {
     OptionPtr option_v6;
     asiolink::IOAddress addr_v6("2001:0db8::ff00:0042:8329");
     OptionBuffer buf(asiolink::V6ADDRESS_LEN);
-    ASSERT_TRUE(addr_v6.getAddress().is_v6());
-    asio::ip::address_v6::bytes_type addr_bytes =
-        addr_v6.getAddress().to_v6().to_bytes();
-    ASSERT_EQ(asiolink::V6ADDRESS_LEN, addr_bytes.size());
-    std::copy(addr_bytes.begin(), addr_bytes.end(), buf.begin());
+    ASSERT_TRUE(addr_v6.isV6());
+    const std::vector<uint8_t>& vec = addr_v6.toBytes();
+    ASSERT_EQ(asiolink::V6ADDRESS_LEN, vec.size());
+    std::copy(vec.begin(), vec.end(), buf.begin());
 
     for (int i = 0; i < option6_iaaddr_len - asiolink::V6ADDRESS_LEN; ++i) {
         buf.push_back(i);

+ 19 - 9
src/lib/dhcpsrv/addr_utilities.cc

@@ -53,8 +53,11 @@ isc::asiolink::IOAddress firstAddrInPrefix6(const isc::asiolink::IOAddress& pref
     }
 
     // First we copy the whole address as 16 bytes.
+    // We don't check that it is a valid IPv6 address and thus has
+    // the required length because it is already checked by
+    // the calling function.
     uint8_t packed[V6ADDRESS_LEN];
-    memcpy(packed, prefix.getAddress().to_v6().to_bytes().data(), 16);
+    memcpy(packed, &prefix.toBytes()[0], V6ADDRESS_LEN);
 
     // If the length is divisible by 8, it is simple. We just zero out the host
     // part. Otherwise we need to handle the byte that has to be partially
@@ -95,6 +98,9 @@ isc::asiolink::IOAddress firstAddrInPrefix4(const isc::asiolink::IOAddress& pref
         isc_throw(isc::BadValue, "Too large netmask. 0..32 is allowed in IPv4");
     }
 
+    // We don't check that it is a valid IPv4 address and thus has
+    // a required length of 4 bytes because it has been already
+    // checked by the calling function.
     uint32_t addr = prefix;
     return (IOAddress(addr & (~bitMask4[len])));
 }
@@ -132,7 +138,7 @@ isc::asiolink::IOAddress lastAddrInPrefix6(const isc::asiolink::IOAddress& prefi
 
     // First we copy the whole address as 16 bytes.
     uint8_t packed[V6ADDRESS_LEN];
-    memcpy(packed, prefix.getAddress().to_v6().to_bytes().data(), 16);
+    memcpy(packed, &prefix.toBytes()[0], 16);
 
     // if the length is divisible by 8, it is simple. We just fill the host part
     // with ones. Otherwise we need to handle the byte that has to be partially
@@ -168,20 +174,24 @@ namespace isc {
 namespace dhcp {
 
 isc::asiolink::IOAddress firstAddrInPrefix(const isc::asiolink::IOAddress& prefix,
-                                            uint8_t len) {
-    if (prefix.getFamily() == AF_INET) {
-        return firstAddrInPrefix4(prefix, len);
+                                           uint8_t len) {
+    if (prefix.isV4()) {
+        return (firstAddrInPrefix4(prefix, len));
+
     } else {
-        return firstAddrInPrefix6(prefix, len);
+        return (firstAddrInPrefix6(prefix, len));
+
     }
 }
 
 isc::asiolink::IOAddress lastAddrInPrefix(const isc::asiolink::IOAddress& prefix,
                                            uint8_t len) {
-    if (prefix.getFamily() == AF_INET) {
-        return lastAddrInPrefix4(prefix, len);
+    if (prefix.isV4()) {
+        return (lastAddrInPrefix4(prefix, len));
+
     } else {
-        return lastAddrInPrefix6(prefix, len);
+        return (lastAddrInPrefix6(prefix, len));
+
     }
 }
 

+ 12 - 11
src/lib/dhcpsrv/alloc_engine.cc

@@ -30,20 +30,21 @@ AllocEngine::IterativeAllocator::IterativeAllocator()
 
 isc::asiolink::IOAddress
 AllocEngine::IterativeAllocator::increaseAddress(const isc::asiolink::IOAddress& addr) {
+    // Get a buffer holding an address.
+    const std::vector<uint8_t>& vec = addr.toBytes();
+    // Get the address length.
+    const int len = vec.size();
+
+    // Since the same array will be used to hold the IPv4 and IPv6
+    // address we have to make sure that the size of the array
+    // we allocate will work for both types of address.
+    BOOST_STATIC_ASSERT(V4ADDRESS_LEN <= V6ADDRESS_LEN);
     uint8_t packed[V6ADDRESS_LEN];
-    int len;
 
-    // First we copy the whole address as 16 bytes.
-    if (addr.getFamily()==AF_INET) {
-        // IPv4
-        std::memcpy(packed, addr.getAddress().to_v4().to_bytes().data(), 4);
-        len = 4;
-    } else {
-        // IPv6
-        std::memcpy(packed, addr.getAddress().to_v6().to_bytes().data(), 16);
-        len = 16;
-    }
+    // Copy the address. It can be either V4 or V6.
+    std::memcpy(packed, &vec[0], len);
 
+    // Increase the address.
     for (int i = len - 1; i >= 0; --i) {
         ++packed[i];
         if (packed[i] != 0) {

+ 4 - 4
src/lib/dhcpsrv/pool.cc

@@ -34,7 +34,7 @@ Pool4::Pool4(const isc::asiolink::IOAddress& first,
              const isc::asiolink::IOAddress& last)
     :Pool(first, last) {
     // check if specified address boundaries are sane
-    if (first.getFamily() != AF_INET || last.getFamily() != AF_INET) {
+    if (!first.isV4() || !last.isV4()) {
         isc_throw(BadValue, "Invalid Pool4 address boundaries: not IPv4");
     }
 
@@ -48,7 +48,7 @@ Pool4::Pool4(const isc::asiolink::IOAddress& prefix,
     :Pool(prefix, IOAddress("0.0.0.0")) {
 
     // check if the prefix is sane
-    if (prefix.getFamily() != AF_INET) {
+    if (!prefix.isV4()) {
         isc_throw(BadValue, "Invalid Pool4 address boundaries: not IPv4");
     }
 
@@ -67,7 +67,7 @@ Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& first,
     :Pool(first, last), type_(type), prefix_len_(0) {
 
     // check if specified address boundaries are sane
-    if (first.getFamily() != AF_INET6 || last.getFamily() != AF_INET6) {
+    if (!first.isV6() || !last.isV6()) {
         isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6");
     }
 
@@ -98,7 +98,7 @@ Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& prefix,
      type_(type), prefix_len_(prefix_len) {
 
     // check if the prefix is sane
-    if (prefix.getFamily() != AF_INET6) {
+    if (!prefix.isV6()) {
         isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6");
     }
 

+ 4 - 4
src/lib/dhcpsrv/subnet.cc

@@ -30,8 +30,8 @@ Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
     :id_(getNextID()), prefix_(prefix), prefix_len_(len), t1_(t1),
      t2_(t2), valid_(valid_lifetime),
      last_allocated_(lastAddrInPrefix(prefix, len)) {
-    if ( (prefix.getFamily() == AF_INET6 && len > 128) ||
-         (prefix.getFamily() == AF_INET && len > 32) ) {
+    if ((prefix.isV6() && len > 128) ||
+        (prefix.isV4() && len > 32)) {
         isc_throw(BadValue, "Invalid prefix length specified for subnet: " << len);
     }
 }
@@ -65,7 +65,7 @@ Subnet4::Subnet4(const isc::asiolink::IOAddress& prefix, uint8_t length,
                  const Triplet<uint32_t>& t2,
                  const Triplet<uint32_t>& valid_lifetime)
     :Subnet(prefix, length, t1, t2, valid_lifetime) {
-    if (prefix.getFamily() != AF_INET) {
+    if (!prefix.isV4()) {
         isc_throw(BadValue, "Non IPv4 prefix " << prefix.toText()
                   << " specified in subnet4");
     }
@@ -136,7 +136,7 @@ Subnet6::Subnet6(const isc::asiolink::IOAddress& prefix, uint8_t length,
                  const Triplet<uint32_t>& valid_lifetime)
     :Subnet(prefix, length, t1, t2, valid_lifetime),
      preferred_(preferred_lifetime){
-    if (prefix.getFamily() != AF_INET6) {
+    if (!prefix.isV6()) {
         isc_throw(BadValue, "Non IPv6 prefix " << prefix.toText()
                   << " specified in subnet6");
     }