mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-10-31 00:08:08 -04:00
88 lines
2.9 KiB
Go
88 lines
2.9 KiB
Go
package flowcontrol
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/congestion"
|
|
"v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/protocol"
|
|
"v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/qerr"
|
|
"v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/utils"
|
|
)
|
|
|
|
type connectionFlowController struct {
|
|
baseFlowController
|
|
|
|
queueWindowUpdate func()
|
|
}
|
|
|
|
var _ ConnectionFlowController = &connectionFlowController{}
|
|
|
|
// NewConnectionFlowController gets a new flow controller for the connection
|
|
// It is created before we receive the peer's transport paramenters, thus it starts with a sendWindow of 0.
|
|
func NewConnectionFlowController(
|
|
receiveWindow protocol.ByteCount,
|
|
maxReceiveWindow protocol.ByteCount,
|
|
queueWindowUpdate func(),
|
|
rttStats *congestion.RTTStats,
|
|
logger utils.Logger,
|
|
) ConnectionFlowController {
|
|
return &connectionFlowController{
|
|
baseFlowController: baseFlowController{
|
|
rttStats: rttStats,
|
|
receiveWindow: receiveWindow,
|
|
receiveWindowSize: receiveWindow,
|
|
maxReceiveWindowSize: maxReceiveWindow,
|
|
logger: logger,
|
|
},
|
|
queueWindowUpdate: queueWindowUpdate,
|
|
}
|
|
}
|
|
|
|
func (c *connectionFlowController) SendWindowSize() protocol.ByteCount {
|
|
return c.baseFlowController.sendWindowSize()
|
|
}
|
|
|
|
// IncrementHighestReceived adds an increment to the highestReceived value
|
|
func (c *connectionFlowController) IncrementHighestReceived(increment protocol.ByteCount) error {
|
|
c.mutex.Lock()
|
|
defer c.mutex.Unlock()
|
|
|
|
c.highestReceived += increment
|
|
if c.checkFlowControlViolation() {
|
|
return qerr.Error(qerr.FlowControlReceivedTooMuchData, fmt.Sprintf("Received %d bytes for the connection, allowed %d bytes", c.highestReceived, c.receiveWindow))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *connectionFlowController) MaybeQueueWindowUpdate() {
|
|
c.mutex.Lock()
|
|
hasWindowUpdate := c.hasWindowUpdate()
|
|
c.mutex.Unlock()
|
|
if hasWindowUpdate {
|
|
c.queueWindowUpdate()
|
|
}
|
|
}
|
|
|
|
func (c *connectionFlowController) GetWindowUpdate() protocol.ByteCount {
|
|
c.mutex.Lock()
|
|
oldWindowSize := c.receiveWindowSize
|
|
offset := c.baseFlowController.getWindowUpdate()
|
|
if oldWindowSize < c.receiveWindowSize {
|
|
c.logger.Debugf("Increasing receive flow control window for the connection to %d kB", c.receiveWindowSize/(1<<10))
|
|
}
|
|
c.mutex.Unlock()
|
|
return offset
|
|
}
|
|
|
|
// EnsureMinimumWindowSize sets a minimum window size
|
|
// it should make sure that the connection-level window is increased when a stream-level window grows
|
|
func (c *connectionFlowController) EnsureMinimumWindowSize(inc protocol.ByteCount) {
|
|
c.mutex.Lock()
|
|
if inc > c.receiveWindowSize {
|
|
c.logger.Debugf("Increasing receive flow control window for the connection to %d kB, in response to stream flow control window increase", c.receiveWindowSize/(1<<10))
|
|
c.receiveWindowSize = utils.MinByteCount(inc, c.maxReceiveWindowSize)
|
|
c.startNewAutoTuningEpoch()
|
|
}
|
|
c.mutex.Unlock()
|
|
}
|