BIND 10 trac1956, updated. 9cd5b8d800ba00b9e0d3d07609853e1221550a2f [1956] Added timestamp update mechanism to pkt6 and pkt4 classes.

BIND 10 source code commits bind10-changes at lists.isc.org
Wed May 30 18:27:51 UTC 2012


The branch, trac1956 has been updated
       via  9cd5b8d800ba00b9e0d3d07609853e1221550a2f (commit)
       via  0a3638e4bae9b7ace20bf59f5aa1ee1e1fe50d1a (commit)
      from  6643603e8bc40fed0bab6d6a4ca6b6d585be6001 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9cd5b8d800ba00b9e0d3d07609853e1221550a2f
Author: Marcin Siodelski <marcin at isc.org>
Date:   Wed May 30 20:26:09 2012 +0200

    [1956] Added timestamp update mechanism to pkt6 and pkt4 classes.

commit 0a3638e4bae9b7ace20bf59f5aa1ee1e1fe50d1a
Author: Marcin Siodelski <marcin at isc.org>
Date:   Wed May 30 19:21:14 2012 +0200

    [1956] Code cleanup - many comments updated.

-----------------------------------------------------------------------

Summary of changes:
 src/lib/dhcp/Makefile.am                |    1 +
 src/lib/dhcp/iface_mgr.cc               |    8 +++++++
 src/lib/dhcp/pkt4.cc                    |    9 ++++++++
 src/lib/dhcp/pkt4.h                     |   20 ++++++++++++++++++
 src/lib/dhcp/pkt6.cc                    |   10 +++++++++
 src/lib/dhcp/pkt6.h                     |   20 ++++++++++++++++++
 src/lib/dhcp/tests/Makefile.am          |    2 +-
 src/lib/dhcp/tests/pkt4_unittest.cc     |   12 +++++++++++
 src/lib/dhcp/tests/pkt6_unittest.cc     |    9 ++++++++
 tests/tools/perfdhcp/localized_option.h |   32 ++++++++++++++++++++--------
 tests/tools/perfdhcp/perf_pkt6.cc       |   11 ++++++----
 tests/tools/perfdhcp/perf_pkt6.h        |   35 ++++++++++++++++++++-----------
 12 files changed, 143 insertions(+), 26 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/dhcp/Makefile.am b/src/lib/dhcp/Makefile.am
index 9e6fb0c..4e64c57 100644
--- a/src/lib/dhcp/Makefile.am
+++ b/src/lib/dhcp/Makefile.am
@@ -31,3 +31,4 @@ libdhcp___la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
 libdhcp___la_LIBADD   = $(top_builddir)/src/lib/asiolink/libasiolink.la
 libdhcp___la_LIBADD  += $(top_builddir)/src/lib/util/libutil.la
 libdhcp___la_LDFLAGS  = -no-undefined -version-info 1:0:0
+libdhcp___la_LDFLAGS += $(CLOCK_GETTIME_LDFLAGS)
diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc
index 1505fbf..005e408 100644
--- a/src/lib/dhcp/iface_mgr.cc
+++ b/src/lib/dhcp/iface_mgr.cc
@@ -597,6 +597,8 @@ IfaceMgr::send(const Pkt6Ptr& pkt) {
     pktinfo->ipi6_ifindex = pkt->getIndex();
     m.msg_controllen = cmsg->cmsg_len;
 
+    pkt->updateTimestamp();
+
     result = sendmsg(getSocket(*pkt), &m, 0);
     if (result < 0) {
         isc_throw(Unexpected, "Pkt6 send failed: sendmsg() returned " << result);
@@ -656,6 +658,8 @@ IfaceMgr::send(const Pkt4Ptr& pkt)
          << " over socket " << getSocket(*pkt) << " on interface "
          << getIface(pkt->getIface())->getFullName() << endl;
 
+    pkt->updateTimestamp();
+
     int result = sendmsg(getSocket(*pkt), &m, 0);
     if (result < 0) {
         isc_throw(Unexpected, "Pkt4 send failed.");
@@ -746,6 +750,8 @@ IfaceMgr::receive4() {
     // We have all data let's create Pkt4 object.
     Pkt4Ptr pkt = Pkt4Ptr(new Pkt4(buf, result));
 
+    pkt->updateTimestamp();
+
     unsigned int ifindex = iface->getIndex();
 
     IOAddress from(htonl(from_addr.sin_addr.s_addr));
@@ -890,6 +896,8 @@ Pkt6Ptr IfaceMgr::receive6() {
         return (Pkt6Ptr()); // NULL
     }
 
+    pkt->updateTimestamp();
+
     pkt->setLocalAddr(IOAddress::from_bytes(AF_INET6,
                       reinterpret_cast<const uint8_t*>(&to_addr)));
     pkt->setRemoteAddr(IOAddress::from_bytes(AF_INET6,
diff --git a/src/lib/dhcp/pkt4.cc b/src/lib/dhcp/pkt4.cc
index e456631..5199551 100644
--- a/src/lib/dhcp/pkt4.cc
+++ b/src/lib/dhcp/pkt4.cc
@@ -53,6 +53,7 @@ Pkt4::Pkt4(uint8_t msg_type, uint32_t transid)
     memset(chaddr_, 0, MAX_CHADDR_LEN);
     memset(sname_, 0, MAX_SNAME_LEN);
     memset(file_, 0, MAX_FILE_LEN);
+    memset(&timestamp_, 0, sizeof(timestamp_));
 }
 
 Pkt4::Pkt4(const uint8_t* data, size_t len)
@@ -81,6 +82,7 @@ Pkt4::Pkt4(const uint8_t* data, size_t len)
 
     data_.resize(len);
     memcpy(&data_[0], data, len);
+    memset(&timestamp_, 0, sizeof(timestamp_));
 }
 
 size_t
@@ -305,6 +307,13 @@ Pkt4::getOption(uint8_t type) {
     return boost::shared_ptr<isc::dhcp::Option>(); // NULL
 }
 
+void
+Pkt4::updateTimestamp() {
+    if (clock_gettime(CLOCK_REALTIME, &timestamp_) < 0) {
+        isc_throw(isc::Unexpected, "Failed to get timestamp for packet");
+    }
+}
+
 } // end of namespace isc::dhcp
 
 } // end of namespace isc
diff --git a/src/lib/dhcp/pkt4.h b/src/lib/dhcp/pkt4.h
index a3f683f..ba59e82 100644
--- a/src/lib/dhcp/pkt4.h
+++ b/src/lib/dhcp/pkt4.h
@@ -16,6 +16,7 @@
 #define PKT4_H
 
 #include <iostream>
+#include <time.h>
 #include <vector>
 #include <boost/shared_ptr.hpp>
 #include "asiolink/io_address.h"
@@ -321,6 +322,14 @@ public:
     /// @return interface name
     std::string getIface() const { return iface_; };
 
+    /// @brief Returns packet timestamp.
+    ///
+    /// Returns packet timestamp value updated when
+    /// packet is received or send.
+    ///
+    /// @return packet timestamp.
+    timespec getTimestamp() const { return timestamp_; }
+
     /// @brief Sets interface name.
     ///
     /// Sets interface name over which packet was received or is
@@ -387,6 +396,14 @@ public:
     /// @return remote port
     uint16_t getRemotePort() { return (remote_port_); }
 
+    /// @brief Update packet timestamp.
+    ///
+    /// Updates packet timestamp. This method is invoked
+    /// by interface manager just before sending or
+    /// just after receiving it.
+    /// @throw isc::Unexpected if timestamp update failed
+    void updateTimestamp();
+
 protected:
 
     /// converts DHCP message type to BOOTP op type
@@ -485,6 +502,9 @@ protected:
 
     /// collection of options present in this message
     isc::dhcp::Option::OptionCollection options_;
+
+    /// packet timestamp
+    timespec timestamp_;
 }; // Pkt4 class
 
 typedef boost::shared_ptr<Pkt4> Pkt4Ptr;
diff --git a/src/lib/dhcp/pkt6.cc b/src/lib/dhcp/pkt6.cc
index aea3cde..519698b 100644
--- a/src/lib/dhcp/pkt6.cc
+++ b/src/lib/dhcp/pkt6.cc
@@ -38,6 +38,7 @@ Pkt6::Pkt6(const uint8_t* buf, uint32_t buf_len, DHCPv6Proto proto /* = UDP */)
     bufferOut_(0) {
     data_.resize(buf_len);
     memcpy(&data_[0], buf, buf_len);
+    memset(&timestamp_, 0, sizeof(timestamp_));
 }
 
 Pkt6::Pkt6(uint8_t msg_type, uint32_t transid, DHCPv6Proto proto /*= UDP*/) :
@@ -51,6 +52,7 @@ Pkt6::Pkt6(uint8_t msg_type, uint32_t transid, DHCPv6Proto proto /*= UDP*/) :
     local_port_(0),
     remote_port_(0),
     bufferOut_(0) {
+    memset(&timestamp_, 0, sizeof(timestamp_));
 }
 
 uint16_t Pkt6::len() {
@@ -202,5 +204,13 @@ void Pkt6::repack() {
     bufferOut_.writeData(&data_[0], data_.size());
 }
 
+void
+Pkt6::updateTimestamp() {
+    if (clock_gettime(CLOCK_REALTIME, &timestamp_) < 0) {
+        isc_throw(isc::Unexpected, "Failed to get timestamp for packet");
+    }
+}
+
+
 } // end of isc::dhcp namespace
 } // end of isc namespace
diff --git a/src/lib/dhcp/pkt6.h b/src/lib/dhcp/pkt6.h
index 97ac996..e02b791 100644
--- a/src/lib/dhcp/pkt6.h
+++ b/src/lib/dhcp/pkt6.h
@@ -16,6 +16,7 @@
 #define PKT6_H
 
 #include <iostream>
+#include <time.h>
 #include <boost/shared_ptr.hpp>
 #include <boost/shared_array.hpp>
 #include "asiolink/io_address.h"
@@ -220,6 +221,14 @@ public:
     /// @return interface name
     std::string getIface() const { return iface_; };
 
+    /// @brief Returns packet timestamp.
+    ///
+    /// Returns packet timestamp value updated when
+    /// packet is received or send.
+    ///
+    /// @return packet timestamp.
+    timespec getTimestamp() const { return timestamp_; }
+
     /// @brief Sets interface name.
     ///
     /// Sets interface name over which packet was received or is
@@ -233,6 +242,14 @@ public:
     /// collection of options present in this message
     isc::dhcp::Option::OptionCollection options_;
 
+    /// @brief Update packet timestamp.
+    ///
+    /// Updates packet timestamp. This method is invoked
+    /// by interface manager just before sending or
+    /// just after receiving it.
+    /// @throw isc::Unexpected if timestamp update failed
+    void updateTimestamp();
+
 protected:
     /// Builds on wire packet for TCP transmission.
     ///
@@ -305,6 +322,9 @@ protected:
 
     /// output buffer (used during message transmission)
     isc::util::OutputBuffer bufferOut_;
+
+    /// packet timestamp
+    timespec timestamp_;
 }; // Pkt6 class
 
 typedef boost::shared_ptr<Pkt6> Pkt6Ptr;
diff --git a/src/lib/dhcp/tests/Makefile.am b/src/lib/dhcp/tests/Makefile.am
index c68de01..6dbd377 100644
--- a/src/lib/dhcp/tests/Makefile.am
+++ b/src/lib/dhcp/tests/Makefile.am
@@ -33,7 +33,7 @@ libdhcp___unittests_SOURCES += ../pkt6.h ../pkt6.cc pkt6_unittest.cc
 libdhcp___unittests_SOURCES += ../pkt4.h ../pkt4.cc pkt4_unittest.cc
 
 libdhcp___unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
-libdhcp___unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
+libdhcp___unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS) $(CLOCK_GETTIME_LDFLAGS)
 
 libdhcp___unittests_CXXFLAGS = $(AM_CXXFLAGS)
 
diff --git a/src/lib/dhcp/tests/pkt4_unittest.cc b/src/lib/dhcp/tests/pkt4_unittest.cc
index bed8c2f..df6381f 100644
--- a/src/lib/dhcp/tests/pkt4_unittest.cc
+++ b/src/lib/dhcp/tests/pkt4_unittest.cc
@@ -598,4 +598,16 @@ TEST(Pkt4Test, metaFields) {
     delete pkt;
 }
 
+TEST(Pkt4Test, Timestamp) {
+    Pkt4* pkt = new Pkt4(DHCPOFFER, 1234);
+    ASSERT_NO_THROW(pkt->updateTimestamp());
+    timespec ts_packet = pkt->getTimestamp();
+    timespec ts_now;
+    ASSERT_FALSE(clock_gettime(CLOCK_REALTIME, &ts_now) < 0);
+    EXPECT_TRUE(ts_packet.tv_sec >= ts_now.tv_sec);
+
+    delete pkt;
+}
+
+
 } // end of anonymous namespace
diff --git a/src/lib/dhcp/tests/pkt6_unittest.cc b/src/lib/dhcp/tests/pkt6_unittest.cc
index e07ea9f..21080f8 100644
--- a/src/lib/dhcp/tests/pkt6_unittest.cc
+++ b/src/lib/dhcp/tests/pkt6_unittest.cc
@@ -204,4 +204,13 @@ TEST_F(Pkt6Test, addGetDelOptions) {
     delete parent;
 }
 
+TEST_F(Pkt6Test, Timestamp) {
+    Pkt6* pkt = new Pkt6(DHCPV6_SOLICIT, 0x020304);
+    ASSERT_NO_THROW(pkt->updateTimestamp());
+    timespec ts_packet = pkt->getTimestamp();
+    timespec ts_now;
+    ASSERT_FALSE(clock_gettime(CLOCK_REALTIME, &ts_now) < 0);
+    EXPECT_TRUE(ts_packet.tv_sec >= ts_now.tv_sec);
+}
+
 }
diff --git a/tests/tools/perfdhcp/localized_option.h b/tests/tools/perfdhcp/localized_option.h
index 9f89c47..a69c560 100644
--- a/tests/tools/perfdhcp/localized_option.h
+++ b/tests/tools/perfdhcp/localized_option.h
@@ -20,10 +20,25 @@
 namespace isc {
 namespace perfdhcp {
 
-/// \brief DHCPv6 option at specific offset
+/// \brief DHCP option at specific offset
 ///
-/// This class represents DHCPv6 option at specified
-/// offset in DHCPv6 message.
+/// This class represents DHCP option at specified
+/// offset in DHCP message.
+/// Objects of this type are intended to be used when DHCP packets
+/// are created from templates (e.g. read from template file).
+/// Such packets have number of that have to be replaced before
+/// sending: e.g. DUID can be randomized. If option of this type
+/// is added to \ref PerfPkt6 options collection,
+/// \ref perfdhcp::PerfPkt6 will call \ref getOffset on this object
+/// to retrieve user-defined option position and replace contents of
+/// the output buffer at this offset before packet is sent to the server.
+/// (\see perfdhcp::PerfPkt6::rawPack).
+/// In order to read on-wire data from incoming packet client class
+/// has to specify options of \ref perfdhcp::LocalizedOption type
+/// with expected offsets of these options in a packet. The
+/// \ret perfdhcp::PerfPkt6 will use offsets to read fragments
+/// of packet and store them in options' buffers.
+/// (\see perfdhcp::PerfPkt6::rawUnpack).
 ///
 class LocalizedOption : public dhcp::Option {
 public:
@@ -32,7 +47,7 @@ public:
     /// \param u specifies universe (V4 or V6)
     /// \param type option type (0-255 for V4 and 0-65535 for V6)
     /// \param data content of the option
-    LocalizedOption(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer& data) : 
+    LocalizedOption(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer& data) :
         dhcp::Option(u, type, data),
         offset_(0) {
     }
@@ -77,21 +92,20 @@ public:
     /// \param first iterator to the first element that should be copied
     /// \param last iterator to the next element after the last one
     ///        to be copied.
-    /// \param offset location of option in a packet (zero is default)
+    /// \param offset offset of option in a packet (zero is default)
     LocalizedOption(dhcp::Option::Universe u, uint16_t type, dhcp::OptionBufferConstIter first,
                     dhcp::OptionBufferConstIter last, const size_t offset) :
         dhcp::Option(u, type, first, last),
         offset_(offset) {
     }
 
-    /// \brief Returns absolute position (offset) of an option in a
-    /// DHCPv6 packet.
+    /// \brief Returns offset of an option in a DHCP packet.
     ///
     /// \return option offset in a packet
     size_t getOffset() const { return offset_; };
-    
+
 private:
-    size_t offset_;   ///< Offset of DHCPv6 option in a packet
+    size_t offset_;   ///< Offset of DHCP option in a packet
 };
 
 
diff --git a/tests/tools/perfdhcp/perf_pkt6.cc b/tests/tools/perfdhcp/perf_pkt6.cc
index bb65b83..1f1aefd 100644
--- a/tests/tools/perfdhcp/perf_pkt6.cc
+++ b/tests/tools/perfdhcp/perf_pkt6.cc
@@ -87,9 +87,8 @@ PerfPkt6::rawPackOptions() {
             // Replace existing option with new value.
             option->pack(bufferOut_);
         }
-        // Seek to the end of the end of the buffer
-        bufferOut_.clear();
-        bufferOut_.skip(data_.size());
+        // Seek to the end of the buffer to make sure size is correct.
+        bufferOut_.skip(data_.size() - bufferOut_.getLength());
     }
     catch (const Exception&) {
         isc_throw(isc::Unexpected, "Failed to build packet (Option build failed");
@@ -113,7 +112,11 @@ PerfPkt6::rawUnpackOptions() {
         }
 
         size_t offset = opt_pos;
-        //        uint16_t opt_type = data_[offset] * 256 + data_[offset + 1];
+        uint16_t opt_type = data_[offset] * 256 + data_[offset + 1];
+        if (opt_type != option->getType()) {
+            isc_throw(isc::BadValue,
+                      "Failed to unpack option from raw buffer (Option type mismatch)");
+        }
         offset += 2;
         uint16_t opt_len = data_[offset] * 256 + data_[offset + 1];
         offset += 2;
diff --git a/tests/tools/perfdhcp/perf_pkt6.h b/tests/tools/perfdhcp/perf_pkt6.h
index 8d3c442..b98044c 100644
--- a/tests/tools/perfdhcp/perf_pkt6.h
+++ b/tests/tools/perfdhcp/perf_pkt6.h
@@ -47,10 +47,6 @@ namespace perfdhcp {
 /// that options must be of the
 /// \ref isc::perfdhcp::LocalizedOption type.
 ///
-/// This class also records timestamps of last pack/unpack
-/// operation on the packet. This is to track DHCP server
-/// performance based on packet's send/receive duration.
-///
 /// \note: if you don't use template files simply use constructors
 /// inherited from parent class and isc::dhcp::Option type instead
 ///
@@ -100,11 +96,10 @@ public:
     /// The method copies user buffer to output buffer and
     /// extracts transaction id from it based on transaction id
     /// offset provided in constructor.
-    /// Eventually, this method updates packet timestamp.
     ///
     /// \note: Use this method to prepare on-wire DHCPv6 message
     /// when you use template packets that require replacement
-    /// of selected options contents before sending.
+    /// of selected options' contents before sending.
     ///
     /// \retrun false, id pack operation failed.
     bool rawPack();
@@ -130,16 +125,32 @@ private:
 
     /// \brief Updates options in the output buffer
     ///
-    /// This method updates options in the output buffer
-    /// with the ones provided with
-    /// \ref isc::dhcp::Pkt6::addOption. It is expected
-    /// that these options will be of the
-    /// \ref isc::perfdhcp::LocalizedOption type
-    /// with their position (offset) specified.
+    /// The method uses options collection added to object
+    /// of this class with \ref dhcp::Pkt6::addOption to
+    /// on-wire data. Option objects has to be of
+    /// \ref perfdhcp::LocalizedOption type and should
+    /// have non-zero values of offsets specified.
+    /// This method will use these offsets to seek to
+    /// given position in output buffer and update option
+    /// on-wire data with contents of option's buffer.
     ///
     /// \throw isc::Unexpected if options update failed.
     void rawPackOptions();
 
+    /// \brief Reads contents of specified options from buffer
+    ///
+    /// The method reads options data from the copy of the buffer
+    /// provided in constructor and stores data in options
+    /// objects that belong to options collection.
+    /// Client class that constructs this object has to create
+    /// options collection prior to calling \ref rawUnpack
+    /// method that in turn calls this method.
+    /// If option is not added to options collection, it will
+    /// not be added by this method. This method will rather
+    /// skip update of such an option even if it is present
+    /// in packet's buffer.
+    ///
+    /// \throw isc::Unexpected if options unpack failed.
     void rawUnpackOptions();
 
     size_t transid_offset_;      ///< transaction id offset



More information about the bind10-changes mailing list