{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Network.QUIC.Receiver (
receiver,
) where
import qualified Data.ByteString as BS
import Network.Control
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 as QUIC
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
Microseconds
ito <- Connection -> IO Microseconds
readMinIdleTimeout Connection
conn
Maybe ReceivedPacket
mx <- forall a. Microseconds -> String -> IO a -> IO (Maybe a)
timeout Microseconds
ito String
"recvTimeout" forall a b. (a -> b) -> a -> b
$ Connection -> IO ReceivedPacket
connRecv Connection
conn
case Maybe ReceivedPacket
mx of
Maybe ReceivedPacket
Nothing -> do
ConnectionState
st <- forall a. Connector a => a -> IO ConnectionState
getConnectionState Connection
conn
let msg0 :: String
msg0
| forall a. Connector a => a -> Bool
isClient Connection
conn = String
"Client"
| Bool
otherwise = String
"Server"
msg :: String
msg = String
msg0 forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ConnectionState
st
forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
E.throwIO forall a b. (a -> b) -> a -> b
$ String -> QUICException
ConnectionIsTimeout String
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
msg :: String
msg =
String
"processReceivedPacketHandshake "
forall a. [a] -> [a] -> [a]
++ if forall a. Connector a => a -> Bool
isServer Connection
conn then String
"Server" else String
"Client"
Maybe ()
mx <- forall a. Microseconds -> String -> IO a -> IO (Maybe a)
timeout (StreamId -> Microseconds
Microseconds StreamId
10000) String
msg 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
rateLimit :: Int
rateLimit :: StreamId
rateLimit = StreamId
10
checkRate :: [Frame] -> Int
checkRate :: [Frame] -> StreamId
checkRate [Frame]
fs0 = forall {t}. Num t => [Frame] -> t -> t
go [Frame]
fs0 StreamId
0
where
go :: [Frame] -> t -> t
go [] t
n = t
n
go (Frame
f : [Frame]
fs) t
n
| Frame -> Bool
rateControled Frame
f = [Frame] -> t -> t
go [Frame]
fs (t
n forall a. Num a => a -> a -> a
+ t
1)
| Bool
otherwise = [Frame] -> t -> t
go [Frame]
fs t
n
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"
let controlled :: StreamId
controlled = [Frame] -> StreamId
checkRate [Frame]
plainFrames
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (StreamId
controlled forall a. Eq a => a -> a -> Bool
/= StreamId
0) forall a b. (a -> b) -> a -> b
$ do
StreamId
rate <- Rate -> StreamId -> IO StreamId
addRate (Connection -> Rate
controlRate Connection
conn) StreamId
controlled
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (StreamId
rate forall a. Ord a => a -> a -> Bool
> StreamId
rateLimit) forall a b. (a -> b) -> a -> b
$ do
TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
QUIC.InternalError ReasonPhrase
"Rate control"
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
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)
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
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 (StreamId
off forall a. Eq a => a -> a -> Bool
== StreamId
0) forall a b. (a -> b) -> a -> b
$ Connection -> StreamId -> IO ()
updatePeerStreamId Connection
conn StreamId
sid
Bool
ok <- Connection -> StreamId -> IO Bool
checkRxMaxStreams Connection
conn StreamId
sid
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
ok forall a b. (a -> b) -> a -> b
$ TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
StreamLimitError ReasonPhrase
"stream id is too large"
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
FlowCntl
fc <- Stream -> RxStreamData -> IO FlowCntl
putRxStreamData Stream
strm RxStreamData
rx
case FlowCntl
fc of
FlowCntl
OverLimit -> TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
FlowControlError ReasonPhrase
"Flow control error for stream in 0-RTT"
FlowCntl
Duplicated -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
FlowCntl
Reassembled -> do
Bool
ok' <- Connection -> StreamId -> IO Bool
checkRxMaxData Connection
conn StreamId
len
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 for connection in 0-RTT"
processFrame Connection
conn EncryptionLevel
RTT1Level (StreamF StreamId
sid StreamId
_ [ByteString
""] Bool
False) = do
Bool
ok <- Connection -> StreamId -> IO Bool
checkRxMaxStreams Connection
conn StreamId
sid
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
ok forall a b. (a -> b) -> a -> b
$ TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
StreamLimitError ReasonPhrase
"stream id is too large"
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 (StreamId
off forall a. Eq a => a -> a -> Bool
== StreamId
0) forall a b. (a -> b) -> a -> b
$ Connection -> StreamId -> IO ()
updatePeerStreamId Connection
conn StreamId
sid
Bool
ok <- Connection -> StreamId -> IO Bool
checkRxMaxStreams Connection
conn StreamId
sid
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
ok forall a b. (a -> b) -> a -> b
$ TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
StreamLimitError ReasonPhrase
"stream id is too large"
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
FlowCntl
fc <- Stream -> RxStreamData -> IO FlowCntl
putRxStreamData Stream
strm RxStreamData
rx
case FlowCntl
fc of
FlowCntl
OverLimit -> TransportError -> ReasonPhrase -> IO ()
closeConnection TransportError
FlowControlError ReasonPhrase
"Flow control error for stream in 1-RTT"
FlowCntl
Duplicated -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
FlowCntl
Reassembled -> do
Bool
ok' <- Connection -> StreamId -> IO Bool
checkRxMaxData Connection
conn StreamId
len
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 for connection 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
2 forall 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 ()
setTxMaxStreams Connection
conn StreamId
n
else Connection -> StreamId -> IO ()
setTxUniMaxStreams 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
2 forall 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 ()
sendFrames1 Connection
conn EncryptionLevel
RTT1Level [PathData -> Frame
PathResponse PathData
dat]
processFrame Connection
conn EncryptionLevel
RTT1Level (PathResponse PathData
dat) =
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
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"
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
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
""