BIND 10 master, updated. be15d120159f1b7380f88707efb05c4b11b121d4 [3177] Merge branch 'trac3177' b10-dhcp6 relay traffic UDP port fix.
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Oct 7 12:02:53 UTC 2013
The branch, master has been updated
via be15d120159f1b7380f88707efb05c4b11b121d4 (commit)
via 6b33de4bea92eecb64b6c673bf1b8ae51f8edcf1 (commit)
via e43c23bc2d1006c2abb5dd7df7ed575cfce00451 (commit)
via 23c944640d1b697af40582f7999b40b05b17a44a (commit)
via 70d44604584934a651d1b3d975a072513aa010ed (commit)
via eee878e7817bcdc270ff56867dc0671f1d223e31 (commit)
from 9b7cc4afda911d762394c8e432fc429d027a106c (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 be15d120159f1b7380f88707efb05c4b11b121d4
Merge: 9b7cc4a 6b33de4
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Mon Oct 7 14:02:24 2013 +0200
[3177] Merge branch 'trac3177' b10-dhcp6 relay traffic UDP port fix.
Conflicts:
ChangeLog
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 12 ++-
src/bin/dhcp6/dhcp6_srv.cc | 16 ++-
src/bin/dhcp6/tests/Makefile.am | 1 +
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc | 76 ++++++++++++++
src/bin/dhcp6/tests/dhcp6_test_utils.h | 15 +++
src/bin/dhcp6/tests/hooks_unittest.cc | 27 -----
src/bin/dhcp6/tests/wireshark.cc | 163 +++++++++++++++++++++++++++++
7 files changed, 275 insertions(+), 35 deletions(-)
create mode 100644 src/bin/dhcp6/tests/wireshark.cc
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 0a2a652..cd57ddc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+686. [bug] tomek
+ b10-dhcp6 now sends back relayed traffic to proper port.
+ (Trac #3177, git 6b33de4bea92eecb64b6c673bf1b8ae51f8edcf1)
+
685. [func] tomek
libdhcpsrv: Allocation Engine is now able to handle IPv6 prefixes.
This will be used in Prefix Delegation.
@@ -24,10 +28,10 @@
show Xfrin" via bindctl when b10-xfrin is running.
(Trac #2274, git ca691626a2be16f08754177bb27983a9f4984702)
-681. [func] tmark
+681. [func] tmark
Added support for prefix delegation configuration to b10-dhcp6
subnets.
- (Trac# 3151 git 79a22be33825bafa1a0cdfa24d5cb751ab1ae2d3)
+ (Trac# 3151, git 79a22be33825bafa1a0cdfa24d5cb751ab1ae2d3)
680. [func] marcin
perfdhcp: Added support for requesting IPv6 prefixes using IA_PD
@@ -37,12 +41,12 @@
679. [func] tmark
b10-dhcp-ddns Finite state machine logic was refactored into its own class,
StateModel.
- (Trac# 3156, git 6e9227b1b15448e834d1f60dd655e5633ff9745c)
+ (Trac# 3156, git 6e9227b1b15448e834d1f60dd655e5633ff9745c)
678. [func] tmark
MySQL backend used by b10-dhcp6 now uses lease type as a
filtering parameter in all IPv6 lease queries.
- (Trac# 3147, git 65b6372b783cb1361fd56efe2b3247bfdbdc47ea)
+ (Trac# 3147, git 65b6372b783cb1361fd56efe2b3247bfdbdc47ea)
677. [func] tomek
libdhcpsrv: CfgMgr is now able to store IA, TA and PD pools in
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
index a584c81..962b89e 100644
--- a/src/bin/dhcp6/dhcp6_srv.cc
+++ b/src/bin/dhcp6/dhcp6_srv.cc
@@ -369,7 +369,15 @@ bool Dhcpv6Srv::run() {
if (rsp) {
rsp->setRemoteAddr(query->getRemoteAddr());
rsp->setLocalAddr(query->getLocalAddr());
- rsp->setRemotePort(DHCP6_CLIENT_PORT);
+
+ if (rsp->relay_info_.empty()) {
+ // Direct traffic, send back to the client directly
+ rsp->setRemotePort(DHCP6_CLIENT_PORT);
+ } else {
+ // Relayed traffic, send back to the relay agent
+ rsp->setRemotePort(DHCP6_SERVER_PORT);
+ }
+
rsp->setLocalPort(DHCP6_SERVER_PORT);
rsp->setIndex(query->getIndex());
rsp->setIface(query->getIface());
@@ -433,10 +441,10 @@ bool Dhcpv6Srv::run() {
// Pass incoming packet as argument
callout_handle->setArgument("response6", rsp);
-
+
// Call callouts
HooksManager::callCallouts(Hooks.hook_index_buffer6_send_, *callout_handle);
-
+
// Callouts decided to skip the next processing step. The next
// processing step would to parse the packet, so skip at this
// stage means drop.
@@ -444,7 +452,7 @@ bool Dhcpv6Srv::run() {
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_BUFFER_SEND_SKIP);
continue;
}
-
+
callout_handle->getArgument("response6", rsp);
}
diff --git a/src/bin/dhcp6/tests/Makefile.am b/src/bin/dhcp6/tests/Makefile.am
index 19c6dea..4b6d3a0 100644
--- a/src/bin/dhcp6/tests/Makefile.am
+++ b/src/bin/dhcp6/tests/Makefile.am
@@ -78,6 +78,7 @@ dhcp6_unittests_SOURCES += ../dhcp6_srv.h ../dhcp6_srv.cc
dhcp6_unittests_SOURCES += ../dhcp6_log.h ../dhcp6_log.cc
dhcp6_unittests_SOURCES += ../ctrl_dhcp6_srv.cc
dhcp6_unittests_SOURCES += ../config_parser.cc ../config_parser.h
+dhcp6_unittests_SOURCES += wireshark.cc
nodist_dhcp6_unittests_SOURCES = ../dhcp6_messages.h ../dhcp6_messages.cc
nodist_dhcp6_unittests_SOURCES += marker_file.h test_libraries.h
diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
index 607b70b..a22a919 100644
--- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
@@ -2116,6 +2116,82 @@ TEST_F(FqdnDhcpv6SrvTest, processRequestRelease) {
}
+// Checks if server responses are sent to the proper port.
+TEST_F(Dhcpv6SrvTest, portsDirectTraffic) {
+
+ NakedDhcpv6Srv srv(0);
+
+ // Let's create a simple SOLICIT
+ Pkt6Ptr sol = captureSimpleSolicit();
+
+ // Simulate that we have received that traffic
+ srv.fakeReceive(sol);
+
+ // Server will now process to run its normal loop, but instead of calling
+ // IfaceMgr::receive6(), it will read all packets from the list set by
+ // fakeReceive()
+ srv.run();
+
+ // Get Advertise...
+ ASSERT_FALSE(srv.fake_sent_.empty());
+ Pkt6Ptr adv = srv.fake_sent_.front();
+ ASSERT_TRUE(adv);
+
+ // This is sent back to client directly, should be port 546
+ EXPECT_EQ(DHCP6_CLIENT_PORT, adv->getRemotePort());
+}
+
+// Checks if server responses are sent to the proper port.
+TEST_F(Dhcpv6SrvTest, portsRelayedTraffic) {
+
+ NakedDhcpv6Srv srv(0);
+
+ // Let's create a simple SOLICIT
+ Pkt6Ptr sol = captureRelayedSolicit();
+
+ // Simulate that we have received that traffic
+ srv.fakeReceive(sol);
+
+ // Server will now process to run its normal loop, but instead of calling
+ // IfaceMgr::receive6(), it will read all packets from the list set by
+ // fakeReceive()
+ srv.run();
+
+ // Get Advertise...
+ ASSERT_FALSE(srv.fake_sent_.empty());
+ Pkt6Ptr adv = srv.fake_sent_.front();
+ ASSERT_TRUE(adv);
+
+ // This is sent back to relay, so port is 547
+ EXPECT_EQ(DHCP6_SERVER_PORT, adv->getRemotePort());
+}
+
+// Checks if server is able to handle a relayed traffic from DOCSIS3.0 modems
+// @todo Uncomment this test as part of #3180 work.
+// Kea code currently fails to handle docsis traffic.
+TEST_F(Dhcpv6SrvTest, DISABLED_docsisTraffic) {
+
+ NakedDhcpv6Srv srv(0);
+
+ // Let's get a traffic capture from DOCSIS3.0 modem
+ Pkt6Ptr sol = captureDocsisRelayedSolicit();
+
+ // Simulate that we have received that traffic
+ srv.fakeReceive(sol);
+
+ // Server will now process to run its normal loop, but instead of calling
+ // IfaceMgr::receive6(), it will read all packets from the list set by
+ // fakeReceive()
+ srv.run();
+
+ // We should have an Advertise in response
+ ASSERT_FALSE(srv.fake_sent_.empty());
+ Pkt6Ptr adv = srv.fake_sent_.front();
+ ASSERT_TRUE(adv);
+
+ /// @todo Check that the ADVERTISE is ok, that it includes all options,
+ /// that is relayed properly, etc.
+}
/// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test
/// to call processX() methods.
diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h
index eb40d71..38a60f5 100644
--- a/src/bin/dhcp6/tests/dhcp6_test_utils.h
+++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h
@@ -394,6 +394,21 @@ public:
return (lease);
}
+ // see wireshark.cc for descriptions
+ // The descriptions are too large and too closely related to the
+ // code, so it is kept in .cc rather than traditionally in .h
+ Pkt6Ptr captureSimpleSolicit();
+ Pkt6Ptr captureRelayedSolicit();
+ Pkt6Ptr captureDocsisRelayedSolicit();
+
+
+ /// @brief Auxiliary method that sets Pkt6 fields
+ ///
+ /// Used to reconstruct captured packets. Sets UDP ports, interface names,
+ /// and other fields to some believable values.
+ /// @param pkt packet that will have its fields set
+ void captureSetDefaultFields(const Pkt6Ptr& pkt);
+
~Dhcpv6SrvTest() {
CfgMgr::instance().deleteSubnets6();
};
diff --git a/src/bin/dhcp6/tests/hooks_unittest.cc b/src/bin/dhcp6/tests/hooks_unittest.cc
index a9df50f..5d0a7cf 100644
--- a/src/bin/dhcp6/tests/hooks_unittest.cc
+++ b/src/bin/dhcp6/tests/hooks_unittest.cc
@@ -85,33 +85,6 @@ TEST_F(Dhcpv6SrvTest, Hooks) {
EXPECT_TRUE(hook_index_lease6_release > 0);
}
-// This function returns buffer for very simple Solicit
-Pkt6* captureSimpleSolicit() {
- Pkt6* pkt;
- uint8_t data[] = {
- 1, // type 1 = SOLICIT
- 0xca, 0xfe, 0x01, // trans-id = 0xcafe01
- 0, 1, // option type 1 (client-id)
- 0, 10, // option lenth 10
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // DUID
- 0, 3, // option type 3 (IA_NA)
- 0, 12, // option length 12
- 0, 0, 0, 1, // iaid = 1
- 0, 0, 0, 0, // T1 = 0
- 0, 0, 0, 0 // T2 = 0
- };
-
- pkt = new Pkt6(data, sizeof(data));
- pkt->setRemotePort(546);
- pkt->setRemoteAddr(IOAddress("fe80::1"));
- pkt->setLocalPort(0);
- pkt->setLocalAddr(IOAddress("ff02::1:2"));
- pkt->setIndex(2);
- pkt->setIface("eth0");
-
- return (pkt);
-}
-
/// @brief a class dedicated to Hooks testing in DHCPv6 server
///
/// This class has a number of static members, because each non-static
diff --git a/src/bin/dhcp6/tests/wireshark.cc b/src/bin/dhcp6/tests/wireshark.cc
new file mode 100644
index 0000000..4e96548
--- /dev/null
+++ b/src/bin/dhcp6/tests/wireshark.cc
@@ -0,0 +1,163 @@
+// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <dhcp6/tests/dhcp6_test_utils.h>
+#include <string>
+
+/// @file wireshark.cc
+///
+/// @brief contains packet captures imported from Wireshark
+///
+/// These are actual packets captured over wire. They are used in various
+/// tests.
+///
+/// The procedure to export Wireshark -> unit-tests is manual, but rather
+/// easy to follow:
+/// 1. Open a file in wireshark
+/// 2. Find the packet you want to export
+/// 3. There's a protocol stack (Frame, Ethernet, IPv6, UDP, DHCPv6, ...)
+/// 4. Right click on DHCPv6 -> Copy -> Bytes -> Hex Stream
+/// 5. Paste it as: string hex_string="[paste here]";
+/// 6. Coding guidelines line restrictions apply, so wrap your code as necessary
+/// 7. Make sure you decribe the capture appropriately
+/// 8. Follow whatever rest of the methods are doing (set ports, ifaces etc.)
+
+using namespace std;
+
+namespace isc {
+namespace test {
+
+void Dhcpv6SrvTest::captureSetDefaultFields(const Pkt6Ptr& pkt) {
+ pkt->setRemotePort(546);
+ pkt->setRemoteAddr(IOAddress("fe80::1"));
+ pkt->setLocalPort(0);
+ pkt->setLocalAddr(IOAddress("ff02::1:2"));
+ pkt->setIndex(2);
+ pkt->setIface("eth0");
+}
+
+// This function returns buffer for very simple Solicit
+Pkt6Ptr Dhcpv6SrvTest::captureSimpleSolicit() {
+ uint8_t data[] = {
+ 1, // type 1 = SOLICIT
+ 0xca, 0xfe, 0x01, // trans-id = 0xcafe01
+ 0, 1, // option type 1 (client-id)
+ 0, 10, // option lenth 10
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // DUID
+ 0, 3, // option type 3 (IA_NA)
+ 0, 12, // option length 12
+ 0, 0, 0, 1, // iaid = 1
+ 0, 0, 0, 0, // T1 = 0
+ 0, 0, 0, 0 // T2 = 0
+ };
+
+ Pkt6Ptr pkt(new Pkt6(data, sizeof(data)));
+ captureSetDefaultFields(pkt);
+
+ return (pkt);
+}
+
+Pkt6Ptr Dhcpv6SrvTest::captureRelayedSolicit() {
+
+ // This is a very simple relayed SOLICIT message:
+ // RELAY-FORW
+ // - interface-id
+ // - relay-message
+ // - SOLICIT
+ // - client-id
+ // - IA_NA (iaid=1, t1=0, t2=0)
+ // - ORO (7)
+
+ // string exported from Wireshark
+ string hex_string =
+ "0c0500000000000000000000000000000000fc00000000000000000000000000000900"
+ "12000231350009002c010517100001000e0001000151b5e46208002758f1e80003000c"
+ "000000010000000000000000000600020007";
+
+ std::vector<uint8_t> bin;
+
+ // Decode the hex string and store it in bin (which happens
+ // to be OptionBuffer format)
+ isc::util::encode::decodeHex(hex_string, bin);
+
+ Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size()));
+ captureSetDefaultFields(pkt);
+
+ return (pkt);
+}
+
+/// returns a buffer with relayed SOLICIT (from DOCSIS3.0 cable modem)
+Pkt6Ptr isc::test::Dhcpv6SrvTest::captureDocsisRelayedSolicit() {
+
+ // This is an actual DOCSIS packet
+ // RELAY-FORW (12)
+ // - Relay Message
+ // - SOLICIT (1)
+ // - client-id
+ // - IA_NA (iaid=7f000788, t2=0, t2=0)
+ // - IAAddress (::, pref=0,valid=0)
+ // - rapid-commit
+ // - ORO
+ // - Reconfigure-accept
+ // - Vendor-Class ("docsis3.0")
+ // - Vendor-specific Info
+ // - subopt 1: Option request = 32,33,34,37,38
+ // - subopt 36: Device identifier
+ // - subopt 35: TLV5
+ // - subopt 2: Device type = ECM
+ // - subopt 3: Embedded components
+ // - subopt 4: Serial Number
+ // - subopt 5: Hardware version
+ // - subopt 6: Software version
+ // - subopt 7: Boot ROM Version
+ // - subopt 8: Organization Unique Identifier
+ // - subopt 9: Model Number
+ // - subopt 10: Vendor Name (Netgear)
+ // - subopt 15: unknown
+ // - Interface-Id
+ // - Vendor-specific Information
+ // - Suboption 1025: CMTS capabilities
+ // - Suboption 1026: Cable Modem MAC addr = 10:0d:7f:00:07:88
+
+ // string exported from Wireshark
+ string hex_string =
+ "0c002a0288fe00fe00015a8d09fffe7af955fe80000000000000120d7ffffe00078800"
+ "090189010d397f0001000a00030001100d7f000788000300287f000788000000000000"
+ "000000050018000000000000000000000000000000000000000000000000000e000000"
+ "0800020000000600020011001400000010000f0000118b0009646f63736973332e3000"
+ "1101200000118b0001000a0020002100220025002600240006100d7f00078800230081"
+ "0101010201030301010401010501010601010701180801080901000a01010b01180c01"
+ "010d0200400e0200100f01011004000000021101011301011401001501381601011701"
+ "011801041901041a01041b01281c01021d01081e01201f011020011821010222010123"
+ "010124011825010126020040270101120701100d7f00078a0002000345434d0003000b"
+ "45434d3a45524f555445520004000d3335463132395550303030353200050004332e31"
+ "310006000956312e30312e31315400070013505350552d426f6f7420312e302e31362e"
+ "323200080006303030393542000900084347343030305444000a00074e657467656172"
+ "000f000745524f5554455200120012427531264361312f3000100d7f00078800000011"
+ "00160000118b040100040102030004020006100d7f000788";
+
+ std::vector<uint8_t> bin;
+
+ // Decode the hex string and store it in bin (which happens
+ // to be OptionBuffer format)
+ isc::util::encode::decodeHex(hex_string, bin);
+
+ Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size()));
+ captureSetDefaultFields(pkt);
+ return (pkt);
+}
+
+}; // end of isc::test namespace
+}; // end of isc namespace
More information about the bind10-changes
mailing list