From: Tomek Mrugalski Date: Fri, 17 Feb 2012 18:27:42 +0000 (+0100) Subject: [1540] Changes after review: X-Git-Tag: trac2351_base~240^2~8^2~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=526f8713fb6e13456f7008b5cd075f6fbdb89161;p=thirdparty%2Fkea.git [1540] Changes after review: - port is now specified using uint16_t in IfaceMgr - support for proper DUID generation implemented - implemented new tests - new HWTYPEs defines - unpack methods now return size_t type - comments updated in option*.h headers --- diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 735c39f7fa..638ae051cd 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -59,10 +59,10 @@ Dhcpv4Srv::~Dhcpv4Srv() { bool Dhcpv4Srv::run() { while (!shutdown_) { - Pkt4Ptr query; // client's message - Pkt4Ptr rsp; // server's response - query = IfaceMgr::instance().receive4(); + // client's message + Pkt4Ptr query = IfaceMgr::instance().receive4(); + Pkt4Ptr rsp; // server's response if (query) { try { diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index b2bd5f54ee..a0e2b08e51 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -12,6 +12,7 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +#include #include #include #include @@ -21,11 +22,13 @@ #include #include #include +#include using namespace std; using namespace isc; using namespace isc::dhcp; using namespace isc::asiolink; +using namespace isc::util; const std::string HARDCODED_LEASE = "2001:db8:1::1234:abcd"; const uint32_t HARDCODED_T1 = 1500; // in seconds @@ -67,13 +70,11 @@ Dhcpv6Srv::~Dhcpv6Srv() { IfaceMgr::instance().closeSockets(); } -bool -Dhcpv6Srv::run() { +bool Dhcpv6Srv::run() { while (!shutdown) { - Pkt6Ptr query; // client's message - Pkt6Ptr rsp; // server's response - query = IfaceMgr::instance().receive6(); + Pkt6Ptr query = IfaceMgr::instance().receive6(); // client's message + Pkt6Ptr rsp; // server's response if (query) { if (!query->unpack()) { @@ -138,24 +139,91 @@ Dhcpv6Srv::run() { return (true); } -void -Dhcpv6Srv::setServerID() { - /// TODO implement this for real once interface detection is done. - /// Use hardcoded server-id for now - - OptionBuffer srvid(14); - srvid[0] = 0; - srvid[1] = 1; // DUID type 1 = DUID-LLT (see section 9.2 of RFC3315) - srvid[2] = 0; - srvid[3] = 6; // HW type = ethernet (I think. I'm typing this from my head - // in hotel, without Internet connection) - for (int i=4; i<14; i++) { - srvid[i]=i-4; +void Dhcpv6Srv::setServerID() { + + /// @todo: DUID should be generated once and then stored, rather + /// than generated each time + + /// @todo: This code implements support for DUID-LLT (the recommended one). + /// We should eventually add support for other DUID types: DUID-LL, DUID-EN + /// and DUID-UUID + + const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces(); + + // let's find suitable interface + for (IfaceMgr::IfaceCollection::const_iterator iface = ifaces.begin(); + iface != ifaces.end(); ++iface) { + // all those conditions could be merged into one multi-condition + // statement, but let's keep them separated as perhaps one day + // we will grow knobs to selectively turn them on or off. Also, + // this code is used only *once* during first start on a new machine + // and then server-id is stored. (or at least it will be once + // DUID storage is implemente + + // I wish there was a this_is_a_real_physical_interface flag... + + // mac at least 6 bytes. All decent physical interfaces (Ethernet, + // WiFi, Infiniband, etc.) have 6 bytes long MAC address + if (iface->mac_len_ < 6) { + continue; + } + + // let's don't use loopback + if (iface->flag_loopback_) { + continue; + } + + // let's skip downed interfaces. It is better to use working ones. + if (!iface->flag_up_) { + continue; + } + + uint8_t zeros[IfaceMgr::MAX_MAC_LEN]; + memset(zeros, 0, IfaceMgr::MAX_MAC_LEN); + + // some interfaces (like lo on Linux) report 6-bytes long + // MAC adress 00:00:00:00:00:00. Let's not use such weird interfaces + // to generate DUID. + if (!memcmp(iface->mac_, zeros, iface->mac_len_)) { + continue; + } + + // Ok, we have useful MAC. Let's generate DUID-LLT based on + // it. See RFC3315, Section 9.2 for details. + + // DUID uses seconds since midnight of 01-01-2000, time() returns + // seconds since 01-01-1970. DUID_TIME_EPOCH substution corrects that. + time_t seconds = time(NULL); + seconds -= DUID_TIME_EPOCH; + + OptionBuffer srvid(8 + iface->mac_len_); + writeUint16(DUID_LLT, &srvid[0]); + writeUint16(HWTYPE_ETHERNET, &srvid[2]); + writeUint32(static_cast(seconds), &srvid[4]); + memcpy(&srvid[0]+8, iface->mac_, iface->mac_len_); + + serverid_ = OptionPtr(new Option(Option::V6, D6O_SERVERID, + srvid.begin(), srvid.end())); + return; } - serverid_ = boost::shared_ptr