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

duke8253 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 fb2f2d6c50 enforce more CONTROL stream rules (#9908)
fb2f2d6c50 is described below

commit fb2f2d6c50e25f4ee4781a61c2030d07d5a44671
Author: Fei Deng <[email protected]>
AuthorDate: Mon Jun 26 12:35:05 2023 -0500

    enforce more CONTROL stream rules (#9908)
---
 proxy/http3/Http3App.cc              | 17 +++++++++++++++--
 proxy/http3/Http3App.h               |  2 ++
 proxy/http3/Http3ProtocolEnforcer.cc |  5 +++++
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/proxy/http3/Http3App.cc b/proxy/http3/Http3App.cc
index 91cb43a5d9..1ec6182852 100644
--- a/proxy/http3/Http3App.cc
+++ b/proxy/http3/Http3App.cc
@@ -192,6 +192,7 @@ Http3App::create_uni_stream(QUICStreamId &new_stream_id, 
Http3StreamType type)
 void
 Http3App::_handle_uni_stream_on_read_ready(int /* event */, VIO *vio)
 {
+  Http3ErrorUPtr error = Http3ErrorUPtr(new Http3NoError());
   Http3StreamType type;
   QUICStreamVCAdapter *adapter = static_cast<QUICStreamVCAdapter 
*>(vio->vc_server);
   auto it                      = 
this->_remote_uni_stream_map.find(adapter->stream().id());
@@ -213,10 +214,22 @@ Http3App::_handle_uni_stream_on_read_ready(int /* event 
*/, VIO *vio)
   }
 
   switch (type) {
-  case Http3StreamType::CONTROL:
-  case Http3StreamType::PUSH: {
+  case Http3StreamType::CONTROL: {
+    if (this->_control_stream_id == 0) {
+      this->_control_stream_id = adapter->stream().id();
+    } else if (this->_control_stream_id != adapter->stream().id()) {
+      error = 
std::make_unique<Http3ConnectionError>(Http3ErrorCode::H3_STREAM_CREATION_ERROR,
+                                                     "Only one control stream 
per peer is permitted");
+      Debug("http3", "Only one control stream per peer is permitted");
+      break;
+    }
     uint64_t nread = 0;
     this->_control_stream_dispatcher.on_read_ready(adapter->stream().id(), 
type, *vio->get_reader(), nread);
+    break;
+  }
+  case Http3StreamType::PUSH: {
+    error = 
std::make_unique<Http3ConnectionError>(Http3ErrorCode::H3_STREAM_CREATION_ERROR,
 "Only servers can push");
+    Debug("http3", "Only servers can push");
     // TODO: when PUSH comes from client, send stream error with 
HTTP_WRONG_STREAM_DIRECTION
     break;
   }
diff --git a/proxy/http3/Http3App.h b/proxy/http3/Http3App.h
index 4ae5a7f27d..5fdf2a6355 100644
--- a/proxy/http3/Http3App.h
+++ b/proxy/http3/Http3App.h
@@ -65,6 +65,8 @@ protected:
 
   std::unordered_map<QUICStreamId, QUICStreamVCAdapter::IOInfo> _streams;
 
+  QUICStreamId _control_stream_id = 0;
+
 private:
   void _handle_uni_stream_on_read_ready(int event, VIO *vio);
   void _handle_uni_stream_on_write_ready(int event, VIO *vio);
diff --git a/proxy/http3/Http3ProtocolEnforcer.cc 
b/proxy/http3/Http3ProtocolEnforcer.cc
index cd19fbdaa9..9a90cda451 100644
--- a/proxy/http3/Http3ProtocolEnforcer.cc
+++ b/proxy/http3/Http3ProtocolEnforcer.cc
@@ -22,6 +22,7 @@
  */
 
 #include "Http3ProtocolEnforcer.h"
+#include "Http3DebugNames.h"
 
 std::vector<Http3FrameType>
 Http3ProtocolEnforcer::interests()
@@ -45,6 +46,10 @@ Http3ProtocolEnforcer::handle_frame(std::shared_ptr<const 
Http3Frame> frame, int
     } else if (frame_seq != 0 && f_type == Http3FrameType::SETTINGS) {
       error = 
std::make_unique<Http3ConnectionError>(Http3ErrorCode::H3_FRAME_UNEXPECTED,
                                                      "only one SETTINGS frame 
is allowed per the control stream");
+    } else if (f_type == Http3FrameType::DATA || f_type == 
Http3FrameType::HEADERS) {
+      std::string error_msg = Http3DebugNames::frame_type(f_type);
+      error_msg.append(" frame is not allowed on control stream");
+      error = 
std::make_unique<Http3ConnectionError>(Http3ErrorCode::H3_FRAME_UNEXPECTED, 
error_msg.c_str());
     }
   }
   return error;

Reply via email to