quic-0.0.0: Network/QUIC/Types/Packet.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
module Network.QUIC.Types.Packet where
import Data.Ix
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 (Eq, Ord, Show)
pattern Negotiation :: Version
pattern Negotiation = Version 0
pattern Version1 :: Version
pattern Version1 = Version 1
pattern Draft29 :: Version
pattern Draft29 = Version 0xff00001d
pattern GreasingVersion :: Version
pattern GreasingVersion = Version 0x0a0a0a0a
pattern GreasingVersion2 :: Version
pattern GreasingVersion2 = Version 0x1a2a3a4a
----------------------------------------------------------------
data PacketI = PacketIV VersionNegotiationPacket
| PacketIR RetryPacket
| PacketIC CryptPacket EncryptionLevel
| PacketIB BrokenPacket
deriving (Eq, Show)
-- Not used internally. Only for 'encodePacket'.
data PacketO = PacketOV VersionNegotiationPacket
| PacketOR RetryPacket
| PacketOP PlainPacket
deriving (Eq, Show)
data VersionNegotiationPacket = VersionNegotiationPacket CID CID [Version]
deriving (Eq, Show)
data RetryPacket = RetryPacket Version CID CID Token (Either CID (ByteString,ByteString))
deriving (Eq, Show)
data BrokenPacket = BrokenPacket deriving (Eq, Show)
data Header = Initial Version CID CID Token
| RTT0 Version CID CID
| Handshake Version CID CID
| Short CID
deriving (Eq, Show)
headerMyCID :: Header -> CID
headerMyCID (Initial _ cid _ _) = cid
headerMyCID (RTT0 _ cid _) = cid
headerMyCID (Handshake _ cid _) = cid
headerMyCID (Short cid) = cid
headerPeerCID :: Header -> CID
headerPeerCID (Initial _ _ cid _) = cid
headerPeerCID (RTT0 _ _ cid) = cid
headerPeerCID (Handshake _ _ cid) = cid
headerPeerCID Short{} = CID ""
data PlainPacket = PlainPacket Header Plain deriving (Eq, Show)
data CryptPacket = CryptPacket Header Crypt deriving (Eq, Show)
data Plain = Plain {
plainFlags :: Flags Raw
, plainPacketNumber :: PacketNumber
, plainFrames :: [Frame]
, plainMarks :: Int
} deriving (Eq, Show)
defaultPlainMarks :: Int
defaultPlainMarks = 0
setIllegalReservedBits :: Int -> Int
setIllegalReservedBits = (`setBit` 0)
setUnknownFrame :: Int -> Int
setUnknownFrame = (`setBit` 1)
setNoFrames :: Int -> Int
setNoFrames = (`setBit` 2)
setNoPaddings :: Int -> Int
setNoPaddings = (`setBit` 8)
set4bytesPN :: Int -> Int
set4bytesPN = (`setBit` 9)
isIllegalReservedBits :: Int -> Bool
isIllegalReservedBits = (`testBit` 0)
isUnknownFrame :: Int -> Bool
isUnknownFrame = (`testBit` 1)
isNoFrames :: Int -> Bool
isNoFrames = (`testBit` 2)
isNoPaddings :: Int -> Bool
isNoPaddings = (`testBit` 8)
is4bytesPN :: Int -> Bool
is4bytesPN = (`testBit` 9)
data Crypt = Crypt {
cryptPktNumOffset :: Int
, cryptPacket :: ByteString
, cryptMarks :: Int
} deriving (Eq, Show)
isCryptLogged :: Crypt -> Bool
isCryptLogged crypt = cryptMarks crypt `testBit` 0
isCryptDelayed :: Crypt -> Bool
isCryptDelayed crypt = cryptMarks crypt `testBit` 1
setCryptLogged :: Crypt -> Crypt
setCryptLogged crypt = crypt { cryptMarks = cryptMarks crypt `setBit` 0 }
setCryptDelayed :: Crypt -> Crypt
setCryptDelayed crypt = crypt { cryptMarks = cryptMarks crypt `setBit` 1 }
data StatelessReset = StatelessReset deriving (Eq, Show)
data ReceivedPacket = ReceivedPacket {
rpCryptPacket :: CryptPacket
, rpTimeRecevied :: TimeMicrosecond
, rpReceivedBytes :: Int
, rpEncryptionLevel :: EncryptionLevel
} deriving (Eq, Show)
mkReceivedPacket :: CryptPacket -> TimeMicrosecond -> Int -> EncryptionLevel -> ReceivedPacket
mkReceivedPacket cpkt tim bytes lvl = ReceivedPacket {
rpCryptPacket = cpkt
, rpTimeRecevied = tim
, rpReceivedBytes = bytes
, rpEncryptionLevel = lvl
}
----------------------------------------------------------------
data LongHeaderPacketType = InitialPacketType
| RTT0PacketType
| HandshakePacketType
| RetryPacketType
deriving (Eq, Show)
data EncryptionLevel = InitialLevel
| RTT0Level
| HandshakeLevel
| RTT1Level
deriving (Eq, Ord, Ix, Show)
packetEncryptionLevel :: Header -> EncryptionLevel
packetEncryptionLevel Initial{} = InitialLevel
packetEncryptionLevel RTT0{} = RTT0Level
packetEncryptionLevel Handshake{} = HandshakeLevel
packetEncryptionLevel Short{} = RTT1Level
----------------------------------------------------------------
newtype Flags a = Flags Word8 deriving (Eq, Show)
data Protected
data Raw
----------------------------------------------------------------
type EncodedPacketNumber = Word32