Skip to content

Commit

Permalink
Use smart pointers for PcapLiveDeviceList's internal memory managemen…
Browse files Browse the repository at this point in the history
…t. (#1440)
  • Loading branch information
Dimi1010 authored Jun 8, 2024
1 parent 93eca5b commit 2f49cf8
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 40 deletions.
20 changes: 12 additions & 8 deletions Pcap++/header/PcapLiveDeviceList.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "IpAddress.h"
#include "PcapLiveDevice.h"
#include <vector>
#include <memory>


/// @file
Expand All @@ -23,20 +24,26 @@ namespace pcpp
class PcapLiveDeviceList
{
private:
std::vector<PcapLiveDevice*> m_LiveDeviceList;
std::vector<std::unique_ptr<PcapLiveDevice>> m_LiveDeviceList;
// Vector of raw device pointers to keep the signature of getPcapLiveDevicesList, as it returns a reference.
std::vector<PcapLiveDevice*> m_LiveDeviceListView;

std::vector<IPv4Address> m_DnsServers;

// private c'tor
PcapLiveDeviceList();
// private copy c'tor
PcapLiveDeviceList( const PcapLiveDeviceList& other );
PcapLiveDeviceList& operator=(const PcapLiveDeviceList& other);

void init();

void setDnsServers();

void updateLiveDeviceListView() const;
public:
PcapLiveDeviceList(const PcapLiveDeviceList&) = delete;
PcapLiveDeviceList(PcapLiveDeviceList&&) noexcept = delete;
PcapLiveDeviceList& operator=(const PcapLiveDeviceList&) = delete;
PcapLiveDeviceList& operator=(PcapLiveDeviceList&&) noexcept = delete;

/**
* The access method to the singleton
* @return The singleton instance of this class
Expand All @@ -50,7 +57,7 @@ namespace pcpp
/**
* @return A vector containing pointers to all live devices currently installed on the machine
*/
const std::vector<PcapLiveDevice*>& getPcapLiveDevicesList() const { return m_LiveDeviceList; }
const std::vector<PcapLiveDevice*>& getPcapLiveDevicesList() const { return m_LiveDeviceListView; };

/**
* Get a pointer to the live device by its IP address. IP address can be both IPv4 or IPv6
Expand Down Expand Up @@ -110,9 +117,6 @@ namespace pcpp
* Reset the live device list and DNS server list, meaning clear and refetch them
*/
void reset();

// d'tor
~PcapLiveDeviceList();
};

} // namespace pcpp
57 changes: 25 additions & 32 deletions Pcap++/src/PcapLiveDeviceList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,6 @@ PcapLiveDeviceList::PcapLiveDeviceList()
init();
}

PcapLiveDeviceList::~PcapLiveDeviceList()
{
for(const auto &devIter : m_LiveDeviceList)
{
delete devIter;
}
}

void PcapLiveDeviceList::init()
{
std::unique_ptr<pcap_if_t, internal::PcapFreeAllDevsDeleter> interfaceList;
Expand All @@ -57,13 +49,18 @@ void PcapLiveDeviceList::init()
for (pcap_if_t* currInterface = interfaceList.get(); currInterface != nullptr; currInterface = currInterface->next)
{
#if defined(_WIN32)
PcapLiveDevice* dev = new WinPcapLiveDevice(currInterface, true, true, true);
auto dev = std::unique_ptr<PcapLiveDevice>(new WinPcapLiveDevice(currInterface, true, true, true));
#else //__linux__, __APPLE__, __FreeBSD__
PcapLiveDevice* dev = new PcapLiveDevice(currInterface, true, true, true);
auto dev = std::unique_ptr<PcapLiveDevice>(new PcapLiveDevice(currInterface, true, true, true));
#endif
m_LiveDeviceList.insert(m_LiveDeviceList.end(), dev);
m_LiveDeviceList.push_back(std::move(dev));
}

m_LiveDeviceListView.resize(m_LiveDeviceList.size());
// Full update of all elements of the view vector to synchronize them with the main vector.
std::transform(m_LiveDeviceList.begin(), m_LiveDeviceList.end(), m_LiveDeviceListView.begin(),
[](const std::unique_ptr<PcapLiveDevice>& ptr) { return ptr.get(); });

setDnsServers();
}

Expand Down Expand Up @@ -268,19 +265,19 @@ PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByIp(const IPAddress& ipAdd
PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByIp(const IPv4Address& ipAddr) const
{
PCPP_LOG_DEBUG("Searching all live devices...");
for(const auto &devIter : m_LiveDeviceList)
for(const auto& devicePtr : m_LiveDeviceList)
{
PCPP_LOG_DEBUG("Searching device '" << devIter->m_Name << "'. Searching all addresses...");
for(const auto &addrIter : devIter->m_Addresses)
PCPP_LOG_DEBUG("Searching device '" << devicePtr->m_Name << "'. Searching all addresses...");
for(const auto& addressInfo : devicePtr->m_Addresses)
{
if (Logger::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && addrIter.addr != nullptr)
if (Logger::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && addressInfo.addr != nullptr)
{
std::array<char, INET6_ADDRSTRLEN> addrAsString;
internal::sockaddr2string(addrIter.addr, addrAsString.data(), addrAsString.size());
internal::sockaddr2string(addressInfo.addr, addrAsString.data(), addrAsString.size());
PCPP_LOG_DEBUG("Searching address " << addrAsString.data());
}

in_addr* currAddr = internal::try_sockaddr2in_addr(addrIter.addr);
in_addr* currAddr = internal::try_sockaddr2in_addr(addressInfo.addr);
if (currAddr == nullptr)
{
PCPP_LOG_DEBUG("Address is nullptr");
Expand All @@ -290,7 +287,7 @@ PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByIp(const IPv4Address& ipA
if (*currAddr == ipAddr)
{
PCPP_LOG_DEBUG("Found matched address!");
return devIter;
return devicePtr.get();
}
}
}
Expand All @@ -301,19 +298,19 @@ PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByIp(const IPv4Address& ipA
PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByIp(const IPv6Address& ip6Addr) const
{
PCPP_LOG_DEBUG("Searching all live devices...");
for(const auto &devIter : m_LiveDeviceList)
for(const auto& devicePtr : m_LiveDeviceList)
{
PCPP_LOG_DEBUG("Searching device '" << devIter->m_Name << "'. Searching all addresses...");
for(const auto &addrIter : devIter->m_Addresses)
PCPP_LOG_DEBUG("Searching device '" << devicePtr->m_Name << "'. Searching all addresses...");
for(const auto& addressInfo : devicePtr->m_Addresses)
{
if (Logger::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && addrIter.addr != nullptr)
if (Logger::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && addressInfo.addr != nullptr)
{
std::array<char, INET6_ADDRSTRLEN> addrAsString;
internal::sockaddr2string(addrIter.addr, addrAsString.data(), addrAsString.size());
internal::sockaddr2string(addressInfo.addr, addrAsString.data(), addrAsString.size());
PCPP_LOG_DEBUG("Searching address " << addrAsString.data());
}

in6_addr* currAddr = internal::try_sockaddr2in6_addr(addrIter.addr);
in6_addr* currAddr = internal::try_sockaddr2in6_addr(addressInfo.addr);
if (currAddr == nullptr)
{
PCPP_LOG_DEBUG("Address is nullptr");
Expand All @@ -323,7 +320,7 @@ PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByIp(const IPv6Address& ip6
if (*currAddr == ip6Addr)
{
PCPP_LOG_DEBUG("Found matched address!");
return devIter;
return devicePtr.get();
}
}
}
Expand Down Expand Up @@ -353,15 +350,15 @@ PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByName(const std::string& n
{
PCPP_LOG_DEBUG("Searching all live devices...");
auto devIter = std::find_if(m_LiveDeviceList.begin(), m_LiveDeviceList.end(),
[&name](const PcapLiveDevice *dev) { return dev->getName() == name; });
[&name](const std::unique_ptr<PcapLiveDevice>& dev) { return dev->getName() == name; });

if (devIter == m_LiveDeviceList.end())
{
PCPP_LOG_DEBUG("Found no live device with name '" << name << "'");
return nullptr;
}

return *devIter;
return devIter->get();
}

PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByIpOrName(const std::string& ipOrName) const
Expand All @@ -384,11 +381,7 @@ PcapLiveDeviceList* PcapLiveDeviceList::clone()

void PcapLiveDeviceList::reset()
{
for(auto devIter : m_LiveDeviceList)
{
delete devIter;
}

m_LiveDeviceListView.clear();
m_LiveDeviceList.clear();
m_DnsServers.clear();

Expand Down

0 comments on commit 2f49cf8

Please sign in to comment.