]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1132] testing mode send to source enabled for kea4
authorWlodek Wencel <wlodek@isc.org>
Thu, 16 Apr 2020 10:33:59 +0000 (12:33 +0200)
committerFrancis Dupont <fdupont@isc.org>
Thu, 23 Apr 2020 13:36:12 +0000 (15:36 +0200)
src/bin/dhcp4/dhcp4_messages.cc
src/bin/dhcp4/dhcp4_messages.h
src/bin/dhcp4/dhcp4_messages.mes
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/dhcp4_srv.h
src/bin/dhcp4/tests/shared_network_unittest.cc

index f4ed874589efeeeec96cb6d14987beaac8a75c00..9bdb9df2d051db2d4fea47ce6c5455fb774e3857 100644 (file)
@@ -143,6 +143,7 @@ extern const isc::log::MessageID DHCP4_SUBNET_DATA = "DHCP4_SUBNET_DATA";
 extern const isc::log::MessageID DHCP4_SUBNET_DYNAMICALLY_CHANGED = "DHCP4_SUBNET_DYNAMICALLY_CHANGED";
 extern const isc::log::MessageID DHCP4_SUBNET_SELECTED = "DHCP4_SUBNET_SELECTED";
 extern const isc::log::MessageID DHCP4_SUBNET_SELECTION_FAILED = "DHCP4_SUBNET_SELECTION_FAILED";
+extern const isc::log::MessageID DHCP4_TESTING_MODE_SEND_TO_SOURCE_ENABLED = "DHCP4_TESTING_MODE_SEND_TO_SOURCE_ENABLED";
 extern const isc::log::MessageID DHCP6_DHCP4O6_PACKET_RECEIVED = "DHCP6_DHCP4O6_PACKET_RECEIVED";
 
 } // namespace dhcp
@@ -287,6 +288,7 @@ const char* values[] = {
     "DHCP4_SUBNET_DYNAMICALLY_CHANGED", "%1: changed selected subnet %2 to subnet %3 from shared network %4 for client assignments",
     "DHCP4_SUBNET_SELECTED", "%1: the subnet with ID %2 was selected for client assignments",
     "DHCP4_SUBNET_SELECTION_FAILED", "%1: failed to select subnet for the client",
+    "DHCP4_TESTING_MODE_SEND_TO_SOURCE_ENABLED", "All packets will be send to source address of an incoming packet - use only for testing",
     "DHCP6_DHCP4O6_PACKET_RECEIVED", "received DHCPv4o6 packet from DHCPv6 server (type %1) for %2 port %3 on interface %4",
     NULL
 };
index fc649fe66f04a24cbe0ac61c6f7cfbb02cb58329..2061e44d12dfb12dc146641c31487eee873e4798 100644 (file)
@@ -144,6 +144,7 @@ extern const isc::log::MessageID DHCP4_SUBNET_DATA;
 extern const isc::log::MessageID DHCP4_SUBNET_DYNAMICALLY_CHANGED;
 extern const isc::log::MessageID DHCP4_SUBNET_SELECTED;
 extern const isc::log::MessageID DHCP4_SUBNET_SELECTION_FAILED;
+extern const isc::log::MessageID DHCP4_TESTING_MODE_SEND_TO_SOURCE_ENABLED;
 extern const isc::log::MessageID DHCP6_DHCP4O6_PACKET_RECEIVED;
 
 } // namespace dhcp
index 7b9cc4774c089063b44a2b1bde8e97a7aa221987..7ecbe1e3875e27a0ef5405b78f819ef378858c8f 100644 (file)
@@ -6,6 +6,12 @@
 
 $NAMESPACE isc::dhcp
 
+% DHCP4_TESTING_MODE_SEND_TO_SOURCE_ENABLED All packets will be send to source address of an incoming packet - use only for testing
+This message is printed then KEA_TEST_SEND_RESPONSES_TO_SOURCE environment
+variable is set to ENABLED. It's causing Kea to send packets to source address
+of incoming packet. Usable just in testing environment to simulate multiple
+subnet traffic from single source.
+
 % DHCP4_ACTIVATE_INTERFACE activating interface %1
 This message is printed when DHCPv4 server enabled an interface to be used
 to receive DHCPv4 traffic. IPv4 socket on this interface will be opened once
index 2faee32d7b6d1376cef46f2250c32c6eb96d865b..1a4f68a5bb7f5ca01d40efce982091bc3ec1692d 100644 (file)
@@ -588,6 +588,8 @@ void Dhcpv4Exchange::evaluateClasses(const Pkt4Ptr& pkt, bool depend_on_known) {
 
 const std::string Dhcpv4Srv::VENDOR_CLASS_PREFIX("VENDOR_CLASS_");
 
+bool Dhcpv4Srv::Dhcpv4Srv::test_send_responses_to_source_(false);
+
 Dhcpv4Srv::Dhcpv4Srv(uint16_t server_port, uint16_t client_port,
                      const bool use_bcast, const bool direct_response_desired)
     : io_service_(new IOService()), server_port_(server_port),
@@ -596,6 +598,14 @@ Dhcpv4Srv::Dhcpv4Srv(uint16_t server_port, uint16_t client_port,
       network_state_(new NetworkState(NetworkState::DHCPv4)),
       cb_control_(new CBControlDHCPv4()) {
 
+    const char* env = std::getenv("KEA_TEST_SEND_RESPONSES_TO_SOURCE");
+    if (env) {
+        if (strncmp(env, "ENABLED", 7) == 0) {
+            LOG_WARN(dhcp4_logger, DHCP4_TESTING_MODE_SEND_TO_SOURCE_ENABLED);
+            setSendResponsesToSource(true);
+        }
+    }
+
     LOG_DEBUG(dhcp4_logger, DBG_DHCP4_START, DHCP4_OPEN_SOCKET)
         .arg(server_port);
 
@@ -2716,6 +2726,11 @@ Dhcpv4Srv::adjustRemoteAddr(Dhcpv4Exchange& ex) {
         } else {
             response->setRemoteAddr(query->getRemoteAddr());
         }
+
+        if (getSendResponsesToSource()) {
+            response->setRemoteAddr(query->getRemoteAddr());
+        }
+
         // Remote address is now set so return.
         return;
     }
@@ -2773,6 +2788,10 @@ Dhcpv4Srv::adjustRemoteAddr(Dhcpv4Exchange& ex) {
         response->setRemoteAddr(query->getRemoteAddr());
 
     }
+
+    if (getSendResponsesToSource()) {
+        response->setRemoteAddr(query->getRemoteAddr());
+    }
 }
 
 void
index bc26386a0f6f8aa4e920f32d5a7bb893ea653d28..107d6b4906d332429551f49f24152c6a3a12f954 100644 (file)
@@ -741,6 +741,24 @@ public:
     /// will cause the packet to be assigned to class VENDOR_CLASS_FOO.
     static const std::string VENDOR_CLASS_PREFIX;
 
+    /// @brief This function set test_send_responses_to_source_ value
+    ///
+    /// If environment variable KEA_TEST_SEND_RESPONSES_TO_SOURCE will be
+    /// set to ENABLED this function will set value true to
+    /// test_send_responses_to_source_.
+    ///
+    /// @param bool value of test_send_responses_to_source_
+    void setSendResponsesToSource(const bool value) {
+        test_send_responses_to_source_ = value;
+    }
+
+    /// @brief returns value of test_send_responses_to_source_
+    ///
+    /// @return bool value of test_send_responses_to_source_
+    static bool getSendResponsesToSource() {
+        return test_send_responses_to_source_;
+    }
+
 private:
     /// @brief Process Client FQDN %Option sent by a client.
     ///
@@ -1060,6 +1078,12 @@ protected:
     /// @brief Controls access to the configuration backends.
     CBControlDHCPv4Ptr cb_control_;
 
+private:
+
+    /// @brief value that define is send response to source mode is enabled
+    /// holds ture if it is.
+    static bool test_send_responses_to_source_;
+
 public:
 
     /// Class methods for DHCPv4-over-DHCPv6 handler
index 2a6720b42cd5831952f12daa8277cf8acc5d73f2..427fa3b80affb5507aa34fad795fc36bf8218de9 100644 (file)
@@ -22,6 +22,7 @@
 #include <boost/pointer_cast.hpp>
 #include <boost/shared_ptr.hpp>
 #include <functional>
+#include <stdlib.h>
 
 using namespace isc;
 using namespace isc::asiolink;
@@ -2198,6 +2199,58 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSubnetSelectedByClass) {
     });
 }
 
+// Check if Kea starts with send to source mode enabled
+TEST_F(Dhcpv4SharedNetworkTest, sharedNetworkCheckIfSendToSourceTestingModeEnabled) {
+    // Set env variable that put kea into testing mode
+    setenv("KEA_TEST_SEND_RESPONSES_TO_SOURCE", "ENABLED", 1);
+    Dhcp4Client client1(Dhcp4Client::SELECTING);
+    configure(NETWORKS_CONFIG[1], *client1.getServer());
+    // Check if send to source testing mode is enabled
+    EXPECT_TRUE(isc::dhcp::test::NakedDhcpv4Srv::getSendResponsesToSource());
+
+    unsetenv("KEA_TEST_SEND_RESPONSES_TO_SOURCE");
+}
+
+// Shared network is selected based on giaddr value (relay specified
+// on shared network level, but response is send to source address.
+TEST_F(Dhcpv4SharedNetworkTest, sharedNetworkSendToSourceTestingModeEnabled) {
+    // Create client #1. This is a relayed client which is using relay
+    // address matching configured shared network.
+    // Source address is set to unrelated to configuration.
+
+    // Set env variable that put kea into testing mode
+    //setenv("KEA_TEST_SEND_RESPONSES_TO_SOURCE", "ENABLED", 1);
+    Dhcp4Client client1(Dhcp4Client::SELECTING);
+    client1.useRelay(true, IOAddress("192.3.5.6"), IOAddress("1.1.1.2"));
+    // Configure the server with one shared network and one subnet outside of the
+    // shared network.
+    configure(NETWORKS_CONFIG[1], *client1.getServer());
+    //EXPECT_TRUE(isc::dhcp::test::NakedDhcpv4Srv::getSendResponsesToSource());
+    // Client #1 should be assigned an address from shared network.
+    testAssigned([this, &client1] {
+        doDORA(client1, "192.0.2.63", "192.0.2.63");
+    });
+
+    // normally Kea would send packet to 192.3.5.6 but we want it get from
+    // 1.1.1.2 in send to source testing mode but still with correctly
+    // assigned address.
+    Pkt4Ptr resp1 = client1.getContext().response_;
+    EXPECT_EQ("1.1.1.2", resp1->getLocalAddr().toText());
+
+    // Create client #2. This is a relayed client which is using relay
+    // address matching subnet outside of the shared network.
+    Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING);
+    client2.useRelay(true, IOAddress("192.1.2.3"), IOAddress("2.2.2.3"));
+    testAssigned([this, &client2] {
+        doDORA(client2, "192.0.2.65", "192.0.2.63");
+    });
+
+    Pkt4Ptr resp2 = client2.getContext().response_;
+    EXPECT_EQ("2.2.2.3", resp2->getLocalAddr().toText());
+    // remove variable
+    unsetenv("KEA_TEST_SEND_RESPONSES_TO_SOURCE");
+}
+
 // Verify option processing precedence
 // Order is global < class < shared-network < subnet < pool < host reservation
 TEST_F(Dhcpv4SharedNetworkTest, precedenceGlobal) {