{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}

module Network.QUIC.Types.Packet where

import Data.Ix
import Network.UDP
import Network.TLS.QUIC (extensionID_QuicTransportParameters, ExtensionID)
import Text.Printf

import Network.QUIC.Imports
import Network.QUIC.Types.Ack
import Network.QUIC.Types.CID
import Network.QUIC.Types.Frame
import Network.QUIC.Types.Time

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

-- | QUIC version.
newtype Version = Version Word32 deriving (Version -> Version -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Version -> Version -> Bool
$c/= :: Version -> Version -> Bool
== :: Version -> Version -> Bool
$c== :: Version -> Version -> Bool
Eq, Eq Version
Version -> Version -> Bool
Version -> Version -> Ordering
Version -> Version -> Version
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Version -> Version -> Version
$cmin :: Version -> Version -> Version
max :: Version -> Version -> Version
$cmax :: Version -> Version -> Version
>= :: Version -> Version -> Bool
$c>= :: Version -> Version -> Bool
> :: Version -> Version -> Bool
$c> :: Version -> Version -> Bool
<= :: Version -> Version -> Bool
$c<= :: Version -> Version -> Bool
< :: Version -> Version -> Bool
$c< :: Version -> Version -> Bool
compare :: Version -> Version -> Ordering
$ccompare :: Version -> Version -> Ordering
Ord)

pattern Negotiation      :: Version
pattern $bNegotiation :: Version
$mNegotiation :: forall {r}. Version -> ((# #) -> r) -> ((# #) -> r) -> r
Negotiation       = Version 0
pattern Version1         :: Version
pattern $bVersion1 :: Version
$mVersion1 :: forall {r}. Version -> ((# #) -> r) -> ((# #) -> r) -> r
Version1          = Version 1
pattern Version2         :: Version
pattern $bVersion2 :: Version
$mVersion2 :: forall {r}. Version -> ((# #) -> r) -> ((# #) -> r) -> r
Version2          = Version 0x6b3343cf
pattern Draft29          :: Version
pattern $bDraft29 :: Version
$mDraft29 :: forall {r}. Version -> ((# #) -> r) -> ((# #) -> r) -> r
Draft29           = Version 0xff00001d
pattern GreasingVersion  :: Version
pattern $bGreasingVersion :: Version
$mGreasingVersion :: forall {r}. Version -> ((# #) -> r) -> ((# #) -> r) -> r
GreasingVersion   = Version 0x0a0a0a0a
pattern GreasingVersion2 :: Version
pattern $bGreasingVersion2 :: Version
$mGreasingVersion2 :: forall {r}. Version -> ((# #) -> r) -> ((# #) -> r) -> r
GreasingVersion2  = Version 0x1a2a3a4a

instance Show Version where
    show :: Version -> String
show (Version          Word32
0) = String
"Negotiation"
    show (Version          Word32
1) = String
"Version1"
    show (Version Word32
0x6b3343cf) = String
"Version2"
    show (Version Word32
0xff00001d) = String
"Draft29"
    show ver :: Version
ver@(Version Word32
v)
      | Version -> Bool
isGreasingVersion Version
ver = String
"Greasing 0x" forall a. [a] -> [a] -> [a]
++ forall r. PrintfType r => String -> r
printf String
"%08x" Word32
v
      | Bool
otherwise             =  String
"Version 0x" forall a. [a] -> [a] -> [a]
++ forall r. PrintfType r => String -> r
printf String
"%08x" Word32
v

isGreasingVersion :: Version -> Bool
isGreasingVersion :: Version -> Bool
isGreasingVersion (Version Word32
v) = Word32
v forall a. Bits a => a -> a -> a
.&. Word32
0x0a0a0a0a forall a. Eq a => a -> a -> Bool
== Word32
0x0a0a0a0a

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

data VersionInfo = VersionInfo {
    VersionInfo -> Version
chosenVersion :: Version
  , VersionInfo -> [Version]
otherVersions :: [Version]
  } deriving (VersionInfo -> VersionInfo -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VersionInfo -> VersionInfo -> Bool
$c/= :: VersionInfo -> VersionInfo -> Bool
== :: VersionInfo -> VersionInfo -> Bool
$c== :: VersionInfo -> VersionInfo -> Bool
Eq, Int -> VersionInfo -> ShowS
[VersionInfo] -> ShowS
VersionInfo -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VersionInfo] -> ShowS
$cshowList :: [VersionInfo] -> ShowS
show :: VersionInfo -> String
$cshow :: VersionInfo -> String
showsPrec :: Int -> VersionInfo -> ShowS
$cshowsPrec :: Int -> VersionInfo -> ShowS
Show)

brokenVersionInfo :: VersionInfo
brokenVersionInfo :: VersionInfo
brokenVersionInfo = Version -> [Version] -> VersionInfo
VersionInfo Version
Negotiation []

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

extensionIDForTtransportParameter :: Version -> ExtensionID
extensionIDForTtransportParameter :: Version -> ExtensionID
extensionIDForTtransportParameter Version
Version1 = ExtensionID
extensionID_QuicTransportParameters
extensionIDForTtransportParameter Version
Version2 = ExtensionID
extensionID_QuicTransportParameters
extensionIDForTtransportParameter Version
_        = ExtensionID
0xffa5

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

data PacketI = PacketIV VersionNegotiationPacket
             | PacketIR RetryPacket
             | PacketIC CryptPacket EncryptionLevel Int
             | PacketIB BrokenPacket
             deriving (PacketI -> PacketI -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PacketI -> PacketI -> Bool
$c/= :: PacketI -> PacketI -> Bool
== :: PacketI -> PacketI -> Bool
$c== :: PacketI -> PacketI -> Bool
Eq, Int -> PacketI -> ShowS
[PacketI] -> ShowS
PacketI -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PacketI] -> ShowS
$cshowList :: [PacketI] -> ShowS
show :: PacketI -> String
$cshow :: PacketI -> String
showsPrec :: Int -> PacketI -> ShowS
$cshowsPrec :: Int -> PacketI -> ShowS
Show)

-- Not used internally. Only for 'encodePacket'.
data PacketO = PacketOV VersionNegotiationPacket
             | PacketOR RetryPacket
             | PacketOP PlainPacket
             deriving (PacketO -> PacketO -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PacketO -> PacketO -> Bool
$c/= :: PacketO -> PacketO -> Bool
== :: PacketO -> PacketO -> Bool
$c== :: PacketO -> PacketO -> Bool
Eq, Int -> PacketO -> ShowS
[PacketO] -> ShowS
PacketO -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PacketO] -> ShowS
$cshowList :: [PacketO] -> ShowS
show :: PacketO -> String
$cshow :: PacketO -> String
showsPrec :: Int -> PacketO -> ShowS
$cshowsPrec :: Int -> PacketO -> ShowS
Show)

data VersionNegotiationPacket = VersionNegotiationPacket CID CID [Version]
                              deriving (VersionNegotiationPacket -> VersionNegotiationPacket -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VersionNegotiationPacket -> VersionNegotiationPacket -> Bool
$c/= :: VersionNegotiationPacket -> VersionNegotiationPacket -> Bool
== :: VersionNegotiationPacket -> VersionNegotiationPacket -> Bool
$c== :: VersionNegotiationPacket -> VersionNegotiationPacket -> Bool
Eq, Int -> VersionNegotiationPacket -> ShowS
[VersionNegotiationPacket] -> ShowS
VersionNegotiationPacket -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VersionNegotiationPacket] -> ShowS
$cshowList :: [VersionNegotiationPacket] -> ShowS
show :: VersionNegotiationPacket -> String
$cshow :: VersionNegotiationPacket -> String
showsPrec :: Int -> VersionNegotiationPacket -> ShowS
$cshowsPrec :: Int -> VersionNegotiationPacket -> ShowS
Show)

data RetryPacket = RetryPacket Version CID CID Token (Either CID (ByteString,ByteString))
                 deriving (RetryPacket -> RetryPacket -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RetryPacket -> RetryPacket -> Bool
$c/= :: RetryPacket -> RetryPacket -> Bool
== :: RetryPacket -> RetryPacket -> Bool
$c== :: RetryPacket -> RetryPacket -> Bool
Eq, Int -> RetryPacket -> ShowS
[RetryPacket] -> ShowS
RetryPacket -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RetryPacket] -> ShowS
$cshowList :: [RetryPacket] -> ShowS
show :: RetryPacket -> String
$cshow :: RetryPacket -> String
showsPrec :: Int -> RetryPacket -> ShowS
$cshowsPrec :: Int -> RetryPacket -> ShowS
Show)

data BrokenPacket = BrokenPacket deriving (BrokenPacket -> BrokenPacket -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BrokenPacket -> BrokenPacket -> Bool
$c/= :: BrokenPacket -> BrokenPacket -> Bool
== :: BrokenPacket -> BrokenPacket -> Bool
$c== :: BrokenPacket -> BrokenPacket -> Bool
Eq, Int -> BrokenPacket -> ShowS
[BrokenPacket] -> ShowS
BrokenPacket -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BrokenPacket] -> ShowS
$cshowList :: [BrokenPacket] -> ShowS
show :: BrokenPacket -> String
$cshow :: BrokenPacket -> String
showsPrec :: Int -> BrokenPacket -> ShowS
$cshowsPrec :: Int -> BrokenPacket -> ShowS
Show)

data Header = Initial   Version  CID CID Token
            | RTT0      Version  CID CID
            | Handshake Version  CID CID
            | Short              CID
            deriving (Header -> Header -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Header -> Header -> Bool
$c/= :: Header -> Header -> Bool
== :: Header -> Header -> Bool
$c== :: Header -> Header -> Bool
Eq, Int -> Header -> ShowS
[Header] -> ShowS
Header -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Header] -> ShowS
$cshowList :: [Header] -> ShowS
show :: Header -> String
$cshow :: Header -> String
showsPrec :: Int -> Header -> ShowS
$cshowsPrec :: Int -> Header -> ShowS
Show)

headerMyCID :: Header -> CID
headerMyCID :: Header -> CID
headerMyCID (Initial   Version
_ CID
cid CID
_ Token
_) = CID
cid
headerMyCID (RTT0      Version
_ CID
cid CID
_)   = CID
cid
headerMyCID (Handshake Version
_ CID
cid CID
_)   = CID
cid
headerMyCID (Short       CID
cid)     = CID
cid

headerPeerCID :: Header -> CID
headerPeerCID :: Header -> CID
headerPeerCID (Initial   Version
_ CID
_ CID
cid Token
_) = CID
cid
headerPeerCID (RTT0      Version
_ CID
_ CID
cid)   = CID
cid
headerPeerCID (Handshake Version
_ CID
_ CID
cid)   = CID
cid
headerPeerCID  Short{}              = Bytes -> CID
CID Bytes
""

data PlainPacket = PlainPacket Header Plain deriving (PlainPacket -> PlainPacket -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PlainPacket -> PlainPacket -> Bool
$c/= :: PlainPacket -> PlainPacket -> Bool
== :: PlainPacket -> PlainPacket -> Bool
$c== :: PlainPacket -> PlainPacket -> Bool
Eq, Int -> PlainPacket -> ShowS
[PlainPacket] -> ShowS
PlainPacket -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PlainPacket] -> ShowS
$cshowList :: [PlainPacket] -> ShowS
show :: PlainPacket -> String
$cshow :: PlainPacket -> String
showsPrec :: Int -> PlainPacket -> ShowS
$cshowsPrec :: Int -> PlainPacket -> ShowS
Show)
data CryptPacket = CryptPacket Header Crypt deriving (CryptPacket -> CryptPacket -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CryptPacket -> CryptPacket -> Bool
$c/= :: CryptPacket -> CryptPacket -> Bool
== :: CryptPacket -> CryptPacket -> Bool
$c== :: CryptPacket -> CryptPacket -> Bool
Eq, Int -> CryptPacket -> ShowS
[CryptPacket] -> ShowS
CryptPacket -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CryptPacket] -> ShowS
$cshowList :: [CryptPacket] -> ShowS
show :: CryptPacket -> String
$cshow :: CryptPacket -> String
showsPrec :: Int -> CryptPacket -> ShowS
$cshowsPrec :: Int -> CryptPacket -> ShowS
Show)

data Plain = Plain {
    Plain -> Flags Raw
plainFlags        :: Flags Raw
  , Plain -> Int
plainPacketNumber :: PacketNumber
  , Plain -> [Frame]
plainFrames       :: [Frame]
  , Plain -> Int
plainMarks        :: Int
  } deriving (Plain -> Plain -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Plain -> Plain -> Bool
$c/= :: Plain -> Plain -> Bool
== :: Plain -> Plain -> Bool
$c== :: Plain -> Plain -> Bool
Eq, Int -> Plain -> ShowS
[Plain] -> ShowS
Plain -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Plain] -> ShowS
$cshowList :: [Plain] -> ShowS
show :: Plain -> String
$cshow :: Plain -> String
showsPrec :: Int -> Plain -> ShowS
$cshowsPrec :: Int -> Plain -> ShowS
Show)

defaultPlainMarks :: Int
defaultPlainMarks :: Int
defaultPlainMarks = Int
0

setIllegalReservedBits :: Int -> Int
setIllegalReservedBits :: Int -> Int
setIllegalReservedBits = (forall a. Bits a => a -> Int -> a
`setBit` Int
0)

setUnknownFrame :: Int -> Int
setUnknownFrame :: Int -> Int
setUnknownFrame = (forall a. Bits a => a -> Int -> a
`setBit` Int
1)

setNoFrames :: Int -> Int
setNoFrames :: Int -> Int
setNoFrames = (forall a. Bits a => a -> Int -> a
`setBit` Int
2)

setNoPaddings :: Int -> Int
setNoPaddings :: Int -> Int
setNoPaddings = (forall a. Bits a => a -> Int -> a
`setBit` Int
8)

set4bytesPN :: Int -> Int
set4bytesPN :: Int -> Int
set4bytesPN = (forall a. Bits a => a -> Int -> a
`setBit` Int
9)

isIllegalReservedBits :: Int -> Bool
isIllegalReservedBits :: Int -> Bool
isIllegalReservedBits = (forall a. Bits a => a -> Int -> Bool
`testBit` Int
0)

isUnknownFrame :: Int -> Bool
isUnknownFrame :: Int -> Bool
isUnknownFrame = (forall a. Bits a => a -> Int -> Bool
`testBit` Int
1)

isNoFrames :: Int -> Bool
isNoFrames :: Int -> Bool
isNoFrames = (forall a. Bits a => a -> Int -> Bool
`testBit` Int
2)

isNoPaddings :: Int -> Bool
isNoPaddings :: Int -> Bool
isNoPaddings = (forall a. Bits a => a -> Int -> Bool
`testBit` Int
8)

is4bytesPN :: Int -> Bool
is4bytesPN :: Int -> Bool
is4bytesPN = (forall a. Bits a => a -> Int -> Bool
`testBit` Int
9)

data MigrationInfo = MigrationInfo ListenSocket ClientSockAddr CID deriving (MigrationInfo -> MigrationInfo -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MigrationInfo -> MigrationInfo -> Bool
$c/= :: MigrationInfo -> MigrationInfo -> Bool
== :: MigrationInfo -> MigrationInfo -> Bool
$c== :: MigrationInfo -> MigrationInfo -> Bool
Eq, Int -> MigrationInfo -> ShowS
[MigrationInfo] -> ShowS
MigrationInfo -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MigrationInfo] -> ShowS
$cshowList :: [MigrationInfo] -> ShowS
show :: MigrationInfo -> String
$cshow :: MigrationInfo -> String
showsPrec :: Int -> MigrationInfo -> ShowS
$cshowsPrec :: Int -> MigrationInfo -> ShowS
Show)

data Crypt = Crypt {
    Crypt -> Int
cryptPktNumOffset :: Int
  , Crypt -> Token
cryptPacket       :: ByteString
  , Crypt -> Int
cryptMarks        :: Int
  , Crypt -> Maybe MigrationInfo
cryptMigraionInfo :: Maybe MigrationInfo
  } deriving (Crypt -> Crypt -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Crypt -> Crypt -> Bool
$c/= :: Crypt -> Crypt -> Bool
== :: Crypt -> Crypt -> Bool
$c== :: Crypt -> Crypt -> Bool
Eq, Int -> Crypt -> ShowS
[Crypt] -> ShowS
Crypt -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Crypt] -> ShowS
$cshowList :: [Crypt] -> ShowS
show :: Crypt -> String
$cshow :: Crypt -> String
showsPrec :: Int -> Crypt -> ShowS
$cshowsPrec :: Int -> Crypt -> ShowS
Show)

isCryptDelayed :: Crypt -> Bool
isCryptDelayed :: Crypt -> Bool
isCryptDelayed Crypt
crypt = Crypt -> Int
cryptMarks Crypt
crypt forall a. Bits a => a -> Int -> Bool
`testBit` Int
1

setCryptDelayed :: Crypt -> Crypt
setCryptDelayed :: Crypt -> Crypt
setCryptDelayed Crypt
crypt = Crypt
crypt { cryptMarks :: Int
cryptMarks = Crypt -> Int
cryptMarks Crypt
crypt forall a. Bits a => a -> Int -> a
`setBit` Int
1 }

data StatelessReset = StatelessReset deriving (StatelessReset -> StatelessReset -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StatelessReset -> StatelessReset -> Bool
$c/= :: StatelessReset -> StatelessReset -> Bool
== :: StatelessReset -> StatelessReset -> Bool
$c== :: StatelessReset -> StatelessReset -> Bool
Eq, Int -> StatelessReset -> ShowS
[StatelessReset] -> ShowS
StatelessReset -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StatelessReset] -> ShowS
$cshowList :: [StatelessReset] -> ShowS
show :: StatelessReset -> String
$cshow :: StatelessReset -> String
showsPrec :: Int -> StatelessReset -> ShowS
$cshowsPrec :: Int -> StatelessReset -> ShowS
Show)

data ReceivedPacket = ReceivedPacket {
    ReceivedPacket -> CryptPacket
rpCryptPacket     :: CryptPacket
  , ReceivedPacket -> TimeMicrosecond
rpTimeRecevied    :: TimeMicrosecond
  , ReceivedPacket -> Int
rpReceivedBytes   :: Int
  , ReceivedPacket -> EncryptionLevel
rpEncryptionLevel :: EncryptionLevel
  } deriving (ReceivedPacket -> ReceivedPacket -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ReceivedPacket -> ReceivedPacket -> Bool
$c/= :: ReceivedPacket -> ReceivedPacket -> Bool
== :: ReceivedPacket -> ReceivedPacket -> Bool
$c== :: ReceivedPacket -> ReceivedPacket -> Bool
Eq, Int -> ReceivedPacket -> ShowS
[ReceivedPacket] -> ShowS
ReceivedPacket -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ReceivedPacket] -> ShowS
$cshowList :: [ReceivedPacket] -> ShowS
show :: ReceivedPacket -> String
$cshow :: ReceivedPacket -> String
showsPrec :: Int -> ReceivedPacket -> ShowS
$cshowsPrec :: Int -> ReceivedPacket -> ShowS
Show)

mkReceivedPacket :: CryptPacket -> TimeMicrosecond -> Int -> EncryptionLevel -> ReceivedPacket
mkReceivedPacket :: CryptPacket
-> TimeMicrosecond -> Int -> EncryptionLevel -> ReceivedPacket
mkReceivedPacket CryptPacket
cpkt TimeMicrosecond
tim Int
bytes EncryptionLevel
lvl = ReceivedPacket {
    rpCryptPacket :: CryptPacket
rpCryptPacket     = CryptPacket
cpkt
  , rpTimeRecevied :: TimeMicrosecond
rpTimeRecevied    = TimeMicrosecond
tim
  , rpReceivedBytes :: Int
rpReceivedBytes   = Int
bytes
  , rpEncryptionLevel :: EncryptionLevel
rpEncryptionLevel = EncryptionLevel
lvl
  }

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

data LongHeaderPacketType = InitialPacketType
                          | RTT0PacketType
                          | HandshakePacketType
                          | RetryPacketType
                          deriving (LongHeaderPacketType -> LongHeaderPacketType -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LongHeaderPacketType -> LongHeaderPacketType -> Bool
$c/= :: LongHeaderPacketType -> LongHeaderPacketType -> Bool
== :: LongHeaderPacketType -> LongHeaderPacketType -> Bool
$c== :: LongHeaderPacketType -> LongHeaderPacketType -> Bool
Eq, Int -> LongHeaderPacketType -> ShowS
[LongHeaderPacketType] -> ShowS
LongHeaderPacketType -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LongHeaderPacketType] -> ShowS
$cshowList :: [LongHeaderPacketType] -> ShowS
show :: LongHeaderPacketType -> String
$cshow :: LongHeaderPacketType -> String
showsPrec :: Int -> LongHeaderPacketType -> ShowS
$cshowsPrec :: Int -> LongHeaderPacketType -> ShowS
Show)

data EncryptionLevel = InitialLevel
                     | RTT0Level
                     | HandshakeLevel
                     | RTT1Level
                     deriving (EncryptionLevel -> EncryptionLevel -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EncryptionLevel -> EncryptionLevel -> Bool
$c/= :: EncryptionLevel -> EncryptionLevel -> Bool
== :: EncryptionLevel -> EncryptionLevel -> Bool
$c== :: EncryptionLevel -> EncryptionLevel -> Bool
Eq, Eq EncryptionLevel
EncryptionLevel -> EncryptionLevel -> Bool
EncryptionLevel -> EncryptionLevel -> Ordering
EncryptionLevel -> EncryptionLevel -> EncryptionLevel
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: EncryptionLevel -> EncryptionLevel -> EncryptionLevel
$cmin :: EncryptionLevel -> EncryptionLevel -> EncryptionLevel
max :: EncryptionLevel -> EncryptionLevel -> EncryptionLevel
$cmax :: EncryptionLevel -> EncryptionLevel -> EncryptionLevel
>= :: EncryptionLevel -> EncryptionLevel -> Bool
$c>= :: EncryptionLevel -> EncryptionLevel -> Bool
> :: EncryptionLevel -> EncryptionLevel -> Bool
$c> :: EncryptionLevel -> EncryptionLevel -> Bool
<= :: EncryptionLevel -> EncryptionLevel -> Bool
$c<= :: EncryptionLevel -> EncryptionLevel -> Bool
< :: EncryptionLevel -> EncryptionLevel -> Bool
$c< :: EncryptionLevel -> EncryptionLevel -> Bool
compare :: EncryptionLevel -> EncryptionLevel -> Ordering
$ccompare :: EncryptionLevel -> EncryptionLevel -> Ordering
Ord, Ord EncryptionLevel
(EncryptionLevel, EncryptionLevel) -> Int
(EncryptionLevel, EncryptionLevel) -> [EncryptionLevel]
(EncryptionLevel, EncryptionLevel) -> EncryptionLevel -> Bool
(EncryptionLevel, EncryptionLevel) -> EncryptionLevel -> Int
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
unsafeRangeSize :: (EncryptionLevel, EncryptionLevel) -> Int
$cunsafeRangeSize :: (EncryptionLevel, EncryptionLevel) -> Int
rangeSize :: (EncryptionLevel, EncryptionLevel) -> Int
$crangeSize :: (EncryptionLevel, EncryptionLevel) -> Int
inRange :: (EncryptionLevel, EncryptionLevel) -> EncryptionLevel -> Bool
$cinRange :: (EncryptionLevel, EncryptionLevel) -> EncryptionLevel -> Bool
unsafeIndex :: (EncryptionLevel, EncryptionLevel) -> EncryptionLevel -> Int
$cunsafeIndex :: (EncryptionLevel, EncryptionLevel) -> EncryptionLevel -> Int
index :: (EncryptionLevel, EncryptionLevel) -> EncryptionLevel -> Int
$cindex :: (EncryptionLevel, EncryptionLevel) -> EncryptionLevel -> Int
range :: (EncryptionLevel, EncryptionLevel) -> [EncryptionLevel]
$crange :: (EncryptionLevel, EncryptionLevel) -> [EncryptionLevel]
Ix, Int -> EncryptionLevel -> ShowS
[EncryptionLevel] -> ShowS
EncryptionLevel -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EncryptionLevel] -> ShowS
$cshowList :: [EncryptionLevel] -> ShowS
show :: EncryptionLevel -> String
$cshow :: EncryptionLevel -> String
showsPrec :: Int -> EncryptionLevel -> ShowS
$cshowsPrec :: Int -> EncryptionLevel -> ShowS
Show)

packetEncryptionLevel :: Header -> EncryptionLevel
packetEncryptionLevel :: Header -> EncryptionLevel
packetEncryptionLevel Initial{}   = EncryptionLevel
InitialLevel
packetEncryptionLevel RTT0{}      = EncryptionLevel
RTT0Level
packetEncryptionLevel Handshake{} = EncryptionLevel
HandshakeLevel
packetEncryptionLevel Short{}     = EncryptionLevel
RTT1Level

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

newtype Flags a = Flags Word8 deriving (Flags a -> Flags a -> Bool
forall a. Flags a -> Flags a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Flags a -> Flags a -> Bool
$c/= :: forall a. Flags a -> Flags a -> Bool
== :: Flags a -> Flags a -> Bool
$c== :: forall a. Flags a -> Flags a -> Bool
Eq, Int -> Flags a -> ShowS
forall a. Int -> Flags a -> ShowS
forall a. [Flags a] -> ShowS
forall a. Flags a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Flags a] -> ShowS
$cshowList :: forall a. [Flags a] -> ShowS
show :: Flags a -> String
$cshow :: forall a. Flags a -> String
showsPrec :: Int -> Flags a -> ShowS
$cshowsPrec :: forall a. Int -> Flags a -> ShowS
Show)

data Protected
data Raw

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

type EncodedPacketNumber = Word32