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

module Network.QUIC.Receiver (
    receiver
  ) where

import qualified Data.ByteString as BS
import Network.TLS (AlertDescription(..))
import UnliftIO.Concurrent (forkIO)
import qualified UnliftIO.Exception as E

import Network.QUIC.Config
import Network.QUIC.Connection
import Network.QUIC.Connector
import Network.QUIC.Crypto
import Network.QUIC.Exception
import Network.QUIC.Imports
import Network.QUIC.Logger
import Network.QUIC.Packet
import Network.QUIC.Parameters
import Network.QUIC.Qlog
import Network.QUIC.Recovery
import Network.QUIC.Server.Reader (runNewServerReader)
import Network.QUIC.Stream
import Network.QUIC.Types

receiver :: Connection -> IO ()
receiver :: Connection -> IO ()
receiver Connection
conn = forall a. DebugLogger -> IO a -> IO a
handleLogT DebugLogger
logAction forall {b}. IO b
body
  where
    body :: IO b
body = do
        IO ()
loopHandshake
        forall {b}. IO b
loopEstablished
    recvTimeout :: IO ReceivedPacket
recvTimeout = do
        -- The spec says that CC is not sent when timeout.
        -- But we intentionally sends CC when timeout.
        Microseconds
ito <- Connection -> IO Microseconds
readMinIdleTimeout Connection
conn
        Maybe ReceivedPacket
mx <- forall a. Microseconds -> IO a -> IO (Maybe a)
timeout Microseconds
ito forall a b. (a -> b) -> a -> b
$ Connection -> IO ReceivedPacket
connRecv Connection
conn -- fixme: taking minimum with peer's one
        case Maybe ReceivedPacket
mx of
          Maybe ReceivedPacket
Nothing -> do
              ConnectionState
st <- forall a. Connector a => a -> IO ConnectionState
getConnectionState Connection
conn
              let msg0 :: [Char]
msg0 | forall a. Connector a => a -> Bool
isClient Connection
conn = [Char]
"Client"
                       | Bool
otherwise     = [Char]
"Server"
                  msg :: [Char]
msg = [Char]
msg0 forall a. [a] -> [a] -> [a]
++ [Char]
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show ConnectionState
st
              forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
E.throwIO forall a b. (a -> b) -> a -> b
$ [Char] -> QUICException
ConnectionIsTimeout [Char]
msg
          Just ReceivedPacket
x  -> forall (m :: * -> *) a. Monad m => a -> m a
return ReceivedPacket
x
    loopHandshake :: IO ()
loopHandshake = do
        ReceivedPacket
rpkt <- IO ReceivedPacket
recvTimeout
        Connection -> ReceivedPacket -> IO ()
processReceivedPacketHandshake Connection
conn ReceivedPacket
rpkt
        Bool
established <- forall a. Connector a => a -> IO Bool
isConnectionEstablished Connection
conn
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
established IO ()
loopHandshake
    loopEstablished :: IO b
loopEstablished = forall (f :: * -> *) a b. Applicative f => f a -> f b
forever forall a b. (a -> b) -> a -> b
$ do
        ReceivedPacket
rpkt <- IO ReceivedPacket
recvTimeout
        let CryptPacket Header
hdr Crypt
_ = ReceivedPacket -> CryptPacket
rpCryptPacket ReceivedPacket
rpkt
            cid :: CID
cid = Header -> CID
headerMyCID Header
hdr
        Maybe StreamId
included <- Connection -> CID -> IO (Maybe StreamId)
myCIDsInclude Connection
conn CID
cid
        case Maybe StreamId
included of
          Just StreamId
nseq -> do
            Bool
shouldUpdate <- Connection -> StreamId -> IO Bool
shouldUpdateMyCID Connection
conn StreamId
nseq
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
shouldUpdate forall a b. (a -> b) -> a -> b
$ do
                Connection -> CID -> IO ()
setMyCID Connection
conn CID
cid
                CIDInfo
cidInfo <- Connection -> IO CIDInfo
getNewMyCID Connection
conn
                forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall a. Connector a => a -> Bool
isServer Connection
conn) forall a b. (a -> b) -> a -> b
$ do
                    CID -> Connection -> IO ()
register <- Connection -> IO (CID -> Connection -> IO ())
getRegister Connection
conn
                    CID -> Connection -> IO ()
register (CIDInfo -> CID
cidInfoCID CIDInfo
cidInfo) Connection
conn
                Connection -> EncryptionLevel -> [Frame] -> IO ()
sendFrames Connection
conn EncryptionLevel
RTT1Level [CIDInfo -> StreamId -> Frame
NewConnectionID CIDInfo
cidInfo StreamId
0]
            Connection -> ReceivedPacket -> IO ()
processReceivedPacket Connection
conn ReceivedPacket
rpkt
            Bool
shouldUpdatePeer <- if Bool
shouldUpdate then Connection -> IO Bool
shouldUpdatePeerCID Connection
conn
                                                else forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
shouldUpdatePeer forall a b. (a -> b) -> a -> b
$ Connection -> IO ()
choosePeerCIDForPrivacy Connection
conn
          Maybe StreamId
_ -> do
            forall q a. (KeepQlog q, Qlog a) => q -> a -> IO ()
qlogDropped Connection
conn Header
hdr
            Connection -> DebugLogger
connDebugLog Connection
conn forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> Builder
bhow CID
cid forall a. Semigroup a => a -> a -> a
<> Builder
" is unknown"
    logAction :: DebugLogger
logAction Builder
msg = Connection -> DebugLogger
connDebugLog Connection
conn (Builder
"debug: receiver: " forall a. Semigroup a => a -> a -> a
<> Builder
msg)

processReceivedPacketHandshake :: Connection -> ReceivedPacket -> IO ()
processReceivedPacketHandshake :: Connection -> ReceivedPacket -> IO ()
processReceivedPacketHandshake Connection
conn ReceivedPacket
rpkt = do
    let CryptPacket Header
hdr Crypt
_ = ReceivedPacket -> CryptPacket
rpCryptPacket ReceivedPacket
rpkt
        lvl :: EncryptionLevel
lvl = ReceivedPacket -> EncryptionLevel
rpEncryptionLevel ReceivedPacket
rpkt
    Maybe ()
mx <- forall a. Microseconds -> IO a -> IO (Maybe a)
timeout (StreamId -> Microseconds
Microseconds StreamId
10000) forall a b. (a -> b) -> a -> b
$ Connection -> EncryptionLevel -> IO ()
waitEncryptionLevel Connection
conn EncryptionLevel
lvl
    case Maybe ()
mx of
      Maybe ()
Nothing -> do
          Connection -> EncryptionLevel -> ReceivedPacket -> IO ()
putOffCrypto Connection
conn EncryptionLevel
lvl ReceivedPacket
rpkt
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall a. Connector a => a -> Bool
isClient Connection
conn) forall a b. (a -> b) -> a -> b
$ do
              EncryptionLevel
lvl' <- forall a. Connector a => a -> IO EncryptionLevel
getEncryptionLevel Connection
conn
              LDCC -> EncryptionLevel -> LogStr -> IO ()
speedup (Connection -> LDCC
connLDCC Connection
conn) EncryptionLevel
lvl' LogStr
"not decryptable"
      Just ()
        | forall a. Connector a => a -> Bool
isClient Connection
conn -> do
              forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
InitialLevel) forall a b. (a -> b) -> a -> b
$ do
                  CID
peercid <- Connection -> IO CID
getPeerCID Connection
conn
                  let newPeerCID :: CID
newPeerCID = Header -> CID
headerPeerCID Header
hdr
                  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (CID
peercid forall a. Eq a => a -> a -> Bool
/= Header -> CID
headerPeerCID Header
hdr) forall a b. (a -> b) -> a -> b
$
                      Connection -> CID -> IO ()
resetPeerCID Connection
conn CID
newPeerCID
                  Connection -> (AuthCIDs -> AuthCIDs) -> IO ()
setPeerAuthCIDs Connection
conn forall a b. (a -> b) -> a -> b
$ \AuthCIDs
auth ->
                      AuthCIDs
auth { initSrcCID :: Maybe CID
initSrcCID = forall a. a -> Maybe a
Just CID
newPeerCID }
              case Header
hdr of
                Initial Version
peerVer CID
_ CID
_ ByteString
_ -> do
                    Version
myVer <- Connection -> IO Version
getVersion Connection
conn
                    let myOrigiVer :: Version
myOrigiVer = Connection -> Version
getOriginalVersion Connection
conn
                        firstTime :: Bool
firstTime = Version
myVer forall a. Eq a => a -> a -> Bool
== Version
myOrigiVer
                    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
firstTime Bool -> Bool -> Bool
&& Version
myVer forall a. Eq a => a -> a -> Bool
/= Version
peerVer) forall a b. (a -> b) -> a -> b
$ do
                        Connection -> Version -> IO ()
setVersion Connection
conn Version
peerVer
                        CID
dcid <- Connection -> IO CID
getClientDstCID Connection
conn
                        forall a.
Connection -> EncryptionLevel -> TrafficSecrets a -> IO ()
initializeCoder Connection
conn EncryptionLevel
InitialLevel forall a b. (a -> b) -> a -> b
$ Version -> CID -> TrafficSecrets InitialSecret
initialSecrets Version
peerVer CID
dcid
                Header
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
              Connection -> ReceivedPacket -> IO ()
processReceivedPacket Connection
conn ReceivedPacket
rpkt
        | Bool
otherwise -> do
              CID
mycid <- Connection -> IO CID
getMyCID Connection
conn
              forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
HandshakeLevel
                    Bool -> Bool -> Bool
|| (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
InitialLevel Bool -> Bool -> Bool
&& CID
mycid forall a. Eq a => a -> a -> Bool
== Header -> CID
headerMyCID Header
hdr)) forall a b. (a -> b) -> a -> b
$ do
                  Connection -> IO ()
setAddressValidated Connection
conn
              forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
HandshakeLevel) forall a b. (a -> b) -> a -> b
$ do
                  let ldcc :: LDCC
ldcc = Connection -> LDCC
connLDCC Connection
conn
                  Bool
discarded <- LDCC -> EncryptionLevel -> IO Bool
getAndSetPacketNumberSpaceDiscarded LDCC
ldcc EncryptionLevel
InitialLevel
                  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
discarded forall a b. (a -> b) -> a -> b
$ Connection -> Microseconds -> IO () -> IO ()
fire Connection
conn (StreamId -> Microseconds
Microseconds StreamId
100000) forall a b. (a -> b) -> a -> b
$ do
                      Connection -> EncryptionLevel -> IO ()
dropSecrets Connection
conn EncryptionLevel
InitialLevel
                      Connection -> EncryptionLevel -> IO ()
clearCryptoStream Connection
conn EncryptionLevel
InitialLevel
                      LDCC -> EncryptionLevel -> IO ()
onPacketNumberSpaceDiscarded LDCC
ldcc EncryptionLevel
InitialLevel
              Connection -> ReceivedPacket -> IO ()
processReceivedPacket Connection
conn ReceivedPacket
rpkt

processReceivedPacket :: Connection -> ReceivedPacket -> IO ()
processReceivedPacket :: Connection -> ReceivedPacket -> IO ()
processReceivedPacket Connection
conn ReceivedPacket
rpkt = do
    let CryptPacket Header
hdr Crypt
crypt = ReceivedPacket -> CryptPacket
rpCryptPacket ReceivedPacket
rpkt
        lvl :: EncryptionLevel
lvl = ReceivedPacket -> EncryptionLevel
rpEncryptionLevel ReceivedPacket
rpkt
        tim :: TimeMicrosecond
tim = ReceivedPacket -> TimeMicrosecond
rpTimeRecevied ReceivedPacket
rpkt
    Maybe Plain
mplain <- Connection -> Crypt -> EncryptionLevel -> IO (Maybe Plain)
decryptCrypt Connection
conn Crypt
crypt EncryptionLevel
lvl
    case Maybe Plain
mplain of
      Just plain :: Plain
plain@Plain{StreamId
[Frame]
Flags Raw
plainMarks :: Plain -> StreamId
plainFrames :: Plain -> [Frame]
plainPacketNumber :: Plain -> StreamId
plainFlags :: Plain -> Flags Raw
plainMarks :: StreamId
plainFrames :: [Frame]
plainPacketNumber :: StreamId
plainFlags :: Flags Raw
..} -> do
          Connection -> StreamId -> IO ()
addRxBytes Connection
conn forall a b. (a -> b) -> a -> b
$ ReceivedPacket -> StreamId
rpReceivedBytes ReceivedPacket
rpkt
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (StreamId -> Bool
isIllegalReservedBits StreamId
plainMarks Bool -> Bool -> Bool
|| StreamId -> Bool
isNoFrames StreamId
plainMarks) forall a b. (a -> b) -> a -> b
$
              TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"Non 0 RR bits or no frames"
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (StreamId -> Bool
isUnknownFrame StreamId
plainMarks) forall a b. (a -> b) -> a -> b
$
              TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
FrameEncodingError ReasonPhrase
"Unknown frame"
          -- For Ping, record PPN first, then send an ACK.
          LDCC -> EncryptionLevel -> StreamId -> IO ()
onPacketReceived (Connection -> LDCC
connLDCC Connection
conn) EncryptionLevel
lvl StreamId
plainPacketNumber
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
RTT1Level) forall a b. (a -> b) -> a -> b
$ Connection -> StreamId -> IO ()
setPeerPacketNumber Connection
conn StreamId
plainPacketNumber
          forall q a.
(KeepQlog q, Qlog a) =>
q -> a -> TimeMicrosecond -> IO ()
qlogReceived Connection
conn (Header -> Plain -> PlainPacket
PlainPacket Header
hdr Plain
plain) TimeMicrosecond
tim
          let ackEli :: Bool
ackEli   = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Frame -> Bool
ackEliciting   [Frame]
plainFrames
          case Crypt -> Maybe MigrationInfo
cryptMigraionInfo Crypt
crypt of
            Maybe MigrationInfo
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
            Just MigrationInfo
miginfo ->
                forall (f :: * -> *) a. Functor f => f a -> f ()
void forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadUnliftIO m => m () -> m ThreadId
forkIO forall a b. (a -> b) -> a -> b
$ Connection -> MigrationInfo -> IO ()
runNewServerReader Connection
conn MigrationInfo
miginfo
          (Bool
ckp,StreamId
cpn) <- Connection -> IO (Bool, StreamId)
getCurrentKeyPhase Connection
conn
          let Flags Word8
flags = Flags Raw
plainFlags
              nkp :: Bool
nkp = Word8
flags forall a. Bits a => a -> StreamId -> Bool
`testBit` StreamId
2
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
nkp forall a. Eq a => a -> a -> Bool
/= Bool
ckp Bool -> Bool -> Bool
&& StreamId
plainPacketNumber forall a. Ord a => a -> a -> Bool
> StreamId
cpn) forall a b. (a -> b) -> a -> b
$ do
              Connection -> Bool -> StreamId -> IO ()
setCurrentKeyPhase Connection
conn Bool
nkp StreamId
plainPacketNumber
              Connection -> Bool -> IO ()
updateCoder1RTT Connection
conn Bool
ckp -- ckp is now next
          forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Connection -> EncryptionLevel -> Frame -> IO ()
processFrame Connection
conn EncryptionLevel
lvl) [Frame]
plainFrames
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
ackEli forall a b. (a -> b) -> a -> b
$ do
              case EncryptionLevel
lvl of
                EncryptionLevel
RTT0Level -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
                EncryptionLevel
RTT1Level -> Connection -> IO ()
delayedAck Connection
conn
                EncryptionLevel
_         -> do
                    Bool
sup <- LDCC -> IO Bool
getSpeedingUp (Connection -> LDCC
connLDCC Connection
conn)
                    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
sup forall a b. (a -> b) -> a -> b
$ do
                        forall q. KeepQlog q => q -> Debug -> IO ()
qlogDebug Connection
conn forall a b. (a -> b) -> a -> b
$ LogStr -> Debug
Debug LogStr
"ping for speedup"
                        Connection -> EncryptionLevel -> [Frame] -> IO ()
sendFrames Connection
conn EncryptionLevel
lvl [Frame
Ping]
      Maybe Plain
Nothing -> do
          Bool
statelessReset <- Connection -> Header -> Crypt -> IO Bool
isStatelessReset Connection
conn Header
hdr Crypt
crypt
          if Bool
statelessReset then do
              forall q a.
(KeepQlog q, Qlog a) =>
q -> a -> TimeMicrosecond -> IO ()
qlogReceived Connection
conn StatelessReset
StatelessReset TimeMicrosecond
tim
              Connection -> DebugLogger
connDebugLog Connection
conn Builder
"debug: connection is reset statelessly"
              forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
E.throwIO QUICException
ConnectionIsReset
            else do
              forall q a. (KeepQlog q, Qlog a) => q -> a -> IO ()
qlogDropped Connection
conn Header
hdr
              Connection -> DebugLogger
connDebugLog Connection
conn forall a b. (a -> b) -> a -> b
$ Builder
"debug: cannot decrypt: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Builder
bhow EncryptionLevel
lvl forall a. Semigroup a => a -> a -> a
<> Builder
" size = " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Builder
bhow (ByteString -> StreamId
BS.length forall a b. (a -> b) -> a -> b
$ Crypt -> ByteString
cryptPacket Crypt
crypt)
              -- fixme: sending statelss reset

isSendOnly :: Connection -> StreamId -> Bool
isSendOnly :: Connection -> StreamId -> Bool
isSendOnly Connection
conn StreamId
sid
  | forall a. Connector a => a -> Bool
isClient Connection
conn = StreamId -> Bool
isClientInitiatedUnidirectional StreamId
sid
  | Bool
otherwise     = StreamId -> Bool
isServerInitiatedUnidirectional StreamId
sid

isReceiveOnly :: Connection -> StreamId -> Bool
isReceiveOnly :: Connection -> StreamId -> Bool
isReceiveOnly Connection
conn StreamId
sid
  | forall a. Connector a => a -> Bool
isClient Connection
conn = StreamId -> Bool
isServerInitiatedUnidirectional StreamId
sid
  | Bool
otherwise     = StreamId -> Bool
isClientInitiatedUnidirectional StreamId
sid

isInitiated :: Connection -> StreamId -> Bool
isInitiated :: Connection -> StreamId -> Bool
isInitiated Connection
conn StreamId
sid
  | forall a. Connector a => a -> Bool
isClient Connection
conn = StreamId -> Bool
isClientInitiated StreamId
sid
  | Bool
otherwise     = StreamId -> Bool
isServerInitiated StreamId
sid

guardStream :: Connection -> StreamId -> Maybe Stream -> IO ()
guardStream :: Connection -> StreamId -> Maybe Stream -> IO ()
guardStream Connection
conn StreamId
sid Maybe Stream
Nothing
  | Connection -> StreamId -> Bool
isInitiated Connection
conn StreamId
sid = do
        StreamId
curSid <- Connection -> IO StreamId
getMyStreamId Connection
conn
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (StreamId
sid forall a. Ord a => a -> a -> Bool
> StreamId
curSid) forall a b. (a -> b) -> a -> b
$
            TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
StreamStateError ReasonPhrase
"a locally-initiated stream that has not yet been created"
guardStream Connection
_ StreamId
_ Maybe Stream
_ = forall (m :: * -> *) a. Monad m => a -> m a
return ()

processFrame :: Connection -> EncryptionLevel -> Frame -> IO ()
processFrame :: Connection -> EncryptionLevel -> Frame -> IO ()
processFrame Connection
_ EncryptionLevel
_ Padding{} = forall (m :: * -> *) a. Monad m => a -> m a
return ()
processFrame Connection
conn EncryptionLevel
lvl Frame
Ping = do
    -- see ackEli above
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
/= EncryptionLevel
InitialLevel Bool -> Bool -> Bool
&& EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
/= EncryptionLevel
RTT1Level) forall a b. (a -> b) -> a -> b
$ Connection -> EncryptionLevel -> [Frame] -> IO ()
sendFrames Connection
conn EncryptionLevel
lvl []
processFrame Connection
conn EncryptionLevel
lvl (Ack AckInfo
ackInfo Delay
ackDelay) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
RTT0Level) forall a b. (a -> b) -> a -> b
$ TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"ACK"
    LDCC -> EncryptionLevel -> AckInfo -> Microseconds -> IO ()
onAckReceived (Connection -> LDCC
connLDCC Connection
conn) EncryptionLevel
lvl AckInfo
ackInfo forall a b. (a -> b) -> a -> b
$ Delay -> Microseconds
milliToMicro Delay
ackDelay
processFrame Connection
conn EncryptionLevel
lvl (ResetStream StreamId
sid ApplicationProtocolError
aerr StreamId
_finlen) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
InitialLevel Bool -> Bool -> Bool
|| EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
HandshakeLevel) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"RESET_STREAM"
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Connection -> StreamId -> Bool
isSendOnly Connection
conn StreamId
sid) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
StreamStateError ReasonPhrase
"Received in a send-only stream"
    Maybe Stream
mstrm <- Connection -> StreamId -> IO (Maybe Stream)
findStream Connection
conn StreamId
sid
    case Maybe Stream
mstrm of
      Maybe Stream
Nothing   -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
      Just Stream
strm -> do
          Hooks -> Stream -> ApplicationProtocolError -> IO ()
onResetStreamReceived (Connection -> Hooks
connHooks Connection
conn) Stream
strm ApplicationProtocolError
aerr
          Stream -> IO ()
setTxStreamClosed Stream
strm
          Stream -> IO ()
setRxStreamClosed Stream
strm
          Connection -> Stream -> IO ()
delStream Connection
conn Stream
strm
processFrame Connection
conn EncryptionLevel
lvl (StopSending StreamId
sid ApplicationProtocolError
err) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
InitialLevel Bool -> Bool -> Bool
|| EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
HandshakeLevel) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"STOP_SENDING"
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Connection -> StreamId -> Bool
isReceiveOnly Connection
conn StreamId
sid) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
StreamStateError ReasonPhrase
"Receive-only stream"
    Maybe Stream
mstrm <- Connection -> StreamId -> IO (Maybe Stream)
findStream Connection
conn StreamId
sid
    case Maybe Stream
mstrm of
      Maybe Stream
Nothing   -> do
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Connection -> StreamId -> Bool
isInitiated Connection
conn StreamId
sid) forall a b. (a -> b) -> a -> b
$
              TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
StreamStateError ReasonPhrase
"No such stream for STOP_SENDING"
      Just Stream
_strm -> Connection -> EncryptionLevel -> [Frame] -> IO ()
sendFrames Connection
conn EncryptionLevel
lvl [StreamId -> ApplicationProtocolError -> StreamId -> Frame
ResetStream StreamId
sid ApplicationProtocolError
err StreamId
0]
processFrame Connection
_ EncryptionLevel
_ (CryptoF StreamId
_ ByteString
"") = forall (m :: * -> *) a. Monad m => a -> m a
return ()
processFrame Connection
conn EncryptionLevel
lvl (CryptoF StreamId
off ByteString
cdat) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
RTT0Level) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"CRYPTO in 0-RTT"
    let len :: StreamId
len = ByteString -> StreamId
BS.length ByteString
cdat
        rx :: RxStreamData
rx = ByteString -> StreamId -> StreamId -> Bool -> RxStreamData
RxStreamData ByteString
cdat StreamId
off StreamId
len Bool
False
    case EncryptionLevel
lvl of
      EncryptionLevel
InitialLevel   -> do
          Bool
dup <- Connection -> EncryptionLevel -> RxStreamData -> IO Bool
putRxCrypto Connection
conn EncryptionLevel
lvl RxStreamData
rx
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
dup forall a b. (a -> b) -> a -> b
$ LDCC -> EncryptionLevel -> LogStr -> IO ()
speedup (Connection -> LDCC
connLDCC Connection
conn) EncryptionLevel
lvl LogStr
"duplicated"
      EncryptionLevel
RTT0Level -> do
          Connection -> DebugLogger
connDebugLog Connection
conn forall a b. (a -> b) -> a -> b
$ Builder
"processFrame: invalid packet type " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Builder
bhow EncryptionLevel
lvl
      EncryptionLevel
HandshakeLevel -> do
          Bool
dup <- Connection -> EncryptionLevel -> RxStreamData -> IO Bool
putRxCrypto Connection
conn EncryptionLevel
lvl RxStreamData
rx
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
dup forall a b. (a -> b) -> a -> b
$ LDCC -> EncryptionLevel -> LogStr -> IO ()
speedup (Connection -> LDCC
connLDCC Connection
conn) EncryptionLevel
lvl LogStr
"duplicated"
      EncryptionLevel
RTT1Level
        | forall a. Connector a => a -> Bool
isClient Connection
conn ->
              forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ Connection -> EncryptionLevel -> RxStreamData -> IO Bool
putRxCrypto Connection
conn EncryptionLevel
lvl RxStreamData
rx
        | Bool
otherwise ->
              TransportError -> ReasonPhrase -> IO ()
closeConnection (AlertDescription -> TransportError
cryptoError AlertDescription
UnexpectedMessage) ReasonPhrase
"CRYPTO in 1-RTT"
processFrame Connection
conn EncryptionLevel
lvl (NewToken ByteString
token) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall a. Connector a => a -> Bool
isServer Connection
conn Bool -> Bool -> Bool
|| EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
/= EncryptionLevel
RTT1Level) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"NEW_TOKEN for server or in 1-RTT"
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall a. Connector a => a -> Bool
isClient Connection
conn) forall a b. (a -> b) -> a -> b
$ Connection -> ByteString -> IO ()
setNewToken Connection
conn ByteString
token
processFrame Connection
conn EncryptionLevel
RTT0Level (StreamF StreamId
sid StreamId
off (ByteString
dat:[ByteString]
_) Bool
fin) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Connection -> StreamId -> Bool
isSendOnly Connection
conn StreamId
sid) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
StreamStateError ReasonPhrase
"send-only stream"
    Maybe Stream
mstrm <- Connection -> StreamId -> IO (Maybe Stream)
findStream Connection
conn StreamId
sid
    Connection -> StreamId -> Maybe Stream -> IO ()
guardStream Connection
conn StreamId
sid Maybe Stream
mstrm
    Stream
strm <- forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Connection -> StreamId -> IO Stream
createStream Connection
conn StreamId
sid) forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Stream
mstrm
    let len :: StreamId
len = ByteString -> StreamId
BS.length ByteString
dat
        rx :: RxStreamData
rx = ByteString -> StreamId -> StreamId -> Bool -> RxStreamData
RxStreamData ByteString
dat StreamId
off StreamId
len Bool
fin
    Bool
ok <- Stream -> RxStreamData -> IO Bool
putRxStreamData Stream
strm RxStreamData
rx
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
ok forall a b. (a -> b) -> a -> b
$ TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
FlowControlError ReasonPhrase
"Flow control error in 0-RTT"
processFrame Connection
conn EncryptionLevel
RTT1Level (StreamF StreamId
sid StreamId
_ [ByteString
""] Bool
False) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Connection -> StreamId -> Bool
isSendOnly Connection
conn StreamId
sid) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
StreamStateError ReasonPhrase
"send-only stream"
    Maybe Stream
mstrm <- Connection -> StreamId -> IO (Maybe Stream)
findStream Connection
conn StreamId
sid
    Connection -> StreamId -> Maybe Stream -> IO ()
guardStream Connection
conn StreamId
sid Maybe Stream
mstrm
processFrame Connection
conn EncryptionLevel
RTT1Level (StreamF StreamId
sid StreamId
off (ByteString
dat:[ByteString]
_) Bool
fin) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Connection -> StreamId -> Bool
isSendOnly Connection
conn StreamId
sid) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
StreamStateError ReasonPhrase
"send-only stream"
    Maybe Stream
mstrm <- Connection -> StreamId -> IO (Maybe Stream)
findStream Connection
conn StreamId
sid
    Connection -> StreamId -> Maybe Stream -> IO ()
guardStream Connection
conn StreamId
sid Maybe Stream
mstrm
    Stream
strm <- forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Connection -> StreamId -> IO Stream
createStream Connection
conn StreamId
sid) forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Stream
mstrm
    let len :: StreamId
len = ByteString -> StreamId
BS.length ByteString
dat
        rx :: RxStreamData
rx = ByteString -> StreamId -> StreamId -> Bool -> RxStreamData
RxStreamData ByteString
dat StreamId
off StreamId
len Bool
fin
    Bool
ok <- Stream -> RxStreamData -> IO Bool
putRxStreamData Stream
strm RxStreamData
rx
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
ok forall a b. (a -> b) -> a -> b
$ TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
FlowControlError ReasonPhrase
"Flow control error in 1-RTT"
processFrame Connection
conn EncryptionLevel
lvl (MaxData StreamId
n) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
InitialLevel Bool -> Bool -> Bool
|| EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
HandshakeLevel) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"MAX_DATA in Initial or Handshake"
    Connection -> StreamId -> IO ()
setTxMaxData Connection
conn StreamId
n
processFrame Connection
conn EncryptionLevel
lvl (MaxStreamData StreamId
sid StreamId
n) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
InitialLevel Bool -> Bool -> Bool
|| EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
HandshakeLevel) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"MAX_STREAM_DATA in Initial or Handshake"
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Connection -> StreamId -> Bool
isReceiveOnly Connection
conn StreamId
sid) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
StreamStateError ReasonPhrase
"Receive-only stream"
    Maybe Stream
mstrm <- Connection -> StreamId -> IO (Maybe Stream)
findStream Connection
conn StreamId
sid
    case Maybe Stream
mstrm of
      Maybe Stream
Nothing   -> do
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Connection -> StreamId -> Bool
isInitiated Connection
conn StreamId
sid) forall a b. (a -> b) -> a -> b
$
              TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
StreamStateError ReasonPhrase
"No such stream for MAX_STREAM_DATA"
      Just Stream
strm -> Stream -> StreamId -> IO ()
setTxMaxStreamData Stream
strm StreamId
n
processFrame Connection
conn EncryptionLevel
lvl (MaxStreams Direction
dir StreamId
n) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
InitialLevel Bool -> Bool -> Bool
|| EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
HandshakeLevel) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"MAX_STREAMS in Initial or Handshake"
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (StreamId
n forall a. Ord a => a -> a -> Bool
> StreamId
2forall a b. (Num a, Integral b) => a -> b -> a
^(StreamId
60 :: Int)) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
FrameEncodingError ReasonPhrase
"Too large MAX_STREAMS"
    if Direction
dir forall a. Eq a => a -> a -> Bool
== Direction
Bidirectional then
        Connection -> StreamId -> IO ()
setMyMaxStreams Connection
conn StreamId
n
      else
        Connection -> StreamId -> IO ()
setMyUniMaxStreams Connection
conn StreamId
n
processFrame Connection
_conn EncryptionLevel
_lvl DataBlocked{} = forall (m :: * -> *) a. Monad m => a -> m a
return ()
processFrame Connection
_conn EncryptionLevel
_lvl (StreamDataBlocked StreamId
_sid StreamId
_) = forall (m :: * -> *) a. Monad m => a -> m a
return ()
processFrame Connection
_conn EncryptionLevel
lvl (StreamsBlocked Direction
_dir StreamId
n) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
InitialLevel Bool -> Bool -> Bool
|| EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
HandshakeLevel) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"STREAMS_BLOCKED in Initial or Handshake"
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (StreamId
n forall a. Ord a => a -> a -> Bool
> StreamId
2forall a b. (Num a, Integral b) => a -> b -> a
^(StreamId
60 :: Int)) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
FrameEncodingError ReasonPhrase
"Too large STREAMS_BLOCKED"
processFrame Connection
conn EncryptionLevel
lvl (NewConnectionID CIDInfo
cidInfo StreamId
rpt) = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
InitialLevel Bool -> Bool -> Bool
|| EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
== EncryptionLevel
HandshakeLevel) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"NEW_CONNECTION_ID in Initial or Handshake"
    Connection -> CIDInfo -> IO ()
addPeerCID Connection
conn CIDInfo
cidInfo
    let (ReasonPhrase
_, Word8
cidlen) = CID -> (ReasonPhrase, Word8)
unpackCID forall a b. (a -> b) -> a -> b
$ CIDInfo -> CID
cidInfoCID CIDInfo
cidInfo
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word8
cidlen forall a. Ord a => a -> a -> Bool
< Word8
1 Bool -> Bool -> Bool
|| Word8
20 forall a. Ord a => a -> a -> Bool
< Word8
cidlen Bool -> Bool -> Bool
|| StreamId
rpt forall a. Ord a => a -> a -> Bool
> CIDInfo -> StreamId
cidInfoSeq CIDInfo
cidInfo) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
FrameEncodingError ReasonPhrase
"NEW_CONNECTION_ID parameter error"
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (StreamId
rpt forall a. Ord a => a -> a -> Bool
>= StreamId
1) forall a b. (a -> b) -> a -> b
$ do
        [StreamId]
seqNums <- Connection -> StreamId -> IO [StreamId]
setPeerCIDAndRetireCIDs Connection
conn StreamId
rpt
        Connection -> EncryptionLevel -> [Frame] -> IO ()
sendFrames Connection
conn EncryptionLevel
RTT1Level forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map StreamId -> Frame
RetireConnectionID [StreamId]
seqNums
processFrame Connection
conn EncryptionLevel
RTT1Level (RetireConnectionID StreamId
sn) = do
    Maybe CIDInfo
mcidInfo <- Connection -> StreamId -> IO (Maybe CIDInfo)
retireMyCID Connection
conn StreamId
sn
    case Maybe CIDInfo
mcidInfo of
      Maybe CIDInfo
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
      Just (CIDInfo StreamId
_ CID
cid StatelessResetToken
_) -> do
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall a. Connector a => a -> Bool
isServer Connection
conn) forall a b. (a -> b) -> a -> b
$ do
              CID -> IO ()
unregister <- Connection -> IO (CID -> IO ())
getUnregister Connection
conn
              CID -> IO ()
unregister CID
cid
processFrame Connection
conn EncryptionLevel
RTT1Level (PathChallenge PathData
dat) =
    Connection -> EncryptionLevel -> [Frame] -> IO ()
sendFrames Connection
conn EncryptionLevel
RTT1Level [PathData -> Frame
PathResponse PathData
dat]
processFrame Connection
conn EncryptionLevel
RTT1Level (PathResponse PathData
dat) =
    -- RTT0Level falls intentionally
    Connection -> PathData -> IO ()
checkResponse Connection
conn PathData
dat
processFrame Connection
conn EncryptionLevel
_lvl (ConnectionClose TransportError
NoError StreamId
_ftyp ReasonPhrase
_reason) =
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall a. Connector a => a -> Bool
isServer Connection
conn) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
E.throwIO QUICException
ConnectionIsClosed
processFrame Connection
_conn EncryptionLevel
_lvl (ConnectionClose TransportError
err StreamId
_ftyp ReasonPhrase
reason) = do
    let quicexc :: QUICException
quicexc = TransportError -> ReasonPhrase -> QUICException
TransportErrorIsReceived TransportError
err ReasonPhrase
reason
    forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
E.throwIO QUICException
quicexc
processFrame Connection
_conn EncryptionLevel
_lvl (ConnectionCloseApp ApplicationProtocolError
err ReasonPhrase
reason) = do
    let quicexc :: QUICException
quicexc = ApplicationProtocolError -> ReasonPhrase -> QUICException
ApplicationProtocolErrorIsReceived ApplicationProtocolError
err ReasonPhrase
reason
    forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
E.throwIO QUICException
quicexc
processFrame Connection
conn EncryptionLevel
lvl Frame
HandshakeDone = do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall a. Connector a => a -> Bool
isServer Connection
conn Bool -> Bool -> Bool
|| EncryptionLevel
lvl forall a. Eq a => a -> a -> Bool
/= EncryptionLevel
RTT1Level) forall a b. (a -> b) -> a -> b
$
        TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"HANDSHAKE_DONE for server"
    Connection -> Microseconds -> IO () -> IO ()
fire Connection
conn (StreamId -> Microseconds
Microseconds StreamId
100000) forall a b. (a -> b) -> a -> b
$ do
        let ldcc :: LDCC
ldcc = Connection -> LDCC
connLDCC Connection
conn
        Bool
discarded0 <- LDCC -> EncryptionLevel -> IO Bool
getAndSetPacketNumberSpaceDiscarded LDCC
ldcc EncryptionLevel
RTT0Level
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
discarded0 forall a b. (a -> b) -> a -> b
$ Connection -> EncryptionLevel -> IO ()
dropSecrets Connection
conn EncryptionLevel
RTT0Level
        Bool
discarded1 <- LDCC -> EncryptionLevel -> IO Bool
getAndSetPacketNumberSpaceDiscarded LDCC
ldcc EncryptionLevel
HandshakeLevel
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
discarded1 forall a b. (a -> b) -> a -> b
$ do
            Connection -> EncryptionLevel -> IO ()
dropSecrets Connection
conn EncryptionLevel
HandshakeLevel
            LDCC -> EncryptionLevel -> IO ()
onPacketNumberSpaceDiscarded LDCC
ldcc EncryptionLevel
HandshakeLevel
        Connection -> EncryptionLevel -> IO ()
clearCryptoStream Connection
conn EncryptionLevel
HandshakeLevel
        Connection -> EncryptionLevel -> IO ()
clearCryptoStream Connection
conn EncryptionLevel
RTT1Level
    Connection -> IO ()
setConnectionEstablished Connection
conn
    -- to receive NewSessionTicket
    Connection -> Microseconds -> IO () -> IO ()
fire Connection
conn (StreamId -> Microseconds
Microseconds StreamId
1000000) forall a b. (a -> b) -> a -> b
$ Connection -> EncryptionLevel -> IO ()
killHandshaker Connection
conn EncryptionLevel
lvl
processFrame Connection
_ EncryptionLevel
_ Frame
_ = TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
ProtocolViolation ReasonPhrase
"Frame is not allowed"

-- QUIC version 1 uses only short packets for stateless reset.
-- But we should check other packets, too.
isStatelessReset :: Connection -> Header -> Crypt -> IO Bool
isStatelessReset :: Connection -> Header -> Crypt -> IO Bool
isStatelessReset Connection
conn Header
hdr Crypt{StreamId
Maybe MigrationInfo
ByteString
cryptMarks :: Crypt -> StreamId
cryptPktNumOffset :: Crypt -> StreamId
cryptMigraionInfo :: Maybe MigrationInfo
cryptMarks :: StreamId
cryptPacket :: ByteString
cryptPktNumOffset :: StreamId
cryptPacket :: Crypt -> ByteString
cryptMigraionInfo :: Crypt -> Maybe MigrationInfo
..} = do
    let cid :: CID
cid = Header -> CID
headerMyCID Header
hdr
    Maybe StreamId
included <- Connection -> CID -> IO (Maybe StreamId)
myCIDsInclude Connection
conn CID
cid
    case Maybe StreamId
included of
      Just StreamId
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
      Maybe StreamId
_      -> case ByteString -> Maybe StatelessResetToken
decodeStatelessResetToken ByteString
cryptPacket of
             Maybe StatelessResetToken
Nothing    -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
             Just StatelessResetToken
token -> Connection -> CID -> StatelessResetToken -> IO Bool
isStatelessRestTokenValid Connection
conn CID
cid StatelessResetToken
token

-- Return value indicates duplication.
putRxCrypto :: Connection -> EncryptionLevel -> RxStreamData -> IO Bool
putRxCrypto :: Connection -> EncryptionLevel -> RxStreamData -> IO Bool
putRxCrypto Connection
conn EncryptionLevel
lvl RxStreamData
rx = do
    Maybe Stream
mstrm <- Connection -> EncryptionLevel -> IO (Maybe Stream)
getCryptoStream Connection
conn EncryptionLevel
lvl
    case Maybe Stream
mstrm of
      Maybe Stream
Nothing   -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
      Just Stream
strm -> do
          let put :: ByteString -> IO ()
put = Connection -> Crypto -> IO ()
putCrypto Connection
conn forall b c a. (b -> c) -> (a -> b) -> a -> c
. EncryptionLevel -> ByteString -> Crypto
InpHandshake EncryptionLevel
lvl
              putFin :: IO ()
putFin = forall (m :: * -> *) a. Monad m => a -> m a
return ()
          Stream -> RxStreamData -> (ByteString -> IO ()) -> IO () -> IO Bool
tryReassemble Stream
strm RxStreamData
rx ByteString -> IO ()
put IO ()
putFin

killHandshaker :: Connection -> EncryptionLevel -> IO ()
killHandshaker :: Connection -> EncryptionLevel -> IO ()
killHandshaker Connection
conn EncryptionLevel
lvl = Connection -> Crypto -> IO ()
putCrypto Connection
conn forall a b. (a -> b) -> a -> b
$ EncryptionLevel -> ByteString -> Crypto
InpHandshake EncryptionLevel
lvl ByteString
""