{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Network.QUIC.Recovery.Release (
releaseByRetry,
releaseOldest,
discard,
onPacketsLost,
) where
import Data.Sequence (Seq, ViewL (..), ViewR (..), (><))
import qualified Data.Sequence as Seq
import UnliftIO.STM
import Network.QUIC.Imports
import Network.QUIC.Recovery.Metrics
import Network.QUIC.Recovery.PeerPacketNumbers
import Network.QUIC.Recovery.Types
import Network.QUIC.Recovery.Utils
import Network.QUIC.Types
discard :: LDCC -> EncryptionLevel -> IO (Seq SentPacket)
discard :: LDCC -> EncryptionLevel -> IO (Seq SentPacket)
discard 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 PacketNumber
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 PacketNumber
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 PacketNumber
peerPacketNumbers :: LDCC -> Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: LDCC -> IORef PeerPacketNumbers
timerInfoQ :: LDCC -> TVar TimerInfoQ
..} EncryptionLevel
lvl = do
Seq SentPacket
packets <- LDCC -> EncryptionLevel -> IO (Seq SentPacket)
releaseByClear LDCC
ldcc EncryptionLevel
lvl
LDCC -> Seq SentPacket -> IO ()
forall (m :: * -> *).
(Functor m, Foldable m) =>
LDCC -> m SentPacket -> IO ()
decreaseCC LDCC
ldcc Seq SentPacket
packets
IORef LossDetection -> LossDetection -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Array EncryptionLevel (IORef LossDetection)
lossDetection Array EncryptionLevel (IORef LossDetection)
-> EncryptionLevel -> IORef LossDetection
forall i e. Ix i => Array i e -> i -> e
! EncryptionLevel
lvl) LossDetection
initialLossDetection
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 = 0}
Seq SentPacket -> IO (Seq SentPacket)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Seq SentPacket
packets
releaseByClear :: LDCC -> EncryptionLevel -> IO (Seq SentPacket)
releaseByClear :: LDCC -> EncryptionLevel -> IO (Seq SentPacket)
releaseByClear 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 PacketNumber
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 PacketNumber
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 PacketNumber
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} EncryptionLevel
lvl = do
LDCC -> EncryptionLevel -> IO ()
clearPeerPacketNumbers LDCC
ldcc EncryptionLevel
lvl
IORef SentPackets
-> (SentPackets -> (SentPackets, Seq SentPacket))
-> IO (Seq SentPacket)
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' (Array EncryptionLevel (IORef SentPackets)
sentPackets Array EncryptionLevel (IORef SentPackets)
-> EncryptionLevel -> IORef SentPackets
forall i e. Ix i => Array i e -> i -> e
! EncryptionLevel
lvl) ((SentPackets -> (SentPackets, Seq SentPacket))
-> IO (Seq SentPacket))
-> (SentPackets -> (SentPackets, Seq SentPacket))
-> IO (Seq SentPacket)
forall a b. (a -> b) -> a -> b
$ \(SentPackets Seq SentPacket
db) ->
(SentPackets
emptySentPackets, Seq SentPacket
db)
releaseByRetry :: LDCC -> IO (Seq PlainPacket)
releaseByRetry :: LDCC -> IO (Seq PlainPacket)
releaseByRetry LDCC
ldcc = do
Seq SentPacket
packets <- LDCC -> EncryptionLevel -> IO (Seq SentPacket)
discard LDCC
ldcc EncryptionLevel
InitialLevel
Seq PlainPacket -> IO (Seq PlainPacket)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (SentPacket -> PlainPacket
spPlainPacket (SentPacket -> PlainPacket) -> Seq SentPacket -> Seq PlainPacket
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Seq SentPacket
packets)
releaseOldest :: LDCC -> EncryptionLevel -> IO (Maybe SentPacket)
releaseOldest :: LDCC -> EncryptionLevel -> IO (Maybe SentPacket)
releaseOldest 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 PacketNumber
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 PacketNumber
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 PacketNumber
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} EncryptionLevel
lvl = do
Maybe SentPacket
mr <- IORef SentPackets
-> (SentPackets -> (SentPackets, Maybe SentPacket))
-> IO (Maybe SentPacket)
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' (Array EncryptionLevel (IORef SentPackets)
sentPackets Array EncryptionLevel (IORef SentPackets)
-> EncryptionLevel -> IORef SentPackets
forall i e. Ix i => Array i e -> i -> e
! EncryptionLevel
lvl) SentPackets -> (SentPackets, Maybe SentPacket)
oldest
case Maybe SentPacket
mr of
Maybe SentPacket
Nothing -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just SentPacket
spkt -> do
LDCC -> EncryptionLevel -> PacketNumber -> IO ()
delPeerPacketNumbers LDCC
ldcc EncryptionLevel
lvl (PacketNumber -> IO ()) -> PacketNumber -> IO ()
forall a b. (a -> b) -> a -> b
$ SentPacket -> PacketNumber
spPacketNumber SentPacket
spkt
LDCC -> [SentPacket] -> IO ()
forall (m :: * -> *).
(Functor m, Foldable m) =>
LDCC -> m SentPacket -> IO ()
decreaseCC LDCC
ldcc [SentPacket
spkt]
Maybe SentPacket -> IO (Maybe SentPacket)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SentPacket
mr
where
oldest :: SentPackets -> (SentPackets, Maybe SentPacket)
oldest (SentPackets Seq SentPacket
db) = case Seq SentPacket -> ViewL SentPacket
forall a. Seq a -> ViewL a
Seq.viewl Seq SentPacket
db2 of
SentPacket
x :< Seq SentPacket
db2' ->
let db' :: Seq SentPacket
db' = Seq SentPacket
db1 Seq SentPacket -> Seq SentPacket -> Seq SentPacket
forall a. Seq a -> Seq a -> Seq a
>< Seq SentPacket
db2'
in (Seq SentPacket -> SentPackets
SentPackets Seq SentPacket
db', SentPacket -> Maybe SentPacket
forall a. a -> Maybe a
Just SentPacket
x)
ViewL SentPacket
_ -> (Seq SentPacket -> SentPackets
SentPackets Seq SentPacket
db, Maybe SentPacket
forall a. Maybe a
Nothing)
where
(Seq SentPacket
db1, Seq SentPacket
db2) = (SentPacket -> Bool)
-> Seq SentPacket -> (Seq SentPacket, Seq SentPacket)
forall a. (a -> Bool) -> Seq a -> (Seq a, Seq a)
Seq.breakl SentPacket -> Bool
spAckEliciting Seq SentPacket
db
onPacketsLost :: LDCC -> Seq SentPacket -> IO ()
onPacketsLost :: LDCC -> Seq SentPacket -> IO ()
onPacketsLost 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 PacketNumber
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 PacketNumber
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 PacketNumber
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} Seq SentPacket
lostPackets = case Seq SentPacket -> ViewR SentPacket
forall a. Seq a -> ViewR a
Seq.viewr Seq SentPacket
lostPackets of
ViewR SentPacket
EmptyR -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Seq SentPacket
_ :> SentPacket
lastPkt -> do
LDCC -> Seq SentPacket -> IO ()
forall (m :: * -> *).
(Functor m, Foldable m) =>
LDCC -> m SentPacket -> IO ()
decreaseCC LDCC
ldcc Seq SentPacket
lostPackets
Bool
isRecovery <-
TimeMicrosecond -> Maybe TimeMicrosecond -> Bool
inCongestionRecovery (SentPacket -> TimeMicrosecond
spTimeSent SentPacket
lastPkt) (Maybe TimeMicrosecond -> Bool)
-> (CC -> Maybe TimeMicrosecond) -> CC -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CC -> Maybe TimeMicrosecond
congestionRecoveryStartTime
(CC -> Bool) -> IO CC -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TVar CC -> IO CC
forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO TVar CC
recoveryCC
LDCC -> Seq SentPacket -> Bool -> IO ()
onCongestionEvent LDCC
ldcc Seq SentPacket
lostPackets Bool
isRecovery
(SentPacket -> IO ()) -> Seq SentPacket -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (LDCC -> LostPacket -> IO ()
forall q. KeepQlog q => q -> LostPacket -> IO ()
qlogPacketLost LDCC
ldcc (LostPacket -> IO ())
-> (SentPacket -> LostPacket) -> SentPacket -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SentPacket -> LostPacket
LostPacket) Seq SentPacket
lostPackets
where
onCongestionEvent :: LDCC -> Seq SentPacket -> Bool -> IO ()
onCongestionEvent = LDCC -> Seq SentPacket -> Bool -> IO ()
updateCC
decreaseCC :: (Functor m, Foldable m) => LDCC -> m SentPacket -> IO ()
decreaseCC :: forall (m :: * -> *).
(Functor m, Foldable m) =>
LDCC -> m SentPacket -> IO ()
decreaseCC 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 PacketNumber
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 PacketNumber
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 PacketNumber
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
previousRTT1PPNs :: IORef PeerPacketNumbers
timerInfoQ :: TVar TimerInfoQ
..} m SentPacket
packets = do
let sentBytes :: PacketNumber
sentBytes = m PacketNumber -> PacketNumber
forall (f :: * -> *).
(Functor f, Foldable f) =>
f PacketNumber -> PacketNumber
sum' (SentPacket -> PacketNumber
spSentBytes (SentPacket -> PacketNumber) -> m SentPacket -> m PacketNumber
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m SentPacket
packets)
num :: PacketNumber
num = m PacketNumber -> PacketNumber
forall (f :: * -> *).
(Functor f, Foldable f) =>
f PacketNumber -> PacketNumber
sum' (SentPacket -> PacketNumber
countAckEli (SentPacket -> PacketNumber) -> m SentPacket -> m PacketNumber
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m SentPacket
packets)
LDCC -> IO () -> IO ()
metricsUpdated LDCC
ldcc (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
STM () -> IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$
TVar CC -> (CC -> CC) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
modifyTVar' TVar CC
recoveryCC ((CC -> CC) -> STM ()) -> (CC -> CC) -> STM ()
forall a b. (a -> b) -> a -> b
$ \CC
cc ->
CC
cc
{ bytesInFlight = bytesInFlight cc - sentBytes
, numOfAckEliciting = numOfAckEliciting cc - num
}