1 /** @file
2  *
3  *  A brief file description
4  *
5  *  @section license License
6  *
7  *  Licensed to the Apache Software Foundation (ASF) under one
8  *  or more contributor license agreements.  See the NOTICE file
9  *  distributed with this work for additional information
10  *  regarding copyright ownership.  The ASF licenses this file
11  *  to you under the Apache License, Version 2.0 (the
12  *  "License"); you may not use this file except in compliance
13  *  with the License.  You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  *  Unless required by applicable law or agreed to in writing, software
18  *  distributed under the License is distributed on an "AS IS" BASIS,
19  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  *  See the License for the specific language governing permissions and
21  *  limitations under the License.
22  */
23 
24 #pragma once
25 
26 #include "QUICFrame.h"
27 #include "QUICFrameRetransmitter.h"
28 
29 class QUICFrameGenerator
30 {
31 public:
~QUICFrameGenerator()32   virtual ~QUICFrameGenerator(){};
33   virtual bool will_generate_frame(QUICEncryptionLevel level, size_t current_packet_size, bool ack_eliciting, uint32_t seq_num) = 0;
34 
35   /*
36    * This function constructs an instance of QUICFrame on buf.
37    * It returns a pointer for the frame if it succeeded, and returns nullptr if it failed.
38    */
39   virtual QUICFrame *generate_frame(uint8_t *buf, QUICEncryptionLevel level, uint64_t connection_credit,
40                                     uint16_t maximum_frame_size, size_t current_packet_size, uint32_t seq_num) = 0;
41 
42   void on_frame_acked(QUICFrameId id);
43   void on_frame_lost(QUICFrameId id);
44 
45 protected:
46   QUICFrameId
_issue_frame_id()47   _issue_frame_id()
48   {
49     return this->_latest_frame_Id++;
50   }
51 
52   virtual void
_on_frame_acked(QUICFrameInformationUPtr & info)53   _on_frame_acked(QUICFrameInformationUPtr &info)
54   {
55   }
56 
57   virtual void
_on_frame_lost(QUICFrameInformationUPtr & info)58   _on_frame_lost(QUICFrameInformationUPtr &info)
59   {
60   }
61 
62   virtual bool _is_level_matched(QUICEncryptionLevel level);
63   void _records_frame(QUICFrameId id, QUICFrameInformationUPtr info);
64 
65 private:
66   QUICFrameId _latest_frame_Id                 = 0;
67   QUICEncryptionLevel _encryption_level_filter = QUICEncryptionLevel::ONE_RTT;
68   std::map<QUICFrameId, QUICFrameInformationUPtr> _info;
69 };
70 
71 // only generate one frame per loop
72 class QUICFrameOnceGenerator : public QUICFrameGenerator
73 {
74 public:
75   bool
will_generate_frame(QUICEncryptionLevel level,size_t current_packet_size,bool ack_eliciting,uint32_t seq_num)76   will_generate_frame(QUICEncryptionLevel level, size_t current_packet_size, bool ack_eliciting, uint32_t seq_num) override
77   {
78     if (this->_seq_num == seq_num) {
79       return false;
80     }
81 
82     this->_seq_num = seq_num;
83     return this->_will_generate_frame(level, current_packet_size, ack_eliciting);
84   }
85 
86   QUICFrame *
generate_frame(uint8_t * buf,QUICEncryptionLevel level,uint64_t connection_credit,uint16_t maximum_frame_size,size_t current_packet_size,uint32_t seq_num)87   generate_frame(uint8_t *buf, QUICEncryptionLevel level, uint64_t connection_credit, uint16_t maximum_frame_size,
88                  size_t current_packet_size, uint32_t seq_num) override
89   {
90     this->_seq_num = seq_num;
91     return this->_generate_frame(buf, level, connection_credit, maximum_frame_size, current_packet_size);
92   }
93 
94 protected:
95   virtual bool _will_generate_frame(QUICEncryptionLevel level, size_t current_packet_size, bool ack_eliciting) = 0;
96   virtual QUICFrame *_generate_frame(uint8_t *buf, QUICEncryptionLevel level, uint64_t connection_credit,
97                                      uint16_t maximum_frame_size, size_t current_packet_size)                  = 0;
98 
99 private:
100   uint32_t _seq_num = UINT32_MAX;
101 };
102 
103 enum QUICFrameGeneratorWeight {
104   EARLY       = 100,
105   BEFORE_DATA = 200,
106   AFTER_DATA  = 300,
107   LATE        = 400,
108 };
109 
110 class QUICFrameGeneratorManager
111 {
112 public:
113   void add_generator(QUICFrameGenerator &generator, int weight);
114   const std::vector<QUICFrameGenerator *> &generators();
115 
116 private:
117   using QUICActiveFrameGenerator = std::pair<int, QUICFrameGenerator *>;
118 
119   std::vector<QUICFrameGenerator *> _generators;
120   std::vector<QUICActiveFrameGenerator> _inline_vector;
121 };
122