:name_(name), ifindex_(ifindex), mac_len_(0), hardware_type_(0),
flag_loopback_(false), flag_up_(false), flag_running_(false),
flag_multicast_(false), flag_broadcast_(false), flags_(0),
- inactive4_(false), inactive6_(false)
+ inactive4_(false), inactive6_(false), read_buffer_()
{
memset(mac_, 0, sizeof(mac_));
}
return (false); // socket not found
}
+uint8_t*
+Iface::getReadBufferPtr() {
+ if (read_buffer_.empty()) {
+ return (NULL);
+ }
+ return (static_cast<uint8_t*>(&read_buffer_[0]));
+}
+
IfaceMgr::IfaceMgr()
:control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))),
control_buf_(new char[control_buf_len_]),
#include <dhcp/pkt6.h>
#include <dhcp/pkt_filter.h>
#include <dhcp/pkt_filter6.h>
+#include <dhcp/option.h>
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
};
-
/// @brief Represents a single network interface
///
/// Iface structure represents network interface with all useful
return unicasts_;
}
+ /// @brief Returns the pointer to the buffer used for data reading.
+ ///
+ /// The returned pointer is only valid during the lifetime of the
+ /// object which returns it or until the buffer is resized.
+ /// This function is meant to be used with socket API to gather
+ /// data from the socket. In order to process the read data,
+ /// the @c getReadBuffer function should be used.
+ ///
+ /// @return Pointer to the first element of the read buffer or
+ /// NULL if the buffer is empty.
+ uint8_t* getReadBufferPtr();
+
+ /// @brief Returns reference to the buffer used for data reading.
+ ///
+ /// The returned reference is only valid during the lifetime of the
+ /// object which returns it or until the buffer is resized.
+ ///
+ /// @return Reference to the read buffer.
+ const OptionBuffer& getReadBuffer() const {
+ return (read_buffer_);
+ }
+
+ /// @brief Returns the current size of the socket read buffer.
+ size_t getReadBufferSize() const {
+ return (read_buffer_.size());
+ }
+
+ /// @brief Resizes the socket read buffer.
+ ///
+ /// @param new_size New size of the buffer.
+ void resizeReadBuffer(const size_t new_size) {
+ read_buffer_.resize(new_size);
+ }
+
protected:
/// Socket used to send data.
SocketCollection sockets_;
/// Indicates that IPv6 sockets should (true) or should not (false)
/// be opened on this interface.
bool inactive6_;
+
+ /// @brief Buffer holding the data read from the socket.
+ ///
+ /// This buffer may be pre-allocated when the socket on the interface
+ /// is being opened. The functions which read the data from the socket
+ /// may use this buffer as a storage for the data being read.
+ OptionBuffer read_buffer_;
};
/// @brief This type describes the callback function invoked when error occurs
#include <asiolink/io_address.h>
#include <dhcp/dhcp4.h>
#include <dhcp/iface_mgr.h>
+#include <dhcp/option.h>
#include <dhcp/pkt6.h>
#include <dhcp/pkt_filter.h>
#include <dhcp/tests/iface_mgr_test_config.h>
// tolerance to 0.01s.
const uint32_t TIMEOUT_TOLERANCE = 10000;
+/// This test verifies that the socket read buffer can be used to
+/// receive the data and that the data can be read from it.
+TEST(IfaceTest, readBuffer) {
+ // Create fake interface object.
+ Iface iface("em0", 0);
+ // The size of read buffer should initially be 0 and the returned
+ // pointer should be NULL.
+ ASSERT_EQ(0, iface.getReadBufferSize());
+ EXPECT_EQ(NULL, iface.getReadBufferPtr());
+
+ // Let's resize the buffer.
+ iface.resizeReadBuffer(256);
+ // Check that the buffer has expected size.
+ ASSERT_EQ(256, iface.getReadBufferSize());
+ // The returned pointer should now be non-NULL.
+ uint8_t* buf_ptr = iface.getReadBufferPtr();
+ ASSERT_FALSE(buf_ptr == NULL);
+
+ // Use the pointer to set some data.
+ for (int i = 0; i < iface.getReadBufferSize(); ++i) {
+ buf_ptr[i] = i;
+ }
+
+ // Validate the data.
+ const OptionBuffer& buf = iface.getReadBuffer();
+ ASSERT_EQ(256, buf.size());
+ for (int i = 0; i < buf.size(); ++i) {
+ // Use assert so as it fails on the first failure, no need
+ // to continue further checks.
+ ASSERT_EQ(i, buf[i]);
+ }
+}
+
/// Mock object implementing PktFilter class. It is used by
/// IfaceMgrTest::setPacketFilter to verify that IfaceMgr::setPacketFilter
/// sets this object as a handler for opening sockets. This dummy