Commit 47e709fb authored by Francis Dupont's avatar Francis Dupont Committed by Tomek Mrugalski

[677-kea4-not-honouring-the-p-switch] Improved -p support

parent e6814e9f
...@@ -466,7 +466,7 @@ const std::string Dhcpv4Srv::VENDOR_CLASS_PREFIX("VENDOR_CLASS_"); ...@@ -466,7 +466,7 @@ const std::string Dhcpv4Srv::VENDOR_CLASS_PREFIX("VENDOR_CLASS_");
Dhcpv4Srv::Dhcpv4Srv(uint16_t server_port, uint16_t client_port, Dhcpv4Srv::Dhcpv4Srv(uint16_t server_port, uint16_t client_port,
const bool use_bcast, const bool direct_response_desired) const bool use_bcast, const bool direct_response_desired)
: io_service_(new IOService()), shutdown_(true), alloc_engine_(), : io_service_(new IOService()), shutdown_(true), alloc_engine_(),
server_port_(server_port), use_bcast_(use_bcast), use_bcast_(use_bcast), server_port_(server_port),
client_port_(client_port), client_port_(client_port),
network_state_(new NetworkState(NetworkState::DHCPv4)), network_state_(new NetworkState(NetworkState::DHCPv4)),
cb_control_(new CBControlDHCPv4()) { cb_control_(new CBControlDHCPv4()) {
...@@ -2461,7 +2461,11 @@ Dhcpv4Srv::adjustIfaceData(Dhcpv4Exchange& ex) { ...@@ -2461,7 +2461,11 @@ Dhcpv4Srv::adjustIfaceData(Dhcpv4Exchange& ex) {
response->setIface(query->getIface()); response->setIface(query->getIface());
} }
response->setLocalPort(DHCP4_SERVER_PORT); if (server_port_) {
response->setLocalPort(server_port_);
} else {
response->setLocalPort(DHCP4_SERVER_PORT);
}
} }
void void
......
...@@ -984,14 +984,14 @@ private: ...@@ -984,14 +984,14 @@ private:
/// @return Option that contains netmask information /// @return Option that contains netmask information
static OptionPtr getNetmaskOption(const Subnet4Ptr& subnet); static OptionPtr getNetmaskOption(const Subnet4Ptr& subnet);
/// UDP port number on which server listens.
uint16_t server_port_;
/// Should broadcast be enabled on sockets (if true). /// Should broadcast be enabled on sockets (if true).
bool use_bcast_; bool use_bcast_;
protected: protected:
/// UDP port number on which server listens.
uint16_t server_port_;
/// UDP port number to which server sends responses. /// UDP port number to which server sends responses.
uint16_t client_port_; uint16_t client_port_;
......
...@@ -200,8 +200,9 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelay) { ...@@ -200,8 +200,9 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelay) {
// Clear remote address. // Clear remote address.
resp->setRemoteAddr(IOAddress("0.0.0.0")); resp->setRemoteAddr(IOAddress("0.0.0.0"));
// Set the client port. // Set the client and server ports.
srv_.client_port_ = 1234; srv_.client_port_ = 1234;
srv_.server_port_ = 2345;
ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); ASSERT_NO_THROW(srv_.adjustIfaceData(ex));
...@@ -210,6 +211,9 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelay) { ...@@ -210,6 +211,9 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelay) {
// Remote port was enforced to the client port. // Remote port was enforced to the client port.
EXPECT_EQ(srv_.client_port_, resp->getRemotePort()); EXPECT_EQ(srv_.client_port_, resp->getRemotePort());
// Local port was enforced to the server port.
EXPECT_EQ(srv_.server_port_, resp->getLocalPort());
} }
// This test verifies that the remote port is adjusted when // This test verifies that the remote port is adjusted when
...@@ -2125,6 +2129,48 @@ TEST_F(Dhcpv4SrvTest, portsClientPort) { ...@@ -2125,6 +2129,48 @@ TEST_F(Dhcpv4SrvTest, portsClientPort) {
EXPECT_EQ(srv.client_port_, offer->getRemotePort()); EXPECT_EQ(srv.client_port_, offer->getRemotePort());
} }
// Checks if server port can be overridden in packets being sent.
TEST_F(Dhcpv4SrvTest, portsServerPort) {
IfaceMgrTestConfig test_config(true);
IfaceMgr::instance().openSockets4();
// Do not use DHCP4_SERVER_PORT here as 0 means don't open sockets.
NakedDhcpv4Srv srv(0);
EXPECT_EQ(0, srv.server_port_);
// Use of the captured DHCPDISCOVER packet requires that
// subnet 10.254.226.0/24 is in use, because this packet
// contains the giaddr which belongs to this subnet and
// this giaddr is used to select the subnet
configure(CONFIGS[0]);
srv.server_port_ = 1234;
// Let's create a relayed DISCOVER. This particular relayed DISCOVER has
// added option 82 (relay agent info) with 3 suboptions. The server
// is supposed to echo it back in its response.
Pkt4Ptr dis;
ASSERT_NO_THROW(dis = PktCaptures::captureRelayedDiscover());
// Simulate that we have received that traffic
srv.fakeReceive(dis);
// Server will now process to run its normal loop, but instead of calling
// IfaceMgr::receive4(), it will read all packets from the list set by
// fakeReceive()
// In particular, it should call registered buffer4_receive callback.
srv.run();
// Check that the server did send a response
ASSERT_EQ(1, srv.fake_sent_.size());
// Make sure that we received a response
Pkt4Ptr offer = srv.fake_sent_.front();
ASSERT_TRUE(offer);
// Get Relay Agent Info from query...
EXPECT_EQ(srv.server_port_, offer->getLocalPort());
}
/// @todo Implement tests for subnetSelect See tests in dhcp6_srv_unittest.cc: /// @todo Implement tests for subnetSelect See tests in dhcp6_srv_unittest.cc:
/// selectSubnetAddr, selectSubnetIface, selectSubnetRelayLinkaddr, /// selectSubnetAddr, selectSubnetIface, selectSubnetRelayLinkaddr,
/// selectSubnetRelayInterfaceId. Note that the concept of interface-id is not /// selectSubnetRelayInterfaceId. Note that the concept of interface-id is not
......
...@@ -229,6 +229,7 @@ public: ...@@ -229,6 +229,7 @@ public:
using Dhcpv4Srv::VENDOR_CLASS_PREFIX; using Dhcpv4Srv::VENDOR_CLASS_PREFIX;
using Dhcpv4Srv::shutdown_; using Dhcpv4Srv::shutdown_;
using Dhcpv4Srv::alloc_engine_; using Dhcpv4Srv::alloc_engine_;
using Dhcpv4Srv::server_port_;
using Dhcpv4Srv::client_port_; using Dhcpv4Srv::client_port_;
}; };
......
...@@ -835,7 +835,11 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { ...@@ -835,7 +835,11 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) {
rsp->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT); rsp->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT);
} }
rsp->setLocalPort(DHCP6_SERVER_PORT); if (server_port_) {
rsp->setLocalPort(server_port_);
} else {
rsp->setLocalPort(DHCP6_SERVER_PORT);
}
rsp->setIndex(query->getIndex()); rsp->setIndex(query->getIndex());
rsp->setIface(query->getIface()); rsp->setIface(query->getIface());
......
...@@ -999,10 +999,10 @@ private: ...@@ -999,10 +999,10 @@ private:
/// @return true if option has been requested in the ORO. /// @return true if option has been requested in the ORO.
bool requestedInORO(const Pkt6Ptr& query, const uint16_t code) const; bool requestedInORO(const Pkt6Ptr& query, const uint16_t code) const;
protected:
/// UDP port number on which server listens. /// UDP port number on which server listens.
uint16_t server_port_; uint16_t server_port_;
protected:
/// UDP port number to which server sends all responses. /// UDP port number to which server sends all responses.
uint16_t client_port_; uint16_t client_port_;
......
...@@ -3,7 +3,7 @@ kea-dhcp6 ...@@ -3,7 +3,7 @@ kea-dhcp6
Kea Kea
kea-dhcp6 kea-dhcp6
DHCPv6 server in Kea DHCPv6 server in Kea
2011-2018 2011-2019
Internet Systems Consortium, Inc. ("ISC") Internet Systems Consortium, Inc. ("ISC")
kea-dhcp6 kea-dhcp6
-v -v
...@@ -16,6 +16,8 @@ config-file ...@@ -16,6 +16,8 @@ config-file
config-file config-file
-p -p
server-port-number server-port-number
-P
client-port-number
DESCRIPTION DESCRIPTION
=========== ===========
...@@ -52,6 +54,10 @@ The arguments are as follows: ...@@ -52,6 +54,10 @@ The arguments are as follows:
Server port number (1-65535) on which the server listens. This is Server port number (1-65535) on which the server listens. This is
useful for testing purposes only. useful for testing purposes only.
``-P``
Client port number (1-65535) to which the server responds. This is
useful for testing purposes only.
DOCUMENTATION DOCUMENTATION
============= =============
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
<info> <info>
<productname>ISC Kea</productname> <productname>ISC Kea</productname>
<date>Aug 28, 2019</date> <date>Oct 11, 2019</date>
<edition>1.6.0</edition> <edition>1.7.1</edition>
<author> <author>
<contrib>The Kea software has been written by a number of <contrib>The Kea software has been written by a number of
engineers working for ISC: Tomek Mrugalski, Stephen Morris, Marcin engineers working for ISC: Tomek Mrugalski, Stephen Morris, Marcin
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
<arg choice="opt" rep="norepeat"><option>-c <replaceable class="parameter">config-file</replaceable></option></arg> <arg choice="opt" rep="norepeat"><option>-c <replaceable class="parameter">config-file</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-t <replaceable class="parameter">config-file</replaceable></option></arg> <arg choice="opt" rep="norepeat"><option>-t <replaceable class="parameter">config-file</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-p <replaceable class="parameter">server-port-number</replaceable></option></arg> <arg choice="opt" rep="norepeat"><option>-p <replaceable class="parameter">server-port-number</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-P <replaceable class="parameter">client-port-number</replaceable></option></arg>
</cmdsynopsis> </cmdsynopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -123,6 +124,14 @@ ...@@ -123,6 +124,14 @@
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>-P</option></term>
<listitem><para>
Client port number (1-65535) to which the server responds.
This is useful for testing purposes only.
</para></listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
......
...@@ -1967,6 +1967,36 @@ TEST_F(Dhcpv6SrvTest, portsClientPort) { ...@@ -1967,6 +1967,36 @@ TEST_F(Dhcpv6SrvTest, portsClientPort) {
EXPECT_EQ(srv.client_port_, adv->getRemotePort()); EXPECT_EQ(srv.client_port_, adv->getRemotePort());
} }
// Checks if server responses are sent to the proper port.
TEST_F(Dhcpv6SrvTest, portsServerPort) {
// Create the test server in test mode.
NakedDhcpv6Srv srv(0);
// Enforce a specific server port value.
EXPECT_EQ(0, srv.server_port_);
srv.server_port_ = 1234;
// Let's create a simple SOLICIT
Pkt6Ptr sol = PktCaptures::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);
// Verify the local port: it must be the server port.
EXPECT_EQ(srv.server_port_, adv->getLocalPort());
}
// Checks if server responses are sent to the proper port. // Checks if server responses are sent to the proper port.
TEST_F(Dhcpv6SrvTest, portsDirectTraffic) { TEST_F(Dhcpv6SrvTest, portsDirectTraffic) {
......
...@@ -272,6 +272,7 @@ public: ...@@ -272,6 +272,7 @@ public:
using Dhcpv6Srv::name_change_reqs_; using Dhcpv6Srv::name_change_reqs_;
using Dhcpv6Srv::VENDOR_CLASS_PREFIX; using Dhcpv6Srv::VENDOR_CLASS_PREFIX;
using Dhcpv6Srv::initContext; using Dhcpv6Srv::initContext;
using Dhcpv6Srv::server_port_;
using Dhcpv6Srv::client_port_; using Dhcpv6Srv::client_port_;
/// @brief packets we pretend to receive /// @brief packets we pretend to receive
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment