packages feed

network 3.2.6.0 → 3.2.7.0

raw patch · 6 files changed

+46/−36 lines, 6 files

Files

CHANGELOG.md view
@@ -1,3 +1,12 @@+## Version 3.2.7.0++* Using nested `bracket` for `gracefulClose`.+  [#591](https://github.com/haskell/network/issues/590)+* Fix memory leak in getaddrinfo and make it async exception safe.+  [#591](https://github.com/haskell/network/pull/591)+* Make call to c_free async exception safe.+  [#592](https://github.com/haskell/network/pull/592)+ ## Version 3.2.6.0  * fixing the Show instance of IPv4-mapped IPv6 address on little endian machines
Network/Socket/Info.hsc view
@@ -7,6 +7,7 @@  module Network.Socket.Info where +import Control.Exception (mask, onException) import Data.List.NonEmpty (NonEmpty(..)) import qualified Data.List.NonEmpty as NE import Foreign.Marshal.Alloc (alloca, allocaBytes)@@ -274,11 +275,12 @@             maybeWith with filteredHints                    $ \c_hints ->                   alloca                                    $ \ptr_ptr_addrs ->                       body c_node c_service c_hints ptr_ptr_addrs-    getaddrinfo c_node c_service c_hints ptr_ptr_addrs = do+    getaddrinfo c_node c_service c_hints ptr_ptr_addrs = mask $ \release -> do         ret <- c_getaddrinfo c_node c_service c_hints ptr_ptr_addrs         if ret == 0 then do             ptr_addrs <- peek ptr_ptr_addrs-            ais       <- followAddrInfo ptr_addrs+            ais       <- release (followAddrInfo ptr_addrs) `onException` c_freeaddrinfo ptr_addrs+            c_freeaddrinfo ptr_addrs             return ais           else do             err <- gai_strerror ret
Network/Socket/Shutdown.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE ScopedTypeVariables #-}  #include "HsNetDef.h" @@ -59,7 +60,8 @@         -- Sending TCP FIN.         ex <- E.try $ shutdown s ShutdownSend         case ex of-          Left (E.SomeException _) -> return ()+          -- Don't catch asynchronous exceptions+          Left (_ :: E.IOException) -> return ()           Right () -> do               -- Giving CPU time to other threads hoping that               -- FIN arrives meanwhile.@@ -93,29 +95,26 @@ recvEOFevent s tmout0 buf = do     tmmgr <- Ev.getSystemTimerManager     tvar <- newTVarIO False-    E.bracket (setup tmmgr tvar) teardown $ \(wait, _) -> do-        waitRes <- wait-        case waitRes of-          TimeoutTripped -> return ()-          -- We don't check the (positive) length.-          -- In normal case, it's 0. That is, only FIN is received.-          -- In error cases, data is available. But there is no-          -- application which can read it. So, let's stop receiving-          -- to prevent attacks.-          MoreData       -> void $ recvBufNoWait s buf bufSize+    E.bracket (setupTimeout tmmgr tvar) (cancelTimeout tmmgr) $ \_ -> do+        E.bracket (setupRead s) cancelRead $ \(rxWait,_) -> do+            let toWait = readTVar tvar >>= check+                wait = atomically ((toWait >> return TimeoutTripped)+                               <|> (rxWait >> return MoreData))+            waitRes <- wait+            case waitRes of+              TimeoutTripped -> return ()+              -- We don't check the (positive) length.+              -- In normal case, it's 0. That is, only FIN is received.+              -- In error cases, data is available. But there is no+              -- application which can read it. So, let's stop receiving+              -- to prevent attacks.+              MoreData       -> void $ recvBufNoWait s buf bufSize   where-    setup tmmgr tvar = do-        -- millisecond to microsecond-        key <- Ev.registerTimeout tmmgr (tmout0 * 1000) $-            atomically $ writeTVar tvar True-        (evWait, evCancel) <- waitAndCancelReadSocketSTM s-        let toWait = do-                tmout <- readTVar tvar-                check tmout-            toCancel = Ev.unregisterTimeout tmmgr key-            wait = atomically ((toWait >> return TimeoutTripped)-                           <|> (evWait >> return MoreData))-            cancel = evCancel >> toCancel-        return (wait, cancel)-    teardown (_, cancel) = cancel+    -- millisecond to microsecond+    tmout = tmout0 * 1000+    setupTimeout tmmgr tvar =+        Ev.registerTimeout tmmgr tmout $ atomically $ writeTVar tvar True+    cancelTimeout = Ev.unregisterTimeout+    setupRead = waitAndCancelReadSocketSTM+    cancelRead (_,cancel) = cancel #endif
Network/Socket/Syscall.hs view
@@ -11,6 +11,7 @@ #endif  #if defined(mingw32_HOST_OS)+import Control.Exception (bracket) import Foreign (FunPtr) import GHC.Conc (asyncDoProc) #else@@ -202,13 +203,12 @@                        throwSocketErrorIfMinus1Retry "Network.Socket.accept" $                          c_accept_safe fd sa ptr_len        | otherwise = do-             paramData <- c_newAcceptParams fd (fromIntegral sz) sa-             rc        <- asyncDoProc c_acceptDoProc paramData-             new_fd    <- c_acceptNewSock paramData-             c_free paramData-             when (rc /= 0) $-               throwSocketErrorCode "Network.Socket.accept" (fromIntegral rc)-             return new_fd+             bracket (c_newAcceptParams fd (fromIntegral sz) sa) c_free $ \paramData -> do+                 rc     <- asyncDoProc c_acceptDoProc paramData+                 new_fd <- c_acceptNewSock paramData+                 when (rc /= 0) $+                     throwSocketErrorCode "Network.Socket.accept" (fromIntegral rc)+                 return new_fd #else      callAccept fd sa sz = with (fromIntegral sz) $ \ ptr_len -> do # ifdef HAVE_ADVANCED_SOCKET_FLAGS
configure.ac view
@@ -1,5 +1,5 @@ AC_INIT([Haskell network package],-        [3.2.6.0],+        [3.2.7.0],         [libraries@haskell.org],         [network]) 
network.cabal view
@@ -1,6 +1,6 @@ cabal-version:      1.18 name:               network-version:            3.2.6.0+version:            3.2.7.0 license:            BSD3 license-file:       LICENSE maintainer:         Kazu Yamamoto, Tamar Christina