blob: 3ff183827e6f16c7f7227528a9abc42e8bef2475 [file] [log] [blame]
/** @file
*
* A brief file description
*
* @section license License
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "I_EventSystem.h"
#include "QUICTypes.h"
#include "QUICFrame.h"
#include "QUICFrameGenerator.h"
#include "QUICLossDetector.h"
class QUICRateAnalyzer
{
public:
void update(QUICOffset offset);
uint64_t expect_recv_bytes(ink_hrtime time) const;
private:
double _rate = 0.0;
ink_hrtime _start_time = Thread::get_hrtime();
};
class QUICFlowController : public QUICFrameGenerator
{
public:
uint64_t credit() const;
QUICOffset current_offset() const;
virtual QUICOffset current_limit() const;
/*
* Returns 0 if succeed
*/
virtual int update(QUICOffset offset);
virtual void forward_limit(QUICOffset limit);
/**
* This is only for flow controllers initialized without a limit (== UINT64_MAX).
* Once a limit is set, it should be updated with forward_limit().
*/
virtual void set_limit(QUICOffset limit);
// QUICFrameGenerator
bool will_generate_frame(QUICEncryptionLevel level, size_t current_packet_size, bool ack_eliciting, uint32_t seq_num) override;
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) override;
protected:
QUICFlowController(uint64_t initial_limit) : _limit(initial_limit) {}
virtual QUICFrame *_create_frame(uint8_t *buf) = 0;
QUICOffset _offset = 0; //< Largest sent/received offset
QUICOffset _limit = 0; //< Maximum amount of data to send/receive
bool _should_create_frame = false;
};
class QUICRemoteFlowController : public QUICFlowController
{
public:
QUICRemoteFlowController(uint64_t initial_limit) : QUICFlowController(initial_limit) {}
int update(QUICOffset offset) override;
void forward_limit(QUICOffset new_limit) override;
private:
void _on_frame_lost(QUICFrameInformationUPtr &info) override;
bool _blocked = false;
};
class QUICLocalFlowController : public QUICFlowController
{
public:
QUICLocalFlowController(QUICRTTProvider *rtt_provider, uint64_t initial_limit)
: QUICFlowController(initial_limit), _rtt_provider(rtt_provider)
{
}
QUICOffset current_limit() const override;
/**
* Unlike QUICRemoteFlowController::forward_limit(), this function forwards limit if needed.
*/
void forward_limit(QUICOffset new_limit) override;
int update(QUICOffset offset) override;
void set_limit(QUICOffset limit) override;
private:
void _on_frame_lost(QUICFrameInformationUPtr &info) override;
bool _need_to_forward_limit();
QUICRateAnalyzer _analyzer;
QUICRTTProvider *_rtt_provider = nullptr;
};
class QUICRemoteConnectionFlowController : public QUICRemoteFlowController
{
public:
QUICRemoteConnectionFlowController(uint64_t initial_limit) : QUICRemoteFlowController(initial_limit) {}
QUICFrame *_create_frame(uint8_t *buf) override;
};
class QUICLocalConnectionFlowController : public QUICLocalFlowController
{
public:
QUICLocalConnectionFlowController(QUICRTTProvider *rtt_provider, uint64_t initial_limit)
: QUICLocalFlowController(rtt_provider, initial_limit)
{
}
QUICFrame *_create_frame(uint8_t *buf) override;
};
class QUICRemoteStreamFlowController : public QUICRemoteFlowController
{
public:
QUICRemoteStreamFlowController(uint64_t initial_limit, QUICStreamId stream_id)
: QUICRemoteFlowController(initial_limit), _stream_id(stream_id)
{
}
QUICFrame *_create_frame(uint8_t *buf) override;
private:
QUICStreamId _stream_id = 0;
};
class QUICLocalStreamFlowController : public QUICLocalFlowController
{
public:
QUICLocalStreamFlowController(QUICRTTProvider *rtt_provider, uint64_t initial_limit, QUICStreamId stream_id)
: QUICLocalFlowController(rtt_provider, initial_limit), _stream_id(stream_id)
{
}
QUICFrame *_create_frame(uint8_t *buf) override;
private:
QUICStreamId _stream_id = 0;
};