This is an automated email from the ASF dual-hosted git repository.

bcall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new a3aa284858 Fixed memory leaks with http/3 (#9342)
a3aa284858 is described below

commit a3aa284858ab48da2c076bde1b0a27379da9b174
Author: Bryan Call <bc...@apache.org>
AuthorDate: Tue Feb 7 11:05:56 2023 -0800

    Fixed memory leaks with http/3 (#9342)
    
    - Leak with not freeing packets
    - Leak in buffers for QPACK
    - Leak with the http/3 session
---
 iocore/net/QUICNet.cc                          |  1 +
 iocore/net/QUICNetVConnection.cc               |  2 --
 iocore/net/quic/QUICApplicationMap.h           |  7 +++++++
 iocore/net/quic/test/test_QUICStreamManager.cc | 20 ++++++++------------
 proxy/http3/QPACK.cc                           |  6 +++++-
 5 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/iocore/net/QUICNet.cc b/iocore/net/QUICNet.cc
index da073dd498..b14cda3ae7 100644
--- a/iocore/net/QUICNet.cc
+++ b/iocore/net/QUICNet.cc
@@ -77,6 +77,7 @@ QUICPollCont::_process_packet(QUICPollEvent *e, NetHandler 
*nh)
   }
 
   // Note: We should free QUICPollEvent here since vc could be freed from 
other thread.
+  p->free();
   e->free();
 }
 #else
diff --git a/iocore/net/QUICNetVConnection.cc b/iocore/net/QUICNetVConnection.cc
index 2b3f3bbdeb..5d8290208d 100644
--- a/iocore/net/QUICNetVConnection.cc
+++ b/iocore/net/QUICNetVConnection.cc
@@ -1649,7 +1649,6 @@ QUICNetVConnection::_packetize_frames(uint8_t 
*packet_buf, QUICEncryptionLevel l
   max_frame_size = std::min(max_frame_size, 
this->_maximum_stream_frame_data_size());
 
   bool probing                   = false;
-  int frame_count                = 0;
   size_t len                     = 0;
   Ptr<IOBufferBlock> first_block = 
make_ptr<IOBufferBlock>(new_IOBufferBlock());
   Ptr<IOBufferBlock> last_block  = first_block;
@@ -1688,7 +1687,6 @@ QUICNetVConnection::_packetize_frames(uint8_t 
*packet_buf, QUICEncryptionLevel l
           break;
         }
 
-        ++frame_count;
         probing |= frame->is_probing_frame();
         if (frame->is_flow_controlled()) {
           int ret = 
this->_remote_flow_controller->update(this->_stream_manager->total_offset_sent());
diff --git a/iocore/net/quic/QUICApplicationMap.h 
b/iocore/net/quic/QUICApplicationMap.h
index a657adf6e4..5a3c1fae4c 100644
--- a/iocore/net/quic/QUICApplicationMap.h
+++ b/iocore/net/quic/QUICApplicationMap.h
@@ -33,6 +33,13 @@ public:
   void set(QUICStreamId id, QUICApplication *app);
   void set_default(QUICApplication *app);
   QUICApplication *get(QUICStreamId id);
+  ~QUICApplicationMap()
+  {
+    for (auto it = _map.begin(); it != _map.end(); ++it) {
+      delete it->second;
+    }
+    delete _default_app;
+  }
 
 private:
   std::map<QUICStreamId, QUICApplication *> _map;
diff --git a/iocore/net/quic/test/test_QUICStreamManager.cc 
b/iocore/net/quic/test/test_QUICStreamManager.cc
index 130454f9dd..9849af3b7e 100644
--- a/iocore/net/quic/test/test_QUICStreamManager.cc
+++ b/iocore/net/quic/test/test_QUICStreamManager.cc
@@ -37,8 +37,7 @@ TEST_CASE("QUICStreamManager_NewStream", "[quic]")
   QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
   QUICApplicationMap app_map;
   MockQUICConnection connection;
-  MockQUICApplication mock_app(&connection);
-  app_map.set_default(&mock_app);
+  app_map.set_default(new MockQUICApplication(&connection));
   MockQUICConnectionInfoProvider cinfo_provider;
   QUICStreamManagerImpl sm(&context, &app_map);
 
@@ -101,8 +100,7 @@ TEST_CASE("QUICStreamManager_first_initial_map", "[quic]")
   QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
   QUICApplicationMap app_map;
   MockQUICConnection connection;
-  MockQUICApplication mock_app(&connection);
-  app_map.set_default(&mock_app);
+  app_map.set_default(new MockQUICApplication(&connection));
   MockQUICConnectionInfoProvider cinfo_provider;
   QUICStreamManagerImpl sm(&context, &app_map);
   std::shared_ptr<QUICTransportParameters> local_tp  = 
std::make_shared<QUICTransportParametersInEncryptedExtensions>();
@@ -127,8 +125,7 @@ TEST_CASE("QUICStreamManager_total_offset_received", 
"[quic]")
   QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
   QUICApplicationMap app_map;
   MockQUICConnection connection;
-  MockQUICApplication mock_app(&connection);
-  app_map.set_default(&mock_app);
+  app_map.set_default(new MockQUICApplication(&connection));
   QUICStreamManagerImpl sm(&context, &app_map);
 
   uint8_t local_tp_buf[] = {
@@ -182,8 +179,8 @@ TEST_CASE("QUICStreamManager_total_offset_sent", "[quic]")
   QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
   QUICApplicationMap app_map;
   MockQUICConnection connection;
-  MockQUICApplication mock_app(&connection);
-  app_map.set_default(&mock_app);
+  auto mock_app = new MockQUICApplication(&connection);
+  app_map.set_default(mock_app);
   QUICStreamManagerImpl sm(&context, &app_map);
 
   uint8_t local_tp_buf[] = {
@@ -232,12 +229,12 @@ TEST_CASE("QUICStreamManager_total_offset_sent", "[quic]")
 
   // total_offset should be a integer in unit of octets
   uint8_t frame_buf[4096];
-  mock_app.send(reinterpret_cast<uint8_t *>(block_1024->buf()), 1024, 0);
+  mock_app->send(reinterpret_cast<uint8_t *>(block_1024->buf()), 1024, 0);
   sm.generate_frame(frame_buf, QUICEncryptionLevel::ONE_RTT, 16384, 16384, 0, 
0, nullptr);
   CHECK(sm.total_offset_sent() == 1024);
 
   // total_offset should be a integer in unit of octets
-  mock_app.send(reinterpret_cast<uint8_t *>(block_1024->buf()), 1024, 4);
+  mock_app->send(reinterpret_cast<uint8_t *>(block_1024->buf()), 1024, 4);
   sm.generate_frame(frame_buf, QUICEncryptionLevel::ONE_RTT, 16384, 16384, 0, 
0, nullptr);
   CHECK(sm.total_offset_sent() == 2048);
 
@@ -250,8 +247,7 @@ TEST_CASE("QUICStreamManager_max_streams", "[quic]")
   QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
   QUICApplicationMap app_map;
   MockQUICConnection connection;
-  MockQUICApplication mock_app(&connection);
-  app_map.set_default(&mock_app);
+  app_map.set_default(new MockQUICApplication(&connection));
   QUICStreamManagerImpl sm(&context, &app_map);
 
   uint8_t local_tp_buf[] = {
diff --git a/proxy/http3/QPACK.cc b/proxy/http3/QPACK.cc
index 092008de28..2e570756a3 100644
--- a/proxy/http3/QPACK.cc
+++ b/proxy/http3/QPACK.cc
@@ -148,7 +148,11 @@ QPACK::QPACK(QUICConnection *qc, uint32_t 
max_header_list_size, uint16_t max_tab
   this->_decoder_stream_sending_instructions_reader = 
this->_decoder_stream_sending_instructions->alloc_reader();
 }
 
-QPACK::~QPACK() {}
+QPACK::~QPACK()
+{
+  free_MIOBuffer(_encoder_stream_sending_instructions);
+  free_MIOBuffer(_decoder_stream_sending_instructions);
+}
 
 void
 QPACK::on_new_stream(QUICStream &stream)

Reply via email to