Browse Source

[991] Moved Iface class out of IfaceMgr.

Marcin Siodelski 12 years ago
parent
commit
d9b1da77a3

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

@@ -287,9 +287,9 @@ Dhcpv4Srv::generateServerID() {
             continue;
         }
 
-        const IfaceMgr::AddressCollection addrs = iface->getAddresses();
+        const Iface::AddressCollection addrs = iface->getAddresses();
 
-        for (IfaceMgr::AddressCollection::const_iterator addr = addrs.begin();
+        for (Iface::AddressCollection::const_iterator addr = addrs.begin();
              addr != addrs.end(); ++addr) {
             if (addr->getFamily() != AF_INET) {
                 continue;

+ 36 - 36
src/lib/dhcp/iface_mgr.cc

@@ -48,7 +48,7 @@ IfaceMgr::instance() {
     return (iface_mgr);
 }
 
-IfaceMgr::Iface::Iface(const std::string& name, int ifindex)
+Iface::Iface(const std::string& name, int ifindex)
     :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)
@@ -57,7 +57,7 @@ IfaceMgr::Iface::Iface(const std::string& name, int ifindex)
 }
 
 void
-IfaceMgr::Iface::closeSockets() {
+Iface::closeSockets() {
     for (SocketCollection::iterator sock = sockets_.begin();
          sock != sockets_.end(); ++sock) {
         close(sock->sockfd_);
@@ -66,14 +66,14 @@ IfaceMgr::Iface::closeSockets() {
 }
 
 std::string
-IfaceMgr::Iface::getFullName() const {
+Iface::getFullName() const {
     ostringstream tmp;
     tmp << name_ << "/" << ifindex_;
     return (tmp.str());
 }
 
 std::string
-IfaceMgr::Iface::getPlainMac() const {
+Iface::getPlainMac() const {
     ostringstream tmp;
     tmp.fill('0');
     tmp << hex;
@@ -87,18 +87,18 @@ IfaceMgr::Iface::getPlainMac() const {
     return (tmp.str());
 }
 
-void IfaceMgr::Iface::setMac(const uint8_t* mac, size_t len) {
-    if (len > IfaceMgr::MAX_MAC_LEN) {
+void Iface::setMac(const uint8_t* mac, size_t len) {
+    if (len > MAX_MAC_LEN) {
         isc_throw(OutOfRange, "Interface " << getFullName()
                   << " was detected to have link address of length "
                   << len << ", but maximum supported length is "
-                  << IfaceMgr::MAX_MAC_LEN);
+                  << MAX_MAC_LEN);
     }
     mac_len_ = len;
     memcpy(mac_, mac, len);
 }
 
-bool IfaceMgr::Iface::delAddress(const isc::asiolink::IOAddress& addr) {
+bool Iface::delAddress(const isc::asiolink::IOAddress& addr) {
     for (AddressCollection::iterator a = addrs_.begin();
          a!=addrs_.end(); ++a) {
         if (*a==addr) {
@@ -109,7 +109,7 @@ bool IfaceMgr::Iface::delAddress(const isc::asiolink::IOAddress& addr) {
     return (false);
 }
 
-bool IfaceMgr::Iface::delSocket(uint16_t sockfd) {
+bool Iface::delSocket(uint16_t sockfd) {
     list<SocketInfo>::iterator sock = sockets_.begin();
     while (sock!=sockets_.end()) {
         if (sock->sockfd_ == sockfd) {
@@ -209,8 +209,8 @@ bool IfaceMgr::openSockets4(const uint16_t port) {
             continue;
         }
 
-        AddressCollection addrs = iface->getAddresses();
-        for (AddressCollection::iterator addr = addrs.begin();
+        Iface::AddressCollection addrs = iface->getAddresses();
+        for (Iface::AddressCollection::iterator addr = addrs.begin();
              addr != addrs.end();
              ++addr) {
 
@@ -246,8 +246,8 @@ bool IfaceMgr::openSockets6(const uint16_t port) {
             continue;
         }
 
-        AddressCollection addrs = iface->getAddresses();
-        for (AddressCollection::iterator addr = addrs.begin();
+        Iface::AddressCollection addrs = iface->getAddresses();
+        for (Iface::AddressCollection::iterator addr = addrs.begin();
              addr != addrs.end();
              ++addr) {
 
@@ -308,7 +308,7 @@ IfaceMgr::printIfaces(std::ostream& out /*= std::cout*/) {
          iface!=ifaces_.end();
          ++iface) {
 
-        const AddressCollection& addrs = iface->getAddresses();
+        const Iface::AddressCollection& addrs = iface->getAddresses();
 
         out << "Detected interface " << iface->getFullName()
             << ", hwtype=" << iface->getHWType()
@@ -322,7 +322,7 @@ IfaceMgr::printIfaces(std::ostream& out /*= std::cout*/) {
             << ")" << endl;
         out << "  " << addrs.size() << " addr(s):";
 
-        for (AddressCollection::const_iterator addr = addrs.begin();
+        for (Iface::AddressCollection::const_iterator addr = addrs.begin();
              addr != addrs.end(); ++addr) {
             out << "  " << addr->toText();
         }
@@ -330,7 +330,7 @@ IfaceMgr::printIfaces(std::ostream& out /*= std::cout*/) {
     }
 }
 
-IfaceMgr::Iface*
+Iface*
 IfaceMgr::getIface(int ifindex) {
     for (IfaceCollection::iterator iface=ifaces_.begin();
          iface!=ifaces_.end();
@@ -342,7 +342,7 @@ IfaceMgr::getIface(int ifindex) {
     return (NULL); // not found
 }
 
-IfaceMgr::Iface*
+Iface*
 IfaceMgr::getIface(const std::string& ifname) {
     for (IfaceCollection::iterator iface=ifaces_.begin();
          iface!=ifaces_.end();
@@ -387,8 +387,8 @@ int IfaceMgr::openSocketFromIface(const std::string& ifname,
 
         // Interface is now detected. Search for address on interface
         // that matches address family (v6 or v4).
-        AddressCollection addrs = iface->getAddresses();
-        AddressCollection::iterator addr_it = addrs.begin();
+        Iface::AddressCollection addrs = iface->getAddresses();
+        Iface::AddressCollection::iterator addr_it = addrs.begin();
         while (addr_it != addrs.end()) {
             if (addr_it->getFamily() == family) {
                 // We have interface and address so let's open socket.
@@ -424,9 +424,9 @@ int IfaceMgr::openSocketFromAddress(const IOAddress& addr,
          iface != ifaces_.end();
          ++iface) {
 
-        AddressCollection addrs = iface->getAddresses();
+        Iface::AddressCollection addrs = iface->getAddresses();
 
-        for (AddressCollection::iterator addr_it = addrs.begin();
+        for (Iface::AddressCollection::iterator addr_it = addrs.begin();
              addr_it != addrs.end();
              ++addr_it) {
 
@@ -581,7 +581,7 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port) {
         }
     }
 
-    SocketInfo info(sock, addr, port);
+    Iface::SocketInfo info(sock, addr, port);
     iface.addSocket(info);
 
     return (sock);
@@ -696,7 +696,7 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
         isc_throw(BadValue, "fractional timeout must be shorter than"
                   " one million microseconds");
     }
-    const SocketInfo* candidate = 0;
+    const Iface::SocketInfo* candidate = 0;
     IfaceCollection::const_iterator iface;
     fd_set sockets;
     int maxfd = 0;
@@ -709,8 +709,8 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
     /// provided set to indicated which sockets have something to read.
     for (iface = ifaces_.begin(); iface != ifaces_.end(); ++iface) {
 
-        const SocketCollection& socket_collection = iface->getSockets();
-        for (SocketCollection::const_iterator s = socket_collection.begin();
+        const Iface::SocketCollection& socket_collection = iface->getSockets();
+        for (Iface::SocketCollection::const_iterator s = socket_collection.begin();
              s != socket_collection.end(); ++s) {
 
             // Only deal with IPv4 addresses.
@@ -765,8 +765,8 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
 
     // Let's find out which interface/socket has the data
     for (iface = ifaces_.begin(); iface != ifaces_.end(); ++iface) {
-        const SocketCollection& socket_collection = iface->getSockets();
-        for (SocketCollection::const_iterator s = socket_collection.begin();
+        const Iface::SocketCollection& socket_collection = iface->getSockets();
+        for (Iface::SocketCollection::const_iterator s = socket_collection.begin();
              s != socket_collection.end(); ++s) {
             if (FD_ISSET(s->sockfd_, &sockets)) {
                 candidate = &(*s);
@@ -850,7 +850,7 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
                   " one million microseconds");
     }
 
-    const SocketInfo* candidate = 0;
+    const Iface::SocketInfo* candidate = 0;
     fd_set sockets;
     int maxfd = 0;
     stringstream names;
@@ -862,8 +862,8 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
     /// provided set to indicated which sockets have something to read.
     IfaceCollection::const_iterator iface;
     for (iface = ifaces_.begin(); iface != ifaces_.end(); ++iface) {
-        const SocketCollection& socket_collection = iface->getSockets();
-        for (SocketCollection::const_iterator s = socket_collection.begin();
+        const Iface::SocketCollection& socket_collection = iface->getSockets();
+        for (Iface::SocketCollection::const_iterator s = socket_collection.begin();
              s != socket_collection.end(); ++s) {
 
             // Only deal with IPv6 addresses.
@@ -918,8 +918,8 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
 
     // Let's find out which interface/socket has the data
     for (iface = ifaces_.begin(); iface != ifaces_.end(); ++iface) {
-        const SocketCollection& socket_collection = iface->getSockets();
-        for (SocketCollection::const_iterator s = socket_collection.begin();
+        const Iface::SocketCollection& socket_collection = iface->getSockets();
+        for (Iface::SocketCollection::const_iterator s = socket_collection.begin();
              s != socket_collection.end(); ++s) {
             if (FD_ISSET(s->sockfd_, &sockets)) {
                 candidate = &(*s);
@@ -1039,8 +1039,8 @@ uint16_t IfaceMgr::getSocket(const isc::dhcp::Pkt6& pkt) {
                   << pkt.getIface());
     }
 
-    const SocketCollection& socket_collection = iface->getSockets();
-    SocketCollection::const_iterator s;
+    const Iface::SocketCollection& socket_collection = iface->getSockets();
+    Iface::SocketCollection::const_iterator s;
     for (s = socket_collection.begin(); s != socket_collection.end(); ++s) {
         if ((s->family_ == AF_INET6) &&
             (!s->addr_.getAddress().to_v6().is_multicast())) {
@@ -1062,8 +1062,8 @@ uint16_t IfaceMgr::getSocket(isc::dhcp::Pkt4 const& pkt) {
                   << pkt.getIface());
     }
 
-    const SocketCollection& socket_collection = iface->getSockets();
-    SocketCollection::const_iterator s;
+    const Iface::SocketCollection& socket_collection = iface->getSockets();
+    Iface::SocketCollection::const_iterator s;
     for (s = socket_collection.begin(); s != socket_collection.end(); ++s) {
         if (s->family_ == AF_INET) {
             return (s->sockfd_);

+ 170 - 169
src/lib/dhcp/iface_mgr.h

@@ -70,31 +70,19 @@ public:
         isc::Exception(file, line, what) { };
 };
 
-/// @brief handles network interfaces, transmission and reception
+/// @brief represents a single network interface
 ///
-/// IfaceMgr is an interface manager class that detects available network
-/// interfaces, configured addresses, link-local addresses, and provides
-/// API for using sockets.
-///
-class IfaceMgr : public boost::noncopyable {
+/// Iface structure represents network interface with all useful
+/// information, like name, interface index, MAC address and
+/// list of assigned addresses
+class Iface {
 public:
-    /// type that defines list of addresses
-    typedef std::vector<isc::asiolink::IOAddress> AddressCollection;
-
-    /// defines callback used when commands are received over control session
-    typedef void (*SessionCallback) (void);
 
     /// maximum MAC address length (Infiniband uses 20 bytes)
     static const unsigned int MAX_MAC_LEN = 20;
 
-    /// @brief Packet reception buffer size
-    ///
-    /// RFC3315 states that server responses may be
-    /// fragmented if they are over MTU. There is no
-    /// text whether client's packets may be larger
-    /// than 1500. For now, we can assume that
-    /// we don't support packets larger than 1500.
-    static const uint32_t RCVBUFSIZE = 1500;
+    /// type that defines list of addresses
+    typedef std::vector<isc::asiolink::IOAddress> AddressCollection;
 
     /// Holds information about socket.
     struct SocketInfo {
@@ -117,189 +105,202 @@ public:
     /// @todo: Add SocketCollectionConstIter type
     typedef std::list<SocketInfo> SocketCollection;
 
+    /// @brief Iface constructor.
+    ///
+    /// Creates Iface object that represents network interface.
+    ///
+    /// @param name name of the interface
+    /// @param ifindex interface index (unique integer identifier)
+    Iface(const std::string& name, int ifindex);
+
+    /// @brief Closes all open sockets on interface.
+    void closeSockets();
 
-    /// @brief represents a single network interface
+    /// @brief Returns full interface name as "ifname/ifindex" string.
     ///
-    /// Iface structure represents network interface with all useful
-    /// information, like name, interface index, MAC address and
-    /// list of assigned addresses
-    class Iface {
-    public:
-        /// @brief Iface constructor.
-        ///
-        /// Creates Iface object that represents network interface.
-        ///
-        /// @param name name of the interface
-        /// @param ifindex interface index (unique integer identifier)
-        Iface(const std::string& name, int ifindex);
+    /// @return string with interface name
+    std::string getFullName() const;
 
-        /// @brief Closes all open sockets on interface.
-        void closeSockets();
+    /// @brief Returns link-layer address a plain text.
+    ///
+    /// @return MAC address as a plain text (string)
+    std::string getPlainMac() const;
 
-        /// @brief Returns full interface name as "ifname/ifindex" string.
-        ///
-        /// @return string with interface name
-        std::string getFullName() const;
+    /// @brief Sets MAC address of the interface.
+    ///
+    /// @param mac pointer to MAC address buffer
+    /// @param macLen length of mac address
+    void setMac(const uint8_t* mac, size_t macLen);
 
-        /// @brief Returns link-layer address a plain text.
-        ///
-        /// @return MAC address as a plain text (string)
-        std::string getPlainMac() const;
+    /// @brief Returns MAC length.
+    ///
+    /// @return length of MAC address
+    size_t getMacLen() const { return mac_len_; }
 
-        /// @brief Sets MAC address of the interface.
-        ///
-        /// @param mac pointer to MAC address buffer
-        /// @param macLen length of mac address
-        void setMac(const uint8_t* mac, size_t macLen);
+    /// @brief Returns pointer to MAC address.
+    ///
+    /// Note: Returned pointer is only valid as long as the interface object
+    /// that returned it.
+    const uint8_t* getMac() const { return mac_; }
 
-        /// @brief Returns MAC length.
-        ///
-        /// @return length of MAC address
-        size_t getMacLen() const { return mac_len_; }
+    /// @brief Sets flag_*_ fields based on bitmask value returned by OS
+    ///
+    /// Note: Implementation of this method is OS-dependent as bits have
+    /// different meaning on each OS.
+    ///
+    /// @param flags bitmask value returned by OS in interface detection
+    void setFlags(uint32_t flags);
 
-        /// @brief Returns pointer to MAC address.
-        ///
-        /// Note: Returned pointer is only valid as long as the interface object
-        /// that returned it.
-        const uint8_t* getMac() const { return mac_; }
+    /// @brief Returns interface index.
+    ///
+    /// @return interface index
+    uint16_t getIndex() const { return ifindex_; }
 
-        /// @brief Sets flag_*_ fields based on bitmask value returned by OS
-        ///
-        /// Note: Implementation of this method is OS-dependent as bits have
-        /// different meaning on each OS.
-        ///
-        /// @param flags bitmask value returned by OS in interface detection
-        void setFlags(uint32_t flags);
+    /// @brief Returns interface name.
+    ///
+    /// @return interface name
+    std::string getName() const { return name_; };
 
-        /// @brief Returns interface index.
-        ///
-        /// @return interface index
-        uint16_t getIndex() const { return ifindex_; }
+    /// @brief Sets up hardware type of the interface.
+    ///
+    /// @param type hardware type
+    void setHWType(uint16_t type ) { hardware_type_ = type; }
 
-        /// @brief Returns interface name.
-        ///
-        /// @return interface name
-        std::string getName() const { return name_; };
+    /// @brief Returns hardware type of the interface.
+    ///
+    /// @return hardware type
+    uint16_t getHWType() const { return hardware_type_; }
 
-        /// @brief Sets up hardware type of the interface.
-        ///
-        /// @param type hardware type
-        void setHWType(uint16_t type ) { hardware_type_ = type; }
+    /// @brief Returns all interfaces available on an interface.
+    ///
+    /// Care should be taken to not use this collection after Iface object
+    /// ceases to exist. That is easy in most cases as Iface objects are
+    /// created by IfaceMgr that is a singleton an is expected to be
+    /// available at all time. We may revisit this if we ever decide to
+    /// implement dynamic interface detection, but such fancy feature would
+    /// mostly be useful for clients with wifi/vpn/virtual interfaces.
+    ///
+    /// @return collection of addresses
+    const AddressCollection& getAddresses() const { return addrs_; }
 
-        /// @brief Returns hardware type of the interface.
-        ///
-        /// @return hardware type
-        uint16_t getHWType() const { return hardware_type_; }
+    /// @brief Adds an address to an interface.
+    ///
+    /// This only adds an address to collection, it does not physically
+    /// configure address on actual network interface.
+    ///
+    /// @param addr address to be added
+    void addAddress(const isc::asiolink::IOAddress& addr) {
+        addrs_.push_back(addr);
+    }
 
-        /// @brief Returns all interfaces available on an interface.
-        ///
-        /// Care should be taken to not use this collection after Iface object
-        /// ceases to exist. That is easy in most cases as Iface objects are
-        /// created by IfaceMgr that is a singleton an is expected to be
-        /// available at all time. We may revisit this if we ever decide to
-        /// implement dynamic interface detection, but such fancy feature would
-        /// mostly be useful for clients with wifi/vpn/virtual interfaces.
-        ///
-        /// @return collection of addresses
-        const AddressCollection& getAddresses() const { return addrs_; }
+    /// @brief Deletes an address from an interface.
+    ///
+    /// This only deletes address from collection, it does not physically
+    /// remove address configuration from actual network interface.
+    ///
+    /// @param addr address to be removed.
+    ///
+    /// @return true if removal was successful (address was in collection),
+    ///         false otherwise
+    bool delAddress(const isc::asiolink::IOAddress& addr);
 
-        /// @brief Adds an address to an interface.
-        ///
-        /// This only adds an address to collection, it does not physically
-        /// configure address on actual network interface.
-        ///
-        /// @param addr address to be added
-        void addAddress(const isc::asiolink::IOAddress& addr) {
-            addrs_.push_back(addr);
-        }
+    /// @brief Adds socket descriptor to an interface.
+    ///
+    /// @param sock SocketInfo structure that describes socket.
+    void addSocket(const SocketInfo& sock) {
+        sockets_.push_back(sock);
+    }
 
-        /// @brief Deletes an address from an interface.
-        ///
-        /// This only deletes address from collection, it does not physically
-        /// remove address configuration from actual network interface.
-        ///
-        /// @param addr address to be removed.
-        ///
-        /// @return true if removal was successful (address was in collection),
-        ///         false otherwise
-        bool delAddress(const isc::asiolink::IOAddress& addr);
+    /// @brief Closes socket.
+    ///
+    /// Closes socket and removes corresponding SocketInfo structure
+    /// from an interface.
+    ///
+    /// @param sockfd socket descriptor to be closed/removed.
+    /// @return true if there was such socket, false otherwise
+    bool delSocket(uint16_t sockfd);
 
-        /// @brief Adds socket descriptor to an interface.
-        ///
-        /// @param sock SocketInfo structure that describes socket.
-        void addSocket(const SocketInfo& sock)
-            { sockets_.push_back(sock); }
+    /// @brief Returns collection of all sockets added to interface.
+    ///
+    /// When new socket is created with @ref IfaceMgr::openSocket
+    /// it is added to sockets collection on particular interface.
+    /// If socket is opened by other means (e.g. function that does
+    /// not use @ref IfaceMgr::openSocket) it will not be available
+    /// in this collection. Note that functions like
+    /// @ref IfaceMgr::openSocketFromIface use
+    /// @ref IfaceMgr::openSocket internally.
+    /// The returned reference is only valid during the lifetime of
+    /// the IfaceMgr object that returned it.
+    ///
+    /// @return collection of sockets added to interface
+    const SocketCollection& getSockets() const { return sockets_; }
 
-        /// @brief Closes socket.
-        ///
-        /// Closes socket and removes corresponding SocketInfo structure
-        /// from an interface.
-        ///
-        /// @param sockfd socket descriptor to be closed/removed.
-        /// @return true if there was such socket, false otherwise
-        bool delSocket(uint16_t sockfd);
+protected:
+    /// socket used to sending data
+    SocketCollection sockets_;
 
-        /// @brief Returns collection of all sockets added to interface.
-        ///
-        /// When new socket is created with @ref IfaceMgr::openSocket
-        /// it is added to sockets collection on particular interface.
-        /// If socket is opened by other means (e.g. function that does
-        /// not use @ref IfaceMgr::openSocket) it will not be available
-        /// in this collection. Note that functions like
-        /// @ref IfaceMgr::openSocketFromIface use
-        /// @ref IfaceMgr::openSocket internally.
-        /// The returned reference is only valid during the lifetime of
-        /// the IfaceMgr object that returned it.
-        ///
-        /// @return collection of sockets added to interface
-        const SocketCollection& getSockets() const { return sockets_; }
+    /// network interface name
+    std::string name_;
 
-    protected:
-        /// socket used to sending data
-        SocketCollection sockets_;
+    /// interface index (a value that uniquely indentifies an interface)
+    int ifindex_;
 
-        /// network interface name
-        std::string name_;
+    /// list of assigned addresses
+    AddressCollection addrs_;
 
-        /// interface index (a value that uniquely indentifies an interface)
-        int ifindex_;
+    /// link-layer address
+    uint8_t mac_[MAX_MAC_LEN];
 
-        /// list of assigned addresses
-        AddressCollection addrs_;
+    /// length of link-layer address (usually 6)
+    size_t mac_len_;
 
-        /// link-layer address
-        uint8_t mac_[MAX_MAC_LEN];
+    /// hardware type
+    uint16_t hardware_type_;
 
-        /// length of link-layer address (usually 6)
-        size_t mac_len_;
+public:
+    /// @todo: Make those fields protected once we start supporting more
+    /// than just Linux
 
-        /// hardware type
-        uint16_t hardware_type_;
+    /// specifies if selected interface is loopback
+    bool flag_loopback_;
 
-    public:
-        /// @todo: Make those fields protected once we start supporting more
-        /// than just Linux
+    /// specifies if selected interface is up
+    bool flag_up_;
 
-        /// specifies if selected interface is loopback
-        bool flag_loopback_;
+    /// flag specifies if selected interface is running
+    /// (e.g. cable plugged in, wifi associated)
+    bool flag_running_;
 
-        /// specifies if selected interface is up
-        bool flag_up_;
+    /// flag specifies if selected interface is multicast capable
+    bool flag_multicast_;
 
-        /// flag specifies if selected interface is running
-        /// (e.g. cable plugged in, wifi associated)
-        bool flag_running_;
+    /// flag specifies if selected interface is broadcast capable
+    bool flag_broadcast_;
 
-        /// flag specifies if selected interface is multicast capable
-        bool flag_multicast_;
+    /// interface flags (this value is as is returned by OS,
+    /// it may mean different things on different OSes)
+    uint32_t flags_;
+};
 
-        /// flag specifies if selected interface is broadcast capable
-        bool flag_broadcast_;
+/// @brief handles network interfaces, transmission and reception
+///
+/// IfaceMgr is an interface manager class that detects available network
+/// interfaces, configured addresses, link-local addresses, and provides
+/// API for using sockets.
+///
+class IfaceMgr : public boost::noncopyable {
+public:
+    /// defines callback used when commands are received over control session
+    typedef void (*SessionCallback) (void);
 
-        /// interface flags (this value is as is returned by OS,
-        /// it may mean different things on different OSes)
-        uint32_t flags_;
-    };
+    /// @brief Packet reception buffer size
+    ///
+    /// RFC3315 states that server responses may be
+    /// fragmented if they are over MTU. There is no
+    /// text whether client's packets may be larger
+    /// than 1500. For now, we can assume that
+    /// we don't support packets larger than 1500.
+    static const uint32_t RCVBUFSIZE = 1500;
 
     // TODO performance improvement: we may change this into
     //      2 maps (ifindex-indexed and name-indexed) and

+ 5 - 5
src/lib/dhcp/iface_mgr_linux.cc

@@ -103,7 +103,7 @@ public:
     void rtnl_send_request(int family, int type);
     void rtnl_store_reply(NetlinkMessages& storage, const nlmsghdr* msg);
     void parse_rtattr(RTattribPtrs& table, rtattr* rta, int len);
-    void ipaddrs_get(IfaceMgr::Iface& iface, NetlinkMessages& addr_info);
+    void ipaddrs_get(Iface& iface, NetlinkMessages& addr_info);
     void rtnl_process_reply(NetlinkMessages& info);
     void release_list(NetlinkMessages& messages);
     void rtnl_close_socket();
@@ -277,7 +277,7 @@ void Netlink::parse_rtattr(RTattribPtrs& table, struct rtattr* rta, int len)
 ///
 /// @param iface interface representation (addresses will be added here)
 /// @param addr_info collection of parsed netlink messages
-void Netlink::ipaddrs_get(IfaceMgr::Iface& iface, NetlinkMessages& addr_info) {
+void Netlink::ipaddrs_get(Iface& iface, NetlinkMessages& addr_info) {
     uint8_t addr[V6ADDRESS_LEN];
     RTattribPtrs rta_tb;
 
@@ -502,10 +502,10 @@ IfaceMgr::isDirectResponseSupported() {
 int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port,
                           bool receive_bcast, bool send_bcast) {
 
-    int sock = packet_filter_->openSocket(iface.getName(), addr, port,
+    int sock = packet_filter_->openSocket(iface, addr, port,
                                           receive_bcast, send_bcast);
 
-    SocketInfo info(sock, addr, port);
+    Iface::SocketInfo info(sock, addr, port);
     iface.addSocket(info);
 
     return (sock);
@@ -517,7 +517,7 @@ int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port,
 /// on different OSes.
 ///
 /// @param flags flags bitfield read from OS
-void IfaceMgr::Iface::setFlags(uint32_t flags) {
+void Iface::setFlags(uint32_t flags) {
     flags_ = flags;
 
     flag_loopback_ = flags & IFF_LOOPBACK;

+ 31 - 31
src/lib/dhcp/tests/iface_mgr_unittest.cc

@@ -166,7 +166,7 @@ TEST_F(IfaceMgrTest, basic) {
 TEST_F(IfaceMgrTest, ifaceClass) {
     // basic tests for Iface inner class
 
-    IfaceMgr::Iface* iface = new IfaceMgr::Iface("eth5", 7);
+    Iface* iface = new Iface("eth5", 7);
 
     EXPECT_STREQ("eth5/7", iface->getFullName().c_str());
 
@@ -181,10 +181,10 @@ TEST_F(IfaceMgrTest, getIface) {
     NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
 
     // interface name, ifindex
-    IfaceMgr::Iface iface1("lo1", 100);
-    IfaceMgr::Iface iface2("eth9", 101);
-    IfaceMgr::Iface iface3("en3", 102);
-    IfaceMgr::Iface iface4("e1000g4", 103);
+    Iface iface1("lo1", 100);
+    Iface iface2("eth9", 101);
+    Iface iface3("en3", 102);
+    Iface iface4("e1000g4", 103);
     cout << "This test assumes that there are less than 100 network interfaces"
          << " in the tested system and there are no lo1, eth9, en3, e1000g4"
          << " or wifi15 interfaces present." << endl;
@@ -205,7 +205,7 @@ TEST_F(IfaceMgrTest, getIface) {
 
 
     // check that interface can be retrieved by ifindex
-    IfaceMgr::Iface* tmp = ifacemgr->getIface(102);
+    Iface* tmp = ifacemgr->getIface(102);
     ASSERT_TRUE(tmp != NULL);
 
     EXPECT_EQ("en3", tmp->getName());
@@ -354,7 +354,7 @@ TEST_F(IfaceMgrTest, multipleSockets) {
 
     // Get loopback interface. If we don't find one we are unable to run
     // this test but we don't want to fail.
-    IfaceMgr::Iface* iface_ptr = ifacemgr->getIface(LOOPBACK);
+    Iface* iface_ptr = ifacemgr->getIface(LOOPBACK);
     if (iface_ptr == NULL) {
         cout << "Local loopback interface not found. Skipping test. " << endl;
         return;
@@ -362,7 +362,7 @@ TEST_F(IfaceMgrTest, multipleSockets) {
     // Once sockets have been sucessfully opened, they are supposed to
     // be on the list. Here we start to test if all expected sockets
     // are on the list and no other (unexpected) socket is there.
-    IfaceMgr::SocketCollection sockets = iface_ptr->getSockets();
+    Iface::SocketCollection sockets = iface_ptr->getSockets();
     int matched_sockets = 0;
     for (std::list<uint16_t>::iterator init_sockets_it =
              init_sockets.begin();
@@ -379,7 +379,7 @@ TEST_F(IfaceMgrTest, multipleSockets) {
         EXPECT_EQ(EWOULDBLOCK, errno);
         // Apart from the ability to use the socket we want to make
         // sure that socket on the list is the one that we created.
-        for (IfaceMgr::SocketCollection::const_iterator socket_it =
+        for (Iface::SocketCollection::const_iterator socket_it =
                  sockets.begin(); socket_it != sockets.end(); ++socket_it) {
             if (*init_sockets_it == socket_it->sockfd_) {
                 // This socket is the one that we created.
@@ -788,9 +788,9 @@ TEST_F(IfaceMgrTest, socket4) {
 
 // Test the Iface structure itself
 TEST_F(IfaceMgrTest, iface) {
-    IfaceMgr::Iface* iface = NULL;
+    Iface* iface = NULL;
     EXPECT_NO_THROW(
-        iface = new IfaceMgr::Iface("eth0",1);
+        iface = new Iface("eth0",1);
     );
 
     EXPECT_EQ("eth0", iface->getName());
@@ -798,7 +798,7 @@ TEST_F(IfaceMgrTest, iface) {
     EXPECT_EQ("eth0/1", iface->getFullName());
 
     // Let's make a copy of this address collection.
-    IfaceMgr::AddressCollection addrs = iface->getAddresses();
+    Iface::AddressCollection addrs = iface->getAddresses();
 
     EXPECT_EQ(0, addrs.size());
 
@@ -828,13 +828,13 @@ TEST_F(IfaceMgrTest, iface) {
 }
 
 TEST_F(IfaceMgrTest, iface_methods) {
-    IfaceMgr::Iface iface("foo", 1234);
+    Iface iface("foo", 1234);
 
     iface.setHWType(42);
     EXPECT_EQ(42, iface.getHWType());
 
-    uint8_t mac[IfaceMgr::MAX_MAC_LEN+10];
-    for (int i = 0; i < IfaceMgr::MAX_MAC_LEN + 10; i++)
+    uint8_t mac[Iface::MAX_MAC_LEN+10];
+    for (int i = 0; i < Iface::MAX_MAC_LEN + 10; i++)
         mac[i] = 255 - i;
 
     EXPECT_EQ("foo", iface.getName());
@@ -843,7 +843,7 @@ TEST_F(IfaceMgrTest, iface_methods) {
     // MAC is too long. Exception should be thrown and
     // MAC length should not be set.
     EXPECT_THROW(
-        iface.setMac(mac, IfaceMgr::MAX_MAC_LEN + 1),
+        iface.setMac(mac, Iface::MAX_MAC_LEN + 1),
         OutOfRange
     );
 
@@ -851,11 +851,11 @@ TEST_F(IfaceMgrTest, iface_methods) {
     EXPECT_EQ(0, iface.getMacLen());
 
     // Setting maximum length MAC should be ok.
-    iface.setMac(mac, IfaceMgr::MAX_MAC_LEN);
+    iface.setMac(mac, Iface::MAX_MAC_LEN);
 
     // For some reason constants cannot be used directly in EXPECT_EQ
     // as this produces linking error.
-    size_t len = IfaceMgr::MAX_MAC_LEN;
+    size_t len = Iface::MAX_MAC_LEN;
     EXPECT_EQ(len, iface.getMacLen());
     EXPECT_EQ(0, memcmp(mac, iface.getMac(), iface.getMacLen()));
 }
@@ -863,14 +863,14 @@ TEST_F(IfaceMgrTest, iface_methods) {
 TEST_F(IfaceMgrTest, socketInfo) {
 
     // check that socketinfo for IPv4 socket is functional
-    IfaceMgr::SocketInfo sock1(7, IOAddress("192.0.2.56"), DHCP4_SERVER_PORT + 7);
+    Iface::SocketInfo sock1(7, IOAddress("192.0.2.56"), DHCP4_SERVER_PORT + 7);
     EXPECT_EQ(7, sock1.sockfd_);
     EXPECT_EQ("192.0.2.56", sock1.addr_.toText());
     EXPECT_EQ(AF_INET, sock1.family_);
     EXPECT_EQ(DHCP4_SERVER_PORT + 7, sock1.port_);
 
     // check that socketinfo for IPv6 socket is functional
-    IfaceMgr::SocketInfo sock2(9, IOAddress("2001:db8:1::56"), DHCP4_SERVER_PORT + 9);
+    Iface::SocketInfo sock2(9, IOAddress("2001:db8:1::56"), DHCP4_SERVER_PORT + 9);
     EXPECT_EQ(9, sock2.sockfd_);
     EXPECT_EQ("2001:db8:1::56", sock2.addr_.toText());
     EXPECT_EQ(AF_INET6, sock2.family_);
@@ -878,7 +878,7 @@ TEST_F(IfaceMgrTest, socketInfo) {
 
     // now let's test if IfaceMgr handles socket info properly
     NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
-    IfaceMgr::Iface* loopback = ifacemgr->getIface(LOOPBACK);
+    Iface* loopback = ifacemgr->getIface(LOOPBACK);
     ASSERT_TRUE(loopback);
     loopback->addSocket(sock1);
     loopback->addSocket(sock2);
@@ -955,7 +955,7 @@ TEST_F(IfaceMgrTest, socketInfo) {
 /// it in binary format. Text format is expected to be separate with
 /// semicolons, e.g. f4:6d:04:96:58:f2
 ///
-/// TODO: IfaceMgr::Iface::mac_ uses uint8_t* type, should be vector<uint8_t>
+/// TODO: Iface::mac_ uses uint8_t* type, should be vector<uint8_t>
 ///
 /// @param textMac string with MAC address to parse
 /// @param mac pointer to output buffer
@@ -1045,7 +1045,7 @@ void parse_ifconfig(const std::string& textFile, IfaceMgr::IfaceCollection& ifac
             string name = line.substr(0, offset);
 
             // sadly, ifconfig does not return ifindex
-            ifaces.push_back(IfaceMgr::Iface(name, 0));
+            ifaces.push_back(Iface(name, 0));
             iface = ifaces.end();
             --iface; // points to the last element
 
@@ -1057,8 +1057,8 @@ void parse_ifconfig(const std::string& textFile, IfaceMgr::IfaceCollection& ifac
                 mac = line.substr(offset, string::npos);
                 mac = mac.substr(0, mac.find_first_of(" "));
 
-                uint8_t buf[IfaceMgr::MAX_MAC_LEN];
-                int mac_len = parse_mac(mac, buf, IfaceMgr::MAX_MAC_LEN);
+                uint8_t buf[Iface::MAX_MAC_LEN];
+                int mac_len = parse_mac(mac, buf, Iface::MAX_MAC_LEN);
                 iface->setMac(buf, mac_len);
             }
         }
@@ -1165,8 +1165,8 @@ TEST_F(IfaceMgrTest, DISABLED_detectIfaces_linux) {
             cout << " BROADCAST";
         }
         cout << ", addrs:";
-        const IfaceMgr::AddressCollection& addrs = i->getAddresses();
-        for (IfaceMgr::AddressCollection::const_iterator a= addrs.begin();
+        const Iface::AddressCollection& addrs = i->getAddresses();
+        for (Iface::AddressCollection::const_iterator a= addrs.begin();
              a != addrs.end(); ++a) {
             cout << a->toText() << " ";
         }
@@ -1208,13 +1208,13 @@ TEST_F(IfaceMgrTest, DISABLED_detectIfaces_linux) {
             EXPECT_EQ(detected->getAddresses().size(), i->getAddresses().size());
 
             // now compare addresses
-            const IfaceMgr::AddressCollection& addrs = detected->getAddresses();
-            for (IfaceMgr::AddressCollection::const_iterator addr = addrs.begin();
+            const Iface::AddressCollection& addrs = detected->getAddresses();
+            for (Iface::AddressCollection::const_iterator addr = addrs.begin();
                  addr != addrs.end(); ++addr) {
                 bool addr_found = false;
 
-                const IfaceMgr::AddressCollection& addrs2 = detected->getAddresses();
-                for (IfaceMgr::AddressCollection::const_iterator a = addrs2.begin();
+                const Iface::AddressCollection& addrs2 = detected->getAddresses();
+                for (Iface::AddressCollection::const_iterator a = addrs2.begin();
                      a != addrs2.end(); ++a) {
                     if (*addr != *a) {
                         continue;