Browse Source

[2827] Changes after review

 - using namespace boost is no longer used in pkt6_unittest.cc
 - copyright years updated
 - Pkt6::getRelayOption() documented
 - several methods are now better commented
 - ChangeLog now refers to libdhcp++, not b10-dhcp6
Tomek Mrugalski 12 years ago
parent
commit
7c0534d4b3

+ 2 - 2
ChangeLog

@@ -1,6 +1,6 @@
 5XX.	[func]		tomek
 5XX.	[func]		tomek
-	b10-dhcp6: Pkt6 class is now able to parse and build relayed
-	DHCPv6 messages.
+	libdhcp++: Pkt6 class is now able to parse and build relayed DHCPv6
+	messages.
 	(Trac #2827, git TBD)
 	(Trac #2827, git TBD)
 
 
 582.	[func]		naokikambe
 582.	[func]		naokikambe

+ 1 - 1
src/lib/dhcp/libdhcp++.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above

+ 1 - 1
src/lib/dhcp/libdhcp++.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2012  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above

+ 1 - 1
src/lib/dhcp/option_custom.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above

+ 24 - 5
src/lib/dhcp/pkt6.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above
@@ -64,6 +64,9 @@ uint16_t Pkt6::len() {
     if (relay_info_.empty()) {
     if (relay_info_.empty()) {
         return (directLen());
         return (directLen());
     } else {
     } else {
+        // Unfortunately we need to re-calculate relay size every time, because
+        // we need to make sure that once a new option is added, its extra size
+        // is reflected in Pkt6::len().
         calculateRelaySizes();
         calculateRelaySizes();
         return (relay_info_[0].relay_msg_len_ + getRelayOverhead(relay_info_[0]));
         return (relay_info_[0].relay_msg_len_ + getRelayOverhead(relay_info_[0]));
     }
     }
@@ -101,12 +104,9 @@ uint16_t Pkt6::calculateRelaySizes() {
 
 
     uint16_t len = directLen(); // start with length of all options
     uint16_t len = directLen(); // start with length of all options
 
 
-    int relay_index = relay_info_.size();
-
-    while (relay_index) {
+    for (int relay_index = relay_info_.size(); relay_index > 0; --relay_index) {
         relay_info_[relay_index - 1].relay_msg_len_ = len;
         relay_info_[relay_index - 1].relay_msg_len_ = len;
         len += getRelayOverhead(relay_info_[relay_index - 1]);
         len += getRelayOverhead(relay_info_[relay_index - 1]);
-        --relay_index;
     }
     }
 
 
     return (len);
     return (len);
@@ -142,11 +142,21 @@ bool
 Pkt6::packUDP() {
 Pkt6::packUDP() {
     try {
     try {
 
 
+        // is this a relayed packet?
         if (!relay_info_.empty()) {
         if (!relay_info_.empty()) {
+
+            // calculate size needed for each relay (if there is only one relay,
+            // then it will be equal to "regular" length + relay-forw header +
+            // size of relay-msg option header + possibly size of interface-id
+            // option (if present). If there is more than one relay, the whole
+            // process is called iteratively for each relay.
             calculateRelaySizes();
             calculateRelaySizes();
 
 
+            // Now for each relay, we need to...
             for (vector<RelayInfo>::iterator relay = relay_info_.begin();
             for (vector<RelayInfo>::iterator relay = relay_info_.begin();
                  relay != relay_info_.end(); ++relay) {
                  relay != relay_info_.end(); ++relay) {
+
+                // build relay-forw/relay-repl header (see RFC3315, section 7)
                 bufferOut_.writeUint8(relay->msg_type_);
                 bufferOut_.writeUint8(relay->msg_type_);
                 bufferOut_.writeUint8(relay->hop_count_);
                 bufferOut_.writeUint8(relay->hop_count_);
                 bufferOut_.writeData(&(relay->linkaddr_.toBytes()[0]),
                 bufferOut_.writeData(&(relay->linkaddr_.toBytes()[0]),
@@ -154,12 +164,21 @@ Pkt6::packUDP() {
                 bufferOut_.writeData(&relay->peeraddr_.toBytes()[0],
                 bufferOut_.writeData(&relay->peeraddr_.toBytes()[0],
                                      isc::asiolink::V6ADDRESS_LEN);
                                      isc::asiolink::V6ADDRESS_LEN);
 
 
+                // store every option in this relay scope. Usually that will be
+                // only interface-id, but occasionally other options may be
+                // present here as well (vendor-opts for Cable modems,
+                // subscriber-id, remote-id, options echoed back from Echo
+                // Request Option, etc.)
                 for (Option::OptionCollection::const_iterator opt =
                 for (Option::OptionCollection::const_iterator opt =
                          relay->options_.begin();
                          relay->options_.begin();
                      opt != relay->options_.end(); ++opt) {
                      opt != relay->options_.end(); ++opt) {
                     (opt->second)->pack(bufferOut_);
                     (opt->second)->pack(bufferOut_);
                 }
                 }
 
 
+                // and include header relay-msg option. Its payload will be
+                // generated in the next iteration (if there are more relays)
+                // or outside the loop (if there are no more relays and the
+                // payload is a direct message)
                 bufferOut_.writeUint16(D6O_RELAY_MSG);
                 bufferOut_.writeUint16(D6O_RELAY_MSG);
                 bufferOut_.writeUint16(relay->relay_msg_len_);
                 bufferOut_.writeUint16(relay->relay_msg_len_);
             }
             }

+ 20 - 4
src/lib/dhcp/pkt6.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above
@@ -184,7 +184,22 @@ public:
     /// @return pointer to found option (or NULL)
     /// @return pointer to found option (or NULL)
     OptionPtr getOption(uint16_t type);
     OptionPtr getOption(uint16_t type);
 
 
-    OptionPtr getRelayOption(uint16_t type, uint8_t nesting_level);
+    /// @brief returns option inserted by relay
+    ///
+    /// Returns an option from specified relay scope (inserted by a given relay
+    /// if this is received packet or to be decapsulated by a given relay if
+    /// this is a transmitted packet). nesting_level specifies which relay
+    /// scope is to be used 0 is the outermost encapsulation (relay closest to
+    /// the server). pkt->relay_info_.size() - 1 is the innermost encapsulation
+    /// (relay closest to the client).
+    ///
+    /// @throw isc::OutOfRange if nesting level has invalid value.
+    ///
+    /// @param option_code code of the requested option
+    /// @param nesting_level see description above
+    ///
+    /// @return pointer to the option (or NULL if there is no such option)
+    OptionPtr getRelayOption(uint16_t option_code, uint8_t nesting_level);
 
 
     /// @brief Returns all instances of specified type.
     /// @brief Returns all instances of specified type.
     ///
     ///
@@ -409,6 +424,7 @@ protected:
     /// @brief calculates overhead introduced in specified relay
     /// @brief calculates overhead introduced in specified relay
     ///
     ///
     /// It is used when calculating message size and packing message
     /// It is used when calculating message size and packing message
+    /// @param relay RelayInfo structure that holds information about relay
     /// @return number of bytes needed to store relay information
     /// @return number of bytes needed to store relay information
     uint16_t getRelayOverhead(const RelayInfo& relay);
     uint16_t getRelayOverhead(const RelayInfo& relay);
 
 
@@ -416,9 +432,9 @@ protected:
     /// @return number of bytes needed to store all relay information
     /// @return number of bytes needed to store all relay information
     uint16_t calculateRelaySizes();
     uint16_t calculateRelaySizes();
 
 
-    /// @brief calculates size of the message as if were sent directly
+    /// @brief calculates size of the message as if it was not relayed at all
     ///
     ///
-    /// This is equal to len() if the message is direct.
+    /// This is equal to len() if the message was not relayed.
     /// @return number of bytes required to store the message
     /// @return number of bytes required to store the message
     uint16_t directLen();
     uint16_t directLen();
 
 

+ 1 - 1
src/lib/dhcp/tests/option_custom_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above

+ 21 - 19
src/lib/dhcp/tests/pkt6_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above
@@ -37,7 +37,6 @@ using namespace std;
 using namespace isc;
 using namespace isc;
 using namespace isc::asiolink;
 using namespace isc::asiolink;
 using namespace isc::dhcp;
 using namespace isc::dhcp;
-using namespace boost;
 
 
 namespace {
 namespace {
 // empty class for now, but may be extended once Addr6 becomes bigger
 // empty class for now, but may be extended once Addr6 becomes bigger
@@ -106,7 +105,7 @@ Pkt6* capture1() {
     return (pkt);
     return (pkt);
 }
 }
 
 
-/// @brief creates doubly related solicit message
+/// @brief creates doubly relayed solicit message
 ///
 ///
 /// This is a traffic capture exported from wireshark. It includes a SOLICIT
 /// This is a traffic capture exported from wireshark. It includes a SOLICIT
 /// message that passed through two relays. Each relay include interface-id,
 /// message that passed through two relays. Each relay include interface-id,
@@ -302,7 +301,7 @@ TEST_F(Pkt6Test, addGetDelOptions) {
 }
 }
 
 
 TEST_F(Pkt6Test, Timestamp) {
 TEST_F(Pkt6Test, Timestamp) {
-    scoped_ptr<Pkt6> pkt(new Pkt6(DHCPV6_SOLICIT, 0x020304));
+    boost::scoped_ptr<Pkt6> pkt(new Pkt6(DHCPV6_SOLICIT, 0x020304));
 
 
     // Just after construction timestamp is invalid
     // Just after construction timestamp is invalid
     ASSERT_TRUE(pkt->getTimestamp().is_not_a_date_time());
     ASSERT_TRUE(pkt->getTimestamp().is_not_a_date_time());
@@ -311,17 +310,17 @@ TEST_F(Pkt6Test, Timestamp) {
     pkt->updateTimestamp();
     pkt->updateTimestamp();
 
 
     // Get updated packet time.
     // Get updated packet time.
-    posix_time::ptime ts_packet = pkt->getTimestamp();
+    boost::posix_time::ptime ts_packet = pkt->getTimestamp();
 
 
     // After timestamp is updated it should be date-time.
     // After timestamp is updated it should be date-time.
     ASSERT_FALSE(ts_packet.is_not_a_date_time());
     ASSERT_FALSE(ts_packet.is_not_a_date_time());
 
 
     // Check current time.
     // Check current time.
-    posix_time::ptime ts_now =
-        posix_time::microsec_clock::universal_time();
+    boost::posix_time::ptime ts_now =
+        boost::posix_time::microsec_clock::universal_time();
 
 
     // Calculate period between packet time and now.
     // Calculate period between packet time and now.
-    posix_time::time_period ts_period(ts_packet, ts_now);
+    boost::posix_time::time_period ts_period(ts_packet, ts_now);
 
 
     // Duration should be positive or zero.
     // Duration should be positive or zero.
     EXPECT_TRUE(ts_period.length().total_microseconds() >= 0);
     EXPECT_TRUE(ts_period.length().total_microseconds() >= 0);
@@ -378,7 +377,7 @@ TEST_F(Pkt6Test, getName) {
 // relays can be parsed properly. See capture2() method description
 // relays can be parsed properly. See capture2() method description
 // for details regarding the packet.
 // for details regarding the packet.
 TEST_F(Pkt6Test, relayUnpack) {
 TEST_F(Pkt6Test, relayUnpack) {
-    scoped_ptr<Pkt6> msg(capture2());
+    boost::scoped_ptr<Pkt6> msg(capture2());
 
 
     EXPECT_NO_THROW(msg->unpack());
     EXPECT_NO_THROW(msg->unpack());
 
 
@@ -405,7 +404,7 @@ TEST_F(Pkt6Test, relayUnpack) {
     // get the remote-id option
     // get the remote-id option
     ASSERT_TRUE(opt = msg->getRelayOption(D6O_REMOTE_ID, 0));
     ASSERT_TRUE(opt = msg->getRelayOption(D6O_REMOTE_ID, 0));
     EXPECT_EQ(22, opt->len()); // 18 bytes of data + 4 bytes header
     EXPECT_EQ(22, opt->len()); // 18 bytes of data + 4 bytes header
-    shared_ptr<OptionCustom> custom = dynamic_pointer_cast<OptionCustom>(opt);
+    boost::shared_ptr<OptionCustom> custom = boost::dynamic_pointer_cast<OptionCustom>(opt);
 
 
     uint32_t vendor_id = custom->readInteger<uint32_t>(0);
     uint32_t vendor_id = custom->readInteger<uint32_t>(0);
     EXPECT_EQ(6527, vendor_id); // 6527 = Panthera Networks
     EXPECT_EQ(6527, vendor_id); // 6527 = Panthera Networks
@@ -428,7 +427,7 @@ TEST_F(Pkt6Test, relayUnpack) {
     // get the remote-id option
     // get the remote-id option
     ASSERT_TRUE(opt = msg->getRelayOption(D6O_REMOTE_ID, 1));
     ASSERT_TRUE(opt = msg->getRelayOption(D6O_REMOTE_ID, 1));
     EXPECT_EQ(8, opt->len());
     EXPECT_EQ(8, opt->len());
-    custom = dynamic_pointer_cast<OptionCustom>(opt);
+    custom = boost::dynamic_pointer_cast<OptionCustom>(opt);
 
 
     vendor_id = custom->readInteger<uint32_t>(0);
     vendor_id = custom->readInteger<uint32_t>(0);
     EXPECT_EQ(3561, vendor_id); // 3561 = Broadband Forum
     EXPECT_EQ(3561, vendor_id); // 3561 = Broadband Forum
@@ -454,7 +453,8 @@ TEST_F(Pkt6Test, relayUnpack) {
     ASSERT_EQ(0, memcmp(&data[0], expected_client_id, data.size()));
     ASSERT_EQ(0, memcmp(&data[0], expected_client_id, data.size()));
 
 
     ASSERT_TRUE(opt = msg->getOption(D6O_IA_NA));
     ASSERT_TRUE(opt = msg->getOption(D6O_IA_NA));
-    shared_ptr<Option6IA> ia = dynamic_pointer_cast<Option6IA>(opt);
+    boost::shared_ptr<Option6IA> ia =
+        boost::dynamic_pointer_cast<Option6IA>(opt);
     ASSERT_TRUE(ia);
     ASSERT_TRUE(ia);
     EXPECT_EQ(1, ia->getIAID());
     EXPECT_EQ(1, ia->getIAID());
     EXPECT_EQ(0xffffffff, ia->getT1());
     EXPECT_EQ(0xffffffff, ia->getT1());
@@ -462,12 +462,14 @@ TEST_F(Pkt6Test, relayUnpack) {
 
 
     ASSERT_TRUE(opt = msg->getOption(D6O_ELAPSED_TIME));
     ASSERT_TRUE(opt = msg->getOption(D6O_ELAPSED_TIME));
     EXPECT_EQ(6, opt->len()); // 2 bytes of data + 4 bytes of header
     EXPECT_EQ(6, opt->len()); // 2 bytes of data + 4 bytes of header
-    shared_ptr<OptionInt<uint16_t> > elapsed = dynamic_pointer_cast<OptionInt<uint16_t> > (opt);
+    boost::shared_ptr<OptionInt<uint16_t> > elapsed =
+        boost::dynamic_pointer_cast<OptionInt<uint16_t> > (opt);
     ASSERT_TRUE(elapsed);
     ASSERT_TRUE(elapsed);
     EXPECT_EQ(0, elapsed->getValue());
     EXPECT_EQ(0, elapsed->getValue());
 
 
     ASSERT_TRUE(opt = msg->getOption(D6O_ORO));
     ASSERT_TRUE(opt = msg->getOption(D6O_ORO));
-    shared_ptr<OptionIntArray<uint16_t> > oro = dynamic_pointer_cast<OptionIntArray<uint16_t> > (opt);
+    boost::shared_ptr<OptionIntArray<uint16_t> > oro =
+        boost::dynamic_pointer_cast<OptionIntArray<uint16_t> > (opt);
     const std::vector<uint16_t> oro_list = oro->getValues();
     const std::vector<uint16_t> oro_list = oro->getValues();
     EXPECT_EQ(3, oro_list.size());
     EXPECT_EQ(3, oro_list.size());
     EXPECT_EQ(23, oro_list[0]);
     EXPECT_EQ(23, oro_list[0]);
@@ -479,7 +481,7 @@ TEST_F(Pkt6Test, relayUnpack) {
 // packed and then unpacked.
 // packed and then unpacked.
 TEST_F(Pkt6Test, relayPack) {
 TEST_F(Pkt6Test, relayPack) {
 
 
-    scoped_ptr<Pkt6> parent(new Pkt6(DHCPV6_ADVERTISE, 0x020304));
+    boost::scoped_ptr<Pkt6> parent(new Pkt6(DHCPV6_ADVERTISE, 0x020304));
 
 
     Pkt6::RelayInfo relay1;
     Pkt6::RelayInfo relay1;
     relay1.msg_type_ = DHCPV6_RELAY_REPL;
     relay1.msg_type_ = DHCPV6_RELAY_REPL;
@@ -492,7 +494,7 @@ TEST_F(Pkt6Test, relayPack) {
 
 
     OptionPtr optRelay1(new Option(Option::V6, 200, relay_data));
     OptionPtr optRelay1(new Option(Option::V6, 200, relay_data));
 
 
-    relay1.options_.insert(pair<int, shared_ptr<Option> >(optRelay1->getType(), optRelay1));
+    relay1.options_.insert(pair<int, boost::shared_ptr<Option> >(optRelay1->getType(), optRelay1));
 
 
     OptionPtr opt1(new Option(Option::V6, 100));
     OptionPtr opt1(new Option(Option::V6, 100));
     OptionPtr opt2(new Option(Option::V6, 101));
     OptionPtr opt2(new Option(Option::V6, 101));
@@ -516,9 +518,9 @@ TEST_F(Pkt6Test, relayPack) {
               parent->len());
               parent->len());
 
 
     // create second packet,based on assembled data from the first one
     // create second packet,based on assembled data from the first one
-    scoped_ptr<Pkt6> clone(new Pkt6(static_cast<const uint8_t*>(
-                                    parent->getBuffer().getData()),
-                                    parent->getBuffer().getLength()));
+    boost::scoped_ptr<Pkt6> clone(new Pkt6(static_cast<const uint8_t*>(
+                                           parent->getBuffer().getData()),
+                                           parent->getBuffer().getLength()));
 
 
     // now recreate options list
     // now recreate options list
     EXPECT_TRUE( clone->unpack() );
     EXPECT_TRUE( clone->unpack() );