{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TupleSections #-}
module Network.QUIC.Recovery.Timer (
getLossTimeAndSpace,
getPtoTimeAndSpace,
setLossDetectionTimer,
beforeAntiAmp,
ldccTimer,
) where
import qualified Data.Sequence as Seq
import Network.QUIC.Event
import UnliftIO.STM
import Network.QUIC.Connector
import Network.QUIC.Imports
import Network.QUIC.Qlog
import Network.QUIC.Recovery.Constants
import Network.QUIC.Recovery.Detect
import Network.QUIC.Recovery.Metrics
import Network.QUIC.Recovery.Misc
import Network.QUIC.Recovery.Persistent
import Network.QUIC.Recovery.Release
import Network.QUIC.Recovery.Types
import Network.QUIC.Recovery.Utils
import Network.QUIC.Types
noInFlightPacket :: LDCC -> EncryptionLevel -> IO Bool
noInFlightPacket :: LDCC -> EncryptionLevel -> IO Bool
noInFlightPacket LDCC{Array EncryptionLevel (IORef Bool)
Array EncryptionLevel (IORef PeerPacketNumbers)
Array EncryptionLevel (IORef LossDetection)
Array EncryptionLevel (IORef SentPackets)
TVar (Maybe EncryptionLevel)
TVar TimerInfoQ
TVar CC
TVar SentPackets
IORef Bool
IORef Int
IORef (Maybe TimeoutKey)
IORef (Maybe TimerInfo)
IORef PeerPacketNumbers
IORef RTT
ConnState
PlainPacket -> IO ()
QLogger
ldccState :: ConnState
ldccQlogger :: QLogger
putRetrans :: PlainPacket -> IO ()
recoveryRTT :: IORef RTT
recoveryCC :: TVar CC
spaceDiscarded :: Array EncryptionLevel (IORef Bool)
sentPackets :: Array EncryptionLevel (IORef SentPackets)
lossDetection :: Array EncryptionLevel (IORef LossDetection)
timerKey :: IORef (Maybe TimeoutKey)
timerInfo :: IORef (Maybe TimerInfo)
lostCandidates :: TVar SentPackets
ptoPing :: TVar (Maybe EncryptionLevel)
speedingUp :: IORef Bool
pktNumPersistent :: IORef Int
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
ldccState :: LDCC -> ConnState
ldccQlogger :: LDCC -> QLogger
putRetrans :: LDCC -> PlainPacket -> IO ()
recoveryRTT :: LDCC -> IORef RTT
recoveryCC :: LDCC -> TVar CC
spaceDiscarded :: LDCC -> Array EncryptionLevel (IORef Bool)
sentPackets :: LDCC -> Array EncryptionLevel (IORef SentPackets)
lossDetection :: LDCC -> Array EncryptionLevel (IORef LossDetection)
timerKey :: LDCC -> IORef (Maybe TimeoutKey)
timerInfo :: LDCC -> IORef (Maybe TimerInfo)
lostCandidates :: LDCC -> TVar SentPackets
ptoPing :: LDCC -> TVar (Maybe EncryptionLevel)
speedingUp :: LDCC -> IORef Bool
pktNumPersistent :: LDCC -> IORef Int
peerPacketNumbers :: LDCC -> Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: LDCC -> IORef PeerPacketNumbers
timerInfoQ :: LDCC -> TVar TimerInfoQ
..} EncryptionLevel
lvl = do
SentPackets Seq SentPacket
db <- IORef SentPackets -> IO SentPackets
forall a. IORef a -> IO a
readIORef (Array EncryptionLevel (IORef SentPackets)
sentPackets Array EncryptionLevel (IORef SentPackets)
-> EncryptionLevel -> IORef SentPackets
forall i e. Ix i => Array i e -> i -> e
! EncryptionLevel
lvl)
Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ Seq SentPacket -> Bool
forall a. Seq a -> Bool
Seq.null Seq SentPacket
db
getLossTimeAndSpace :: LDCC -> IO (Maybe (TimeMicrosecond, EncryptionLevel))
getLossTimeAndSpace :: LDCC -> IO (Maybe (TimeMicrosecond, EncryptionLevel))
getLossTimeAndSpace LDCC{Array EncryptionLevel (IORef Bool)
Array EncryptionLevel (IORef PeerPacketNumbers)
Array EncryptionLevel (IORef LossDetection)
Array EncryptionLevel (IORef SentPackets)
TVar (Maybe EncryptionLevel)
TVar TimerInfoQ
TVar CC
TVar SentPackets
IORef Bool
IORef Int
IORef (Maybe TimeoutKey)
IORef (Maybe TimerInfo)
IORef PeerPacketNumbers
IORef RTT
ConnState
PlainPacket -> IO ()
QLogger
ldccState :: LDCC -> ConnState
ldccQlogger :: LDCC -> QLogger
putRetrans :: LDCC -> PlainPacket -> IO ()
recoveryRTT :: LDCC -> IORef RTT
recoveryCC :: LDCC -> TVar CC
spaceDiscarded :: LDCC -> Array EncryptionLevel (IORef Bool)
sentPackets :: LDCC -> Array EncryptionLevel (IORef SentPackets)
lossDetection :: LDCC -> Array EncryptionLevel (IORef LossDetection)
timerKey :: LDCC -> IORef (Maybe TimeoutKey)
timerInfo :: LDCC -> IORef (Maybe TimerInfo)
lostCandidates :: LDCC -> TVar SentPackets
ptoPing :: LDCC -> TVar (Maybe EncryptionLevel)
speedingUp :: LDCC -> IORef Bool
pktNumPersistent :: LDCC -> IORef Int
peerPacketNumbers :: LDCC -> Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: LDCC -> IORef PeerPacketNumbers
timerInfoQ :: LDCC -> TVar TimerInfoQ
ldccState :: ConnState
ldccQlogger :: QLogger
putRetrans :: PlainPacket -> IO ()
recoveryRTT :: IORef RTT
recoveryCC :: TVar CC
spaceDiscarded :: Array EncryptionLevel (IORef Bool)
sentPackets :: Array EncryptionLevel (IORef SentPackets)
lossDetection :: Array EncryptionLevel (IORef LossDetection)
timerKey :: IORef (Maybe TimeoutKey)
timerInfo :: IORef (Maybe TimerInfo)
lostCandidates :: TVar SentPackets
ptoPing :: TVar (Maybe EncryptionLevel)
speedingUp :: IORef Bool
pktNumPersistent :: IORef Int
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} =
[EncryptionLevel]
-> Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
loop [EncryptionLevel
InitialLevel, EncryptionLevel
HandshakeLevel, EncryptionLevel
RTT1Level] Maybe (TimeMicrosecond, EncryptionLevel)
forall a. Maybe a
Nothing
where
loop :: [EncryptionLevel]
-> Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
loop [] Maybe (TimeMicrosecond, EncryptionLevel)
r = Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (TimeMicrosecond, EncryptionLevel)
r
loop (EncryptionLevel
l : [EncryptionLevel]
ls) Maybe (TimeMicrosecond, EncryptionLevel)
r = do
Maybe TimeMicrosecond
mt <- LossDetection -> Maybe TimeMicrosecond
lossTime (LossDetection -> Maybe TimeMicrosecond)
-> IO LossDetection -> IO (Maybe TimeMicrosecond)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef LossDetection -> IO LossDetection
forall a. IORef a -> IO a
readIORef (Array EncryptionLevel (IORef LossDetection)
lossDetection Array EncryptionLevel (IORef LossDetection)
-> EncryptionLevel -> IORef LossDetection
forall i e. Ix i => Array i e -> i -> e
! EncryptionLevel
l)
case Maybe TimeMicrosecond
mt of
Maybe TimeMicrosecond
Nothing -> [EncryptionLevel]
-> Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
loop [EncryptionLevel]
ls Maybe (TimeMicrosecond, EncryptionLevel)
r
Just TimeMicrosecond
t -> case Maybe (TimeMicrosecond, EncryptionLevel)
r of
Maybe (TimeMicrosecond, EncryptionLevel)
Nothing -> [EncryptionLevel]
-> Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
loop [EncryptionLevel]
ls (Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel)))
-> Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
forall a b. (a -> b) -> a -> b
$ (TimeMicrosecond, EncryptionLevel)
-> Maybe (TimeMicrosecond, EncryptionLevel)
forall a. a -> Maybe a
Just (TimeMicrosecond
t, EncryptionLevel
l)
Just (TimeMicrosecond
t0, EncryptionLevel
_)
| TimeMicrosecond
t TimeMicrosecond -> TimeMicrosecond -> Bool
forall a. Ord a => a -> a -> Bool
< TimeMicrosecond
t0 -> [EncryptionLevel]
-> Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
loop [EncryptionLevel]
ls (Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel)))
-> Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
forall a b. (a -> b) -> a -> b
$ (TimeMicrosecond, EncryptionLevel)
-> Maybe (TimeMicrosecond, EncryptionLevel)
forall a. a -> Maybe a
Just (TimeMicrosecond
t, EncryptionLevel
l)
| Bool
otherwise -> [EncryptionLevel]
-> Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
loop [EncryptionLevel]
ls Maybe (TimeMicrosecond, EncryptionLevel)
r
getPtoTimeAndSpace :: LDCC -> IO (Maybe (TimeMicrosecond, EncryptionLevel))
getPtoTimeAndSpace :: LDCC -> IO (Maybe (TimeMicrosecond, EncryptionLevel))
getPtoTimeAndSpace ldcc :: LDCC
ldcc@LDCC{Array EncryptionLevel (IORef Bool)
Array EncryptionLevel (IORef PeerPacketNumbers)
Array EncryptionLevel (IORef LossDetection)
Array EncryptionLevel (IORef SentPackets)
TVar (Maybe EncryptionLevel)
TVar TimerInfoQ
TVar CC
TVar SentPackets
IORef Bool
IORef Int
IORef (Maybe TimeoutKey)
IORef (Maybe TimerInfo)
IORef PeerPacketNumbers
IORef RTT
ConnState
PlainPacket -> IO ()
QLogger
ldccState :: LDCC -> ConnState
ldccQlogger :: LDCC -> QLogger
putRetrans :: LDCC -> PlainPacket -> IO ()
recoveryRTT :: LDCC -> IORef RTT
recoveryCC :: LDCC -> TVar CC
spaceDiscarded :: LDCC -> Array EncryptionLevel (IORef Bool)
sentPackets :: LDCC -> Array EncryptionLevel (IORef SentPackets)
lossDetection :: LDCC -> Array EncryptionLevel (IORef LossDetection)
timerKey :: LDCC -> IORef (Maybe TimeoutKey)
timerInfo :: LDCC -> IORef (Maybe TimerInfo)
lostCandidates :: LDCC -> TVar SentPackets
ptoPing :: LDCC -> TVar (Maybe EncryptionLevel)
speedingUp :: LDCC -> IORef Bool
pktNumPersistent :: LDCC -> IORef Int
peerPacketNumbers :: LDCC -> Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: LDCC -> IORef PeerPacketNumbers
timerInfoQ :: LDCC -> TVar TimerInfoQ
ldccState :: ConnState
ldccQlogger :: QLogger
putRetrans :: PlainPacket -> IO ()
recoveryRTT :: IORef RTT
recoveryCC :: TVar CC
spaceDiscarded :: Array EncryptionLevel (IORef Bool)
sentPackets :: Array EncryptionLevel (IORef SentPackets)
lossDetection :: Array EncryptionLevel (IORef LossDetection)
timerKey :: IORef (Maybe TimeoutKey)
timerInfo :: IORef (Maybe TimerInfo)
lostCandidates :: TVar SentPackets
ptoPing :: TVar (Maybe EncryptionLevel)
speedingUp :: IORef Bool
pktNumPersistent :: IORef Int
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} = do
CC{Int
Maybe TimeMicrosecond
CCMode
bytesInFlight :: Int
congestionWindow :: Int
congestionRecoveryStartTime :: Maybe TimeMicrosecond
ssthresh :: Int
bytesAcked :: Int
numOfAckEliciting :: Int
ccMode :: CCMode
bytesInFlight :: CC -> Int
congestionWindow :: CC -> Int
congestionRecoveryStartTime :: CC -> Maybe TimeMicrosecond
ssthresh :: CC -> Int
bytesAcked :: CC -> Int
numOfAckEliciting :: CC -> Int
ccMode :: CC -> CCMode
..} <- TVar CC -> IO CC
forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO TVar CC
recoveryCC
if Int
bytesInFlight Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0
then do
Bool
validated <- LDCC -> IO Bool
peerCompletedAddressValidation LDCC
ldcc
if Bool
validated
then do
LDCC -> Debug -> IO ()
forall q. KeepQlog q => q -> Debug -> IO ()
qlogDebug LDCC
ldcc (Debug -> IO ()) -> Debug -> IO ()
forall a b. (a -> b) -> a -> b
$ LogStr -> Debug
Debug LogStr
"getPtoTimeAndSpace: validated"
Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (TimeMicrosecond, EncryptionLevel)
forall a. Maybe a
Nothing
else do
RTT
rtt <- IORef RTT -> IO RTT
forall a. IORef a -> IO a
readIORef IORef RTT
recoveryRTT
EncryptionLevel
lvl <- LDCC -> IO EncryptionLevel
forall a. Connector a => a -> IO EncryptionLevel
getEncryptionLevel LDCC
ldcc
let pto :: Microseconds
pto = Microseconds -> Int -> Microseconds
backOff (RTT -> Maybe EncryptionLevel -> Microseconds
calcPTO RTT
rtt (Maybe EncryptionLevel -> Microseconds)
-> Maybe EncryptionLevel -> Microseconds
forall a b. (a -> b) -> a -> b
$ EncryptionLevel -> Maybe EncryptionLevel
forall a. a -> Maybe a
Just EncryptionLevel
lvl) (RTT -> Int
ptoCount RTT
rtt)
TimeMicrosecond
ptoTime <- Microseconds -> IO TimeMicrosecond
getFutureTimeMicrosecond Microseconds
pto
Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel)))
-> Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
forall a b. (a -> b) -> a -> b
$ (TimeMicrosecond, EncryptionLevel)
-> Maybe (TimeMicrosecond, EncryptionLevel)
forall a. a -> Maybe a
Just (TimeMicrosecond
ptoTime, EncryptionLevel
lvl)
else do
Bool
completed <- LDCC -> IO Bool
forall a. Connector a => a -> IO Bool
isConnectionEstablished LDCC
ldcc
let lvls :: [EncryptionLevel]
lvls
| Bool
completed = [EncryptionLevel
InitialLevel, EncryptionLevel
HandshakeLevel, EncryptionLevel
RTT1Level]
| Bool
otherwise = [EncryptionLevel
InitialLevel, EncryptionLevel
HandshakeLevel]
[EncryptionLevel] -> IO (Maybe (TimeMicrosecond, EncryptionLevel))
loop [EncryptionLevel]
lvls
where
loop :: [EncryptionLevel] -> IO (Maybe (TimeMicrosecond, EncryptionLevel))
loop :: [EncryptionLevel] -> IO (Maybe (TimeMicrosecond, EncryptionLevel))
loop [] = Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (TimeMicrosecond, EncryptionLevel)
forall a. Maybe a
Nothing
loop (EncryptionLevel
l : [EncryptionLevel]
ls) = do
Bool
notInFlight <- LDCC -> EncryptionLevel -> IO Bool
noInFlightPacket LDCC
ldcc EncryptionLevel
l
if Bool
notInFlight
then [EncryptionLevel] -> IO (Maybe (TimeMicrosecond, EncryptionLevel))
loop [EncryptionLevel]
ls
else do
LossDetection{Int
Maybe TimeMicrosecond
TimeMicrosecond
AckInfo
lossTime :: LossDetection -> Maybe TimeMicrosecond
largestAckedPacket :: Int
previousAckInfo :: AckInfo
timeOfLastAckElicitingPacket :: TimeMicrosecond
lossTime :: Maybe TimeMicrosecond
largestAckedPacket :: LossDetection -> Int
previousAckInfo :: LossDetection -> AckInfo
timeOfLastAckElicitingPacket :: LossDetection -> TimeMicrosecond
..} <- IORef LossDetection -> IO LossDetection
forall a. IORef a -> IO a
readIORef (Array EncryptionLevel (IORef LossDetection)
lossDetection Array EncryptionLevel (IORef LossDetection)
-> EncryptionLevel -> IORef LossDetection
forall i e. Ix i => Array i e -> i -> e
! EncryptionLevel
l)
if TimeMicrosecond
timeOfLastAckElicitingPacket TimeMicrosecond -> TimeMicrosecond -> Bool
forall a. Eq a => a -> a -> Bool
== TimeMicrosecond
timeMicrosecond0
then [EncryptionLevel] -> IO (Maybe (TimeMicrosecond, EncryptionLevel))
loop [EncryptionLevel]
ls
else do
RTT
rtt <- IORef RTT -> IO RTT
forall a. IORef a -> IO a
readIORef IORef RTT
recoveryRTT
let pto0 :: Microseconds
pto0 = Microseconds -> Int -> Microseconds
backOff (RTT -> Maybe EncryptionLevel -> Microseconds
calcPTO RTT
rtt (Maybe EncryptionLevel -> Microseconds)
-> Maybe EncryptionLevel -> Microseconds
forall a b. (a -> b) -> a -> b
$ EncryptionLevel -> Maybe EncryptionLevel
forall a. a -> Maybe a
Just EncryptionLevel
l) (RTT -> Int
ptoCount RTT
rtt)
pto :: Microseconds
pto = Microseconds -> Microseconds -> Microseconds
forall a. Ord a => a -> a -> a
max Microseconds
pto0 Microseconds
kGranularity
ptoTime :: TimeMicrosecond
ptoTime = TimeMicrosecond
timeOfLastAckElicitingPacket TimeMicrosecond -> Microseconds -> TimeMicrosecond
`addMicroseconds` Microseconds
pto
Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel)))
-> Maybe (TimeMicrosecond, EncryptionLevel)
-> IO (Maybe (TimeMicrosecond, EncryptionLevel))
forall a b. (a -> b) -> a -> b
$ (TimeMicrosecond, EncryptionLevel)
-> Maybe (TimeMicrosecond, EncryptionLevel)
forall a. a -> Maybe a
Just (TimeMicrosecond
ptoTime, EncryptionLevel
l)
cancelLossDetectionTimer :: LDCC -> IO ()
cancelLossDetectionTimer :: LDCC -> IO ()
cancelLossDetectionTimer ldcc :: LDCC
ldcc@LDCC{Array EncryptionLevel (IORef Bool)
Array EncryptionLevel (IORef PeerPacketNumbers)
Array EncryptionLevel (IORef LossDetection)
Array EncryptionLevel (IORef SentPackets)
TVar (Maybe EncryptionLevel)
TVar TimerInfoQ
TVar CC
TVar SentPackets
IORef Bool
IORef Int
IORef (Maybe TimeoutKey)
IORef (Maybe TimerInfo)
IORef PeerPacketNumbers
IORef RTT
ConnState
PlainPacket -> IO ()
QLogger
ldccState :: LDCC -> ConnState
ldccQlogger :: LDCC -> QLogger
putRetrans :: LDCC -> PlainPacket -> IO ()
recoveryRTT :: LDCC -> IORef RTT
recoveryCC :: LDCC -> TVar CC
spaceDiscarded :: LDCC -> Array EncryptionLevel (IORef Bool)
sentPackets :: LDCC -> Array EncryptionLevel (IORef SentPackets)
lossDetection :: LDCC -> Array EncryptionLevel (IORef LossDetection)
timerKey :: LDCC -> IORef (Maybe TimeoutKey)
timerInfo :: LDCC -> IORef (Maybe TimerInfo)
lostCandidates :: LDCC -> TVar SentPackets
ptoPing :: LDCC -> TVar (Maybe EncryptionLevel)
speedingUp :: LDCC -> IORef Bool
pktNumPersistent :: LDCC -> IORef Int
peerPacketNumbers :: LDCC -> Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: LDCC -> IORef PeerPacketNumbers
timerInfoQ :: LDCC -> TVar TimerInfoQ
ldccState :: ConnState
ldccQlogger :: QLogger
putRetrans :: PlainPacket -> IO ()
recoveryRTT :: IORef RTT
recoveryCC :: TVar CC
spaceDiscarded :: Array EncryptionLevel (IORef Bool)
sentPackets :: Array EncryptionLevel (IORef SentPackets)
lossDetection :: Array EncryptionLevel (IORef LossDetection)
timerKey :: IORef (Maybe TimeoutKey)
timerInfo :: IORef (Maybe TimerInfo)
lostCandidates :: TVar SentPackets
ptoPing :: TVar (Maybe EncryptionLevel)
speedingUp :: IORef Bool
pktNumPersistent :: IORef Int
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} = do
STM () -> IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TVar TimerInfoQ -> TimerInfoQ -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar TimerInfoQ
timerInfoQ TimerInfoQ
Empty
Maybe TimeoutKey
mk <- IORef (Maybe TimeoutKey)
-> (Maybe TimeoutKey -> (Maybe TimeoutKey, Maybe TimeoutKey))
-> IO (Maybe TimeoutKey)
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef (Maybe TimeoutKey)
timerKey (Maybe TimeoutKey
forall a. Maybe a
Nothing,)
Maybe TimeoutKey -> (TimeoutKey -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ Maybe TimeoutKey
mk ((TimeoutKey -> IO ()) -> IO ()) -> (TimeoutKey -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \TimeoutKey
k -> do
TimerManager
mgr <- IO TimerManager
getSystemTimerManager
TimerManager -> TimeoutKey -> IO ()
unregisterTimeout TimerManager
mgr TimeoutKey
k
IORef (Maybe TimerInfo) -> Maybe TimerInfo -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe TimerInfo)
timerInfo Maybe TimerInfo
forall a. Maybe a
Nothing
LDCC -> IO ()
forall q. KeepQlog q => q -> IO ()
qlogLossTimerCancelled LDCC
ldcc
updateLossDetectionTimer :: LDCC -> TimerInfo -> IO ()
updateLossDetectionTimer :: LDCC -> TimerInfo -> IO ()
updateLossDetectionTimer ldcc :: LDCC
ldcc@LDCC{Array EncryptionLevel (IORef Bool)
Array EncryptionLevel (IORef PeerPacketNumbers)
Array EncryptionLevel (IORef LossDetection)
Array EncryptionLevel (IORef SentPackets)
TVar (Maybe EncryptionLevel)
TVar TimerInfoQ
TVar CC
TVar SentPackets
IORef Bool
IORef Int
IORef (Maybe TimeoutKey)
IORef (Maybe TimerInfo)
IORef PeerPacketNumbers
IORef RTT
ConnState
PlainPacket -> IO ()
QLogger
ldccState :: LDCC -> ConnState
ldccQlogger :: LDCC -> QLogger
putRetrans :: LDCC -> PlainPacket -> IO ()
recoveryRTT :: LDCC -> IORef RTT
recoveryCC :: LDCC -> TVar CC
spaceDiscarded :: LDCC -> Array EncryptionLevel (IORef Bool)
sentPackets :: LDCC -> Array EncryptionLevel (IORef SentPackets)
lossDetection :: LDCC -> Array EncryptionLevel (IORef LossDetection)
timerKey :: LDCC -> IORef (Maybe TimeoutKey)
timerInfo :: LDCC -> IORef (Maybe TimerInfo)
lostCandidates :: LDCC -> TVar SentPackets
ptoPing :: LDCC -> TVar (Maybe EncryptionLevel)
speedingUp :: LDCC -> IORef Bool
pktNumPersistent :: LDCC -> IORef Int
peerPacketNumbers :: LDCC -> Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: LDCC -> IORef PeerPacketNumbers
timerInfoQ :: LDCC -> TVar TimerInfoQ
ldccState :: ConnState
ldccQlogger :: QLogger
putRetrans :: PlainPacket -> IO ()
recoveryRTT :: IORef RTT
recoveryCC :: TVar CC
spaceDiscarded :: Array EncryptionLevel (IORef Bool)
sentPackets :: Array EncryptionLevel (IORef SentPackets)
lossDetection :: Array EncryptionLevel (IORef LossDetection)
timerKey :: IORef (Maybe TimeoutKey)
timerInfo :: IORef (Maybe TimerInfo)
lostCandidates :: TVar SentPackets
ptoPing :: TVar (Maybe EncryptionLevel)
speedingUp :: IORef Bool
pktNumPersistent :: IORef Int
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} TimerInfo
tmi = do
Maybe TimerInfo
mtmi <- IORef (Maybe TimerInfo) -> IO (Maybe TimerInfo)
forall a. IORef a -> IO a
readIORef IORef (Maybe TimerInfo)
timerInfo
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Maybe TimerInfo
mtmi Maybe TimerInfo -> Maybe TimerInfo -> Bool
forall a. Eq a => a -> a -> Bool
/= TimerInfo -> Maybe TimerInfo
forall a. a -> Maybe a
Just TimerInfo
tmi) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
if TimerInfo -> EncryptionLevel
timerLevel TimerInfo
tmi EncryptionLevel -> EncryptionLevel -> Bool
forall a. Eq a => a -> a -> Bool
== EncryptionLevel
RTT1Level
then STM () -> IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TVar TimerInfoQ -> TimerInfoQ -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar TimerInfoQ
timerInfoQ (TimerInfoQ -> STM ()) -> TimerInfoQ -> STM ()
forall a b. (a -> b) -> a -> b
$ TimerInfo -> TimerInfoQ
Next TimerInfo
tmi
else LDCC -> TimerInfo -> IO ()
updateLossDetectionTimer' LDCC
ldcc TimerInfo
tmi
ldccTimer :: LDCC -> IO ()
ldccTimer :: LDCC -> IO ()
ldccTimer ldcc :: LDCC
ldcc@LDCC{Array EncryptionLevel (IORef Bool)
Array EncryptionLevel (IORef PeerPacketNumbers)
Array EncryptionLevel (IORef LossDetection)
Array EncryptionLevel (IORef SentPackets)
TVar (Maybe EncryptionLevel)
TVar TimerInfoQ
TVar CC
TVar SentPackets
IORef Bool
IORef Int
IORef (Maybe TimeoutKey)
IORef (Maybe TimerInfo)
IORef PeerPacketNumbers
IORef RTT
ConnState
PlainPacket -> IO ()
QLogger
ldccState :: LDCC -> ConnState
ldccQlogger :: LDCC -> QLogger
putRetrans :: LDCC -> PlainPacket -> IO ()
recoveryRTT :: LDCC -> IORef RTT
recoveryCC :: LDCC -> TVar CC
spaceDiscarded :: LDCC -> Array EncryptionLevel (IORef Bool)
sentPackets :: LDCC -> Array EncryptionLevel (IORef SentPackets)
lossDetection :: LDCC -> Array EncryptionLevel (IORef LossDetection)
timerKey :: LDCC -> IORef (Maybe TimeoutKey)
timerInfo :: LDCC -> IORef (Maybe TimerInfo)
lostCandidates :: LDCC -> TVar SentPackets
ptoPing :: LDCC -> TVar (Maybe EncryptionLevel)
speedingUp :: LDCC -> IORef Bool
pktNumPersistent :: LDCC -> IORef Int
peerPacketNumbers :: LDCC -> Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: LDCC -> IORef PeerPacketNumbers
timerInfoQ :: LDCC -> TVar TimerInfoQ
ldccState :: ConnState
ldccQlogger :: QLogger
putRetrans :: PlainPacket -> IO ()
recoveryRTT :: IORef RTT
recoveryCC :: TVar CC
spaceDiscarded :: Array EncryptionLevel (IORef Bool)
sentPackets :: Array EncryptionLevel (IORef SentPackets)
lossDetection :: Array EncryptionLevel (IORef LossDetection)
timerKey :: IORef (Maybe TimeoutKey)
timerInfo :: IORef (Maybe TimerInfo)
lostCandidates :: TVar SentPackets
ptoPing :: TVar (Maybe EncryptionLevel)
speedingUp :: IORef Bool
pktNumPersistent :: IORef Int
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} = IO () -> IO ()
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
STM () -> IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
TimerInfoQ
x <- TVar TimerInfoQ -> STM TimerInfoQ
forall a. TVar a -> STM a
readTVar TVar TimerInfoQ
timerInfoQ
Bool -> STM ()
checkSTM (TimerInfoQ
x TimerInfoQ -> TimerInfoQ -> Bool
forall a. Eq a => a -> a -> Bool
/= TimerInfoQ
Empty)
Microseconds -> IO ()
delay Microseconds
timerGranularity
LDCC -> IO ()
updateWithNext LDCC
ldcc
updateWithNext :: LDCC -> IO ()
updateWithNext :: LDCC -> IO ()
updateWithNext ldcc :: LDCC
ldcc@LDCC{Array EncryptionLevel (IORef Bool)
Array EncryptionLevel (IORef PeerPacketNumbers)
Array EncryptionLevel (IORef LossDetection)
Array EncryptionLevel (IORef SentPackets)
TVar (Maybe EncryptionLevel)
TVar TimerInfoQ
TVar CC
TVar SentPackets
IORef Bool
IORef Int
IORef (Maybe TimeoutKey)
IORef (Maybe TimerInfo)
IORef PeerPacketNumbers
IORef RTT
ConnState
PlainPacket -> IO ()
QLogger
ldccState :: LDCC -> ConnState
ldccQlogger :: LDCC -> QLogger
putRetrans :: LDCC -> PlainPacket -> IO ()
recoveryRTT :: LDCC -> IORef RTT
recoveryCC :: LDCC -> TVar CC
spaceDiscarded :: LDCC -> Array EncryptionLevel (IORef Bool)
sentPackets :: LDCC -> Array EncryptionLevel (IORef SentPackets)
lossDetection :: LDCC -> Array EncryptionLevel (IORef LossDetection)
timerKey :: LDCC -> IORef (Maybe TimeoutKey)
timerInfo :: LDCC -> IORef (Maybe TimerInfo)
lostCandidates :: LDCC -> TVar SentPackets
ptoPing :: LDCC -> TVar (Maybe EncryptionLevel)
speedingUp :: LDCC -> IORef Bool
pktNumPersistent :: LDCC -> IORef Int
peerPacketNumbers :: LDCC -> Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: LDCC -> IORef PeerPacketNumbers
timerInfoQ :: LDCC -> TVar TimerInfoQ
ldccState :: ConnState
ldccQlogger :: QLogger
putRetrans :: PlainPacket -> IO ()
recoveryRTT :: IORef RTT
recoveryCC :: TVar CC
spaceDiscarded :: Array EncryptionLevel (IORef Bool)
sentPackets :: Array EncryptionLevel (IORef SentPackets)
lossDetection :: Array EncryptionLevel (IORef LossDetection)
timerKey :: IORef (Maybe TimeoutKey)
timerInfo :: IORef (Maybe TimerInfo)
lostCandidates :: TVar SentPackets
ptoPing :: TVar (Maybe EncryptionLevel)
speedingUp :: IORef Bool
pktNumPersistent :: IORef Int
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} = do
TimerInfoQ
x <- TVar TimerInfoQ -> IO TimerInfoQ
forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO TVar TimerInfoQ
timerInfoQ
case TimerInfoQ
x of
TimerInfoQ
Empty -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Next TimerInfo
tmi -> LDCC -> TimerInfo -> IO ()
updateLossDetectionTimer' LDCC
ldcc TimerInfo
tmi
updateLossDetectionTimer' :: LDCC -> TimerInfo -> IO ()
updateLossDetectionTimer' :: LDCC -> TimerInfo -> IO ()
updateLossDetectionTimer' ldcc :: LDCC
ldcc@LDCC{Array EncryptionLevel (IORef Bool)
Array EncryptionLevel (IORef PeerPacketNumbers)
Array EncryptionLevel (IORef LossDetection)
Array EncryptionLevel (IORef SentPackets)
TVar (Maybe EncryptionLevel)
TVar TimerInfoQ
TVar CC
TVar SentPackets
IORef Bool
IORef Int
IORef (Maybe TimeoutKey)
IORef (Maybe TimerInfo)
IORef PeerPacketNumbers
IORef RTT
ConnState
PlainPacket -> IO ()
QLogger
ldccState :: LDCC -> ConnState
ldccQlogger :: LDCC -> QLogger
putRetrans :: LDCC -> PlainPacket -> IO ()
recoveryRTT :: LDCC -> IORef RTT
recoveryCC :: LDCC -> TVar CC
spaceDiscarded :: LDCC -> Array EncryptionLevel (IORef Bool)
sentPackets :: LDCC -> Array EncryptionLevel (IORef SentPackets)
lossDetection :: LDCC -> Array EncryptionLevel (IORef LossDetection)
timerKey :: LDCC -> IORef (Maybe TimeoutKey)
timerInfo :: LDCC -> IORef (Maybe TimerInfo)
lostCandidates :: LDCC -> TVar SentPackets
ptoPing :: LDCC -> TVar (Maybe EncryptionLevel)
speedingUp :: LDCC -> IORef Bool
pktNumPersistent :: LDCC -> IORef Int
peerPacketNumbers :: LDCC -> Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: LDCC -> IORef PeerPacketNumbers
timerInfoQ :: LDCC -> TVar TimerInfoQ
ldccState :: ConnState
ldccQlogger :: QLogger
putRetrans :: PlainPacket -> IO ()
recoveryRTT :: IORef RTT
recoveryCC :: TVar CC
spaceDiscarded :: Array EncryptionLevel (IORef Bool)
sentPackets :: Array EncryptionLevel (IORef SentPackets)
lossDetection :: Array EncryptionLevel (IORef LossDetection)
timerKey :: IORef (Maybe TimeoutKey)
timerInfo :: IORef (Maybe TimerInfo)
lostCandidates :: TVar SentPackets
ptoPing :: TVar (Maybe EncryptionLevel)
speedingUp :: IORef Bool
pktNumPersistent :: IORef Int
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} TimerInfo
tmi = do
STM () -> IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TVar TimerInfoQ -> TimerInfoQ -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar TimerInfoQ
timerInfoQ TimerInfoQ
Empty
let tim :: TimeMicrosecond
tim = TimerInfo -> TimeMicrosecond
timerTime TimerInfo
tmi
Microseconds Int
us0 <- TimeMicrosecond -> IO Microseconds
getTimeoutInMicrosecond TimeMicrosecond
tim
let us :: Int
us
| Int
us0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = Int
10000
| Bool
otherwise = Int
us0
Int -> IO ()
update Int
us
LDCC -> (TimerInfo, Microseconds) -> IO ()
forall q. KeepQlog q => q -> (TimerInfo, Microseconds) -> IO ()
qlogLossTimerUpdated LDCC
ldcc (TimerInfo
tmi, Int -> Microseconds
Microseconds Int
us)
where
update :: Int -> IO ()
update Int
us = do
TimerManager
mgr <- IO TimerManager
getSystemTimerManager
TimeoutKey
key <- TimerManager -> Int -> IO () -> IO TimeoutKey
registerTimeout TimerManager
mgr Int
us (LDCC -> IO ()
onLossDetectionTimeout LDCC
ldcc)
Maybe TimeoutKey
mk <- IORef (Maybe TimeoutKey)
-> (Maybe TimeoutKey -> (Maybe TimeoutKey, Maybe TimeoutKey))
-> IO (Maybe TimeoutKey)
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef (Maybe TimeoutKey)
timerKey (TimeoutKey -> Maybe TimeoutKey
forall a. a -> Maybe a
Just TimeoutKey
key,)
Maybe TimeoutKey -> (TimeoutKey -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ Maybe TimeoutKey
mk ((TimeoutKey -> IO ()) -> IO ()) -> (TimeoutKey -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ TimerManager -> TimeoutKey -> IO ()
unregisterTimeout TimerManager
mgr
IORef (Maybe TimerInfo) -> Maybe TimerInfo -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe TimerInfo)
timerInfo (Maybe TimerInfo -> IO ()) -> Maybe TimerInfo -> IO ()
forall a b. (a -> b) -> a -> b
$ TimerInfo -> Maybe TimerInfo
forall a. a -> Maybe a
Just TimerInfo
tmi
setLossDetectionTimer :: LDCC -> EncryptionLevel -> IO ()
setLossDetectionTimer :: LDCC -> EncryptionLevel -> IO ()
setLossDetectionTimer ldcc :: LDCC
ldcc@LDCC{Array EncryptionLevel (IORef Bool)
Array EncryptionLevel (IORef PeerPacketNumbers)
Array EncryptionLevel (IORef LossDetection)
Array EncryptionLevel (IORef SentPackets)
TVar (Maybe EncryptionLevel)
TVar TimerInfoQ
TVar CC
TVar SentPackets
IORef Bool
IORef Int
IORef (Maybe TimeoutKey)
IORef (Maybe TimerInfo)
IORef PeerPacketNumbers
IORef RTT
ConnState
PlainPacket -> IO ()
QLogger
ldccState :: LDCC -> ConnState
ldccQlogger :: LDCC -> QLogger
putRetrans :: LDCC -> PlainPacket -> IO ()
recoveryRTT :: LDCC -> IORef RTT
recoveryCC :: LDCC -> TVar CC
spaceDiscarded :: LDCC -> Array EncryptionLevel (IORef Bool)
sentPackets :: LDCC -> Array EncryptionLevel (IORef SentPackets)
lossDetection :: LDCC -> Array EncryptionLevel (IORef LossDetection)
timerKey :: LDCC -> IORef (Maybe TimeoutKey)
timerInfo :: LDCC -> IORef (Maybe TimerInfo)
lostCandidates :: LDCC -> TVar SentPackets
ptoPing :: LDCC -> TVar (Maybe EncryptionLevel)
speedingUp :: LDCC -> IORef Bool
pktNumPersistent :: LDCC -> IORef Int
peerPacketNumbers :: LDCC -> Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: LDCC -> IORef PeerPacketNumbers
timerInfoQ :: LDCC -> TVar TimerInfoQ
ldccState :: ConnState
ldccQlogger :: QLogger
putRetrans :: PlainPacket -> IO ()
recoveryRTT :: IORef RTT
recoveryCC :: TVar CC
spaceDiscarded :: Array EncryptionLevel (IORef Bool)
sentPackets :: Array EncryptionLevel (IORef SentPackets)
lossDetection :: Array EncryptionLevel (IORef LossDetection)
timerKey :: IORef (Maybe TimeoutKey)
timerInfo :: IORef (Maybe TimerInfo)
lostCandidates :: TVar SentPackets
ptoPing :: TVar (Maybe EncryptionLevel)
speedingUp :: IORef Bool
pktNumPersistent :: IORef Int
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} EncryptionLevel
lvl0 = do
Maybe (TimeMicrosecond, EncryptionLevel)
mtl <- LDCC -> IO (Maybe (TimeMicrosecond, EncryptionLevel))
getLossTimeAndSpace LDCC
ldcc
case Maybe (TimeMicrosecond, EncryptionLevel)
mtl of
Just (TimeMicrosecond
earliestLossTime, EncryptionLevel
lvl) -> do
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl0 EncryptionLevel -> EncryptionLevel -> Bool
forall a. Eq a => a -> a -> Bool
== EncryptionLevel
lvl) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let tmi :: TimerInfo
tmi = TimeMicrosecond -> EncryptionLevel -> TimerType -> TimerInfo
TimerInfo TimeMicrosecond
earliestLossTime EncryptionLevel
lvl TimerType
LossTime
LDCC -> TimerInfo -> IO ()
updateLossDetectionTimer LDCC
ldcc TimerInfo
tmi
Maybe (TimeMicrosecond, EncryptionLevel)
Nothing -> do
CC{Int
Maybe TimeMicrosecond
CCMode
bytesInFlight :: CC -> Int
congestionWindow :: CC -> Int
congestionRecoveryStartTime :: CC -> Maybe TimeMicrosecond
ssthresh :: CC -> Int
bytesAcked :: CC -> Int
numOfAckEliciting :: CC -> Int
ccMode :: CC -> CCMode
bytesInFlight :: Int
congestionWindow :: Int
congestionRecoveryStartTime :: Maybe TimeMicrosecond
ssthresh :: Int
bytesAcked :: Int
numOfAckEliciting :: Int
ccMode :: CCMode
..} <- TVar CC -> IO CC
forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO TVar CC
recoveryCC
Bool
validated <- LDCC -> IO Bool
peerCompletedAddressValidation LDCC
ldcc
if Int
numOfAckEliciting Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 Bool -> Bool -> Bool
&& Bool
validated
then
LDCC -> IO ()
cancelLossDetectionTimer LDCC
ldcc
else do
Maybe (TimeMicrosecond, EncryptionLevel)
mx <- LDCC -> IO (Maybe (TimeMicrosecond, EncryptionLevel))
getPtoTimeAndSpace LDCC
ldcc
case Maybe (TimeMicrosecond, EncryptionLevel)
mx of
Maybe (TimeMicrosecond, EncryptionLevel)
Nothing -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just (TimeMicrosecond
ptoTime, EncryptionLevel
lvl) -> do
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl0 EncryptionLevel -> EncryptionLevel -> Bool
forall a. Eq a => a -> a -> Bool
== EncryptionLevel
lvl) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let tmi :: TimerInfo
tmi = TimeMicrosecond -> EncryptionLevel -> TimerType -> TimerInfo
TimerInfo TimeMicrosecond
ptoTime EncryptionLevel
lvl TimerType
PTO
LDCC -> TimerInfo -> IO ()
updateLossDetectionTimer LDCC
ldcc TimerInfo
tmi
beforeAntiAmp :: LDCC -> IO ()
beforeAntiAmp :: LDCC -> IO ()
beforeAntiAmp LDCC
ldcc = LDCC -> IO ()
cancelLossDetectionTimer LDCC
ldcc
onLossDetectionTimeout :: LDCC -> IO ()
onLossDetectionTimeout :: LDCC -> IO ()
onLossDetectionTimeout ldcc :: LDCC
ldcc@LDCC{Array EncryptionLevel (IORef Bool)
Array EncryptionLevel (IORef PeerPacketNumbers)
Array EncryptionLevel (IORef LossDetection)
Array EncryptionLevel (IORef SentPackets)
TVar (Maybe EncryptionLevel)
TVar TimerInfoQ
TVar CC
TVar SentPackets
IORef Bool
IORef Int
IORef (Maybe TimeoutKey)
IORef (Maybe TimerInfo)
IORef PeerPacketNumbers
IORef RTT
ConnState
PlainPacket -> IO ()
QLogger
ldccState :: LDCC -> ConnState
ldccQlogger :: LDCC -> QLogger
putRetrans :: LDCC -> PlainPacket -> IO ()
recoveryRTT :: LDCC -> IORef RTT
recoveryCC :: LDCC -> TVar CC
spaceDiscarded :: LDCC -> Array EncryptionLevel (IORef Bool)
sentPackets :: LDCC -> Array EncryptionLevel (IORef SentPackets)
lossDetection :: LDCC -> Array EncryptionLevel (IORef LossDetection)
timerKey :: LDCC -> IORef (Maybe TimeoutKey)
timerInfo :: LDCC -> IORef (Maybe TimerInfo)
lostCandidates :: LDCC -> TVar SentPackets
ptoPing :: LDCC -> TVar (Maybe EncryptionLevel)
speedingUp :: LDCC -> IORef Bool
pktNumPersistent :: LDCC -> IORef Int
peerPacketNumbers :: LDCC -> Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: LDCC -> IORef PeerPacketNumbers
timerInfoQ :: LDCC -> TVar TimerInfoQ
ldccState :: ConnState
ldccQlogger :: QLogger
putRetrans :: PlainPacket -> IO ()
recoveryRTT :: IORef RTT
recoveryCC :: TVar CC
spaceDiscarded :: Array EncryptionLevel (IORef Bool)
sentPackets :: Array EncryptionLevel (IORef SentPackets)
lossDetection :: Array EncryptionLevel (IORef LossDetection)
timerKey :: IORef (Maybe TimeoutKey)
timerInfo :: IORef (Maybe TimerInfo)
lostCandidates :: TVar SentPackets
ptoPing :: TVar (Maybe EncryptionLevel)
speedingUp :: IORef Bool
pktNumPersistent :: IORef Int
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} = do
Bool
alive <- LDCC -> IO Bool
forall a. Connector a => a -> IO Bool
getAlive LDCC
ldcc
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
alive (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
Maybe TimerInfo
mtmi <- IORef (Maybe TimerInfo) -> IO (Maybe TimerInfo)
forall a. IORef a -> IO a
readIORef IORef (Maybe TimerInfo)
timerInfo
case Maybe TimerInfo
mtmi of
Maybe TimerInfo
Nothing -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just TimerInfo
tmi -> do
let lvl :: EncryptionLevel
lvl = TimerInfo -> EncryptionLevel
timerLevel TimerInfo
tmi
Bool
discarded <- LDCC -> EncryptionLevel -> IO Bool
getPacketNumberSpaceDiscarded LDCC
ldcc EncryptionLevel
lvl
if Bool
discarded
then LDCC -> IO ()
updateWithNext LDCC
ldcc
else EncryptionLevel -> TimerInfo -> IO ()
lossTimeOrPTO EncryptionLevel
lvl TimerInfo
tmi
where
lossTimeOrPTO :: EncryptionLevel -> TimerInfo -> IO ()
lossTimeOrPTO EncryptionLevel
lvl TimerInfo
tmi = do
LDCC -> IO ()
forall q. KeepQlog q => q -> IO ()
qlogLossTimerExpired LDCC
ldcc
case TimerInfo -> TimerType
timerType TimerInfo
tmi of
TimerType
LossTime -> do
Seq SentPacket
lostPackets <- LDCC -> EncryptionLevel -> IO (Seq SentPacket)
detectAndRemoveLostPackets LDCC
ldcc EncryptionLevel
lvl
Seq SentPacket
lostPackets' <- LDCC -> Seq SentPacket -> IO (Seq SentPacket)
mergeLostCandidatesAndClear LDCC
ldcc Seq SentPacket
lostPackets
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Seq SentPacket -> Bool
forall a. Seq a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Seq SentPacket
lostPackets') (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ LDCC -> Debug -> IO ()
forall q. KeepQlog q => q -> Debug -> IO ()
qlogDebug LDCC
ldcc (Debug -> IO ()) -> Debug -> IO ()
forall a b. (a -> b) -> a -> b
$ LogStr -> Debug
Debug LogStr
"onLossDetectionTimeout: null"
LDCC -> Seq SentPacket -> IO ()
onPacketsLost LDCC
ldcc Seq SentPacket
lostPackets'
LDCC -> Seq SentPacket -> IO ()
retransmit LDCC
ldcc Seq SentPacket
lostPackets'
LDCC -> EncryptionLevel -> IO ()
setLossDetectionTimer LDCC
ldcc EncryptionLevel
lvl
TimerType
PTO -> do
CC{Int
Maybe TimeMicrosecond
CCMode
bytesInFlight :: CC -> Int
congestionWindow :: CC -> Int
congestionRecoveryStartTime :: CC -> Maybe TimeMicrosecond
ssthresh :: CC -> Int
bytesAcked :: CC -> Int
numOfAckEliciting :: CC -> Int
ccMode :: CC -> CCMode
bytesInFlight :: Int
congestionWindow :: Int
congestionRecoveryStartTime :: Maybe TimeMicrosecond
ssthresh :: Int
bytesAcked :: Int
numOfAckEliciting :: Int
ccMode :: CCMode
..} <- TVar CC -> IO CC
forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO TVar CC
recoveryCC
if Int
bytesInFlight Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
then do
LDCC -> EncryptionLevel -> IO ()
sendPing LDCC
ldcc EncryptionLevel
lvl
else do
Bool
validated <- LDCC -> IO Bool
peerCompletedAddressValidation LDCC
ldcc
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
validated (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ LDCC -> Debug -> IO ()
forall q. KeepQlog q => q -> Debug -> IO ()
qlogDebug LDCC
ldcc (Debug -> IO ()) -> Debug -> IO ()
forall a b. (a -> b) -> a -> b
$ LogStr -> Debug
Debug LogStr
"onLossDetectionTimeout: RTT1"
EncryptionLevel
lvl' <- LDCC -> IO EncryptionLevel
forall a. Connector a => a -> IO EncryptionLevel
getEncryptionLevel LDCC
ldcc
LDCC -> EncryptionLevel -> IO ()
sendPing LDCC
ldcc EncryptionLevel
lvl'
LDCC -> IO () -> IO ()
metricsUpdated LDCC
ldcc (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
IORef RTT -> (RTT -> RTT) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
atomicModifyIORef'' IORef RTT
recoveryRTT ((RTT -> RTT) -> IO ()) -> (RTT -> RTT) -> IO ()
forall a b. (a -> b) -> a -> b
$
\RTT
rtt -> RTT
rtt{ptoCount = ptoCount rtt + 1}
LDCC -> EncryptionLevel -> IO ()
setLossDetectionTimer LDCC
ldcc EncryptionLevel
lvl