{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

module Network.QUIC.Recovery.Types (
    SentPacket (..),
    mkSentPacket,
    fixSentPacket,
    LostPacket (..),
    SentPackets (..),
    emptySentPackets,
    RTT (..),
    initialRTT,
    CCMode (..),
    CC (..),
    initialCC,
    LossDetection (..),
    initialLossDetection,
    MetricsDiff (..),
    TimerType (..),
    TimerInfo (..),
    TimerInfoQ (..),
    TimerCancelled,
    TimerExpired,
    makeSentPackets,
    makeLossDetection,
    LDCC (..),
    newLDCC,
    qlogSent,
    qlogMetricsUpdated,
    qlogPacketLost,
    qlogContestionStateUpdated,
    qlogLossTimerUpdated,
    qlogLossTimerCancelled,
    qlogLossTimerExpired,
) where

import Data.IORef
import Data.List (intersperse)
import Data.Sequence (Seq)
import qualified Data.Sequence as Seq
import Network.QUIC.Event
import System.Log.FastLogger
import UnliftIO.STM

import Network.QUIC.Connector
import Network.QUIC.Imports
import Network.QUIC.Qlog
import Network.QUIC.Types

----------------------------------------------------------------

data SentPacket = SentPacket
    { SentPacket -> PlainPacket
spPlainPacket :: PlainPacket
    , SentPacket -> TimeMicrosecond
spTimeSent :: TimeMicrosecond
    , SentPacket -> Int
spSentBytes :: Int
    , SentPacket -> EncryptionLevel
spEncryptionLevel :: EncryptionLevel
    , SentPacket -> Int
spPacketNumber :: PacketNumber
    , SentPacket -> PeerPacketNumbers
spPeerPacketNumbers :: PeerPacketNumbers
    , SentPacket -> Bool
spAckEliciting :: Bool
    }
    deriving (SentPacket -> SentPacket -> Bool
(SentPacket -> SentPacket -> Bool)
-> (SentPacket -> SentPacket -> Bool) -> Eq SentPacket
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SentPacket -> SentPacket -> Bool
== :: SentPacket -> SentPacket -> Bool
$c/= :: SentPacket -> SentPacket -> Bool
/= :: SentPacket -> SentPacket -> Bool
Eq, Int -> SentPacket -> ShowS
[SentPacket] -> ShowS
SentPacket -> String
(Int -> SentPacket -> ShowS)
-> (SentPacket -> String)
-> ([SentPacket] -> ShowS)
-> Show SentPacket
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SentPacket -> ShowS
showsPrec :: Int -> SentPacket -> ShowS
$cshow :: SentPacket -> String
show :: SentPacket -> String
$cshowList :: [SentPacket] -> ShowS
showList :: [SentPacket] -> ShowS
Show)

instance Ord SentPacket where
    SentPacket
x <= :: SentPacket -> SentPacket -> Bool
<= SentPacket
y = SentPacket -> Int
spPacketNumber SentPacket
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= SentPacket -> Int
spPacketNumber SentPacket
y

newtype LostPacket = LostPacket SentPacket

mkSentPacket
    :: PacketNumber
    -> EncryptionLevel
    -> PlainPacket
    -> PeerPacketNumbers
    -> Bool
    -> SentPacket
mkSentPacket :: Int
-> EncryptionLevel
-> PlainPacket
-> PeerPacketNumbers
-> Bool
-> SentPacket
mkSentPacket Int
mypn EncryptionLevel
lvl PlainPacket
ppkt PeerPacketNumbers
ppns Bool
ackeli =
    SentPacket
        { spPlainPacket :: PlainPacket
spPlainPacket = PlainPacket
ppkt
        , spTimeSent :: TimeMicrosecond
spTimeSent = TimeMicrosecond
timeMicrosecond0
        , spSentBytes :: Int
spSentBytes = Int
0
        , spEncryptionLevel :: EncryptionLevel
spEncryptionLevel = EncryptionLevel
lvl
        , spPacketNumber :: Int
spPacketNumber = Int
mypn
        , spPeerPacketNumbers :: PeerPacketNumbers
spPeerPacketNumbers = PeerPacketNumbers
ppns
        , spAckEliciting :: Bool
spAckEliciting = Bool
ackeli
        }

fixSentPacket :: SentPacket -> Int -> Int -> SentPacket
fixSentPacket :: SentPacket -> Int -> Int -> SentPacket
fixSentPacket SentPacket
spkt Int
bytes Int
padLen =
    SentPacket
spkt
        { spPlainPacket =
            if padLen /= 0
                then addPadding padLen $ spPlainPacket spkt
                else spPlainPacket spkt
        , spSentBytes = bytes
        }

addPadding :: Int -> PlainPacket -> PlainPacket
addPadding :: Int -> PlainPacket -> PlainPacket
addPadding Int
n (PlainPacket Header
hdr Plain
plain) = Header -> Plain -> PlainPacket
PlainPacket Header
hdr Plain
plain'
  where
    plain' :: Plain
plain' =
        Plain
plain
            { plainFrames = plainFrames plain ++ [Padding n]
            }

----------------------------------------------------------------

newtype SentPackets = SentPackets (Seq SentPacket) deriving (SentPackets -> SentPackets -> Bool
(SentPackets -> SentPackets -> Bool)
-> (SentPackets -> SentPackets -> Bool) -> Eq SentPackets
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SentPackets -> SentPackets -> Bool
== :: SentPackets -> SentPackets -> Bool
$c/= :: SentPackets -> SentPackets -> Bool
/= :: SentPackets -> SentPackets -> Bool
Eq)

emptySentPackets :: SentPackets
emptySentPackets :: SentPackets
emptySentPackets = Seq SentPacket -> SentPackets
SentPackets Seq SentPacket
forall a. Seq a
Seq.empty

----------------------------------------------------------------

data RTT = RTT
    { RTT -> Microseconds
latestRTT :: Microseconds
    -- ^ The most recent RTT measurement made when receiving an ack for
    --   a previously unacked packet.
    , RTT -> Microseconds
smoothedRTT :: Microseconds
    -- ^ The smoothed RTT of the connection.
    , RTT -> Microseconds
rttvar :: Microseconds
    -- ^ The RTT variation.
    , RTT -> Microseconds
minRTT :: Microseconds
    -- ^ The minimum RTT seen in the connection, ignoring ack delay.
    , RTT -> Microseconds
maxAckDelay1RTT :: Microseconds
    -- ^ The maximum amount of time by which the receiver intends to
    --   delay acknowledgments for packets in the ApplicationData packet
    --   number space.  The actual ack_delay in a received ACK frame may
    --   be larger due to late timers, reordering, or lost ACK frames.
    , RTT -> Int
ptoCount :: Int
    -- ^ The number of times a PTO has been sent without receiving
    --  an ack.
    }
    deriving (Int -> RTT -> ShowS
[RTT] -> ShowS
RTT -> String
(Int -> RTT -> ShowS)
-> (RTT -> String) -> ([RTT] -> ShowS) -> Show RTT
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RTT -> ShowS
showsPrec :: Int -> RTT -> ShowS
$cshow :: RTT -> String
show :: RTT -> String
$cshowList :: [RTT] -> ShowS
showList :: [RTT] -> ShowS
Show)

-- | The RTT used before an RTT sample is taken.
kInitialRTT :: Microseconds
kInitialRTT :: Microseconds
kInitialRTT = Int -> Microseconds
Microseconds Int
333000

initialRTT :: RTT
initialRTT :: RTT
initialRTT =
    RTT
        { latestRTT :: Microseconds
latestRTT = Int -> Microseconds
Microseconds Int
0
        , smoothedRTT :: Microseconds
smoothedRTT = Microseconds
kInitialRTT
        , rttvar :: Microseconds
rttvar = Microseconds
kInitialRTT Microseconds -> Int -> Microseconds
forall a. Bits a => a -> Int -> a
!>>. Int
1
        , minRTT :: Microseconds
minRTT = Int -> Microseconds
Microseconds Int
0
        , maxAckDelay1RTT :: Microseconds
maxAckDelay1RTT = Int -> Microseconds
Microseconds Int
0
        , ptoCount :: Int
ptoCount = Int
0
        }

----------------------------------------------------------------

data CCMode
    = SlowStart
    | Avoidance
    | Recovery
    deriving (CCMode -> CCMode -> Bool
(CCMode -> CCMode -> Bool)
-> (CCMode -> CCMode -> Bool) -> Eq CCMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CCMode -> CCMode -> Bool
== :: CCMode -> CCMode -> Bool
$c/= :: CCMode -> CCMode -> Bool
/= :: CCMode -> CCMode -> Bool
Eq)

instance Show CCMode where
    show :: CCMode -> String
show CCMode
SlowStart = String
"slow_start"
    show CCMode
Avoidance = String
"avoidance"
    show CCMode
Recovery = String
"recovery"

data CC = CC
    { CC -> Int
bytesInFlight :: Int
    -- ^ The sum of the size in bytes of all sent packets that contain
    --   at least one ack-eliciting or PADDING frame, and have not been
    --   acked or declared lost.  The size does not include IP or UDP
    --   overhead, but does include the QUIC header and AEAD overhead.
    --   Packets only containing ACK frames do not count towards
    --   bytes_in_flight to ensure congestion control does not impede
    --   congestion feedback.
    , CC -> Int
congestionWindow :: Int
    -- ^ Maximum number of bytes-in-flight that may be sent.
    , CC -> Maybe TimeMicrosecond
congestionRecoveryStartTime :: Maybe TimeMicrosecond
    -- ^ The time when QUIC first detects congestion due to loss or ECN,
    --   causing it to enter congestion recovery.  When a packet sent
    --   after this time is acknowledged, QUIC exits congestion
    --   recovery.
    , CC -> Int
ssthresh :: Int
    -- ^ Slow start threshold in bytes.  When the congestion window is
    --   below ssthresh, the mode is slow start and the window grows by
    --   the number of bytes acknowledged.
    , CC -> Int
bytesAcked :: Int
    -- ^ Records number of bytes acked, and used for incrementing
    --   the congestion window during congestion avoidance.
    , CC -> Int
numOfAckEliciting :: Int
    , CC -> CCMode
ccMode :: CCMode
    }
    deriving (Int -> CC -> ShowS
[CC] -> ShowS
CC -> String
(Int -> CC -> ShowS)
-> (CC -> String) -> ([CC] -> ShowS) -> Show CC
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CC -> ShowS
showsPrec :: Int -> CC -> ShowS
$cshow :: CC -> String
show :: CC -> String
$cshowList :: [CC] -> ShowS
showList :: [CC] -> ShowS
Show)

initialCC :: CC
initialCC :: CC
initialCC =
    CC
        { bytesInFlight :: Int
bytesInFlight = Int
0
        , congestionWindow :: Int
congestionWindow = Int
0
        , congestionRecoveryStartTime :: Maybe TimeMicrosecond
congestionRecoveryStartTime = Maybe TimeMicrosecond
forall a. Maybe a
Nothing
        , ssthresh :: Int
ssthresh = Int
forall a. Bounded a => a
maxBound
        , bytesAcked :: Int
bytesAcked = Int
0
        , numOfAckEliciting :: Int
numOfAckEliciting = Int
0
        , ccMode :: CCMode
ccMode = CCMode
SlowStart
        }

----------------------------------------------------------------

data LossDetection = LossDetection
    { LossDetection -> Int
largestAckedPacket :: PacketNumber
    , LossDetection -> AckInfo
previousAckInfo :: AckInfo
    , LossDetection -> TimeMicrosecond
timeOfLastAckElicitingPacket :: TimeMicrosecond
    , LossDetection -> Maybe TimeMicrosecond
lossTime :: Maybe TimeMicrosecond
    }
    deriving (Int -> LossDetection -> ShowS
[LossDetection] -> ShowS
LossDetection -> String
(Int -> LossDetection -> ShowS)
-> (LossDetection -> String)
-> ([LossDetection] -> ShowS)
-> Show LossDetection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LossDetection -> ShowS
showsPrec :: Int -> LossDetection -> ShowS
$cshow :: LossDetection -> String
show :: LossDetection -> String
$cshowList :: [LossDetection] -> ShowS
showList :: [LossDetection] -> ShowS
Show)

initialLossDetection :: LossDetection
initialLossDetection :: LossDetection
initialLossDetection = Int
-> AckInfo
-> TimeMicrosecond
-> Maybe TimeMicrosecond
-> LossDetection
LossDetection (-Int
1) AckInfo
ackInfo0 TimeMicrosecond
timeMicrosecond0 Maybe TimeMicrosecond
forall a. Maybe a
Nothing

----------------------------------------------------------------

newtype MetricsDiff = MetricsDiff [(String, Int)]

----------------------------------------------------------------

data TimerType
    = LossTime
    | PTO
    deriving (TimerType -> TimerType -> Bool
(TimerType -> TimerType -> Bool)
-> (TimerType -> TimerType -> Bool) -> Eq TimerType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TimerType -> TimerType -> Bool
== :: TimerType -> TimerType -> Bool
$c/= :: TimerType -> TimerType -> Bool
/= :: TimerType -> TimerType -> Bool
Eq)

instance Show TimerType where
    show :: TimerType -> String
show TimerType
LossTime = String
"loss_time"
    show TimerType
PTO = String
"pto"

data TimerExpired = TimerExpired

data TimerCancelled = TimerCancelled

data TimerInfo = TimerInfo
    { TimerInfo -> TimeMicrosecond
timerTime :: TimeMicrosecond
    , TimerInfo -> EncryptionLevel
timerLevel :: EncryptionLevel
    , TimerInfo -> TimerType
timerType :: TimerType
    }
    deriving (TimerInfo -> TimerInfo -> Bool
(TimerInfo -> TimerInfo -> Bool)
-> (TimerInfo -> TimerInfo -> Bool) -> Eq TimerInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TimerInfo -> TimerInfo -> Bool
== :: TimerInfo -> TimerInfo -> Bool
$c/= :: TimerInfo -> TimerInfo -> Bool
/= :: TimerInfo -> TimerInfo -> Bool
Eq, Int -> TimerInfo -> ShowS
[TimerInfo] -> ShowS
TimerInfo -> String
(Int -> TimerInfo -> ShowS)
-> (TimerInfo -> String)
-> ([TimerInfo] -> ShowS)
-> Show TimerInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TimerInfo -> ShowS
showsPrec :: Int -> TimerInfo -> ShowS
$cshow :: TimerInfo -> String
show :: TimerInfo -> String
$cshowList :: [TimerInfo] -> ShowS
showList :: [TimerInfo] -> ShowS
Show)

data TimerInfoQ
    = Empty
    | Next TimerInfo
    deriving (TimerInfoQ -> TimerInfoQ -> Bool
(TimerInfoQ -> TimerInfoQ -> Bool)
-> (TimerInfoQ -> TimerInfoQ -> Bool) -> Eq TimerInfoQ
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TimerInfoQ -> TimerInfoQ -> Bool
== :: TimerInfoQ -> TimerInfoQ -> Bool
$c/= :: TimerInfoQ -> TimerInfoQ -> Bool
/= :: TimerInfoQ -> TimerInfoQ -> Bool
Eq)

----------------------------------------------------------------

makeSpaceDiscarded :: IO (Array EncryptionLevel (IORef Bool))
makeSpaceDiscarded :: IO (Array EncryptionLevel (IORef Bool))
makeSpaceDiscarded = do
    IORef Bool
i1 <- Bool -> IO (IORef Bool)
forall a. a -> IO (IORef a)
newIORef Bool
False
    IORef Bool
i2 <- Bool -> IO (IORef Bool)
forall a. a -> IO (IORef a)
newIORef Bool
False
    IORef Bool
i3 <- Bool -> IO (IORef Bool)
forall a. a -> IO (IORef a)
newIORef Bool
False
    IORef Bool
i4 <- Bool -> IO (IORef Bool)
forall a. a -> IO (IORef a)
newIORef Bool
False
    let lst :: [(EncryptionLevel, IORef Bool)]
lst = [(EncryptionLevel
InitialLevel, IORef Bool
i1), (EncryptionLevel
RTT0Level, IORef Bool
i2), (EncryptionLevel
HandshakeLevel, IORef Bool
i3), (EncryptionLevel
RTT1Level, IORef Bool
i4)]
        arr :: Array EncryptionLevel (IORef Bool)
arr = (EncryptionLevel, EncryptionLevel)
-> [(EncryptionLevel, IORef Bool)]
-> Array EncryptionLevel (IORef Bool)
forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array (EncryptionLevel
InitialLevel, EncryptionLevel
RTT1Level) [(EncryptionLevel, IORef Bool)]
lst
    Array EncryptionLevel (IORef Bool)
-> IO (Array EncryptionLevel (IORef Bool))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Array EncryptionLevel (IORef Bool)
arr

makeSentPackets :: IO (Array EncryptionLevel (IORef SentPackets))
makeSentPackets :: IO (Array EncryptionLevel (IORef SentPackets))
makeSentPackets = do
    IORef SentPackets
i1 <- SentPackets -> IO (IORef SentPackets)
forall a. a -> IO (IORef a)
newIORef SentPackets
emptySentPackets
    IORef SentPackets
i2 <- SentPackets -> IO (IORef SentPackets)
forall a. a -> IO (IORef a)
newIORef SentPackets
emptySentPackets
    IORef SentPackets
i3 <- SentPackets -> IO (IORef SentPackets)
forall a. a -> IO (IORef a)
newIORef SentPackets
emptySentPackets
    let lst :: [(EncryptionLevel, IORef SentPackets)]
lst = [(EncryptionLevel
InitialLevel, IORef SentPackets
i1), (EncryptionLevel
HandshakeLevel, IORef SentPackets
i2), (EncryptionLevel
RTT1Level, IORef SentPackets
i3)]
        arr :: Array EncryptionLevel (IORef SentPackets)
arr = (EncryptionLevel, EncryptionLevel)
-> [(EncryptionLevel, IORef SentPackets)]
-> Array EncryptionLevel (IORef SentPackets)
forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array (EncryptionLevel
InitialLevel, EncryptionLevel
RTT1Level) [(EncryptionLevel, IORef SentPackets)]
lst
    Array EncryptionLevel (IORef SentPackets)
-> IO (Array EncryptionLevel (IORef SentPackets))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Array EncryptionLevel (IORef SentPackets)
arr

makeLossDetection :: IO (Array EncryptionLevel (IORef LossDetection))
makeLossDetection :: IO (Array EncryptionLevel (IORef LossDetection))
makeLossDetection = do
    IORef LossDetection
i1 <- LossDetection -> IO (IORef LossDetection)
forall a. a -> IO (IORef a)
newIORef LossDetection
initialLossDetection
    IORef LossDetection
i2 <- LossDetection -> IO (IORef LossDetection)
forall a. a -> IO (IORef a)
newIORef LossDetection
initialLossDetection
    IORef LossDetection
i3 <- LossDetection -> IO (IORef LossDetection)
forall a. a -> IO (IORef a)
newIORef LossDetection
initialLossDetection
    let lst :: [(EncryptionLevel, IORef LossDetection)]
lst = [(EncryptionLevel
InitialLevel, IORef LossDetection
i1), (EncryptionLevel
HandshakeLevel, IORef LossDetection
i2), (EncryptionLevel
RTT1Level, IORef LossDetection
i3)]
        arr :: Array EncryptionLevel (IORef LossDetection)
arr = (EncryptionLevel, EncryptionLevel)
-> [(EncryptionLevel, IORef LossDetection)]
-> Array EncryptionLevel (IORef LossDetection)
forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array (EncryptionLevel
InitialLevel, EncryptionLevel
RTT1Level) [(EncryptionLevel, IORef LossDetection)]
lst
    Array EncryptionLevel (IORef LossDetection)
-> IO (Array EncryptionLevel (IORef LossDetection))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Array EncryptionLevel (IORef LossDetection)
arr

data LDCC = LDCC
    { LDCC -> ConnState
ldccState :: ConnState
    , LDCC -> QLogger
ldccQlogger :: QLogger
    , LDCC -> PlainPacket -> IO ()
putRetrans :: PlainPacket -> IO ()
    , LDCC -> IORef RTT
recoveryRTT :: IORef RTT
    , LDCC -> TVar CC
recoveryCC :: TVar CC
    , LDCC -> Array EncryptionLevel (IORef Bool)
spaceDiscarded :: Array EncryptionLevel (IORef Bool)
    , LDCC -> Array EncryptionLevel (IORef SentPackets)
sentPackets :: Array EncryptionLevel (IORef SentPackets)
    , LDCC -> Array EncryptionLevel (IORef LossDetection)
lossDetection :: Array EncryptionLevel (IORef LossDetection)
    , -- The current timer key
      LDCC -> IORef (Maybe TimeoutKey)
timerKey :: IORef (Maybe TimeoutKey)
    , -- The current timer value
      LDCC -> IORef (Maybe TimerInfo)
timerInfo :: IORef (Maybe TimerInfo)
    , LDCC -> TVar SentPackets
lostCandidates :: TVar SentPackets
    , LDCC -> TVar (Maybe EncryptionLevel)
ptoPing :: TVar (Maybe EncryptionLevel)
    , LDCC -> IORef Bool
speedingUp :: IORef Bool
    , LDCC -> IORef Int
pktNumPersistent :: IORef PacketNumber
    , LDCC -> Array EncryptionLevel (IORef PeerPacketNumbers)
peerPacketNumbers :: Array EncryptionLevel (IORef PeerPacketNumbers)
    , LDCC -> IORef PeerPacketNumbers
previousRTT1PPNs :: IORef PeerPacketNumbers -- for RTT1
    -- Pending timer value
    , LDCC -> TVar TimerInfoQ
timerInfoQ :: TVar TimerInfoQ
    }

makePPN :: IO (Array EncryptionLevel (IORef PeerPacketNumbers))
makePPN :: IO (Array EncryptionLevel (IORef PeerPacketNumbers))
makePPN = do
    IORef PeerPacketNumbers
ref1 <- PeerPacketNumbers -> IO (IORef PeerPacketNumbers)
forall a. a -> IO (IORef a)
newIORef PeerPacketNumbers
emptyPeerPacketNumbers
    IORef PeerPacketNumbers
ref2 <- PeerPacketNumbers -> IO (IORef PeerPacketNumbers)
forall a. a -> IO (IORef a)
newIORef PeerPacketNumbers
emptyPeerPacketNumbers
    IORef PeerPacketNumbers
ref3 <- PeerPacketNumbers -> IO (IORef PeerPacketNumbers)
forall a. a -> IO (IORef a)
newIORef PeerPacketNumbers
emptyPeerPacketNumbers
    -- using the ref for RTT0Level and RTT1Level
    let lst :: [(EncryptionLevel, IORef PeerPacketNumbers)]
lst =
            [ (EncryptionLevel
InitialLevel, IORef PeerPacketNumbers
ref1)
            , (EncryptionLevel
RTT0Level, IORef PeerPacketNumbers
ref3)
            , (EncryptionLevel
HandshakeLevel, IORef PeerPacketNumbers
ref2)
            , (EncryptionLevel
RTT1Level, IORef PeerPacketNumbers
ref3)
            ]
        arr :: Array EncryptionLevel (IORef PeerPacketNumbers)
arr = (EncryptionLevel, EncryptionLevel)
-> [(EncryptionLevel, IORef PeerPacketNumbers)]
-> Array EncryptionLevel (IORef PeerPacketNumbers)
forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array (EncryptionLevel
InitialLevel, EncryptionLevel
RTT1Level) [(EncryptionLevel, IORef PeerPacketNumbers)]
lst
    Array EncryptionLevel (IORef PeerPacketNumbers)
-> IO (Array EncryptionLevel (IORef PeerPacketNumbers))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Array EncryptionLevel (IORef PeerPacketNumbers)
arr

newLDCC :: ConnState -> QLogger -> (PlainPacket -> IO ()) -> IO LDCC
newLDCC :: ConnState -> QLogger -> (PlainPacket -> IO ()) -> IO LDCC
newLDCC ConnState
cs QLogger
qLog PlainPacket -> IO ()
put =
    ConnState
-> QLogger
-> (PlainPacket -> IO ())
-> IORef RTT
-> TVar CC
-> Array EncryptionLevel (IORef Bool)
-> Array EncryptionLevel (IORef SentPackets)
-> Array EncryptionLevel (IORef LossDetection)
-> IORef (Maybe TimeoutKey)
-> IORef (Maybe TimerInfo)
-> TVar SentPackets
-> TVar (Maybe EncryptionLevel)
-> IORef Bool
-> IORef Int
-> Array EncryptionLevel (IORef PeerPacketNumbers)
-> IORef PeerPacketNumbers
-> TVar TimerInfoQ
-> LDCC
LDCC ConnState
cs QLogger
qLog PlainPacket -> IO ()
put
        (IORef RTT
 -> TVar CC
 -> Array EncryptionLevel (IORef Bool)
 -> Array EncryptionLevel (IORef SentPackets)
 -> Array EncryptionLevel (IORef LossDetection)
 -> IORef (Maybe TimeoutKey)
 -> IORef (Maybe TimerInfo)
 -> TVar SentPackets
 -> TVar (Maybe EncryptionLevel)
 -> IORef Bool
 -> IORef Int
 -> Array EncryptionLevel (IORef PeerPacketNumbers)
 -> IORef PeerPacketNumbers
 -> TVar TimerInfoQ
 -> LDCC)
-> IO (IORef RTT)
-> IO
     (TVar CC
      -> Array EncryptionLevel (IORef Bool)
      -> Array EncryptionLevel (IORef SentPackets)
      -> Array EncryptionLevel (IORef LossDetection)
      -> IORef (Maybe TimeoutKey)
      -> IORef (Maybe TimerInfo)
      -> TVar SentPackets
      -> TVar (Maybe EncryptionLevel)
      -> IORef Bool
      -> IORef Int
      -> Array EncryptionLevel (IORef PeerPacketNumbers)
      -> IORef PeerPacketNumbers
      -> TVar TimerInfoQ
      -> LDCC)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RTT -> IO (IORef RTT)
forall a. a -> IO (IORef a)
newIORef RTT
initialRTT
        IO
  (TVar CC
   -> Array EncryptionLevel (IORef Bool)
   -> Array EncryptionLevel (IORef SentPackets)
   -> Array EncryptionLevel (IORef LossDetection)
   -> IORef (Maybe TimeoutKey)
   -> IORef (Maybe TimerInfo)
   -> TVar SentPackets
   -> TVar (Maybe EncryptionLevel)
   -> IORef Bool
   -> IORef Int
   -> Array EncryptionLevel (IORef PeerPacketNumbers)
   -> IORef PeerPacketNumbers
   -> TVar TimerInfoQ
   -> LDCC)
-> IO (TVar CC)
-> IO
     (Array EncryptionLevel (IORef Bool)
      -> Array EncryptionLevel (IORef SentPackets)
      -> Array EncryptionLevel (IORef LossDetection)
      -> IORef (Maybe TimeoutKey)
      -> IORef (Maybe TimerInfo)
      -> TVar SentPackets
      -> TVar (Maybe EncryptionLevel)
      -> IORef Bool
      -> IORef Int
      -> Array EncryptionLevel (IORef PeerPacketNumbers)
      -> IORef PeerPacketNumbers
      -> TVar TimerInfoQ
      -> LDCC)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> CC -> IO (TVar CC)
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO CC
initialCC
        IO
  (Array EncryptionLevel (IORef Bool)
   -> Array EncryptionLevel (IORef SentPackets)
   -> Array EncryptionLevel (IORef LossDetection)
   -> IORef (Maybe TimeoutKey)
   -> IORef (Maybe TimerInfo)
   -> TVar SentPackets
   -> TVar (Maybe EncryptionLevel)
   -> IORef Bool
   -> IORef Int
   -> Array EncryptionLevel (IORef PeerPacketNumbers)
   -> IORef PeerPacketNumbers
   -> TVar TimerInfoQ
   -> LDCC)
-> IO (Array EncryptionLevel (IORef Bool))
-> IO
     (Array EncryptionLevel (IORef SentPackets)
      -> Array EncryptionLevel (IORef LossDetection)
      -> IORef (Maybe TimeoutKey)
      -> IORef (Maybe TimerInfo)
      -> TVar SentPackets
      -> TVar (Maybe EncryptionLevel)
      -> IORef Bool
      -> IORef Int
      -> Array EncryptionLevel (IORef PeerPacketNumbers)
      -> IORef PeerPacketNumbers
      -> TVar TimerInfoQ
      -> LDCC)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> IO (Array EncryptionLevel (IORef Bool))
makeSpaceDiscarded
        IO
  (Array EncryptionLevel (IORef SentPackets)
   -> Array EncryptionLevel (IORef LossDetection)
   -> IORef (Maybe TimeoutKey)
   -> IORef (Maybe TimerInfo)
   -> TVar SentPackets
   -> TVar (Maybe EncryptionLevel)
   -> IORef Bool
   -> IORef Int
   -> Array EncryptionLevel (IORef PeerPacketNumbers)
   -> IORef PeerPacketNumbers
   -> TVar TimerInfoQ
   -> LDCC)
-> IO (Array EncryptionLevel (IORef SentPackets))
-> IO
     (Array EncryptionLevel (IORef LossDetection)
      -> IORef (Maybe TimeoutKey)
      -> IORef (Maybe TimerInfo)
      -> TVar SentPackets
      -> TVar (Maybe EncryptionLevel)
      -> IORef Bool
      -> IORef Int
      -> Array EncryptionLevel (IORef PeerPacketNumbers)
      -> IORef PeerPacketNumbers
      -> TVar TimerInfoQ
      -> LDCC)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> IO (Array EncryptionLevel (IORef SentPackets))
makeSentPackets
        IO
  (Array EncryptionLevel (IORef LossDetection)
   -> IORef (Maybe TimeoutKey)
   -> IORef (Maybe TimerInfo)
   -> TVar SentPackets
   -> TVar (Maybe EncryptionLevel)
   -> IORef Bool
   -> IORef Int
   -> Array EncryptionLevel (IORef PeerPacketNumbers)
   -> IORef PeerPacketNumbers
   -> TVar TimerInfoQ
   -> LDCC)
-> IO (Array EncryptionLevel (IORef LossDetection))
-> IO
     (IORef (Maybe TimeoutKey)
      -> IORef (Maybe TimerInfo)
      -> TVar SentPackets
      -> TVar (Maybe EncryptionLevel)
      -> IORef Bool
      -> IORef Int
      -> Array EncryptionLevel (IORef PeerPacketNumbers)
      -> IORef PeerPacketNumbers
      -> TVar TimerInfoQ
      -> LDCC)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> IO (Array EncryptionLevel (IORef LossDetection))
makeLossDetection
        IO
  (IORef (Maybe TimeoutKey)
   -> IORef (Maybe TimerInfo)
   -> TVar SentPackets
   -> TVar (Maybe EncryptionLevel)
   -> IORef Bool
   -> IORef Int
   -> Array EncryptionLevel (IORef PeerPacketNumbers)
   -> IORef PeerPacketNumbers
   -> TVar TimerInfoQ
   -> LDCC)
-> IO (IORef (Maybe TimeoutKey))
-> IO
     (IORef (Maybe TimerInfo)
      -> TVar SentPackets
      -> TVar (Maybe EncryptionLevel)
      -> IORef Bool
      -> IORef Int
      -> Array EncryptionLevel (IORef PeerPacketNumbers)
      -> IORef PeerPacketNumbers
      -> TVar TimerInfoQ
      -> LDCC)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe TimeoutKey -> IO (IORef (Maybe TimeoutKey))
forall a. a -> IO (IORef a)
newIORef Maybe TimeoutKey
forall a. Maybe a
Nothing
        IO
  (IORef (Maybe TimerInfo)
   -> TVar SentPackets
   -> TVar (Maybe EncryptionLevel)
   -> IORef Bool
   -> IORef Int
   -> Array EncryptionLevel (IORef PeerPacketNumbers)
   -> IORef PeerPacketNumbers
   -> TVar TimerInfoQ
   -> LDCC)
-> IO (IORef (Maybe TimerInfo))
-> IO
     (TVar SentPackets
      -> TVar (Maybe EncryptionLevel)
      -> IORef Bool
      -> IORef Int
      -> Array EncryptionLevel (IORef PeerPacketNumbers)
      -> IORef PeerPacketNumbers
      -> TVar TimerInfoQ
      -> LDCC)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe TimerInfo -> IO (IORef (Maybe TimerInfo))
forall a. a -> IO (IORef a)
newIORef Maybe TimerInfo
forall a. Maybe a
Nothing
        IO
  (TVar SentPackets
   -> TVar (Maybe EncryptionLevel)
   -> IORef Bool
   -> IORef Int
   -> Array EncryptionLevel (IORef PeerPacketNumbers)
   -> IORef PeerPacketNumbers
   -> TVar TimerInfoQ
   -> LDCC)
-> IO (TVar SentPackets)
-> IO
     (TVar (Maybe EncryptionLevel)
      -> IORef Bool
      -> IORef Int
      -> Array EncryptionLevel (IORef PeerPacketNumbers)
      -> IORef PeerPacketNumbers
      -> TVar TimerInfoQ
      -> LDCC)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SentPackets -> IO (TVar SentPackets)
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO SentPackets
emptySentPackets
        IO
  (TVar (Maybe EncryptionLevel)
   -> IORef Bool
   -> IORef Int
   -> Array EncryptionLevel (IORef PeerPacketNumbers)
   -> IORef PeerPacketNumbers
   -> TVar TimerInfoQ
   -> LDCC)
-> IO (TVar (Maybe EncryptionLevel))
-> IO
     (IORef Bool
      -> IORef Int
      -> Array EncryptionLevel (IORef PeerPacketNumbers)
      -> IORef PeerPacketNumbers
      -> TVar TimerInfoQ
      -> LDCC)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe EncryptionLevel -> IO (TVar (Maybe EncryptionLevel))
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO Maybe EncryptionLevel
forall a. Maybe a
Nothing
        IO
  (IORef Bool
   -> IORef Int
   -> Array EncryptionLevel (IORef PeerPacketNumbers)
   -> IORef PeerPacketNumbers
   -> TVar TimerInfoQ
   -> LDCC)
-> IO (IORef Bool)
-> IO
     (IORef Int
      -> Array EncryptionLevel (IORef PeerPacketNumbers)
      -> IORef PeerPacketNumbers
      -> TVar TimerInfoQ
      -> LDCC)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Bool -> IO (IORef Bool)
forall a. a -> IO (IORef a)
newIORef Bool
False
        IO
  (IORef Int
   -> Array EncryptionLevel (IORef PeerPacketNumbers)
   -> IORef PeerPacketNumbers
   -> TVar TimerInfoQ
   -> LDCC)
-> IO (IORef Int)
-> IO
     (Array EncryptionLevel (IORef PeerPacketNumbers)
      -> IORef PeerPacketNumbers -> TVar TimerInfoQ -> LDCC)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> IO (IORef Int)
forall a. a -> IO (IORef a)
newIORef Int
forall a. Bounded a => a
maxBound
        IO
  (Array EncryptionLevel (IORef PeerPacketNumbers)
   -> IORef PeerPacketNumbers -> TVar TimerInfoQ -> LDCC)
-> IO (Array EncryptionLevel (IORef PeerPacketNumbers))
-> IO (IORef PeerPacketNumbers -> TVar TimerInfoQ -> LDCC)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> IO (Array EncryptionLevel (IORef PeerPacketNumbers))
makePPN
        IO (IORef PeerPacketNumbers -> TVar TimerInfoQ -> LDCC)
-> IO (IORef PeerPacketNumbers) -> IO (TVar TimerInfoQ -> LDCC)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> PeerPacketNumbers -> IO (IORef PeerPacketNumbers)
forall a. a -> IO (IORef a)
newIORef PeerPacketNumbers
emptyPeerPacketNumbers
        IO (TVar TimerInfoQ -> LDCC) -> IO (TVar TimerInfoQ) -> IO LDCC
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> TimerInfoQ -> IO (TVar TimerInfoQ)
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO TimerInfoQ
Empty

instance KeepQlog LDCC where
    keepQlog :: LDCC -> QLogger
keepQlog = LDCC -> QLogger
ldccQlogger

instance Connector LDCC where
    getRole :: LDCC -> Role
getRole = ConnState -> Role
role (ConnState -> Role) -> (LDCC -> ConnState) -> LDCC -> Role
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LDCC -> ConnState
ldccState
    getEncryptionLevel :: LDCC -> IO EncryptionLevel
getEncryptionLevel = TVar EncryptionLevel -> IO EncryptionLevel
forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO (TVar EncryptionLevel -> IO EncryptionLevel)
-> (LDCC -> TVar EncryptionLevel) -> LDCC -> IO EncryptionLevel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConnState -> TVar EncryptionLevel
encryptionLevel (ConnState -> TVar EncryptionLevel)
-> (LDCC -> ConnState) -> LDCC -> TVar EncryptionLevel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LDCC -> ConnState
ldccState
    getMaxPacketSize :: LDCC -> IO Int
getMaxPacketSize = IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (IORef Int -> IO Int) -> (LDCC -> IORef Int) -> LDCC -> IO Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConnState -> IORef Int
maxPacketSize (ConnState -> IORef Int)
-> (LDCC -> ConnState) -> LDCC -> IORef Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LDCC -> ConnState
ldccState
    getConnectionState :: LDCC -> IO ConnectionState
getConnectionState = TVar ConnectionState -> IO ConnectionState
forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO (TVar ConnectionState -> IO ConnectionState)
-> (LDCC -> TVar ConnectionState) -> LDCC -> IO ConnectionState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConnState -> TVar ConnectionState
connectionState (ConnState -> TVar ConnectionState)
-> (LDCC -> ConnState) -> LDCC -> TVar ConnectionState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LDCC -> ConnState
ldccState
    getPacketNumber :: LDCC -> IO Int
getPacketNumber = IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (IORef Int -> IO Int) -> (LDCC -> IORef Int) -> LDCC -> IO Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConnState -> IORef Int
packetNumber (ConnState -> IORef Int)
-> (LDCC -> ConnState) -> LDCC -> IORef Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LDCC -> ConnState
ldccState
    getAlive :: LDCC -> IO Bool
getAlive = IORef Bool -> IO Bool
forall a. IORef a -> IO a
readIORef (IORef Bool -> IO Bool) -> (LDCC -> IORef Bool) -> LDCC -> IO Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConnState -> IORef Bool
connectionAlive (ConnState -> IORef Bool)
-> (LDCC -> ConnState) -> LDCC -> IORef Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LDCC -> ConnState
ldccState

----------------------------------------------------------------

instance Qlog SentPacket where
    qlog :: SentPacket -> LogStr
qlog SentPacket{Bool
Int
TimeMicrosecond
PeerPacketNumbers
EncryptionLevel
PlainPacket
spPlainPacket :: SentPacket -> PlainPacket
spTimeSent :: SentPacket -> TimeMicrosecond
spSentBytes :: SentPacket -> Int
spEncryptionLevel :: SentPacket -> EncryptionLevel
spPacketNumber :: SentPacket -> Int
spPeerPacketNumbers :: SentPacket -> PeerPacketNumbers
spAckEliciting :: SentPacket -> Bool
spPlainPacket :: PlainPacket
spTimeSent :: TimeMicrosecond
spSentBytes :: Int
spEncryptionLevel :: EncryptionLevel
spPacketNumber :: Int
spPeerPacketNumbers :: PeerPacketNumbers
spAckEliciting :: Bool
..} =
        LogStr
"{\"raw\":{\"length\":"
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> Int -> LogStr
forall a. Show a => a -> LogStr
sw Int
spSentBytes
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"},\"header\":{\"packet_type\":\""
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr -> LogStr
forall msg. ToLogStr msg => msg -> LogStr
toLogStr (Header -> LogStr
packetType Header
hdr)
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"\",\"packet_number\":\""
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> Int -> LogStr
forall a. Show a => a -> LogStr
sw Int
plainPacketNumber
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"\",\"dcid\":\""
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> CID -> LogStr
forall a. Show a => a -> LogStr
sw (Header -> CID
headerMyCID Header
hdr)
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"\"},\"frames\":"
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"["
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> (LogStr -> LogStr -> LogStr) -> LogStr -> [LogStr] -> LogStr
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
(<>) LogStr
"" (LogStr -> [LogStr] -> [LogStr]
forall a. a -> [a] -> [a]
intersperse LogStr
"," ((Frame -> LogStr) -> [Frame] -> [LogStr]
forall a b. (a -> b) -> [a] -> [b]
map Frame -> LogStr
forall a. Qlog a => a -> LogStr
qlog [Frame]
plainFrames))
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"]"
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"}"
      where
        PlainPacket Header
hdr Plain{Int
[Frame]
Flags Raw
plainFrames :: Plain -> [Frame]
plainPacketNumber :: Int
plainFrames :: [Frame]
plainFlags :: Flags Raw
plainMarks :: Int
plainFlags :: Plain -> Flags Raw
plainPacketNumber :: Plain -> Int
plainMarks :: Plain -> Int
..} = PlainPacket
spPlainPacket

instance Qlog LostPacket where
    qlog :: LostPacket -> LogStr
qlog (LostPacket SentPacket{Bool
Int
TimeMicrosecond
PeerPacketNumbers
EncryptionLevel
PlainPacket
spPlainPacket :: SentPacket -> PlainPacket
spTimeSent :: SentPacket -> TimeMicrosecond
spSentBytes :: SentPacket -> Int
spEncryptionLevel :: SentPacket -> EncryptionLevel
spPacketNumber :: SentPacket -> Int
spPeerPacketNumbers :: SentPacket -> PeerPacketNumbers
spAckEliciting :: SentPacket -> Bool
spPlainPacket :: PlainPacket
spTimeSent :: TimeMicrosecond
spSentBytes :: Int
spEncryptionLevel :: EncryptionLevel
spPacketNumber :: Int
spPeerPacketNumbers :: PeerPacketNumbers
spAckEliciting :: Bool
..}) =
        LogStr
"{\"header\":{\"packet_type\":\""
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr -> LogStr
forall msg. ToLogStr msg => msg -> LogStr
toLogStr (Header -> LogStr
packetType Header
hdr)
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"\""
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
",\"packet_number\":"
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> Int -> LogStr
forall a. Show a => a -> LogStr
sw Int
spPacketNumber
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"}}"
      where
        PlainPacket Header
hdr Plain
_ = PlainPacket
spPlainPacket

instance Qlog MetricsDiff where
    qlog :: MetricsDiff -> LogStr
qlog (MetricsDiff []) = LogStr
"{}"
    qlog (MetricsDiff ((String, Int)
x : [(String, Int)]
xs)) = LogStr
"{" LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> (String, Int) -> LogStr
forall {msg} {a}. (ToLogStr msg, Show a) => (msg, a) -> LogStr
tv0 (String, Int)
x LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> ((String, Int) -> LogStr -> LogStr)
-> LogStr -> [(String, Int)] -> LogStr
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (String, Int) -> LogStr -> LogStr
forall {msg} {a}.
(ToLogStr msg, Show a) =>
(msg, a) -> LogStr -> LogStr
tv LogStr
"" [(String, Int)]
xs LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"}"
      where
        tv0 :: (msg, a) -> LogStr
tv0 (msg
tag, a
val) = LogStr
"\"" LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> msg -> LogStr
forall msg. ToLogStr msg => msg -> LogStr
toLogStr msg
tag LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"\":" LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> a -> LogStr
forall a. Show a => a -> LogStr
sw a
val
        tv :: (msg, a) -> LogStr -> LogStr
tv (msg
tag, a
val) LogStr
pre = LogStr
",\"" LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> msg -> LogStr
forall msg. ToLogStr msg => msg -> LogStr
toLogStr msg
tag LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"\":" LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> a -> LogStr
forall a. Show a => a -> LogStr
sw a
val LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
pre

instance Qlog CCMode where
    qlog :: CCMode -> LogStr
qlog CCMode
mode = LogStr
"{\"new\":\"" LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> CCMode -> LogStr
forall a. Show a => a -> LogStr
sw CCMode
mode LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"\"}"

instance Qlog TimerCancelled where
    qlog :: TimerCancelled -> LogStr
qlog TimerCancelled
TimerCancelled = LogStr
"{\"event_type\":\"cancelled\"}"

instance Qlog TimerExpired where
    qlog :: TimerExpired -> LogStr
qlog TimerExpired
TimerExpired = LogStr
"{\"event_type\":\"expired\"}"

instance Qlog (TimerInfo, Microseconds) where
    qlog :: (TimerInfo, Microseconds) -> LogStr
qlog (TimerInfo{TimeMicrosecond
EncryptionLevel
TimerType
timerTime :: TimerInfo -> TimeMicrosecond
timerLevel :: TimerInfo -> EncryptionLevel
timerType :: TimerInfo -> TimerType
timerTime :: TimeMicrosecond
timerLevel :: EncryptionLevel
timerType :: TimerType
..}, Microseconds
us) =
        LogStr
"{\"event_type\":\"set\""
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
",\"timer_type\":\""
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> TimerType -> LogStr
forall a. Show a => a -> LogStr
sw TimerType
timerType
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"\""
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
",\"packet_number_space\":\""
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> EncryptionLevel -> LogStr
packetNumberSpace EncryptionLevel
timerLevel
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"\""
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
",\"delta\":"
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> Microseconds -> LogStr
delta Microseconds
us
            LogStr -> LogStr -> LogStr
forall a. Semigroup a => a -> a -> a
<> LogStr
"}"

packetNumberSpace :: EncryptionLevel -> LogStr
packetNumberSpace :: EncryptionLevel -> LogStr
packetNumberSpace EncryptionLevel
InitialLevel = LogStr
"initial"
packetNumberSpace EncryptionLevel
RTT0Level = LogStr
"application_data"
packetNumberSpace EncryptionLevel
HandshakeLevel = LogStr
"handshake"
packetNumberSpace EncryptionLevel
RTT1Level = LogStr
"application_data"

delta :: Microseconds -> LogStr
delta :: Microseconds -> LogStr
delta (Microseconds Int
n) = Int -> LogStr
forall a. Show a => a -> LogStr
sw Int
n

qlogSent :: (KeepQlog q, Qlog pkt) => q -> pkt -> TimeMicrosecond -> IO ()
qlogSent :: forall q pkt.
(KeepQlog q, Qlog pkt) =>
q -> pkt -> TimeMicrosecond -> IO ()
qlogSent q
q pkt
pkt TimeMicrosecond
tim = q -> QLogger
forall a. KeepQlog a => a -> QLogger
keepQlog q
q QLogger -> QLogger
forall a b. (a -> b) -> a -> b
$ LogStr -> TimeMicrosecond -> QlogMsg
QSent (pkt -> LogStr
forall a. Qlog a => a -> LogStr
qlog pkt
pkt) TimeMicrosecond
tim

qlogMetricsUpdated :: KeepQlog q => q -> MetricsDiff -> IO ()
qlogMetricsUpdated :: forall q. KeepQlog q => q -> MetricsDiff -> IO ()
qlogMetricsUpdated q
q MetricsDiff
m = do
    TimeMicrosecond
tim <- IO TimeMicrosecond
getTimeMicrosecond
    q -> QLogger
forall a. KeepQlog a => a -> QLogger
keepQlog q
q QLogger -> QLogger
forall a b. (a -> b) -> a -> b
$ LogStr -> TimeMicrosecond -> QlogMsg
QMetricsUpdated (MetricsDiff -> LogStr
forall a. Qlog a => a -> LogStr
qlog MetricsDiff
m) TimeMicrosecond
tim

qlogPacketLost :: KeepQlog q => q -> LostPacket -> IO ()
qlogPacketLost :: forall q. KeepQlog q => q -> LostPacket -> IO ()
qlogPacketLost q
q LostPacket
lpkt = do
    TimeMicrosecond
tim <- IO TimeMicrosecond
getTimeMicrosecond
    q -> QLogger
forall a. KeepQlog a => a -> QLogger
keepQlog q
q QLogger -> QLogger
forall a b. (a -> b) -> a -> b
$ LogStr -> TimeMicrosecond -> QlogMsg
QPacketLost (LostPacket -> LogStr
forall a. Qlog a => a -> LogStr
qlog LostPacket
lpkt) TimeMicrosecond
tim

qlogContestionStateUpdated :: KeepQlog q => q -> CCMode -> IO ()
qlogContestionStateUpdated :: forall q. KeepQlog q => q -> CCMode -> IO ()
qlogContestionStateUpdated q
q CCMode
mode = do
    TimeMicrosecond
tim <- IO TimeMicrosecond
getTimeMicrosecond
    q -> QLogger
forall a. KeepQlog a => a -> QLogger
keepQlog q
q QLogger -> QLogger
forall a b. (a -> b) -> a -> b
$ LogStr -> TimeMicrosecond -> QlogMsg
QCongestionStateUpdated (CCMode -> LogStr
forall a. Qlog a => a -> LogStr
qlog CCMode
mode) TimeMicrosecond
tim

qlogLossTimerUpdated :: KeepQlog q => q -> (TimerInfo, Microseconds) -> IO ()
qlogLossTimerUpdated :: forall q. KeepQlog q => q -> (TimerInfo, Microseconds) -> IO ()
qlogLossTimerUpdated q
q (TimerInfo, Microseconds)
tmi = do
    TimeMicrosecond
tim <- IO TimeMicrosecond
getTimeMicrosecond
    q -> QLogger
forall a. KeepQlog a => a -> QLogger
keepQlog q
q QLogger -> QLogger
forall a b. (a -> b) -> a -> b
$ LogStr -> TimeMicrosecond -> QlogMsg
QLossTimerUpdated ((TimerInfo, Microseconds) -> LogStr
forall a. Qlog a => a -> LogStr
qlog (TimerInfo, Microseconds)
tmi) TimeMicrosecond
tim

qlogLossTimerCancelled :: KeepQlog q => q -> IO ()
qlogLossTimerCancelled :: forall q. KeepQlog q => q -> IO ()
qlogLossTimerCancelled q
q = do
    TimeMicrosecond
tim <- IO TimeMicrosecond
getTimeMicrosecond
    q -> QLogger
forall a. KeepQlog a => a -> QLogger
keepQlog q
q QLogger -> QLogger
forall a b. (a -> b) -> a -> b
$ LogStr -> TimeMicrosecond -> QlogMsg
QLossTimerUpdated (TimerCancelled -> LogStr
forall a. Qlog a => a -> LogStr
qlog TimerCancelled
TimerCancelled) TimeMicrosecond
tim

qlogLossTimerExpired :: KeepQlog q => q -> IO ()
qlogLossTimerExpired :: forall q. KeepQlog q => q -> IO ()
qlogLossTimerExpired q
q = do
    TimeMicrosecond
tim <- IO TimeMicrosecond
getTimeMicrosecond
    q -> QLogger
forall a. KeepQlog a => a -> QLogger
keepQlog q
q QLogger -> QLogger
forall a b. (a -> b) -> a -> b
$ LogStr -> TimeMicrosecond -> QlogMsg
QLossTimerUpdated (TimerExpired -> LogStr
forall a. Qlog a => a -> LogStr
qlog TimerExpired
TimerExpired) TimeMicrosecond
tim