</table>
</section>
- <!-- proper section structure added in ticket 3794, will merge it
- appropiately -->
-
-
- <section id="dummy">
- <title>MERGE ME</title>
- <para>
- <itemizedlist>
- <listitem>
- <simpara><emphasis>subnet[id].total-addresses</emphasis> (integer) -
- this statistic shows the total number of addresses available for the
- DHCPv4 management. In other words, this is the sum of all addresses in
- all configured pools. This statistic changes only during configuration
- changes. Note it does not take into account any addresses that may be
- reserved due to host reservation. The <emphasis>id</emphasis> is the
- subnet-id of a given subnet. This statistic is exposed for each subnet
- separately. This statistic is reset during reconfiguration event.
- </simpara>
- </listitem>
- <listitem>
- <simpara><emphasis>subnet[id].assigned-addresses</emphasis> (integer) -
- this statistic shows the number of assigned addresses in a given subnet.
- This statistic increases every time a new lease is allocated (as a result
- of receiving a DHCPREQUEST message) and is decreased every time a lease is
- released (a DHCPRELEASE message is received). When lease expiration
- is implemented (planned for Kea 1.0), it will also decrease when a lease
- is expired. The <emphasis>id</emphasis> is the subnet-id of a given
- subnet. This statistic is exposed for each subnet separately. This
- statistic is reset during reconfiguration event.
- </simpara>
- </listitem>
- </itemizedlist>
- </para>
- </section>
-
+ <section id="dhcp4-ctrl-channel">
+ <title>Management API for the DHCPv4 server</title>
+ <para>
+ Management API has been introduced in Kea 0.9.2. It allows issuing specific
+ management commands, like statistics retrieval, reconfiguration or shutdown.
+ For more details, see <xref linkend="ctrl-channel" />. Currently the only
+ supported communication channel type is UNIX stream socket. By default there
+ are no sockets open. To instruct Kea to open a socket, the following entry
+ in the configuration file can be used:
+<screen>
+"Dhcp4": {
+ "control-socket": {
+ "socket-type": "unix",
+ "socket-name": <userinput>"/path/to/the/unix/socket"</userinput>
+ },
+
+ "subnet4": [
+ ...
+ ],
+ ...
+}
+</screen>
+ </para>
+
+ <para>
+ Communication over control channel is conducted using JSON structures.
+ See the Control Channel section in the Kea Developer's Guide for more details.
+ </para>
+
+ <para>DHCPv4 server supports <command>statistic-get</command>,
+ <command>statistic-reset</command>, <command>statistic-remove</command>,
+ <command>statistic-get-all</command>, <command>statistic-reset-all</command>
+ and <command>statistic-remove-all</command>, specified in
+ <xref linkend="command-stats"/>. It also supports
+ <command>list-commands</command> and <command>shutdown</command>,
+ specified in <xref linkend="command-list-commands" /> and
+ <xref linkend="command-shutdown" />, respectively.</para>
+ </section>
+
<section id="dhcp4-std">
<title>Supported DHCP Standards</title>
<para>The following standards are currently supported:</para>
EXPECT_EQ(0, CfgMgr::instance().getD2ClientMgr().getQueueSize());
}
- client.setDestAddress(asiolink::IOAddress("2001:db8::1")); // Pretend it's unicast
-
+ // This test verifies that regular Solicit/Adv/Request/Reply exchange will
+ // result in appropriately set statistics.
+ TEST_F(SARRTest, sarrStats) {
+
+ // Let's use one of the existing configurations and tell the client to
+ // ask for an address.
+ Dhcp6Client client;
+ configure(CONFIGS[1], *client.getServer());
+ client.setInterface("eth1");
+ client.useNA();
+
+ // Make sure we ended-up having expected number of subnets configured.
+ const Subnet6Collection* subnets = CfgMgr::instance().getCurrentCfg()->
+ getCfgSubnets6()->getAll();
+ ASSERT_EQ(2, subnets->size());
+
+ // Ok, let's check the statistics. None should be present.
+ using namespace isc::stats;
+ StatsMgr& mgr = StatsMgr::instance();
+ ObservationPtr pkt6_rcvd = mgr.getObservation("pkt6-received");
+ ObservationPtr pkt6_solicit_rcvd = mgr.getObservation("pkt6-solicit-received");
+ ObservationPtr pkt6_adv_sent = mgr.getObservation("pkt6-advertise-sent");
+ ObservationPtr pkt6_request_rcvd = mgr.getObservation("pkt6-request-received");
+ ObservationPtr pkt6_reply_sent = mgr.getObservation("pkt6-reply-sent");
+ ObservationPtr pkt6_sent = mgr.getObservation("pkt6-sent");
+ EXPECT_FALSE(pkt6_rcvd);
+ EXPECT_FALSE(pkt6_solicit_rcvd);
+ EXPECT_FALSE(pkt6_adv_sent);
+ EXPECT_FALSE(pkt6_request_rcvd);
+ EXPECT_FALSE(pkt6_reply_sent);
+ EXPECT_FALSE(pkt6_sent);
+
+ // Perform 4-way exchange.
+ ASSERT_NO_THROW(client.doSARR());
+ // Server should have assigned a prefix.
+ ASSERT_EQ(1, client.getLeaseNum());
+
+ // All expected statstics must be present now.
+ pkt6_rcvd = mgr.getObservation("pkt6-received");
+ pkt6_solicit_rcvd = mgr.getObservation("pkt6-solicit-received");
+ pkt6_adv_sent = mgr.getObservation("pkt6-advertise-sent");
+ pkt6_request_rcvd = mgr.getObservation("pkt6-request-received");
+ pkt6_reply_sent = mgr.getObservation("pkt6-reply-sent");
+ pkt6_sent = mgr.getObservation("pkt6-sent");
+ ASSERT_TRUE(pkt6_rcvd);
+ ASSERT_TRUE(pkt6_solicit_rcvd);
+ ASSERT_TRUE(pkt6_adv_sent);
+ ASSERT_TRUE(pkt6_request_rcvd);
+ ASSERT_TRUE(pkt6_reply_sent);
+ ASSERT_TRUE(pkt6_sent);
+
+ // They also must have expected values.
+ EXPECT_EQ(2, pkt6_rcvd->getInteger().first);
+ EXPECT_EQ(1, pkt6_solicit_rcvd->getInteger().first);
+ EXPECT_EQ(1, pkt6_adv_sent->getInteger().first);
+ EXPECT_EQ(1, pkt6_request_rcvd->getInteger().first);
+ EXPECT_EQ(1, pkt6_reply_sent->getInteger().first);
+ EXPECT_EQ(2, pkt6_sent->getInteger().first);
+ }
+
+ // This test verifies that pkt6-receive-drop is increased properly when the
+ // client's packet is rejected due to mismatched server-id value.
+ TEST_F(SARRTest, pkt6ReceiveDropStat1) {
+
+ // Dummy server-id (0xff repeated 10 times)
+ std::vector<uint8_t> data(10, 0xff);
+ OptionPtr bogus_srv_id(new Option(Option::V6, D6O_SERVERID, data));
+
+ // Let's use one of the existing configurations and tell the client to
+ // ask for an address.
+ Dhcp6Client client;
+ configure(CONFIGS[1], *client.getServer());
+ client.setInterface("eth1");
+ client.useNA();
+
+ client.doSolicit();
+ client.useServerId(bogus_srv_id);
+ client.doRequest();
+
+ // Ok, let's check the statistic. pkt6-receive-drop should be set to 1.
+ using namespace isc::stats;
+ StatsMgr& mgr = StatsMgr::instance();
+
+ ObservationPtr pkt6_recv_drop = mgr.getObservation("pkt6-receive-drop");
+ ASSERT_TRUE(pkt6_recv_drop);
+
+ EXPECT_EQ(1, pkt6_recv_drop->getInteger().first);
+ }
+
+ // This test verifies that pkt6-receive-drop is increased properly when the
+ // client's packet is rejected due to being unicast communication.
+ TEST_F(SARRTest, pkt6ReceiveDropStat2) {
+
+ // Let's use one of the existing configurations and tell the client to
+ // ask for an address.
+ Dhcp6Client client;
+ configure(CONFIGS[1], *client.getServer());
+ client.setInterface("eth1");
+ client.useNA();
+
+ client.setDestAddress(asiolink::IOAddress("2001:db8::1")); // Pretend it's unicast
+ client.doSolicit();
+
+ // Ok, let's check the statistic. pkt6-receive-drop should be set to 1.
+ using namespace isc::stats;
+ StatsMgr& mgr = StatsMgr::instance();
+
+ ObservationPtr pkt6_recv_drop = mgr.getObservation("pkt6-receive-drop");
+ ASSERT_TRUE(pkt6_recv_drop);
+
+ EXPECT_EQ(1, pkt6_recv_drop->getInteger().first);
+ }
+
+ // This test verifies that pkt6-receive-drop is increased properly when the
+ // client's packet is rejected due to having too many client-id options
+ // (exactly one is expected).
+ TEST_F(SARRTest, pkt6ReceiveDropStat3) {
+
+ // Let's use one of the existing configurations and tell the client to
+ // ask for an address.
+ Dhcp6Client client;
+ configure(CONFIGS[1], *client.getServer());
+ client.setInterface("eth1");
+ client.useNA();
+
+ // Let's send our client-id as server-id. That will result in the
+ // packet containing the client-id twice. That should cause RFCViolation
+ // exception.
+ client.useServerId(client.getClientId());
+ client.doSolicit();
+
+ // Ok, let's check the statistic. pkt6-receive-drop should be set to 1.
+ using namespace isc::stats;
+ StatsMgr& mgr = StatsMgr::instance();
+
+ ObservationPtr pkt6_recv_drop = mgr.getObservation("pkt6-receive-drop");
+ ASSERT_TRUE(pkt6_recv_drop);
+
+ EXPECT_EQ(1, pkt6_recv_drop->getInteger().first);
+ }
+
} // end of anonymous namespace