packages feed

quic 0.3.2 → 0.3.3

raw patch · 10 files changed

+75/−19 lines, 10 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Network.QUIC.Internal: [onResetStreamReceived2] :: Hooks -> Maybe Stream -> ApplicationProtocolError -> Int -> IO ()
+ Network.QUIC.Internal: getTxStreamFinalSize :: Stream -> IO Offset
- Network.QUIC.Internal: Hooks :: IO () -> (EncryptionLevel -> Plain -> Plain) -> (Parameters -> Parameters) -> ([ExtensionRaw] -> [ExtensionRaw]) -> ([(EncryptionLevel, CryptoData)] -> ([(EncryptionLevel, CryptoData)], Bool)) -> (Stream -> ApplicationProtocolError -> IO ()) -> IO () -> (ConnectionInfo -> IO ()) -> Hooks
+ Network.QUIC.Internal: Hooks :: IO () -> (EncryptionLevel -> Plain -> Plain) -> (Parameters -> Parameters) -> ([ExtensionRaw] -> [ExtensionRaw]) -> ([(EncryptionLevel, CryptoData)] -> ([(EncryptionLevel, CryptoData)], Bool)) -> (Stream -> ApplicationProtocolError -> IO ()) -> (Maybe Stream -> ApplicationProtocolError -> Int -> IO ()) -> IO () -> (ConnectionInfo -> IO ()) -> Hooks

Files

ChangeLog.md view
@@ -1,5 +1,10 @@ # ChangeLog +## 0.3.3++* RST_STREAM now contains a proper final size.+  [#93](https://github.com/kazu-yamamoto/quic/pull/93)+ ## 0.3.2  * Support Unreliable Datagrams extension (RFC9221)
Network/QUIC/Config.hs view
@@ -36,6 +36,7 @@         :: [(EncryptionLevel, CryptoData)]         -> ([(EncryptionLevel, CryptoData)], Bool)     , onResetStreamReceived :: Stream -> ApplicationProtocolError -> IO ()+    , onResetStreamReceived2 :: Maybe Stream -> ApplicationProtocolError -> Int -> IO ()     , onServerReady :: IO ()     , onConnectionEstablished :: ConnectionInfo -> IO ()     }@@ -50,6 +51,7 @@         , onTLSExtensionCreated = id         , onTLSHandshakeCreated = (,False)         , onResetStreamReceived = \_ _ -> return ()+        , onResetStreamReceived2 = \_ _ _ -> return ()         , onServerReady = return ()         , onConnectionEstablished = \_ -> return ()         }
Network/QUIC/IO.hs view
@@ -217,10 +217,11 @@     let sid = streamId s     sclosed <- isTxStreamClosed s     unless sclosed $ do+        finalSize <- getTxStreamFinalSize s         setTxStreamClosed s         setRxStreamClosed s         lvl <- getEncryptionLevel conn-        let frame = ResetStream sid aerr 0+        let frame = ResetStream sid aerr finalSize         putOutput conn $ OutControl lvl [frame]     delStream conn s 
Network/QUIC/Receiver.hs view
@@ -11,6 +11,7 @@ import Network.TLS (AlertDescription (..)) import System.Log.FastLogger +import Control.Concurrent.STM import Network.QUIC.Config import Network.QUIC.Connection import Network.QUIC.Connector@@ -23,7 +24,6 @@ import Network.QUIC.Parameters import Network.QUIC.Qlog import Network.QUIC.Recovery-import Control.Concurrent.STM import Network.QUIC.Stream import Network.QUIC.Types as QUIC @@ -242,12 +242,13 @@ processFrame conn lvl (Ack ackInfo ackDelay) = do     when (lvl == RTT0Level) $ closeConnection conn ProtocolViolation "ACK"     onAckReceived (connLDCC conn) lvl ackInfo $ milliToMicro ackDelay-processFrame conn lvl (ResetStream sid aerr _finlen) = do+processFrame conn lvl (ResetStream sid aerr finlen) = do     when (lvl == InitialLevel || lvl == HandshakeLevel) $         closeConnection conn ProtocolViolation "RESET_STREAM"     when (isSendOnly conn sid) $         closeConnection conn StreamStateError "Received in a send-only stream"     mstrm <- findStream conn sid+    onResetStreamReceived2 (connHooks conn) mstrm aerr finlen     case mstrm of         Nothing -> return ()         Just strm -> do@@ -265,7 +266,9 @@         mstrm <- findStream conn sid         case mstrm of             Nothing -> streamNotCreatedYet conn sid "No such stream for STOP_SENDING"-            Just _strm -> sendFrames conn lvl [ResetStream sid err 0]+            Just strm -> do+                finalSize <- getTxStreamFinalSize strm+                sendFrames conn lvl [ResetStream sid err finalSize] processFrame _ _ (CryptoF _ "") = return () processFrame conn lvl (CryptoF off cdat) = do     when (lvl == RTT0Level) $
Network/QUIC/Stream.hs view
@@ -13,6 +13,7 @@     waitFinTx,      -- * Misc+    getTxStreamFinalSize,     getTxStreamOffset,     isTxStreamClosed,     setTxStreamClosed,
Network/QUIC/Stream/Misc.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE RecordWildCards #-}  module Network.QUIC.Stream.Misc (+    getTxStreamFinalSize,     getTxStreamOffset,     isTxStreamClosed,     setTxStreamClosed,@@ -26,6 +27,9 @@ import Network.QUIC.Stream.Types  ----------------------------------------------------------------++getTxStreamFinalSize :: Stream -> IO Offset+getTxStreamFinalSize Stream{..} = streamOffset <$> readIORef streamStateTx  getTxStreamOffset :: Stream -> Int -> IO Offset getTxStreamOffset Stream{..} len = atomicModifyIORef' streamStateTx get
Network/QUIC/Utils.hs view
@@ -3,7 +3,7 @@  module Network.QUIC.Utils where -import Control.Exception+import qualified Control.Exception as E import Control.Monad (replicateM) import qualified Data.ByteString as BS import Data.ByteString.Base16@@ -60,18 +60,18 @@ shortpack :: String -> ShortByteString shortpack = Short.toShort . C8.pack -ignore :: SomeException -> IO ()+ignore :: E.SomeException -> IO () ignore se-    | isAsyncException se = throwIO se+    | isAsyncException se = E.throwIO se     | otherwise = return () -isAsyncException :: Exception e => e -> Bool+isAsyncException :: E.Exception e => e -> Bool isAsyncException e =-    case fromException (toException e) of-        Just (SomeAsyncException _) -> True+    case E.fromException (E.toException e) of+        Just (E.SomeAsyncException _) -> True         Nothing -> False -throughAsync :: IO a -> SomeException -> IO a-throughAsync action (SomeException e)-    | isAsyncException e = throwIO e+throughAsync :: IO a -> E.SomeException -> IO a+throughAsync action (E.SomeException e)+    | isAsyncException e = E.throwIO e     | otherwise = action
Network/QUIC/Windows.hs view
@@ -6,16 +6,16 @@  #if defined(mingw32_HOST_OS) import Control.Concurrent-import qualified Control.Exception as CE+import qualified Control.Exception as E import Control.Monad  windowsThreadBlockHack :: IO a -> IO a windowsThreadBlockHack act = do-    var <- newEmptyMVar :: IO (MVar (Either CE.SomeException a))-    void . forkIO $ CE.try act >>= putMVar var+    var <- newEmptyMVar :: IO (MVar (Either E.SomeException a))+    void . forkIO $ E.try act >>= putMVar var     res <- takeMVar var     case res of-        Left e -> print e >> CE.throwIO e+        Left e -> print e >> E.throwIO e         Right r -> return r #else windowsThreadBlockHack :: IO a -> IO a
quic.cabal view
@@ -1,6 +1,6 @@ cabal-version:      >=1.10 name:               quic-version:            0.3.2+version:            0.3.3 license:            BSD3 license-file:       LICENSE maintainer:         kazu@iij.ad.jp@@ -151,7 +151,7 @@         serialise,         stm >=2.5 && <2.6,         tls >=2.4.0 && <2.5,-        unix-time >=0.4.12 && <0.5+        unix-time >=0.4.12 && <0.6      if os(linux)         cc-options: -DOS_Linux
test/IOSpec.hs view
@@ -7,6 +7,7 @@ import qualified Control.Exception as E import Control.Monad import qualified Data.ByteString as BS+import qualified System.Timeout as Timeout import Test.Hspec  import Network.QUIC@@ -86,6 +87,12 @@             withPipe (Randomly 20) $ testRecvStreamClientStopFirst cc sc waitS         it "don't block if server stop sending first" $ do             withPipe (Randomly 20) $ testRecvStreamServerStopFirst cc sc waitS+        -- RFC 9000: https://www.rfc-editor.org/rfc/rfc9000.html+        -- Section 3.5 says STOP_SENDING asks the peer to send RESET_STREAM.+        -- Sections 4.5 and 19.4 define RESET_STREAM Final Size as the+        -- number of bytes sent by the RESET_STREAM sender.+        it "sends RESET_STREAM with the bytes sent as final size" $ do+            withPipe (DropClientPacket []) $ testResetStreamFinalSize cc sc waitS     describe "concurrency" $ do         it "can handle multiple clients" $ do             withPipe (Randomly 20) $ testMultiSendRecv cc sc waitS 500@@ -104,6 +111,39 @@  assertEndOfStream :: Stream -> IO () assertEndOfStream strm = recvStream strm 1024 `shouldReturn` ""++testResetStreamFinalSize+    :: C.ClientConfig -> ServerConfig -> IO () -> IO ()+testResetStreamFinalSize cc0 sc waitS = do+    finalSizeVar <- newEmptyMVar+    doneVar <- newEmptyMVar+    let request = "open"+        payload = BS.replicate 1234 0+        hooks = (ccHooks cc0){onResetStreamReceived2 = record finalSizeVar}+        cc = cc0{ccHooks = hooks}+    E.bracket (forkIO $ server request payload doneVar) killThread $ \_ ->+        client cc request payload finalSizeVar doneVar+  where+    aerr = ApplicationProtocolError 0++    record finalSizeVar _strm _aerr finalSize = void $ tryPutMVar finalSizeVar finalSize++    client cc request payload finalSizeVar doneVar = do+        waitS+        C.run cc $ \conn -> do+            strm <- stream conn+            sendStream strm request+            consumeBytes strm (BS.length payload)+            stopStream strm aerr+            mres <- Timeout.timeout 5000000 $ takeMVar finalSizeVar+            mres `shouldBe` Just (BS.length payload)+            putMVar doneVar ()++    server request payload doneVar = run sc $ \conn -> do+        strm <- acceptStream conn+        consumeBytes strm (BS.length request)+        sendStream strm payload+        takeMVar doneVar  testRecvStreamClientStopFirst     :: C.ClientConfig -> ServerConfig -> IO () -> IO ()