Browse Source

[github23] Select client port for DHCPINFORM message.

Michal Humpula 9 years ago
parent
commit
bdf81033b6
2 changed files with 8 additions and 4 deletions
  1. 4 4
      src/bin/dhcp4/dhcp4_srv.cc
  2. 4 0
      src/bin/dhcp4/tests/inform_unittest.cc

+ 4 - 4
src/bin/dhcp4/dhcp4_srv.cc

@@ -1777,14 +1777,14 @@ Dhcpv4Srv::adjustIfaceData(Dhcpv4Exchange& ex) {
     Pkt4Ptr response = ex.getResponse();
     Pkt4Ptr response = ex.getResponse();
 
 
     // For the non-relayed message, the destination port is the client's port.
     // For the non-relayed message, the destination port is the client's port.
-    // For the relayed message, the server/relay port is a destination.
+    // For the relayed message, the server/relay port is a destination unless
+    // the message is DHCPINFORM.
     // Note that the call to this function may throw if invalid combination
     // Note that the call to this function may throw if invalid combination
     // of hops and giaddr is found (hops = 0 if giaddr = 0 and hops != 0 if
     // of hops and giaddr is found (hops = 0 if giaddr = 0 and hops != 0 if
     // giaddr != 0). The exception will propagate down and eventually cause the
     // giaddr != 0). The exception will propagate down and eventually cause the
     // packet to be discarded.
     // packet to be discarded.
-    response->setRemotePort(query->isRelayed() ? DHCP4_SERVER_PORT :
-                            DHCP4_CLIENT_PORT);
-
+    const bool server_port = query->isRelayed() && ((query->getType() == DHCPINFORM) ? query->getCiaddr().isV4Zero() : true);
+    response->setRemotePort(server_port ? DHCP4_SERVER_PORT : DHCP4_CLIENT_PORT);
 
 
     IOAddress local_addr = query->getLocalAddr();
     IOAddress local_addr = query->getLocalAddr();
 
 

+ 4 - 0
src/bin/dhcp4/tests/inform_unittest.cc

@@ -303,6 +303,8 @@ TEST_F(InformTest, relayedClient) {
     EXPECT_EQ(IOAddress("192.0.2.56"), resp->getLocalAddr());
     EXPECT_EQ(IOAddress("192.0.2.56"), resp->getLocalAddr());
     // Response is unicast to the client, so it must not be relayed.
     // Response is unicast to the client, so it must not be relayed.
     EXPECT_FALSE(resp->isRelayed());
     EXPECT_FALSE(resp->isRelayed());
+    EXPECT_EQ(DHCP4_CLIENT_PORT, resp->getLocalPort());
+    EXPECT_EQ(DHCP4_SERVER_PORT, resp->getRemotePort());
     // Make sure that the server id is present.
     // Make sure that the server id is present.
     EXPECT_EQ("10.0.0.1", client.config_.serverid_.toText());
     EXPECT_EQ("10.0.0.1", client.config_.serverid_.toText());
     // Make sure that the Routers option has been received.
     // Make sure that the Routers option has been received.
@@ -342,6 +344,8 @@ TEST_F(InformTest, relayedClientNoCiaddr) {
     EXPECT_EQ(IOAddress("192.0.2.2"), resp->getLocalAddr());
     EXPECT_EQ(IOAddress("192.0.2.2"), resp->getLocalAddr());
     EXPECT_EQ(IOAddress("192.0.2.2"), resp->getGiaddr());
     EXPECT_EQ(IOAddress("192.0.2.2"), resp->getGiaddr());
     EXPECT_EQ(1, resp->getHops());
     EXPECT_EQ(1, resp->getHops());
+    EXPECT_EQ(DHCP4_SERVER_PORT, resp->getLocalPort());
+    EXPECT_EQ(DHCP4_SERVER_PORT, resp->getRemotePort());
     // In the case when the client didn't set the ciaddr and the message
     // In the case when the client didn't set the ciaddr and the message
     // was received via relay the server sets the Broadcast flag to help
     // was received via relay the server sets the Broadcast flag to help
     // the relay forwarding the message (without yiaddr) to the client.
     // the relay forwarding the message (without yiaddr) to the client.