quic-0.1.9: Network/QUIC/Connection/StreamTable.hs
{-# LANGUAGE RecordWildCards #-}
module Network.QUIC.Connection.StreamTable (
createStream,
findStream,
addStream,
delStream,
initialRxMaxStreamData,
setupCryptoStreams,
clearCryptoStream,
getCryptoStream,
) where
import Network.QUIC.Connection.Misc
import Network.QUIC.Connection.Queue
import Network.QUIC.Connection.Types
import Network.QUIC.Connector
import Network.QUIC.Imports
import Network.QUIC.Parameters
import Network.QUIC.Stream
import Network.QUIC.Types
createStream :: Connection -> StreamId -> IO Stream
createStream conn sid = do
strm <- addStream conn sid
putInput conn $ InpStream strm
return strm
findStream :: Connection -> StreamId -> IO (Maybe Stream)
findStream Connection{..} sid = lookupStream sid <$> readIORef streamTable
addStream :: Connection -> StreamId -> IO Stream
addStream conn@Connection{..} sid = do
strm <-
if isClient conn
then do
serverParams <- getPeerParameters conn
let txLim = serverInitial sid serverParams
let clientParams = getMyParameters conn
rxLim = clientInitial sid clientParams
newStream conn sid txLim rxLim
else do
clientParams <- getPeerParameters conn
let txLim = clientInitial sid clientParams
serverParams = getMyParameters conn
rxLim = serverInitial sid serverParams
newStream conn sid txLim rxLim
atomicModifyIORef'' streamTable $ insertStream sid strm
return strm
delStream :: Connection -> Stream -> IO ()
delStream Connection{..} strm =
atomicModifyIORef'' streamTable $ deleteStream $ streamId strm
initialRxMaxStreamData :: Connection -> StreamId -> Int
initialRxMaxStreamData conn sid
| isClient conn = clientInitial sid params
| otherwise = serverInitial sid params
where
params = getMyParameters conn
clientInitial :: StreamId -> Parameters -> Int
clientInitial sid params
| isClientInitiatedBidirectional sid = initialMaxStreamDataBidiLocal params
| isServerInitiatedBidirectional sid = initialMaxStreamDataBidiRemote params
-- intentionally not using isServerInitiatedUnidirectional
| otherwise = initialMaxStreamDataUni params
serverInitial :: StreamId -> Parameters -> Int
serverInitial sid params
| isServerInitiatedBidirectional sid = initialMaxStreamDataBidiLocal params
| isClientInitiatedBidirectional sid = initialMaxStreamDataBidiRemote params
-- intentionally not using isClientInitiatedUnidirectional
| otherwise = initialMaxStreamDataUni params
----------------------------------------------------------------
setupCryptoStreams :: Connection -> IO ()
setupCryptoStreams conn@Connection{..} = do
stbl0 <- readIORef streamTable
stbl <- insertCryptoStreams conn stbl0
writeIORef streamTable stbl
clearCryptoStream :: Connection -> EncryptionLevel -> IO ()
clearCryptoStream Connection{..} lvl =
atomicModifyIORef'' streamTable $ deleteCryptoStream lvl
----------------------------------------------------------------
getCryptoStream :: Connection -> EncryptionLevel -> IO (Maybe Stream)
getCryptoStream Connection{..} lvl =
lookupCryptoStream lvl <$> readIORef streamTable