{-# LANGUAGE RecordWildCards #-}

module Network.QUIC.Types.Resumption where

import Network.TLS hiding (Version)
import Network.TLS.QUIC

import Network.QUIC.Imports
import Network.QUIC.Types.Frame
import Network.QUIC.Types.Packet

type SessionEstablish = SessionID -> SessionData -> IO ()

-- | Information about resumption
data ResumptionInfo = ResumptionInfo {
    ResumptionInfo -> Version
resumptionVersion :: Version
  , ResumptionInfo -> Maybe (Token, SessionData)
resumptionSession :: Maybe (SessionID, SessionData)
  , ResumptionInfo -> Token
resumptionToken   :: Token
  , ResumptionInfo -> Bool
resumptionRetry   :: Bool
  } deriving (ResumptionInfo -> ResumptionInfo -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ResumptionInfo -> ResumptionInfo -> Bool
$c/= :: ResumptionInfo -> ResumptionInfo -> Bool
== :: ResumptionInfo -> ResumptionInfo -> Bool
$c== :: ResumptionInfo -> ResumptionInfo -> Bool
Eq, Int -> ResumptionInfo -> ShowS
[ResumptionInfo] -> ShowS
ResumptionInfo -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ResumptionInfo] -> ShowS
$cshowList :: [ResumptionInfo] -> ShowS
show :: ResumptionInfo -> String
$cshow :: ResumptionInfo -> String
showsPrec :: Int -> ResumptionInfo -> ShowS
$cshowsPrec :: Int -> ResumptionInfo -> ShowS
Show)

defaultResumptionInfo :: ResumptionInfo
defaultResumptionInfo :: ResumptionInfo
defaultResumptionInfo = ResumptionInfo {
    resumptionVersion :: Version
resumptionVersion = Version
Version1
  , resumptionSession :: Maybe (Token, SessionData)
resumptionSession = forall a. Maybe a
Nothing
  , resumptionToken :: Token
resumptionToken   = Token
emptyToken
  , resumptionRetry :: Bool
resumptionRetry   = Bool
False
  }

-- | Is 0RTT possible?
is0RTTPossible :: ResumptionInfo -> Bool
is0RTTPossible :: ResumptionInfo -> Bool
is0RTTPossible ResumptionInfo{Bool
Maybe (Token, SessionData)
Token
Version
resumptionRetry :: Bool
resumptionToken :: Token
resumptionSession :: Maybe (Token, SessionData)
resumptionVersion :: Version
resumptionRetry :: ResumptionInfo -> Bool
resumptionToken :: ResumptionInfo -> Token
resumptionSession :: ResumptionInfo -> Maybe (Token, SessionData)
resumptionVersion :: ResumptionInfo -> Version
..} =
    Bool
rtt0OK Bool -> Bool -> Bool
&& (Bool -> Bool
not Bool
resumptionRetry Bool -> Bool -> Bool
|| Token
resumptionToken forall a. Eq a => a -> a -> Bool
/= Token
emptyToken)
  where
    rtt0OK :: Bool
rtt0OK = case Maybe (Token, SessionData)
resumptionSession of
      Maybe (Token, SessionData)
Nothing      -> Bool
False
      Just (Token
_, SessionData
sd) -> SessionData -> Int
sessionMaxEarlyDataSize SessionData
sd forall a. Eq a => a -> a -> Bool
== Int
quicMaxEarlyDataSize

-- | Is resumption possible?
isResumptionPossible :: ResumptionInfo -> Bool
isResumptionPossible :: ResumptionInfo -> Bool
isResumptionPossible ResumptionInfo{Bool
Maybe (Token, SessionData)
Token
Version
resumptionRetry :: Bool
resumptionToken :: Token
resumptionSession :: Maybe (Token, SessionData)
resumptionVersion :: Version
resumptionRetry :: ResumptionInfo -> Bool
resumptionToken :: ResumptionInfo -> Token
resumptionSession :: ResumptionInfo -> Maybe (Token, SessionData)
resumptionVersion :: ResumptionInfo -> Version
..} = forall a. Maybe a -> Bool
isJust Maybe (Token, SessionData)
resumptionSession

get0RTTCipher :: ResumptionInfo -> Maybe CipherID
get0RTTCipher :: ResumptionInfo -> Maybe CipherID
get0RTTCipher ResumptionInfo
ri = case ResumptionInfo -> Maybe (Token, SessionData)
resumptionSession ResumptionInfo
ri of
  Maybe (Token, SessionData)
Nothing      -> forall a. Maybe a
Nothing
  Just (Token
_, SessionData
sd) -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ SessionData -> CipherID
sessionCipher SessionData
sd