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 "I_EventSystem.h"
27 #include "QUICTypes.h"
28 #include "QUICFrame.h"
29 #include "QUICFrameGenerator.h"
30 #include "QUICLossDetector.h"
31 
32 class QUICRateAnalyzer
33 {
34 public:
35   void update(QUICOffset offset);
36   uint64_t expect_recv_bytes(ink_hrtime time);
37 
38 private:
39   double _rate           = 0.0;
40   ink_hrtime _start_time = Thread::get_hrtime();
41 };
42 
43 class QUICFlowController : public QUICFrameGenerator
44 {
45 public:
46   uint64_t credit() const;
47   QUICOffset current_offset() const;
48   virtual QUICOffset current_limit() const;
49 
50   /*
51    * Returns 0 if succeed
52    */
53   virtual int update(QUICOffset offset);
54   virtual void forward_limit(QUICOffset limit);
55 
56   /**
57    * This is only for flow controllers initialized without a limit (== UINT64_MAX).
58    * Once a limit is set, it should be updated with forward_limit().
59    */
60   virtual void set_limit(QUICOffset limit);
61 
62   // QUICFrameGenerator
63   bool will_generate_frame(QUICEncryptionLevel level, size_t current_packet_size, bool ack_eliciting, uint32_t seq_num) override;
64   QUICFrame *generate_frame(uint8_t *buf, QUICEncryptionLevel level, uint64_t connection_credit, uint16_t maximum_frame_size,
65                             size_t current_packet_size, uint32_t seq_num) override;
66 
67 protected:
QUICFlowController(uint64_t initial_limit)68   QUICFlowController(uint64_t initial_limit) : _limit(initial_limit) {}
69   virtual QUICFrame *_create_frame(uint8_t *buf) = 0;
70 
71   QUICOffset _offset        = 0; //< Largest sent/received offset
72   QUICOffset _limit         = 0; //< Maximum amount of data to send/receive
73   bool _should_create_frame = false;
74 };
75 
76 class QUICRemoteFlowController : public QUICFlowController
77 {
78 public:
QUICRemoteFlowController(uint64_t initial_limit)79   QUICRemoteFlowController(uint64_t initial_limit) : QUICFlowController(initial_limit) {}
80   int update(QUICOffset offset) override;
81   void forward_limit(QUICOffset new_limit) override;
82 
83 private:
84   void _on_frame_lost(QUICFrameInformationUPtr &info) override;
85   bool _blocked = false;
86 };
87 
88 class QUICLocalFlowController : public QUICFlowController
89 {
90 public:
QUICLocalFlowController(QUICRTTProvider * rtt_provider,uint64_t initial_limit)91   QUICLocalFlowController(QUICRTTProvider *rtt_provider, uint64_t initial_limit)
92     : QUICFlowController(initial_limit), _rtt_provider(rtt_provider)
93   {
94   }
95   QUICOffset current_limit() const override;
96 
97   /**
98    * Unlike QUICRemoteFlowController::forward_limit(), this function forwards limit if needed.
99    */
100   void forward_limit(QUICOffset new_limit) override;
101   int update(QUICOffset offset) override;
102   void set_limit(QUICOffset limit) override;
103 
104 private:
105   void _on_frame_lost(QUICFrameInformationUPtr &info) override;
106   bool _need_to_forward_limit();
107 
108   QUICRateAnalyzer _analyzer;
109   QUICRTTProvider *_rtt_provider = nullptr;
110 };
111 
112 class QUICRemoteConnectionFlowController : public QUICRemoteFlowController
113 {
114 public:
QUICRemoteConnectionFlowController(uint64_t initial_limit)115   QUICRemoteConnectionFlowController(uint64_t initial_limit) : QUICRemoteFlowController(initial_limit) {}
116   QUICFrame *_create_frame(uint8_t *buf) override;
117 };
118 
119 class QUICLocalConnectionFlowController : public QUICLocalFlowController
120 {
121 public:
QUICLocalConnectionFlowController(QUICRTTProvider * rtt_provider,uint64_t initial_limit)122   QUICLocalConnectionFlowController(QUICRTTProvider *rtt_provider, uint64_t initial_limit)
123     : QUICLocalFlowController(rtt_provider, initial_limit)
124   {
125   }
126   QUICFrame *_create_frame(uint8_t *buf) override;
127 };
128 
129 class QUICRemoteStreamFlowController : public QUICRemoteFlowController
130 {
131 public:
QUICRemoteStreamFlowController(uint64_t initial_limit,QUICStreamId stream_id)132   QUICRemoteStreamFlowController(uint64_t initial_limit, QUICStreamId stream_id)
133     : QUICRemoteFlowController(initial_limit), _stream_id(stream_id)
134   {
135   }
136   QUICFrame *_create_frame(uint8_t *buf) override;
137 
138 private:
139   QUICStreamId _stream_id = 0;
140 };
141 
142 class QUICLocalStreamFlowController : public QUICLocalFlowController
143 {
144 public:
QUICLocalStreamFlowController(QUICRTTProvider * rtt_provider,uint64_t initial_limit,QUICStreamId stream_id)145   QUICLocalStreamFlowController(QUICRTTProvider *rtt_provider, uint64_t initial_limit, QUICStreamId stream_id)
146     : QUICLocalFlowController(rtt_provider, initial_limit), _stream_id(stream_id)
147   {
148   }
149   QUICFrame *_create_frame(uint8_t *buf) override;
150 
151 private:
152   QUICStreamId _stream_id = 0;
153 };
154