From f567417bb399f59a410906c3c52cc2f913c154f6 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Dec 2021 15:16:13 -0500 Subject: [PATCH] memory pool for RouterInfo buffer --- libi2pd/NetDb.cpp | 2 ++ libi2pd/NetDb.hpp | 4 ++++ libi2pd/RouterInfo.cpp | 33 ++++++++++++++++----------------- libi2pd/RouterInfo.h | 8 +++++--- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 4ed51312..97b803b4 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -659,6 +659,8 @@ namespace data ++it; } } + + m_RouterInfoBuffersPool.CleanUpMt (); } void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete, bool direct) diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index ddac573e..f4f7a097 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -30,6 +30,7 @@ #include "NetDbRequests.h" #include "Family.h" #include "version.h" +#include "util.h" namespace i2p { @@ -120,6 +121,7 @@ namespace data size_t VisitRandomRouterInfos(RouterInfoFilter f, RouterInfoVisitor v, size_t n); void ClearRouterInfos () { m_RouterInfos.clear (); }; + std::shared_ptr NewRouterInfoBuffer () { return m_RouterInfoBuffersPool.AcquireSharedMt (); }; uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; }; @@ -175,6 +177,8 @@ namespace data std::set m_PublishExcluded; uint32_t m_PublishReplyToken = 0; + + i2p::util::MemoryPoolMt m_RouterInfoBuffersPool; }; extern NetDb netdb; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 9566c8d7..2e294356 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -40,7 +40,7 @@ namespace data m_Caps (0), m_Version (0) { m_Addresses = boost::make_shared(); // create empty list - m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; + m_Buffer = netdb.NewRouterInfoBuffer (); ReadFromFile (fullPath); } @@ -51,8 +51,8 @@ namespace data m_Addresses = boost::make_shared(); // create empty list if (len <= MAX_RI_BUFFER_SIZE) { - m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; - memcpy (m_Buffer, buf, len); + m_Buffer = netdb.NewRouterInfoBuffer (); + memcpy (m_Buffer->data (), buf, len); m_BufferLen = len; ReadFromBuffer (true); } @@ -66,7 +66,6 @@ namespace data RouterInfo::~RouterInfo () { - delete[] m_Buffer; } void RouterInfo::Update (const uint8_t * buf, size_t len) @@ -91,13 +90,13 @@ namespace data m_Properties.clear (); // copy buffer if (!m_Buffer) - m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; - memcpy (m_Buffer, buf, len); + m_Buffer = netdb.NewRouterInfoBuffer (); + memcpy (m_Buffer->data (), buf, len); m_BufferLen = len; // skip identity size_t identityLen = m_RouterIdentity->GetFullLen (); // read new RI - std::stringstream str (std::string ((char *)m_Buffer + identityLen, m_BufferLen - identityLen)); + std::stringstream str (std::string ((char *)m_Buffer->data () + identityLen, m_BufferLen - identityLen)); ReadFromStream (str); // don't delete buffer until saved to the file } @@ -128,8 +127,8 @@ namespace data } s.seekg(0, std::ios::beg); if (!m_Buffer) - m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; - s.read((char *)m_Buffer, m_BufferLen); + m_Buffer = netdb.NewRouterInfoBuffer (); + s.read((char *)m_Buffer->data (), m_BufferLen); } else { @@ -154,7 +153,7 @@ namespace data m_IsUnreachable = true; return; } - m_RouterIdentity = std::make_shared(m_Buffer, m_BufferLen); + m_RouterIdentity = std::make_shared(m_Buffer->data (), m_BufferLen); size_t identityLen = m_RouterIdentity->GetFullLen (); if (identityLen >= m_BufferLen) { @@ -173,7 +172,7 @@ namespace data } // verify signature int l = m_BufferLen - m_RouterIdentity->GetSignatureLen (); - if (l < 0 || !m_RouterIdentity->Verify ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l)) + if (l < 0 || !m_RouterIdentity->Verify ((uint8_t *)m_Buffer->data (), l, (uint8_t *)m_Buffer->data () + l)) { LogPrint (eLogError, "RouterInfo: Signature verification failed"); m_IsUnreachable = true; @@ -183,7 +182,7 @@ namespace data } // parse RI std::stringstream str; - str.write ((const char *)m_Buffer + identityLen, m_BufferLen - identityLen); + str.write ((const char *)m_Buffer->data () + identityLen, m_BufferLen - identityLen); ReadFromStream (str); if (!str) { @@ -775,7 +774,7 @@ namespace data if (LoadFile (fullPath)) LogPrint (eLogDebug, "RouterInfo: Buffer for ", GetIdentHashAbbreviation (GetIdentHash ()), " loaded from file"); } - return m_Buffer; + return m_Buffer->data (); } void RouterInfo::CreateBuffer (const PrivateKeys& privateKeys) @@ -789,12 +788,12 @@ namespace data WriteToStream (s); m_BufferLen = s.str ().size (); if (!m_Buffer) - m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; + m_Buffer = netdb.NewRouterInfoBuffer (); if (m_BufferLen + signatureLen < MAX_RI_BUFFER_SIZE) { - memcpy (m_Buffer, s.str ().c_str (), m_BufferLen); + memcpy (m_Buffer->data (), s.str ().c_str (), m_BufferLen); // signature - privateKeys.Sign ((uint8_t *)m_Buffer, m_BufferLen, (uint8_t *)m_Buffer + m_BufferLen); + privateKeys.Sign ((uint8_t *)m_Buffer->data (), m_BufferLen, (uint8_t *)m_Buffer->data () + m_BufferLen); m_BufferLen += signatureLen; } else @@ -813,7 +812,7 @@ namespace data LogPrint(eLogError, "RouterInfo: Can't save to ", fullPath); return false; } - f.write ((char *)m_Buffer, m_BufferLen); + f.write ((char *)m_Buffer->data (), m_BufferLen); return true; } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 2a341be8..d807c74b 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -158,6 +159,7 @@ namespace data bool IsV6 () const { return (caps & AddressCaps::eV6) || (host.is_v6 () && !host.is_unspecified ()); }; }; typedef std::vector > Addresses; + typedef std::array Buffer; RouterInfo (); RouterInfo (const std::string& fullPath); @@ -225,7 +227,7 @@ namespace data void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; }; bool IsUnreachable () const { return m_IsUnreachable; }; - const uint8_t * GetBuffer () const { return m_Buffer; }; + const uint8_t * GetBuffer () const { return m_Buffer->data (); }; const uint8_t * LoadBuffer (const std::string& fullPath); // load if necessary int GetBufferLen () const { return m_BufferLen; }; void CreateBuffer (const PrivateKeys& privateKeys); @@ -238,7 +240,7 @@ namespace data void SaveProfile () { if (m_Profile) m_Profile->Save (GetIdentHash ()); }; void Update (const uint8_t * buf, size_t len); - void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; }; + void DeleteBuffer () { m_Buffer = nullptr; }; bool IsNewer (const uint8_t * buf, size_t len) const; /** return true if we are in a router family and the signature is valid */ @@ -269,7 +271,7 @@ namespace data std::string m_Family; std::shared_ptr m_RouterIdentity; - uint8_t * m_Buffer; + std::shared_ptr m_Buffer; size_t m_BufferLen; uint64_t m_Timestamp; boost::shared_ptr m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9