Browse Source

[4300] Host class holds identifier rather than HW address or DUID.

Marcin Siodelski 9 years ago
parent
commit
e4a879e3e2
3 changed files with 69 additions and 82 deletions
  1. 35 46
      src/lib/dhcpsrv/host.cc
  2. 24 32
      src/lib/dhcpsrv/host.h
  3. 10 4
      src/lib/dhcpsrv/mysql_host_data_source.cc

+ 35 - 46
src/lib/dhcpsrv/host.cc

@@ -75,7 +75,8 @@ Host::Host(const uint8_t* identifier, const size_t identifier_len,
            const std::string& hostname,
            const std::string& dhcp4_client_classes,
            const std::string& dhcp6_client_classes)
-    : hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id),
+    : identifier_type_(identifier_type),
+      identifier_value_(), ipv4_subnet_id_(ipv4_subnet_id),
       ipv6_subnet_id_(ipv6_subnet_id),
       ipv4_reservation_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
       hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
@@ -97,14 +98,15 @@ Host::Host(const std::string& identifier, const std::string& identifier_name,
            const std::string& hostname,
            const std::string& dhcp4_client_classes,
            const std::string& dhcp6_client_classes)
-    : hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id),
+    : identifier_type_(IDENT_HWADDR),
+      identifier_value_(), ipv4_subnet_id_(ipv4_subnet_id),
       ipv6_subnet_id_(ipv6_subnet_id),
       ipv4_reservation_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
       hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
       dhcp6_client_classes_(dhcp6_client_classes), host_id_(0),
       cfg_option4_(new CfgOption()), cfg_option6_(new CfgOption()) {
 
-    // Initialize HWAddr or DUID
+    // Initialize host identifier.
     setIdentifier(identifier, identifier_name);
 
     if (!ipv4_reservation.isV4Zero()) {
@@ -115,40 +117,31 @@ Host::Host(const std::string& identifier, const std::string& identifier_name,
 
 const std::vector<uint8_t>&
 Host::getIdentifier() const {
-    if (hw_address_) {
-        return (hw_address_->hwaddr_);
-
-    } else if (duid_) {
-        return (duid_->getDuid());
-
-    }
-    static std::vector<uint8_t> empty_vector;
-    return (empty_vector);
+    return (identifier_value_);
 }
 
 Host::IdentifierType
 Host::getIdentifierType() const {
-    if (hw_address_) {
-        return (IDENT_HWADDR);
-    }
-    return (IDENT_DUID);
+    return (identifier_type_);
 }
 
-std::string
-Host::getIdentifierAsText() const {
-    std::string txt;
-    if (hw_address_) {
-        txt = getIdentifierAsText(IDENT_HWADDR, &hw_address_->hwaddr_[0],
-                                  hw_address_->hwaddr_.size());
-    } else if (duid_) {
-        txt = getIdentifierAsText(IDENT_DUID, &duid_->getDuid()[0],
-                                  duid_->getDuid().size());
-    } else {
-        txt = "(none)";
-    }
+HWAddrPtr
+Host::getHWAddress() const {
+    return ((identifier_type_ == IDENT_HWADDR) ?
+            HWAddrPtr(new HWAddr(identifier_value_, HTYPE_ETHER)) : HWAddrPtr());
+}
+
+DuidPtr
+Host::getDuid() const {
+    return ((identifier_type_ == IDENT_DUID) ?
+            DuidPtr(new DUID(identifier_value_)) : DuidPtr());
+}
 
-    return (txt);
 
+std::string
+Host::getIdentifierAsText() const {
+    return (getIdentifierAsText(identifier_type_, &identifier_value_[0],
+                                identifier_value_.size()));
 }
 
 std::string
@@ -182,30 +175,26 @@ Host::getIdentifierAsText(const IdentifierType& type, const uint8_t* value,
 void
 Host::setIdentifier(const uint8_t* identifier, const size_t len,
                     const IdentifierType& type) {
-    switch (type) {
-    case IDENT_HWADDR:
-        hw_address_ = HWAddrPtr(new HWAddr(identifier, len, HTYPE_ETHER));
-        duid_.reset();
-        break;
-    case IDENT_DUID:
-        duid_ = DuidPtr(new DUID(identifier, len));
-        hw_address_.reset();
-        break;
-    default:
-        isc_throw(isc::BadValue, "invalid client identifier type '"
-                  << static_cast<int>(type) << "' when creating host "
-                  " instance");
+    if (len < 1) {
+        isc_throw(BadValue, "invalid client identifier length 0");
     }
+
+    identifier_type_ = type;
+    identifier_value_.assign(identifier, identifier + len);
 }
 
 void
 Host::setIdentifier(const std::string& identifier, const std::string& name) {
     if (name == "hw-address") {
-        hw_address_ = HWAddrPtr(new HWAddr(HWAddr::fromText(identifier)));
-        duid_.reset();
+        HWAddr hwaddr(HWAddr::fromText(identifier));
+        identifier_type_= IDENT_HWADDR;
+        identifier_value_ = hwaddr.hwaddr_;
+
     } else if (name == "duid") {
-        duid_ = DuidPtr(new DUID(DUID::fromText(identifier)));
-        hw_address_.reset();
+        identifier_type_ = IDENT_DUID;
+        DUID duid(DUID::fromText(identifier));
+        identifier_value_ = duid.getDuid();
+
     } else {
         isc_throw(isc::BadValue, "invalid client identifier type '"
                   << name << "' when creating host instance");

+ 24 - 32
src/lib/dhcpsrv/host.h

@@ -179,7 +179,8 @@ public:
     /// DHCPv6 client's DUID are supported.
     enum IdentifierType {
         IDENT_HWADDR,
-        IDENT_DUID
+        IDENT_DUID,
+        IDENT_CIRCUIT_ID
     };
 
     /// @brief Constructor.
@@ -222,11 +223,11 @@ public:
     /// is useful in cases when the reservation is specified in the server
     /// configuration file, where:
     /// - MAC address is specified as: "01:02:03:04:05:06"
-    /// - DUID is specified as: "010203040506abcd"
+    /// - Other identifiers are specified as: "010203040506abcd"
     ///
     /// @param identifier Identifier in the textual format. The expected formats
-    /// for the hardware address and DUID have been shown above.
-    /// @param identifier_name One of "hw-address" or "duid"
+    /// for the hardware address and other identifiers are provided above.
+    /// @param identifier_name One of "hw-address", "duid", "circuit-id".
     /// @param ipv4_subnet_id Identifier of the IPv4 subnet to which the host
     /// is connected.
     /// @param ipv6_subnet_id Identifier of the IPv6 subnet to which the host
@@ -251,13 +252,10 @@ public:
 
     /// @brief Replaces currently used identifier with a new identifier.
     ///
-    /// This method initializes hardware address or DUID (@c hw_address_ or
-    /// @c duid_ respectively). The other (not initialized member) is
-    /// deallocated.
-    ///
+    /// This method sets a new identifier type and value for a host.
     /// This method is called by the @c Host constructor.
     ///
-    /// @param identifier Pointer to the new identifier in the textual format.
+    /// @param identifier Pointer to a buffer holding an identifier.
     /// @param len Length of the identifier that the @c identifier points to.
     /// @param type Identifier type.
     ///
@@ -267,14 +265,11 @@ public:
 
     /// @brief Replaces currently used identifier with a new identifier.
     ///
-    /// This method initializes hardware address or DUID (@c hw_address_ or
-    /// @c duid_ respectively). The other (not initialized member) is
-    /// deallocated.
-    ///
+    /// This method sets a new identifier type and value for a host.
     /// This method is called by the @c Host constructor.
     ///
-    /// @param identifier Pointer to the new identifier in the textual format.
-    /// @param name One of "hw-address" or "duid".
+    /// @param identifier Reference to a new identifier in the textual format.
+    /// @param name One of "hw-address", "duid", "circuit-id".
     ///
     /// @throw BadValue if the identifier is invalid.
     void setIdentifier(const std::string& identifier, const std::string& name);
@@ -283,28 +278,27 @@ public:
     ///
     /// @return Pointer to the @c HWAddr structure or null if the reservation
     /// is not associated with a hardware address.
-    HWAddrPtr getHWAddress() const {
-        return (hw_address_);
-    }
+    HWAddrPtr getHWAddress() const;
 
     /// @brief Returns DUID for which the reservations are made.
     ///
     /// @return Pointer to the @c DUID structure or null if the reservation
     /// is not associated with a DUID.
-    DuidPtr getDuid() const {
-        return (duid_);
-    }
+    DuidPtr getDuid() const;
 
-    /// @brief Returns the identifier (MAC or DUID) in binary form.
-    /// @return const reference to MAC or DUID in vector<uint8_t> form
+    /// @brief Returns the identifier in a binary form.
+    ///
+    /// @return const reference to a vector<uint8_t> holding an identifier
+    /// value.
     const std::vector<uint8_t>& getIdentifier() const;
 
     /// @brief Returns the identifier type.
-    /// @return the identifier type
+    ///
     IdentifierType getIdentifierType() const;
 
-    /// @brief Returns host identifier (mac or DUID) in printer friendly form.
-    /// @return text form of the identifier, including (duid= or mac=).
+    /// @brief Returns host identifier in a textual form.
+    ///
+    /// @return Identifier in the form of <type>=<value>.
     std::string getIdentifierAsText() const;
 
     /// @brief Returns host identifier in textual form.
@@ -487,12 +481,10 @@ private:
     void addClientClassInternal(ClientClasses& classes,
                                 const std::string& class_name);
 
-    /// @brief Pointer to the hardware address associated with the reservations
-    /// for the host.
-    HWAddrPtr hw_address_;
-    /// @brief Pointer to the DUID associated with the reservations for the
-    /// host.
-    DuidPtr duid_;
+    /// @brief Identifier type.
+    IdentifierType identifier_type_;
+    /// @brief Vector holding identifier value.
+    std::vector<uint8_t> identifier_value_;
     /// @brief Subnet identifier for the DHCPv4 client.
     SubnetID ipv4_subnet_id_;
     /// @brief Subnet identifier for the DHCPv6 client.

+ 10 - 4
src/lib/dhcpsrv/mysql_host_data_source.cc

@@ -302,17 +302,23 @@ public:
             // Check which of the identifiers is used and set values accordingly
             if (host->getDuid()) {
                 dhcp_identifier_length_ = host->getDuid()->getDuid().size();
+                memcpy(static_cast<void*>(dhcp_identifier_buffer_),
+                       &(host->getDuid()->getDuid()[0]),
+                       host->getDuid()->getDuid().size());
+
                 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
-                bind_[1].buffer = reinterpret_cast<char*>
-                    (const_cast<uint8_t*>(&(host->getDuid()->getDuid()[0])));
+                bind_[1].buffer = dhcp_identifier_buffer_;
                 bind_[1].buffer_length = dhcp_identifier_length_;
                 bind_[1].length = &dhcp_identifier_length_;
 
             } else if (host->getHWAddress()){
                 dhcp_identifier_length_ = host->getHWAddress()->hwaddr_.size();
+                memcpy(static_cast<void*>(dhcp_identifier_buffer_),
+                       &(host->getHWAddress()->hwaddr_[0]),
+                       host->getHWAddress()->hwaddr_.size());
+
                 bind_[1].buffer_type = MYSQL_TYPE_BLOB;
-                bind_[1].buffer = reinterpret_cast<char*>
-                    (&(host->getHWAddress()->hwaddr_[0]));
+                bind_[1].buffer = dhcp_identifier_buffer_;
                 bind_[1].buffer_length = dhcp_identifier_length_;
                 bind_[1].length = &dhcp_identifier_length_;