Commit 9cd5b8d8 authored by Marcin Siodelski's avatar Marcin Siodelski

[1956] Added timestamp update mechanism to pkt6 and pkt4 classes.

parent 0a3638e4
......@@ -31,3 +31,4 @@ libdhcp___la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
libdhcp___la_LIBADD = $(top_builddir)/src/lib/asiolink/libasiolink.la
libdhcp___la_LIBADD += $(top_builddir)/src/lib/util/libutil.la
libdhcp___la_LDFLAGS = -no-undefined -version-info 1:0:0
libdhcp___la_LDFLAGS += $(CLOCK_GETTIME_LDFLAGS)
......@@ -597,6 +597,8 @@ IfaceMgr::send(const Pkt6Ptr& pkt) {
pktinfo->ipi6_ifindex = pkt->getIndex();
m.msg_controllen = cmsg->cmsg_len;
pkt->updateTimestamp();
result = sendmsg(getSocket(*pkt), &m, 0);
if (result < 0) {
isc_throw(Unexpected, "Pkt6 send failed: sendmsg() returned " << result);
......@@ -656,6 +658,8 @@ IfaceMgr::send(const Pkt4Ptr& pkt)
<< " over socket " << getSocket(*pkt) << " on interface "
<< getIface(pkt->getIface())->getFullName() << endl;
pkt->updateTimestamp();
int result = sendmsg(getSocket(*pkt), &m, 0);
if (result < 0) {
isc_throw(Unexpected, "Pkt4 send failed.");
......@@ -746,6 +750,8 @@ IfaceMgr::receive4() {
// We have all data let's create Pkt4 object.
Pkt4Ptr pkt = Pkt4Ptr(new Pkt4(buf, result));
pkt->updateTimestamp();
unsigned int ifindex = iface->getIndex();
IOAddress from(htonl(from_addr.sin_addr.s_addr));
......@@ -890,6 +896,8 @@ Pkt6Ptr IfaceMgr::receive6() {
return (Pkt6Ptr()); // NULL
}
pkt->updateTimestamp();
pkt->setLocalAddr(IOAddress::from_bytes(AF_INET6,
reinterpret_cast<const uint8_t*>(&to_addr)));
pkt->setRemoteAddr(IOAddress::from_bytes(AF_INET6,
......
......@@ -53,6 +53,7 @@ Pkt4::Pkt4(uint8_t msg_type, uint32_t transid)
memset(chaddr_, 0, MAX_CHADDR_LEN);
memset(sname_, 0, MAX_SNAME_LEN);
memset(file_, 0, MAX_FILE_LEN);
memset(&timestamp_, 0, sizeof(timestamp_));
}
Pkt4::Pkt4(const uint8_t* data, size_t len)
......@@ -81,6 +82,7 @@ Pkt4::Pkt4(const uint8_t* data, size_t len)
data_.resize(len);
memcpy(&data_[0], data, len);
memset(&timestamp_, 0, sizeof(timestamp_));
}
size_t
......@@ -305,6 +307,13 @@ Pkt4::getOption(uint8_t type) {
return boost::shared_ptr<isc::dhcp::Option>(); // NULL
}
void
Pkt4::updateTimestamp() {
if (clock_gettime(CLOCK_REALTIME, &timestamp_) < 0) {
isc_throw(isc::Unexpected, "Failed to get timestamp for packet");
}
}
} // end of namespace isc::dhcp
} // end of namespace isc
......@@ -16,6 +16,7 @@
#define PKT4_H
#include <iostream>
#include <time.h>
#include <vector>
#include <boost/shared_ptr.hpp>
#include "asiolink/io_address.h"
......@@ -321,6 +322,14 @@ public:
/// @return interface name
std::string getIface() const { return iface_; };
/// @brief Returns packet timestamp.
///
/// Returns packet timestamp value updated when
/// packet is received or send.
///
/// @return packet timestamp.
timespec getTimestamp() const { return timestamp_; }
/// @brief Sets interface name.
///
/// Sets interface name over which packet was received or is
......@@ -387,6 +396,14 @@ public:
/// @return remote port
uint16_t getRemotePort() { return (remote_port_); }
/// @brief Update packet timestamp.
///
/// Updates packet timestamp. This method is invoked
/// by interface manager just before sending or
/// just after receiving it.
/// @throw isc::Unexpected if timestamp update failed
void updateTimestamp();
protected:
/// converts DHCP message type to BOOTP op type
......@@ -485,6 +502,9 @@ protected:
/// collection of options present in this message
isc::dhcp::Option::OptionCollection options_;
/// packet timestamp
timespec timestamp_;
}; // Pkt4 class
typedef boost::shared_ptr<Pkt4> Pkt4Ptr;
......
......@@ -38,6 +38,7 @@ Pkt6::Pkt6(const uint8_t* buf, uint32_t buf_len, DHCPv6Proto proto /* = UDP */)
bufferOut_(0) {
data_.resize(buf_len);
memcpy(&data_[0], buf, buf_len);
memset(&timestamp_, 0, sizeof(timestamp_));
}
Pkt6::Pkt6(uint8_t msg_type, uint32_t transid, DHCPv6Proto proto /*= UDP*/) :
......@@ -51,6 +52,7 @@ Pkt6::Pkt6(uint8_t msg_type, uint32_t transid, DHCPv6Proto proto /*= UDP*/) :
local_port_(0),
remote_port_(0),
bufferOut_(0) {
memset(&timestamp_, 0, sizeof(timestamp_));
}
uint16_t Pkt6::len() {
......@@ -202,5 +204,13 @@ void Pkt6::repack() {
bufferOut_.writeData(&data_[0], data_.size());
}
void
Pkt6::updateTimestamp() {
if (clock_gettime(CLOCK_REALTIME, &timestamp_) < 0) {
isc_throw(isc::Unexpected, "Failed to get timestamp for packet");
}
}
} // end of isc::dhcp namespace
} // end of isc namespace
......@@ -16,6 +16,7 @@
#define PKT6_H
#include <iostream>
#include <time.h>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include "asiolink/io_address.h"
......@@ -220,6 +221,14 @@ public:
/// @return interface name
std::string getIface() const { return iface_; };
/// @brief Returns packet timestamp.
///
/// Returns packet timestamp value updated when
/// packet is received or send.
///
/// @return packet timestamp.
timespec getTimestamp() const { return timestamp_; }
/// @brief Sets interface name.
///
/// Sets interface name over which packet was received or is
......@@ -233,6 +242,14 @@ public:
/// collection of options present in this message
isc::dhcp::Option::OptionCollection options_;
/// @brief Update packet timestamp.
///
/// Updates packet timestamp. This method is invoked
/// by interface manager just before sending or
/// just after receiving it.
/// @throw isc::Unexpected if timestamp update failed
void updateTimestamp();
protected:
/// Builds on wire packet for TCP transmission.
///
......@@ -305,6 +322,9 @@ protected:
/// output buffer (used during message transmission)
isc::util::OutputBuffer bufferOut_;
/// packet timestamp
timespec timestamp_;
}; // Pkt6 class
typedef boost::shared_ptr<Pkt6> Pkt6Ptr;
......
......@@ -33,7 +33,7 @@ libdhcp___unittests_SOURCES += ../pkt6.h ../pkt6.cc pkt6_unittest.cc
libdhcp___unittests_SOURCES += ../pkt4.h ../pkt4.cc pkt4_unittest.cc
libdhcp___unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
libdhcp___unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
libdhcp___unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(CLOCK_GETTIME_LDFLAGS)
libdhcp___unittests_CXXFLAGS = $(AM_CXXFLAGS)
......
......@@ -598,4 +598,16 @@ TEST(Pkt4Test, metaFields) {
delete pkt;
}
TEST(Pkt4Test, Timestamp) {
Pkt4* pkt = new Pkt4(DHCPOFFER, 1234);
ASSERT_NO_THROW(pkt->updateTimestamp());
timespec ts_packet = pkt->getTimestamp();
timespec ts_now;
ASSERT_FALSE(clock_gettime(CLOCK_REALTIME, &ts_now) < 0);
EXPECT_TRUE(ts_packet.tv_sec >= ts_now.tv_sec);
delete pkt;
}
} // end of anonymous namespace
......@@ -204,4 +204,13 @@ TEST_F(Pkt6Test, addGetDelOptions) {
delete parent;
}
TEST_F(Pkt6Test, Timestamp) {
Pkt6* pkt = new Pkt6(DHCPV6_SOLICIT, 0x020304);
ASSERT_NO_THROW(pkt->updateTimestamp());
timespec ts_packet = pkt->getTimestamp();
timespec ts_now;
ASSERT_FALSE(clock_gettime(CLOCK_REALTIME, &ts_now) < 0);
EXPECT_TRUE(ts_packet.tv_sec >= ts_now.tv_sec);
}
}
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